blob: f223b4543b37caaf7592c34f89764331807264fe [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302 * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wlan_hdd_hostapd.c
30 *
31 * WLAN Host Device Driver implementation
32 */
33
34/* Include Files */
35
36#include <linux/version.h>
37#include <linux/module.h>
38#include <linux/kernel.h>
39#include <linux/init.h>
40#include <linux/wireless.h>
41#include <linux/semaphore.h>
42#include <linux/compat.h>
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070043#include <cdp_txrx_stats.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080044#include <cds_api.h>
45#include <cds_sched.h>
46#include <linux/etherdevice.h>
47#include <wlan_hdd_includes.h>
48#include <qc_sap_ioctl.h>
49#include <wlan_hdd_hostapd.h>
50#include <sap_api.h>
51#include <sap_internal.h>
52#include <wlan_hdd_softap_tx_rx.h>
53#include <wlan_hdd_main.h>
54#include <wlan_hdd_ioctl.h>
55#include <wlan_hdd_stats.h>
56#include <linux/netdevice.h>
57#include <linux/rtnetlink.h>
58#include <linux/mmc/sdio_func.h>
59#include "wlan_hdd_p2p.h"
60#include <wlan_hdd_ipa.h>
61#include "cfg_api.h"
62#include "wni_cfg.h"
63#include "wlan_hdd_misc.h"
64#include <cds_utils.h>
Yuanyuan Liu13738502016-04-06 17:41:37 -070065#include "pld_common.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080066
67#include "wma.h"
Srinivas Girigowda6147c582016-10-18 12:26:15 -070068#ifdef WLAN_DEBUG
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080069#include "wma_api.h"
70#endif
71#include "wlan_hdd_trace.h"
Anurag Chouhan6d760662016-02-20 16:05:43 +053072#include "qdf_types.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053073#include "qdf_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080074#include "wlan_hdd_cfg.h"
75#include "cds_concurrency.h"
Manikandan Mohandcc21ba2016-03-15 14:31:56 -070076#include "wlan_hdd_tsf.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080077#include "wlan_hdd_green_ap.h"
Himanshu Agarwal11c874a2016-05-06 18:35:29 +053078#include "ol_rx_fwd.h"
Dustin Brownd95b96b2016-12-09 15:08:26 -080079#include "wlan_hdd_power.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080080
81#define IS_UP(_dev) \
82 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
83#define IS_UP_AUTO(_ic) \
84 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
85#define WE_WLAN_VERSION 1
86#define WE_GET_STA_INFO_SIZE 30
87/* WEXT limitation: MAX allowed buf len for any *
88 * IW_PRIV_TYPE_CHAR is 2Kbytes *
89 */
90#define WE_SAP_MAX_STA_INFO 0x7FF
91
92#define RC_2_RATE_IDX(_rc) ((_rc) & 0x7)
93#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1)
94#define RC_2_RATE_IDX_11AC(_rc) ((_rc) & 0xf)
95#define HT_RC_2_STREAMS_11AC(_rc) ((((_rc) & 0x30) >> 4) + 1)
96
97#define SAP_24GHZ_CH_COUNT (14)
98#define ACS_SCAN_EXPIRY_TIMEOUT_S 4
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080099
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800100
101/* Function definitions */
102
103/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700104 * hdd_sap_context_init() - Initialize SAP context.
105 * @hdd_ctx: HDD context.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800106 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700107 * Initialize SAP context.
108 *
109 * Return: 0 on success.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800110 */
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700111int hdd_sap_context_init(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800112{
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700113 qdf_wake_lock_create(&hdd_ctx->sap_dfs_wakelock, "sap_dfs_wakelock");
114 atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0);
115
116 mutex_init(&hdd_ctx->sap_lock);
117 qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock");
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +0530118 qdf_spinlock_create(&hdd_ctx->sap_update_info_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700119
Arif Hussain1969ec82016-07-08 10:37:01 -0700120 qdf_atomic_init(&hdd_ctx->dfs_radar_found);
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700121
122 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800123}
124
125/**
126 * hdd_hostapd_channel_allow_suspend() - allow suspend in a channel.
127 * Called when, 1. bss stopped, 2. channel switch
128 *
129 * @pAdapter: pointer to hdd adapter
130 * @channel: current channel
131 *
132 * Return: None
133 */
Jeff Johnsone4090f72016-10-05 16:00:23 -0700134static void hdd_hostapd_channel_allow_suspend(hdd_adapter_t *pAdapter,
135 uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800136{
137
138 hdd_context_t *pHddCtx = (hdd_context_t *) (pAdapter->pHddCtx);
139 hdd_hostapd_state_t *pHostapdState =
140 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
141
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700142 hdd_notice("bssState: %d, channel: %d, dfs_ref_cnt: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800143 pHostapdState->bssState, channel,
144 atomic_read(&pHddCtx->sap_dfs_ref_cnt));
145
146 /* Return if BSS is already stopped */
147 if (pHostapdState->bssState == BSS_STOP)
148 return;
149
Komal Seelam81cb1662016-09-29 12:39:08 +0530150 if (CHANNEL_STATE_DFS != cds_get_channel_state(channel))
151 return;
152
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800153 /* Release wakelock when no more DFS channels are used */
Komal Seelam81cb1662016-09-29 12:39:08 +0530154 if (atomic_dec_and_test(&pHddCtx->sap_dfs_ref_cnt)) {
155 hdd_err("DFS: allowing suspend (chan %d)", channel);
156 qdf_wake_lock_release(&pHddCtx->sap_dfs_wakelock,
157 WIFI_POWER_EVENT_WAKELOCK_DFS);
158 qdf_runtime_pm_allow_suspend(pHddCtx->runtime_context.dfs);
159
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800160 }
161}
162
163/**
164 * hdd_hostapd_channel_prevent_suspend() - prevent suspend in a channel.
165 * Called when, 1. bss started, 2. channel switch
166 *
167 * @pAdapter: pointer to hdd adapter
168 * @channel: current channel
169 *
170 * Return - None
171 */
Jeff Johnsone4090f72016-10-05 16:00:23 -0700172static void hdd_hostapd_channel_prevent_suspend(hdd_adapter_t *pAdapter,
173 uint8_t channel)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800174{
175 hdd_context_t *pHddCtx = (hdd_context_t *) (pAdapter->pHddCtx);
176 hdd_hostapd_state_t *pHostapdState =
177 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
178
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700179 hdd_notice("bssState: %d, channel: %d, dfs_ref_cnt: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800180 pHostapdState->bssState, channel,
181 atomic_read(&pHddCtx->sap_dfs_ref_cnt));
182
183 /* Return if BSS is already started && wakelock is acquired */
184 if ((pHostapdState->bssState == BSS_START) &&
185 (atomic_read(&pHddCtx->sap_dfs_ref_cnt) >= 1))
186 return;
187
Komal Seelam81cb1662016-09-29 12:39:08 +0530188 if (CHANNEL_STATE_DFS != cds_get_channel_state(channel))
189 return;
190
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800191 /* Acquire wakelock if we have at least one DFS channel in use */
Komal Seelam81cb1662016-09-29 12:39:08 +0530192 if (atomic_inc_return(&pHddCtx->sap_dfs_ref_cnt) == 1) {
193 hdd_err("DFS: preventing suspend (chan %d)", channel);
194 qdf_runtime_pm_prevent_suspend(pHddCtx->runtime_context.dfs);
195 qdf_wake_lock_acquire(&pHddCtx->sap_dfs_wakelock,
196 WIFI_POWER_EVENT_WAKELOCK_DFS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800197 }
198}
199
200/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700201 * hdd_sap_context_destroy() - Destroy SAP context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800202 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700203 * @hdd_ctx: HDD context.
204 *
205 * Destroy SAP context.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800206 *
207 * Return: None
208 */
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700209void hdd_sap_context_destroy(hdd_context_t *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800210{
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700211 if (atomic_read(&hdd_ctx->sap_dfs_ref_cnt)) {
212 qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800213 WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT);
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700214
215 atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0);
216 hdd_warn("DFS: Allowing suspend");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800217 }
218
Prashanth Bhatta527fd752016-04-28 12:35:23 -0700219 qdf_wake_lock_destroy(&hdd_ctx->sap_dfs_wakelock);
220
221 mutex_destroy(&hdd_ctx->sap_lock);
222 qdf_wake_lock_destroy(&hdd_ctx->sap_wake_lock);
223
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +0530224 qdf_spinlock_destroy(&hdd_ctx->sap_update_info_lock);
225
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800226}
227
228/**
229 * __hdd_hostapd_open() - hdd open function for hostapd interface
230 * This is called in response to ifconfig up
231 * @dev: pointer to net_device structure
232 *
233 * Return - 0 for success non-zero for failure
234 */
235static int __hdd_hostapd_open(struct net_device *dev)
236{
237 hdd_adapter_t *pAdapter = netdev_priv(dev);
Arunk Khandavalli702e1702016-12-06 18:01:55 +0530238 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
239 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800240
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800241 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800242
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530243 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800244 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
245
Arunk Khandavalli702e1702016-12-06 18:01:55 +0530246 ret = wlan_hdd_validate_context(hdd_ctx);
247 if (ret)
248 return ret;
249 /*
250 * Check statemachine state and also stop iface change timer if running
251 */
252 ret = hdd_wlan_start_modules(hdd_ctx, pAdapter, false);
253
254 if (ret) {
255 hdd_err("Failed to start WLAN modules return");
256 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800257 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800258
Arun Khandavalli97f28382016-09-09 17:36:50 +0530259 set_bit(DEVICE_IFACE_OPENED, &pAdapter->event_flags);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800260 /* Enable all Tx queues */
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700261 hdd_notice("Enabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800262 wlan_hdd_netif_queue_control(pAdapter,
263 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
264 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800265 EXIT();
266 return 0;
267}
268
269/**
270 * hdd_hostapd_open() - SSR wrapper for __hdd_hostapd_open
271 * @dev: pointer to net device
272 *
273 * Return: 0 on success, error number otherwise
274 */
275static int hdd_hostapd_open(struct net_device *dev)
276{
277 int ret;
278
279 cds_ssr_protect(__func__);
280 ret = __hdd_hostapd_open(dev);
281 cds_ssr_unprotect(__func__);
282
283 return ret;
284}
285
286/**
287 * __hdd_hostapd_stop() - hdd stop function for hostapd interface
288 * This is called in response to ifconfig down
289 *
290 * @dev: pointer to net_device structure
291 *
292 * Return - 0 for success non-zero for failure
293 */
294static int __hdd_hostapd_stop(struct net_device *dev)
295{
296 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800297
298 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800299
Arun Khandavalli97f28382016-09-09 17:36:50 +0530300 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800301 /* Stop all tx queues */
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700302 hdd_notice("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800303 wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
304 WLAN_CONTROL_PATH);
305
306 EXIT();
307 return 0;
308}
309
310/**
311 * hdd_hostapd_stop() - SSR wrapper for__hdd_hostapd_stop
312 * @dev: pointer to net_device
313 *
314 * This is called in response to ifconfig down
315 *
316 * Return: 0 on success, error number otherwise
317 */
318int hdd_hostapd_stop(struct net_device *dev)
319{
320 int ret;
321
322 cds_ssr_protect(__func__);
323 ret = __hdd_hostapd_stop(dev);
324 cds_ssr_unprotect(__func__);
325
326 return ret;
327}
328
329/**
330 * __hdd_hostapd_uninit() - hdd uninit function
331 * This is called during the netdev unregister to uninitialize all data
332 * associated with the device.
333 *
334 * @dev: pointer to net_device structure
335 *
336 * Return: None
337 */
338static void __hdd_hostapd_uninit(struct net_device *dev)
339{
340 hdd_adapter_t *adapter = netdev_priv(dev);
341 hdd_context_t *hdd_ctx;
342
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800343 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800344
345 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700346 hdd_err("Invalid magic");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800347 return;
348 }
349
350 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
351 if (NULL == hdd_ctx) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700352 hdd_err("NULL hdd_ctx");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800353 return;
354 }
355
356 hdd_deinit_adapter(hdd_ctx, adapter, true);
357
358 /* after uninit our adapter structure will no longer be valid */
359 adapter->dev = NULL;
360 adapter->magic = 0;
361
362 EXIT();
363}
364
365/**
366 * hdd_hostapd_uninit() - SSR wrapper for __hdd_hostapd_uninit
367 * @dev: pointer to net_device
368 *
369 * Return: 0 on success, error number otherwise
370 */
371static void hdd_hostapd_uninit(struct net_device *dev)
372{
373 cds_ssr_protect(__func__);
374 __hdd_hostapd_uninit(dev);
375 cds_ssr_unprotect(__func__);
376}
377
378/**
379 * __hdd_hostapd_change_mtu() - change mtu
380 * @dev: pointer to net_device
381 * @new_mtu: new mtu
382 *
383 * Return: 0 on success, error number otherwise
384 */
385static int __hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
386{
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800387 ENTER_DEV(dev);
388
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800389 return 0;
390}
391
392/**
393 * hdd_hostapd_change_mtu() - SSR wrapper for __hdd_hostapd_change_mtu
394 * @dev: pointer to net_device
395 * @new_mtu: new mtu
396 *
397 * Return: 0 on success, error number otherwise
398 */
399static int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
400{
401 int ret;
402
403 cds_ssr_protect(__func__);
404 ret = __hdd_hostapd_change_mtu(dev, new_mtu);
405 cds_ssr_unprotect(__func__);
406
407 return ret;
408}
409
410#ifdef QCA_HT_2040_COEX
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530411QDF_STATUS hdd_set_sap_ht2040_mode(hdd_adapter_t *pHostapdAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800412 uint8_t channel_type)
413{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530414 QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800415 void *hHal = NULL;
416
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700417 hdd_err("change HT20/40 mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800418
Krunal Soni056ea0f2016-03-10 13:07:10 -0800419 if (QDF_SAP_MODE == pHostapdAdapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800420 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
421 if (NULL == hHal) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700422 hdd_err("Hal ctx is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530423 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800424 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530425 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800426 sme_set_ht2040_mode(hHal, pHostapdAdapter->sessionId,
427 channel_type, true);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530428 if (qdf_ret_status == QDF_STATUS_E_FAILURE) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700429 hdd_err("Failed to change HT20/40 mode");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530430 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800431 }
432 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530433 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800434}
435#endif
436
437/**
438 * __hdd_hostapd_set_mac_address() -
439 * This function sets the user specified mac address using
440 * the command ifconfig wlanX hw ether <mac address>.
441 *
442 * @dev: pointer to the net device.
443 * @addr: pointer to the sockaddr.
444 *
445 * Return: 0 for success, non zero for failure
446 */
447static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
448{
449 struct sockaddr *psta_mac_addr = addr;
450 hdd_adapter_t *adapter;
451 hdd_context_t *hdd_ctx;
452 int ret = 0;
453
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800454 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800455
456 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
457 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
458 ret = wlan_hdd_validate_context(hdd_ctx);
459 if (0 != ret)
460 return ret;
461
462 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
463 EXIT();
464 return 0;
465}
466
467/**
468 * hdd_hostapd_set_mac_address() - set mac address
469 * @dev: pointer to net_device
470 * @addr: mac address
471 *
472 * Return: 0 on success, error number otherwise
473 */
474static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
475{
476 int ret;
477
478 cds_ssr_protect(__func__);
479 ret = __hdd_hostapd_set_mac_address(dev, addr);
480 cds_ssr_unprotect(__func__);
481
482 return ret;
483}
484
Jeff Johnsone4090f72016-10-05 16:00:23 -0700485/**
486 * hdd_hostapd_inactivity_timer_cb() - Inactivity timeout handler
487 * @context: Context registered with qdf_mc_timer_init()
488 *
489 * This is the callback function registered with qdf_mc_timer_init()
490 * to handle the AP inactivity timer. The @context registered is the
491 * struct net_device associated with the interface. When this
492 * function is called it means the AP inactivity timer has fired, and
493 * this function in turn indicates the timeout to userspace.
494 */
495
496static void hdd_hostapd_inactivity_timer_cb(void *context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800497{
Jeff Johnsone4090f72016-10-05 16:00:23 -0700498 struct net_device *dev = (struct net_device *)context;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800499 uint8_t we_custom_event[64];
500 union iwreq_data wrqu;
501#ifdef DISABLE_CONCURRENCY_AUTOSAVE
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530502 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800503 hdd_adapter_t *pHostapdAdapter;
504 hdd_ap_ctx_t *pHddApCtx;
505#endif /* DISABLE_CONCURRENCY_AUTOSAVE */
506
507 /* event_name space-delimiter driver_module_name
508 * Format of the event is "AUTO-SHUT.indication" " " "module_name"
509 */
510 char *autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
511
512 /* For the NULL at the end */
513 int event_len = strlen(autoShutEvent) + 1;
514
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800515 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800516
517#ifdef DISABLE_CONCURRENCY_AUTOSAVE
518 if (cds_concurrent_open_sessions_running()) {
519 /*
520 * This timer routine is going to be called only when AP
521 * persona is up.
522 * If there are concurrent sessions running we do not want
523 * to shut down the Bss.Instead we run the timer again so
524 * that if Autosave is enabled next time and other session
525 was down only then we bring down AP
526 */
527 pHostapdAdapter = netdev_priv(dev);
c_hpothud5009242016-08-18 12:10:36 +0530528 if (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic) {
529 hdd_err("invalid adapter: %p", pHostapdAdapter);
530 return;
531 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800532 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530533 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +0530534 qdf_mc_timer_start(&pHddApCtx->hdd_ap_inactivity_timer,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800535 (WLAN_HDD_GET_CTX(pHostapdAdapter))->
536 config->nAPAutoShutOff * 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530537 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700538 hdd_err("Failed to init AP inactivity timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800539 }
540 EXIT();
541 return;
542 }
543#endif /* DISABLE_CONCURRENCY_AUTOSAVE */
544 memset(&we_custom_event, '\0', sizeof(we_custom_event));
545 memcpy(&we_custom_event, autoShutEvent, event_len);
546
547 memset(&wrqu, 0, sizeof(wrqu));
548 wrqu.data.length = event_len;
549
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700550 hdd_notice("Shutting down AP interface due to inactivity");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800551 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
552
553 EXIT();
554}
555
Jeff Johnsone4090f72016-10-05 16:00:23 -0700556static void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter,
557 void *usrDataForCallback)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800558{
559 uint8_t staId = 0;
560 struct net_device *dev;
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +0530561 struct tagCsrDelStaParams del_sta_params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800562 dev = (struct net_device *)usrDataForCallback;
563
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700564 hdd_err("Clearing all the STA entry....");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800565 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) {
566 if (pHostapdAdapter->aStaInfo[staId].isUsed &&
567 (staId !=
568 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)) {
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +0530569 wlansap_populate_del_sta_params(
570 &pHostapdAdapter->aStaInfo[staId].macAddrSTA.
571 bytes[0], eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
572 (SIR_MAC_MGMT_DISASSOC >> 4), &del_sta_params);
573
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800574 /* Disconnect all the stations */
575 hdd_softap_sta_disassoc(pHostapdAdapter,
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +0530576 &del_sta_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800577 }
578 }
579}
580
581static int hdd_stop_bss_link(hdd_adapter_t *pHostapdAdapter,
582 void *usrDataForCallback)
583{
584 struct net_device *dev;
585 hdd_context_t *pHddCtx = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530586 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800587 dev = (struct net_device *)usrDataForCallback;
588 ENTER();
589
590 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
591 status = wlan_hdd_validate_context(pHddCtx);
592
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +0530593 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800594 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800595
596 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
Dustin Brown5118e8e2016-09-13 15:54:23 -0700597 status = wlansap_stop_bss(
598 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530599 if (QDF_IS_STATUS_SUCCESS(status))
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700600 hdd_err("Deleting SAP/P2P link!!!!!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800601
602 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -0800603 cds_decr_session_set_pcl(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800604 pHostapdAdapter->sessionId);
605 }
606 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530607 return (status == QDF_STATUS_SUCCESS) ? 0 : -EBUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800608}
609
610/**
611 * hdd_issue_stored_joinreq() - This function will trigger stations's
612 * cached connect request to proceed.
613 * @hdd_ctx: pointer to hdd context.
614 * @sta_adater: pointer to station adapter.
615 *
616 * This function will call SME to release station's stored/cached connect
617 * request to proceed.
618 *
619 * Return: none.
620 */
621static void hdd_issue_stored_joinreq(hdd_adapter_t *sta_adapter,
622 hdd_context_t *hdd_ctx)
623{
624 tHalHandle hal_handle;
625 uint32_t roam_id;
626
627 if (NULL == sta_adapter) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700628 hdd_err("Invalid station adapter, ignore issueing join req");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800629 return;
630 }
631 hal_handle = WLAN_HDD_GET_HAL_CTX(sta_adapter);
632
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800633 if (true == cds_is_sta_connection_pending()) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530634 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800635 TRACE_CODE_HDD_ISSUE_JOIN_REQ,
636 sta_adapter->sessionId, roam_id));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530637 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800638 sme_issue_stored_joinreq(hal_handle,
639 &roam_id,
640 sta_adapter->sessionId)) {
641 /* change back to NotAssociated */
642 hdd_conn_set_connection_state(sta_adapter,
643 eConnectionState_NotConnected);
644 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800645 cds_change_sta_conn_pending_status(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800646 }
647}
648
Wu Gao2c3a8002016-01-22 10:56:07 +0800649/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800650 * hdd_chan_change_notify() - Function to notify hostapd about channel change
651 * @hostapd_adapter hostapd adapter
652 * @dev: Net device structure
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +0530653 * @chan_change: New channel change parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800654 *
655 * This function is used to notify hostapd about the channel change
656 *
657 * Return: Success on intimating userspace
658 *
659 */
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +0530660QDF_STATUS hdd_chan_change_notify(hdd_adapter_t *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800661 struct net_device *dev,
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +0530662 struct hdd_chan_change_params chan_change)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800663{
664 struct ieee80211_channel *chan;
665 struct cfg80211_chan_def chandef;
666 enum nl80211_channel_type channel_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800667 uint32_t freq;
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +0530668 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800669
670 if (NULL == hal) {
671 hdd_err("hal is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530672 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800673 }
674
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +0530675 hdd_info("chan:%d width:%d sec_ch_offset:%d seg0:%d seg1:%d",
676 chan_change.chan, chan_change.chan_params.ch_width,
677 chan_change.chan_params.sec_ch_offset,
678 chan_change.chan_params.center_freq_seg0,
679 chan_change.chan_params.center_freq_seg1);
680
681 freq = cds_chan_to_freq(chan_change.chan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800682
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +0530683 chan = __ieee80211_get_channel(adapter->wdev.wiphy, freq);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800684
685 if (!chan) {
686 hdd_err("Invalid input frequency for channel conversion");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530687 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800688 }
689
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +0530690 switch (chan_change.chan_params.sec_ch_offset) {
691 case PHY_SINGLE_CHANNEL_CENTERED:
692 channel_type = NL80211_CHAN_HT20;
693 break;
694 case PHY_DOUBLE_CHANNEL_HIGH_PRIMARY:
695 channel_type = NL80211_CHAN_HT40MINUS;
696 break;
697 case PHY_DOUBLE_CHANNEL_LOW_PRIMARY:
698 channel_type = NL80211_CHAN_HT40PLUS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800699 break;
700 default:
701 channel_type = NL80211_CHAN_NO_HT;
702 break;
703 }
704
705 cfg80211_chandef_create(&chandef, chan, channel_type);
706
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +0530707 /* cfg80211_chandef_create() does update of width and center_freq1
708 * only for NL80211_CHAN_NO_HT, NL80211_CHAN_HT20, NL80211_CHAN_HT40PLUS
709 * and NL80211_CHAN_HT40MINUS.
710 */
711 if (chan_change.chan_params.ch_width == CH_WIDTH_80MHZ)
712 chandef.width = NL80211_CHAN_WIDTH_80;
713 else if (chan_change.chan_params.ch_width == CH_WIDTH_80P80MHZ)
714 chandef.width = NL80211_CHAN_WIDTH_80P80;
715 else if (chan_change.chan_params.ch_width == CH_WIDTH_160MHZ)
716 chandef.width = NL80211_CHAN_WIDTH_160;
717
718 if ((chan_change.chan_params.ch_width == CH_WIDTH_80MHZ) ||
719 (chan_change.chan_params.ch_width == CH_WIDTH_80P80MHZ) ||
720 (chan_change.chan_params.ch_width == CH_WIDTH_160MHZ)) {
721 if (chan_change.chan_params.center_freq_seg0)
722 chandef.center_freq1 = cds_chan_to_freq(
723 chan_change.chan_params.center_freq_seg0);
724
725 if (chan_change.chan_params.center_freq_seg1)
726 chandef.center_freq2 = cds_chan_to_freq(
727 chan_change.chan_params.center_freq_seg1);
728 }
729
730 hdd_info("notify: chan:%d width:%d freq1:%d freq2:%d",
731 chandef.chan->center_freq, chandef.width, chandef.center_freq1,
732 chandef.center_freq2);
Wu Gao2c3a8002016-01-22 10:56:07 +0800733
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800734 cfg80211_ch_switch_notify(dev, &chandef);
735
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530736 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800737}
738
739/**
740 * hdd_send_radar_event() - Function to send radar events to user space
741 * @hdd_context: HDD context
742 * @event: Type of radar event
743 * @dfs_info: Structure containing DFS channel and country
744 * @wdev: Wireless device structure
745 *
746 * This function is used to send radar events such as CAC start, CAC
747 * end etc., to userspace
748 *
749 * Return: Success on sending notifying userspace
750 *
751 */
Jeff Johnsone4090f72016-10-05 16:00:23 -0700752static QDF_STATUS hdd_send_radar_event(hdd_context_t *hdd_context,
753 eSapHddEvent event,
754 struct wlan_dfs_info dfs_info,
755 struct wireless_dev *wdev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756{
757
758 struct sk_buff *vendor_event;
759 enum qca_nl80211_vendor_subcmds_index index;
760 uint32_t freq, ret;
761 uint32_t data_size;
762
763 if (!hdd_context) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700764 hdd_err("HDD context is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530765 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800766 }
767
768 freq = cds_chan_to_freq(dfs_info.channel);
769
770 switch (event) {
771 case eSAP_DFS_CAC_START:
772 index =
773 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED_INDEX;
774 data_size = sizeof(uint32_t);
775 break;
776 case eSAP_DFS_CAC_END:
777 index =
778 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED_INDEX;
779 data_size = sizeof(uint32_t);
780 break;
781 case eSAP_DFS_RADAR_DETECT:
782 index =
783 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED_INDEX;
784 data_size = sizeof(uint32_t);
785 break;
786 default:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530787 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800788 }
789
790 vendor_event = cfg80211_vendor_event_alloc(hdd_context->wiphy,
791 wdev,
792 data_size + NLMSG_HDRLEN,
793 index,
794 GFP_KERNEL);
795 if (!vendor_event) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700796 hdd_err("cfg80211_vendor_event_alloc failed for %d", index);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530797 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800798 }
799
800 ret = nla_put_u32(vendor_event, NL80211_ATTR_WIPHY_FREQ, freq);
801
802 if (ret) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -0700803 hdd_err("NL80211_ATTR_WIPHY_FREQ put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800804 kfree_skb(vendor_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530805 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800806 }
807
808 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530809 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800810}
811
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +0530812/**
813 * hdd_send_conditional_chan_switch_status() - Send conditional channel switch
814 * status
815 * @hdd_ctx: HDD context
816 * @wdev: Wireless device structure
817 * @status: Status of conditional channel switch
818 * (0: Success, Non-zero: Failure)
819 *
820 * Sends the status of conditional channel switch to user space. This is named
821 * conditional channel switch because the SAP will move to the provided channel
822 * after some condition (pre-cac) is met.
823 *
824 * Return: None
825 */
826static void hdd_send_conditional_chan_switch_status(hdd_context_t *hdd_ctx,
827 struct wireless_dev *wdev,
828 bool status)
829{
830 struct sk_buff *event;
831
832 ENTER_DEV(wdev->netdev);
833
834 if (!hdd_ctx) {
835 hdd_err("Invalid HDD context pointer");
836 return;
837 }
838
839 event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
840 wdev, sizeof(uint32_t) + NLMSG_HDRLEN,
841 QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH_INDEX,
842 GFP_KERNEL);
843 if (!event) {
844 hdd_err("cfg80211_vendor_event_alloc failed");
845 return;
846 }
847
848 if (nla_put_u32(event,
849 QCA_WLAN_VENDOR_ATTR_SAP_CONDITIONAL_CHAN_SWITCH_STATUS,
850 status)) {
851 hdd_err("nla put failed");
852 kfree_skb(event);
853 return;
854 }
855
856 cfg80211_vendor_event(event, GFP_KERNEL);
857}
858
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +0530859/**
860 * wlan_hdd_set_pre_cac_complete_status() - Set pre cac complete status
861 * @ap_adapter: AP adapter
862 * @status: Status which can be true or false
863 *
864 * Sets the status of pre cac i.e., whether it is complete or not
865 *
866 * Return: Zero on success, non-zero on failure
867 */
868static int wlan_hdd_set_pre_cac_complete_status(hdd_adapter_t *ap_adapter,
869 bool status)
870{
871 QDF_STATUS ret;
872
873 ret = wlan_sap_set_pre_cac_complete_status(
874 WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter), status);
875 if (QDF_IS_STATUS_ERROR(ret))
876 return -EINVAL;
877
878 return 0;
879}
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +0530880
881/**
882 * wlan_hdd_sap_pre_cac_failure() - Process the pre cac failure
883 * @data: AP adapter
884 *
885 * Deletes the pre cac adapter
886 *
887 * Return: None
888 */
889void wlan_hdd_sap_pre_cac_failure(void *data)
890{
891 hdd_adapter_t *pHostapdAdapter;
892 hdd_context_t *hdd_ctx;
893
894 ENTER();
895
896 pHostapdAdapter = (hdd_adapter_t *) data;
897 if (!pHostapdAdapter) {
898 hdd_err("AP adapter is NULL");
899 return;
900 }
901
902 hdd_ctx = (hdd_context_t *) (pHostapdAdapter->pHddCtx);
903 if (!hdd_ctx) {
904 hdd_err("HDD context is null");
905 return;
906 }
907
908 cds_ssr_protect(__func__);
Krunal Sonib37bb352016-12-20 14:12:21 -0800909 wlan_hdd_release_intf_addr(hdd_ctx,
910 pHostapdAdapter->macAddressCurrent.bytes);
Manishekar Chandrasekarandfdf2a82016-08-24 16:16:16 +0530911 hdd_stop_adapter(hdd_ctx, pHostapdAdapter, true);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +0530912 hdd_close_adapter(hdd_ctx, pHostapdAdapter, false);
913 cds_ssr_unprotect(__func__);
914}
915
916
917/**
918 * wlan_hdd_sap_pre_cac_success() - Process the pre cac result
919 * @data: AP adapter
920 *
921 * Deletes the pre cac adapter and moves the existing SAP to the pre cac
922 * channel
923 *
924 * Return: None
925 */
926static void wlan_hdd_sap_pre_cac_success(void *data)
927{
928 hdd_adapter_t *pHostapdAdapter, *ap_adapter;
929 int i;
930 hdd_context_t *hdd_ctx;
931
932 ENTER();
933
934 pHostapdAdapter = (hdd_adapter_t *) data;
935 if (!pHostapdAdapter) {
936 hdd_err("AP adapter is NULL");
937 return;
938 }
939
940 hdd_ctx = (hdd_context_t *) (pHostapdAdapter->pHddCtx);
941 if (!hdd_ctx) {
942 hdd_err("HDD context is null");
943 return;
944 }
945
946 cds_ssr_protect(__func__);
Krunal Soni38152c92017-01-06 11:05:43 -0800947 wlan_hdd_release_intf_addr(hdd_ctx,
948 pHostapdAdapter->macAddressCurrent.bytes);
Manishekar Chandrasekarandfdf2a82016-08-24 16:16:16 +0530949 hdd_stop_adapter(hdd_ctx, pHostapdAdapter, true);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +0530950 hdd_close_adapter(hdd_ctx, pHostapdAdapter, false);
951 cds_ssr_unprotect(__func__);
952
953 /* Prepare to switch AP from 2.4GHz channel to the pre CAC channel */
954 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
955 if (!ap_adapter) {
956 hdd_err("failed to get SAP adapter, no restart on pre CAC channel");
957 return;
958 }
959
960 /*
961 * Setting of the pre cac complete status will ensure that on channel
962 * switch to the pre CAC DFS channel, there is no CAC again.
963 */
964 wlan_hdd_set_pre_cac_complete_status(ap_adapter, true);
965 i = hdd_softap_set_channel_change(ap_adapter->dev,
966 ap_adapter->pre_cac_chan,
967 CH_WIDTH_MAX);
968 if (0 != i) {
969 hdd_err("failed to change channel");
970 wlan_hdd_set_pre_cac_complete_status(ap_adapter, false);
971 }
972}
973
Liangwei Dongaef84342016-10-21 05:28:00 -0400974#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
975/**
976 * hdd_handle_acs_scan_event() - handle acs scan event for SAP
977 * @sap_event: tpSap_Event
978 * @adapter: hdd_adapter_t for SAP
979 *
980 * The function is to handle the eSAP_ACS_SCAN_SUCCESS_EVENT event.
981 * It will update scan result to cfg80211 and start a timer to flush the
982 * cached acs scan result.
983 *
984 * Return: QDF_STATUS_SUCCESS on success,
985 * other value on failure
986 */
987static QDF_STATUS hdd_handle_acs_scan_event(tpSap_Event sap_event,
988 hdd_adapter_t *adapter)
989{
990 hdd_context_t *hdd_ctx;
991 struct sap_acs_scan_complete_event *comp_evt;
992 QDF_STATUS qdf_status;
993 int chan_list_size;
994
995 hdd_ctx = (hdd_context_t *)(adapter->pHddCtx);
996 if (!hdd_ctx) {
997 hdd_err("HDD context is null");
998 return QDF_STATUS_E_FAILURE;
999 }
1000 comp_evt = &sap_event->sapevt.sap_acs_scan_comp;
1001 hdd_ctx->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN;
1002 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
1003 qdf_mem_free(hdd_ctx->last_acs_channel_list);
1004 hdd_ctx->last_acs_channel_list = NULL;
1005 hdd_ctx->num_of_channels = 0;
1006 /* cache the previous ACS scan channel list .
1007 * If the following OBSS scan chan list is covered by ACS chan list,
1008 * we can skip OBSS Scan to save SAP starting total time.
1009 */
1010 if (comp_evt->num_of_channels && comp_evt->channellist) {
1011 chan_list_size = comp_evt->num_of_channels *
1012 sizeof(comp_evt->channellist[0]);
1013 hdd_ctx->last_acs_channel_list = qdf_mem_malloc(
1014 chan_list_size);
1015 if (hdd_ctx->last_acs_channel_list) {
1016 qdf_mem_copy(hdd_ctx->last_acs_channel_list,
1017 comp_evt->channellist,
1018 chan_list_size);
1019 hdd_ctx->num_of_channels = comp_evt->num_of_channels;
1020 }
1021 }
1022 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
1023 /* Update ACS scan result to cfg80211. Then OBSS scan can reuse the
1024 * scan result.
1025 */
1026 if (wlan_hdd_cfg80211_update_bss(hdd_ctx->wiphy, adapter, 0))
1027 hdd_info("NO SCAN result");
1028
1029 hdd_info("Reusing Last ACS scan result for %d sec",
1030 ACS_SCAN_EXPIRY_TIMEOUT_S);
1031 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
1032 qdf_status = qdf_mc_timer_start(&hdd_ctx->skip_acs_scan_timer,
1033 ACS_SCAN_EXPIRY_TIMEOUT_S * 1000);
1034 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
1035 hdd_err("Failed to start ACS scan expiry timer");
1036 return QDF_STATUS_SUCCESS;
1037}
1038#else
1039static QDF_STATUS hdd_handle_acs_scan_event(tpSap_Event sap_event,
1040 hdd_adapter_t *adapter)
1041{
1042 return QDF_STATUS_SUCCESS;
1043}
1044#endif
1045
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301046QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001047 void *usrDataForCallback)
1048{
1049 hdd_adapter_t *pHostapdAdapter;
1050 hdd_ap_ctx_t *pHddApCtx;
1051 hdd_hostapd_state_t *pHostapdState;
1052 struct net_device *dev;
1053 eSapHddEvent sapEvent;
1054 union iwreq_data wrqu;
1055 uint8_t *we_custom_event_generic = NULL;
1056 int we_event = 0;
1057 int i = 0;
1058 uint8_t staId;
Anurag Chouhance0dc992016-02-16 18:18:03 +05301059 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001060 bool bWPSState;
1061 bool bAuthRequired = true;
1062 tpSap_AssocMacAddr pAssocStasArray = NULL;
1063 char unknownSTAEvent[IW_CUSTOM_MAX + 1];
1064 char maxAssocExceededEvent[IW_CUSTOM_MAX + 1];
1065 uint8_t we_custom_start_event[64];
1066 char *startBssEvent;
1067 hdd_context_t *pHddCtx;
1068 hdd_scaninfo_t *pScanInfo = NULL;
1069 struct iw_michaelmicfailure msg;
1070 uint8_t ignoreCAC = 0;
1071 struct hdd_config *cfg = NULL;
1072 struct wlan_dfs_info dfs_info;
1073 uint8_t cc_len = WLAN_SVC_COUNTRY_CODE_LEN;
1074 hdd_adapter_t *con_sap_adapter;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301075 QDF_STATUS status = QDF_STATUS_SUCCESS;
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05301076 struct hdd_chan_change_params chan_change;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001077 int ret = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001078
1079 dev = (struct net_device *)usrDataForCallback;
1080 if (!dev) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001081 hdd_err("usrDataForCallback is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301082 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001083 }
1084
1085 pHostapdAdapter = netdev_priv(dev);
1086
1087 if ((NULL == pHostapdAdapter) ||
1088 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001089 hdd_err("invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301090 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001091 }
1092
1093 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1094 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
1095
1096 if (!pSapEvent) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001097 hdd_err("pSapEvent is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301098 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001099 }
1100
1101 sapEvent = pSapEvent->sapHddEventCode;
1102 memset(&wrqu, '\0', sizeof(wrqu));
1103 pHddCtx = (hdd_context_t *) (pHostapdAdapter->pHddCtx);
1104
1105 if (!pHddCtx) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001106 hdd_err("HDD context is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301107 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001108 }
1109
1110 cfg = pHddCtx->config;
1111
1112 if (!cfg) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001113 hdd_err("HDD config is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301114 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001115 }
1116
1117 dfs_info.channel = pHddApCtx->operatingChannel;
1118 sme_get_country_code(pHddCtx->hHal, dfs_info.country_code, &cc_len);
1119
1120 switch (sapEvent) {
1121 case eSAP_START_BSS_EVENT:
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001122 hdd_notice("BSS status = %s, channel = %u, bc sta Id = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001123 pSapEvent->sapevt.sapStartBssCompleteEvent.
1124 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
1125 pSapEvent->sapevt.sapStartBssCompleteEvent.
1126 operatingChannel,
1127 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
1128
1129 pHostapdAdapter->sessionId =
1130 pSapEvent->sapevt.sapStartBssCompleteEvent.sessionId;
1131
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301132 pHostapdState->qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001133 pSapEvent->sapevt.sapStartBssCompleteEvent.status;
Krunal Soni35fc8ea2016-10-26 18:52:38 -07001134 if (pHostapdState->qdf_status) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001135 hdd_err("ERROR: startbss event failed!!");
Krunal Soni35fc8ea2016-10-26 18:52:38 -07001136 /*
1137 * Make sure to set the event before proceeding
1138 * for error handling otherwise caller thread will
1139 * wait till 10 secs and no other connection will
1140 * go through before that.
1141 */
Krunal Sonib37bb352016-12-20 14:12:21 -08001142 pHostapdState->bssState = BSS_STOP;
Krunal Soni35fc8ea2016-10-26 18:52:38 -07001143 qdf_event_set(&pHostapdState->qdf_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001144 goto stopbss;
1145 } else {
1146 sme_ch_avoid_update_req(pHddCtx->hHal);
1147
1148 pHddApCtx->uBCStaId =
1149 pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
1150
1151 hdd_register_tx_flow_control(pHostapdAdapter,
1152 hdd_softap_tx_resume_timer_expired_handler,
1153 hdd_softap_tx_resume_cb);
1154
1155 /* @@@ need wep logic here to set privacy bit */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301156 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001157 hdd_softap_register_bc_sta(pHostapdAdapter,
1158 pHddApCtx->uPrivacy);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301159 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001160 hdd_warn("Failed to register BC STA %d",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301161 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001162 hdd_stop_bss_link(pHostapdAdapter,
1163 usrDataForCallback);
1164 }
1165 }
1166
1167 if (hdd_ipa_is_enabled(pHddCtx)) {
1168 status = hdd_ipa_wlan_evt(pHostapdAdapter,
1169 pHddApCtx->uBCStaId,
Mohit Khannafa99aea2016-05-12 21:43:13 -07001170 HDD_IPA_AP_CONNECT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001171 pHostapdAdapter->dev->dev_addr);
1172 if (status) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001173 hdd_err("WLAN_AP_CONNECT event failed!!");
Krunal Soni35fc8ea2016-10-26 18:52:38 -07001174 /*
1175 * Make sure to set the event before proceeding
1176 * for error handling otherwise caller thread
1177 * will wait till 10 secs and no other
1178 * connection will go through before that.
1179 */
1180 qdf_event_set(&pHostapdState->qdf_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001181 goto stopbss;
1182 }
1183 }
1184
1185 if (0 !=
1186 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
1187 nAPAutoShutOff) {
1188 /* AP Inactivity timer init and start */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301189 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05301190 qdf_mc_timer_init(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001191 hdd_ap_inactivity_timer,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301192 QDF_TIMER_TYPE_SW,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001193 hdd_hostapd_inactivity_timer_cb,
1194 dev);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301195 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001196 hdd_err("Failed to init inactivity timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001197
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301198 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05301199 qdf_mc_timer_start(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001200 hdd_ap_inactivity_timer,
1201 (WLAN_HDD_GET_CTX
1202 (pHostapdAdapter))->config->
1203 nAPAutoShutOff * 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301204 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001205 hdd_err("Failed to init inactivity timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001206
1207 }
1208#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1209 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1210#endif
1211 pHddApCtx->operatingChannel =
1212 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
1213
1214 hdd_hostapd_channel_prevent_suspend(pHostapdAdapter,
1215 pHddApCtx->
1216 operatingChannel);
1217
1218 pHostapdState->bssState = BSS_START;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001219
Kondabattini, Ganesh702d90e2016-09-03 01:54:22 +05301220 /* Set default key index */
1221 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO,
1222 "%s: default key index %hu", __func__,
1223 pHddApCtx->wep_def_key_idx);
1224
1225 sme_roam_set_default_key_index(
1226 WLAN_HDD_GET_HAL_CTX(pHostapdAdapter),
1227 pHostapdAdapter->sessionId,
1228 pHddApCtx->wep_def_key_idx);
1229
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001230 /* Set group key / WEP key every time when BSS is restarted */
1231 if (pHddApCtx->groupKey.keyLength) {
1232 status = wlansap_set_key_sta(
Dustin Brown5118e8e2016-09-13 15:54:23 -07001233 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001234 &pHddApCtx->groupKey);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301235 if (!QDF_IS_STATUS_SUCCESS(status))
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001236 hdd_err("wlansap_set_key_sta failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001237 } else {
1238 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
1239 if (!pHddApCtx->wepKey[i].keyLength)
1240 continue;
1241
1242 status = wlansap_set_key_sta(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001243 WLAN_HDD_GET_SAP_CTX_PTR
1244 (pHostapdAdapter),
Dustin Brown5118e8e2016-09-13 15:54:23 -07001245 &pHddApCtx->wepKey[i]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301246 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001247 hdd_err("set_key failed idx %d", i);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001248 }
1249 }
1250 }
1251
Arif Hussain1969ec82016-07-08 10:37:01 -07001252 qdf_atomic_set(&pHddCtx->dfs_radar_found, 0);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301253
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001254 wlansap_get_dfs_ignore_cac(pHddCtx->hHal, &ignoreCAC);
1255
1256 /* DFS requirement: DO NOT transmit during CAC. */
1257 if ((CHANNEL_STATE_DFS !=
1258 cds_get_channel_state(pHddApCtx->operatingChannel))
1259 || ignoreCAC
1260 || pHddCtx->dev_dfs_cac_status == DFS_CAC_ALREADY_DONE)
1261 pHddApCtx->dfs_cac_block_tx = false;
1262 else
1263 pHddApCtx->dfs_cac_block_tx = true;
1264
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301265 hdd_info("The value of dfs_cac_block_tx[%d] for ApCtx[%p]:%d",
1266 pHddApCtx->dfs_cac_block_tx, pHddApCtx,
1267 pHostapdAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001268
1269 if ((CHANNEL_STATE_DFS ==
1270 cds_get_channel_state(pHddApCtx->operatingChannel))
1271 && (pHddCtx->config->IsSapDfsChSifsBurstEnabled == 0)) {
1272
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001273 hdd_notice("Set SIFS Burst disable for DFS channel %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001274 pHddApCtx->operatingChannel);
1275
1276 if (wma_cli_set_command(pHostapdAdapter->sessionId,
1277 WMI_PDEV_PARAM_BURST_ENABLE,
1278 0, PDEV_CMD)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001279 hdd_err("Failed to Set SIFS Burst %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001280 pHddApCtx->operatingChannel);
1281 }
1282 }
1283 /* Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled */
1284 startBssEvent = "SOFTAP.enabled";
1285 memset(&we_custom_start_event, '\0',
1286 sizeof(we_custom_start_event));
1287 memcpy(&we_custom_start_event, startBssEvent,
1288 strlen(startBssEvent));
1289 memset(&wrqu, 0, sizeof(wrqu));
1290 wrqu.data.length = strlen(startBssEvent);
1291 we_event = IWEVCUSTOM;
1292 we_custom_event_generic = we_custom_start_event;
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001293 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001294 /* Send SCC/MCC Switching event to IPA */
1295 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05301296
1297 if (cds_is_hw_mode_change_after_vdev_up()) {
1298 hdd_info("check for possible hw mode change");
1299 status = cds_set_hw_mode_on_channel_switch(
1300 pHostapdAdapter->sessionId);
1301 if (QDF_IS_STATUS_ERROR(status))
1302 hdd_info("set hw mode change not done");
1303 cds_set_do_hw_mode_change_flag(false);
1304 }
Krunal Soni35fc8ea2016-10-26 18:52:38 -07001305 /*
1306 * set this event at the very end because once this events
1307 * get set, caller thread is waiting to do further processing.
1308 * so once this event gets set, current worker thread might get
1309 * pre-empted by caller thread.
1310 */
1311 qdf_status = qdf_event_set(&pHostapdState->qdf_event);
1312 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
1313 hdd_err("ERROR: startbss event set failed!!");
1314 goto stopbss;
1315 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001316 break; /* Event will be sent after Switch-Case stmt */
1317
1318 case eSAP_STOP_BSS_EVENT:
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001319 hdd_notice("BSS stop status = %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001320 pSapEvent->sapevt.sapStopBssCompleteEvent.
1321 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1322
1323 hdd_hostapd_channel_allow_suspend(pHostapdAdapter,
1324 pHddApCtx->operatingChannel);
1325
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001326 /* Free up Channel List incase if it is set */
Dustin Brown5118e8e2016-09-13 15:54:23 -07001327 sap_cleanup_channel_list(
1328 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
1329
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001330 /* Invalidate the channel info. */
1331 pHddApCtx->operatingChannel = 0;
1332 if (hdd_ipa_is_enabled(pHddCtx)) {
1333 status = hdd_ipa_wlan_evt(pHostapdAdapter,
1334 pHddApCtx->uBCStaId,
Mohit Khannafa99aea2016-05-12 21:43:13 -07001335 HDD_IPA_AP_DISCONNECT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001336 pHostapdAdapter->dev->dev_addr);
1337 if (status) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001338 hdd_err("WLAN_AP_DISCONNECT event failed!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001339 goto stopbss;
1340 }
1341 }
1342
1343 /* reset the dfs_cac_status and dfs_cac_block_tx flag only when
1344 * the last BSS is stopped
1345 */
1346 con_sap_adapter = hdd_get_con_sap_adapter(pHostapdAdapter, true);
1347 if (!con_sap_adapter) {
1348 pHddApCtx->dfs_cac_block_tx = true;
1349 pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
1350 }
1351 if (pHddCtx->config->conc_custom_rule2 &&
Krunal Soni056ea0f2016-03-10 13:07:10 -08001352 (QDF_P2P_GO_MODE == pHostapdAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001353 hdd_adapter_t *sta_adapter = hdd_get_adapter(pHddCtx,
Krunal Soni056ea0f2016-03-10 13:07:10 -08001354 QDF_STA_MODE);
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001355 hdd_info("P2PGO is going down now");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001356 hdd_issue_stored_joinreq(sta_adapter, pHddCtx);
1357 }
wadesong6d04e322016-10-10 18:22:31 +08001358 pHddApCtx->groupKey.keyLength = 0;
1359 for (i = 0; i < CSR_MAX_NUM_KEY; i++)
1360 pHddApCtx->wepKey[i].keyLength = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001361 goto stopbss;
1362
1363 case eSAP_DFS_CAC_START:
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05301364 wlan_hdd_send_svc_nlink_msg(pHddCtx->radio_index,
1365 WLAN_SVC_DFS_CAC_START_IND,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001366 &dfs_info,
1367 sizeof(struct wlan_dfs_info));
1368 pHddCtx->dev_dfs_cac_status = DFS_CAC_IN_PROGRESS;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301369 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001370 hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_START,
1371 dfs_info, &pHostapdAdapter->wdev)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001372 hdd_err("Unable to indicate CAC start NL event");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001373 } else {
1374 hdd_info("Sent CAC start to user space");
1375 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301376
Arif Hussain1969ec82016-07-08 10:37:01 -07001377 qdf_atomic_set(&pHddCtx->dfs_radar_found, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001378 break;
1379 case eSAP_DFS_CAC_INTERRUPTED:
1380 /*
1381 * The CAC timer did not run completely and a radar was detected
1382 * during the CAC time. This new state will keep the tx path
1383 * blocked since we do not want any transmission on the DFS
1384 * channel. CAC end will only be reported here since the user
1385 * space applications are waiting on CAC end for their state
1386 * management.
1387 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301388 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001389 hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_END,
1390 dfs_info, &pHostapdAdapter->wdev)) {
1391 hdd_err("Unable to indicate CAC end (interrupted) event");
1392 } else {
1393 hdd_info("Sent CAC end (interrupted) to user space");
1394 }
1395 break;
1396 case eSAP_DFS_CAC_END:
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05301397 wlan_hdd_send_svc_nlink_msg(pHddCtx->radio_index,
1398 WLAN_SVC_DFS_CAC_END_IND,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001399 &dfs_info,
1400 sizeof(struct wlan_dfs_info));
1401 pHddApCtx->dfs_cac_block_tx = false;
1402 pHddCtx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301403 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001404 hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_END,
1405 dfs_info, &pHostapdAdapter->wdev)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001406 hdd_err("Unable to indicate CAC end NL event");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001407 } else {
1408 hdd_info("Sent CAC end to user space");
1409 }
1410 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001411 case eSAP_DFS_RADAR_DETECT:
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05301412 wlan_hdd_send_svc_nlink_msg(pHddCtx->radio_index,
1413 WLAN_SVC_DFS_RADAR_DETECT_IND,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001414 &dfs_info,
1415 sizeof(struct wlan_dfs_info));
1416 pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301417 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001418 hdd_send_radar_event(pHddCtx, eSAP_DFS_RADAR_DETECT,
1419 dfs_info, &pHostapdAdapter->wdev)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001420 hdd_err("Unable to indicate Radar detect NL event");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001421 } else {
1422 hdd_info("Sent radar detected to user space");
1423 }
1424 break;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301425 case eSAP_DFS_RADAR_DETECT_DURING_PRE_CAC:
1426 hdd_debug("notification for radar detect during pre cac:%d",
1427 pHostapdAdapter->sessionId);
1428 hdd_send_conditional_chan_switch_status(pHddCtx,
1429 &pHostapdAdapter->wdev, false);
1430 pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
1431 qdf_create_work(0, &pHddCtx->sap_pre_cac_work,
1432 wlan_hdd_sap_pre_cac_failure,
1433 (void *)pHostapdAdapter);
1434 qdf_sched_work(0, &pHddCtx->sap_pre_cac_work);
1435 break;
1436 case eSAP_DFS_PRE_CAC_END:
1437 hdd_debug("pre cac end notification received:%d",
1438 pHostapdAdapter->sessionId);
1439 hdd_send_conditional_chan_switch_status(pHddCtx,
1440 &pHostapdAdapter->wdev, true);
1441 pHddApCtx->dfs_cac_block_tx = false;
1442 pHddCtx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001443
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301444 qdf_create_work(0, &pHddCtx->sap_pre_cac_work,
1445 wlan_hdd_sap_pre_cac_success,
1446 (void *)pHostapdAdapter);
1447 qdf_sched_work(0, &pHddCtx->sap_pre_cac_work);
1448 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001449 case eSAP_DFS_NO_AVAILABLE_CHANNEL:
1450 wlan_hdd_send_svc_nlink_msg
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +05301451 (pHddCtx->radio_index,
1452 WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND, &dfs_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001453 sizeof(struct wlan_dfs_info));
1454 break;
1455
1456 case eSAP_STA_SET_KEY_EVENT:
1457 /* TODO:
1458 * forward the message to hostapd once implementation
1459 * is done for now just print
1460 */
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001461 hdd_notice("SET Key: configured status = %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001462 pSapEvent->sapevt.sapStationSetKeyCompleteEvent.
1463 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301464 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001465 case eSAP_STA_MIC_FAILURE_EVENT:
1466 {
1467 memset(&msg, '\0', sizeof(msg));
1468 msg.src_addr.sa_family = ARPHRD_ETHER;
1469 memcpy(msg.src_addr.sa_data,
1470 &pSapEvent->sapevt.sapStationMICFailureEvent.
Anurag Chouhan6d760662016-02-20 16:05:43 +05301471 staMac, QDF_MAC_ADDR_SIZE);
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001472 hdd_notice("MIC MAC " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001473 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
1474 if (pSapEvent->sapevt.sapStationMICFailureEvent.
1475 multicast == eSAP_TRUE)
1476 msg.flags = IW_MICFAILURE_GROUP;
1477 else
1478 msg.flags = IW_MICFAILURE_PAIRWISE;
1479 memset(&wrqu, 0, sizeof(wrqu));
1480 wrqu.data.length = sizeof(msg);
1481 we_event = IWEVMICHAELMICFAILURE;
1482 we_custom_event_generic = (uint8_t *) &msg;
1483 }
1484 /* inform mic failure to nl80211 */
1485 cfg80211_michael_mic_failure(dev,
1486 pSapEvent->
1487 sapevt.sapStationMICFailureEvent.
1488 staMac.bytes,
1489 ((pSapEvent->sapevt.
1490 sapStationMICFailureEvent.
1491 multicast ==
1492 eSAP_TRUE) ?
1493 NL80211_KEYTYPE_GROUP :
1494 NL80211_KEYTYPE_PAIRWISE),
1495 pSapEvent->sapevt.
1496 sapStationMICFailureEvent.keyId,
1497 pSapEvent->sapevt.
1498 sapStationMICFailureEvent.TSC,
1499 GFP_KERNEL);
1500 break;
1501
1502 case eSAP_STA_ASSOC_EVENT:
1503 case eSAP_STA_REASSOC_EVENT:
1504 wrqu.addr.sa_family = ARPHRD_ETHER;
1505 memcpy(wrqu.addr.sa_data,
1506 &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.
Anurag Chouhan6d760662016-02-20 16:05:43 +05301507 staMac, QDF_MAC_ADDR_SIZE);
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001508 hdd_notice(" associated " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001509 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1510 we_event = IWEVREGISTERED;
1511
Dustin Brown5118e8e2016-09-13 15:54:23 -07001512 wlansap_get_wps_state(
1513 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
1514 &bWPSState);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001515
1516 if ((eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
1517 (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
1518 pHddApCtx->ucEncryptType)
1519 || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
1520 pHddApCtx->ucEncryptType)) {
1521 bAuthRequired = false;
1522 }
1523
1524 if (bAuthRequired || bWPSState == true) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301525 qdf_status = hdd_softap_register_sta(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001526 pHostapdAdapter,
1527 true,
1528 pHddApCtx->uPrivacy,
1529 pSapEvent->sapevt.
1530 sapStationAssocReassocCompleteEvent.
1531 staId, 0, 0,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301532 (struct qdf_mac_addr *)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001533 wrqu.addr.sa_data,
1534 pSapEvent->sapevt.
1535 sapStationAssocReassocCompleteEvent.
1536 wmmEnabled);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301537 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001538 hdd_warn("Failed to register STA %d "
1539 MAC_ADDRESS_STR "", qdf_status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001540 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1541 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301542 qdf_status = hdd_softap_register_sta(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001543 pHostapdAdapter,
1544 false,
1545 pHddApCtx->uPrivacy,
1546 pSapEvent->sapevt.
1547 sapStationAssocReassocCompleteEvent.
1548 staId, 0, 0,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301549 (struct qdf_mac_addr *)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001550 wrqu.addr.sa_data,
1551 pSapEvent->sapevt.
1552 sapStationAssocReassocCompleteEvent.
1553 wmmEnabled);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301554 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001555 hdd_warn("Failed to register STA %d "
1556 MAC_ADDRESS_STR "", qdf_status,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1558 }
1559
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05301560 staId =
1561 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301562 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05301563 pHostapdAdapter->aStaInfo[staId].nss =
1564 pSapEvent->sapevt.
1565 sapStationAssocReassocCompleteEvent.
1566 chan_info.nss;
1567 pHostapdAdapter->aStaInfo[staId].rate_flags =
1568 pSapEvent->sapevt.
1569 sapStationAssocReassocCompleteEvent.
1570 chan_info.rate_flags;
1571 }
1572
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001573 if (hdd_ipa_is_enabled(pHddCtx)) {
1574 status = hdd_ipa_wlan_evt(pHostapdAdapter,
1575 pSapEvent->sapevt.
1576 sapStationAssocReassocCompleteEvent.
Mohit Khannafa99aea2016-05-12 21:43:13 -07001577 staId, HDD_IPA_CLIENT_CONNECT_EX,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001578 pSapEvent->sapevt.
1579 sapStationAssocReassocCompleteEvent.
1580 staMac.bytes);
1581 if (status) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001582 hdd_err("WLAN_CLIENT_CONNECT_EX event failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001583 goto stopbss;
1584 }
1585 }
1586
Nirav Shah1da77682016-05-03 20:16:39 +05301587 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
1588 pHostapdAdapter->sessionId,
1589 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001590
1591#ifdef MSM_PLATFORM
1592 /* start timer in sap/p2p_go */
1593 if (pHddApCtx->bApActive == false) {
1594 spin_lock_bh(&pHddCtx->bus_bw_lock);
1595 pHostapdAdapter->prev_tx_packets =
1596 pHostapdAdapter->stats.tx_packets;
1597 pHostapdAdapter->prev_rx_packets =
1598 pHostapdAdapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05301599 ol_get_intra_bss_fwd_pkts_count(
1600 pHostapdAdapter->sessionId,
1601 &pHostapdAdapter->prev_fwd_tx_packets,
1602 &pHostapdAdapter->prev_fwd_rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001603 spin_unlock_bh(&pHddCtx->bus_bw_lock);
1604 hdd_start_bus_bw_compute_timer(pHostapdAdapter);
1605 }
1606#endif
1607 pHddApCtx->bApActive = true;
1608 /* Stop AP inactivity timer */
1609 if (pHddApCtx->hdd_ap_inactivity_timer.state ==
Anurag Chouhan210db072016-02-22 18:42:15 +05301610 QDF_TIMER_STATE_RUNNING) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301611 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05301612 qdf_mc_timer_stop(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001613 hdd_ap_inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301614 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001615 hdd_err("Failed to start inactivity timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001616 }
1617 }
1618#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1619 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1620#endif
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05301621 cds_host_diag_log_work(&pHddCtx->sap_wake_lock,
1622 HDD_SAP_WAKE_LOCK_DURATION,
1623 WIFI_POWER_EVENT_WAKELOCK_SAP);
Anurag Chouhana37b5b72016-02-21 14:53:42 +05301624 qdf_wake_lock_timeout_acquire(&pHddCtx->sap_wake_lock,
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05301625 HDD_SAP_WAKE_LOCK_DURATION);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001626 {
Manjeet Singhd295b1d2016-07-28 15:57:38 +05301627 struct station_info *sta_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001628 uint16_t iesLen =
1629 pSapEvent->sapevt.
1630 sapStationAssocReassocCompleteEvent.iesLen;
1631
Manjeet Singhd295b1d2016-07-28 15:57:38 +05301632 sta_info = qdf_mem_malloc(sizeof(*sta_info));
1633 if (!sta_info) {
1634 hdd_err("Failed to allocate station info");
1635 return QDF_STATUS_E_FAILURE;
1636 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001637 if (iesLen <= MAX_ASSOC_IND_IE_LEN) {
Manjeet Singhd295b1d2016-07-28 15:57:38 +05301638 sta_info->assoc_req_ies =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001639 (const u8 *)&pSapEvent->sapevt.
1640 sapStationAssocReassocCompleteEvent.ies[0];
Manjeet Singhd295b1d2016-07-28 15:57:38 +05301641 sta_info->assoc_req_ies_len = iesLen;
Ryan Hsue7bc3a72016-01-18 12:08:22 -08001642#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
1643 /*
1644 * After Kernel 4.0, it's no longer need to set
1645 * STATION_INFO_ASSOC_REQ_IES flag, as it
1646 * changed to use assoc_req_ies_len length to
1647 * check the existance of request IE.
1648 */
Manjeet Singhd295b1d2016-07-28 15:57:38 +05301649 sta_info->filled |= STATION_INFO_ASSOC_REQ_IES;
Ryan Hsue7bc3a72016-01-18 12:08:22 -08001650#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001651 cfg80211_new_sta(dev,
1652 (const u8 *)&pSapEvent->sapevt.
1653 sapStationAssocReassocCompleteEvent.
Manjeet Singhd295b1d2016-07-28 15:57:38 +05301654 staMac.bytes[0], sta_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001655 GFP_KERNEL);
1656 } else {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001657 hdd_err("Assoc Ie length is too long");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001658 }
Manjeet Singhd295b1d2016-07-28 15:57:38 +05301659 qdf_mem_free(sta_info);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001660 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001661 pScanInfo = &pHostapdAdapter->scan_info;
1662 /* Lets do abort scan to ensure smooth authentication for client */
1663 if ((pScanInfo != NULL) && pScanInfo->mScanPending) {
1664 hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId,
1665 eCSR_SCAN_ABORT_DEFAULT);
1666 }
Krunal Soni056ea0f2016-03-10 13:07:10 -08001667 if (pHostapdAdapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001668 /* send peer status indication to oem app */
1669 hdd_send_peer_status_ind_to_oem_app(&pSapEvent->sapevt.
Abhishek Singh1c676222016-05-09 14:20:28 +05301670 sapStationAssocReassocCompleteEvent.
1671 staMac, ePeerConnected,
1672 pSapEvent->sapevt.
1673 sapStationAssocReassocCompleteEvent.
1674 timingMeasCap,
1675 pHostapdAdapter->sessionId,
1676 &pSapEvent->sapevt.
1677 sapStationAssocReassocCompleteEvent.
1678 chan_info,
1679 pHostapdAdapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680 }
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301681
1682 qdf_status = hdd_add_peer_object(pHostapdAdapter->hdd_vdev,
1683 pHostapdAdapter->device_mode,
1684 pSapEvent->sapevt.
1685 sapStationAssocReassocCompleteEvent.
1686 staMac.bytes);
1687 if (QDF_IS_STATUS_ERROR(qdf_status))
1688 hdd_err("Peer object "MAC_ADDRESS_STR" add fails!",
1689 MAC_ADDR_ARRAY(pSapEvent->sapevt.
1690 sapStationAssocReassocCompleteEvent.
1691 staMac.bytes));
1692
Jeff Johnsona7e5eed2016-09-28 15:19:13 -07001693 hdd_green_ap_add_sta(pHddCtx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001694 break;
1695
1696 case eSAP_STA_DISASSOC_EVENT:
1697 memcpy(wrqu.addr.sa_data,
1698 &pSapEvent->sapevt.sapStationDisassocCompleteEvent.
Anurag Chouhan6d760662016-02-20 16:05:43 +05301699 staMac, QDF_MAC_ADDR_SIZE);
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001700 hdd_notice(" disassociated " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001701 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1702
Wei Song2f76f642016-11-18 16:32:53 +08001703 qdf_status = qdf_event_set(&pHostapdState->qdf_sta_disassoc_event);
Anurag Chouhance0dc992016-02-16 18:18:03 +05301704 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001705 hdd_err("ERR: Station Deauth event Set failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001706
1707 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason ==
1708 eSAP_USR_INITATED_DISASSOC)
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001709 hdd_notice(" User initiated disassociation");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001710 else
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001711 hdd_notice(" MAC initiated disassociation");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001712 we_event = IWEVEXPIRED;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301713 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001714 hdd_softap_get_sta_id(pHostapdAdapter,
1715 &pSapEvent->sapevt.
1716 sapStationDisassocCompleteEvent.staMac,
1717 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301718 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001719 hdd_err("ERROR: HDD Failed to find sta id!!");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301720 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001721 }
1722#ifdef IPA_OFFLOAD
1723 if (hdd_ipa_is_enabled(pHddCtx)) {
1724 status = hdd_ipa_wlan_evt(pHostapdAdapter, staId,
Mohit Khannafa99aea2016-05-12 21:43:13 -07001725 HDD_IPA_CLIENT_DISCONNECT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001726 pSapEvent->sapevt.
1727 sapStationDisassocCompleteEvent.
1728 staMac.bytes);
1729
1730 if (status) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001731 hdd_err("ERROR: WLAN_CLIENT_DISCONNECT event failed!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001732 goto stopbss;
1733 }
1734 }
1735#endif
Nirav Shah1da77682016-05-03 20:16:39 +05301736 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
1737 pHostapdAdapter->sessionId,
1738 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_DISASSOC));
1739
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001740 hdd_softap_deregister_sta(pHostapdAdapter, staId);
1741
1742 pHddApCtx->bApActive = false;
1743 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
1744 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
1745 if (pHostapdAdapter->aStaInfo[i].isUsed
1746 && i !=
1747 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
1748 uBCStaId) {
1749 pHddApCtx->bApActive = true;
1750 break;
1751 }
1752 }
1753 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
1754
1755 /* Start AP inactivity timer if no stations associated with it */
1756 if ((0 !=
1757 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
1758 nAPAutoShutOff)) {
1759 if (pHddApCtx->bApActive == false) {
1760 if (pHddApCtx->hdd_ap_inactivity_timer.state ==
Anurag Chouhan210db072016-02-22 18:42:15 +05301761 QDF_TIMER_STATE_STOPPED) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301762 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05301763 qdf_mc_timer_start(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001764 hdd_ap_inactivity_timer,
1765 (WLAN_HDD_GET_CTX
1766 (pHostapdAdapter))->
1767 config->
1768 nAPAutoShutOff *
1769 1000);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301770 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001771 hdd_err("Failed to init AP inactivity timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001772 } else
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301773 QDF_ASSERT
Anurag Chouhan210db072016-02-22 18:42:15 +05301774 (qdf_mc_timer_get_current_state
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001775 (&pHddApCtx->
1776 hdd_ap_inactivity_timer) ==
Anurag Chouhan210db072016-02-22 18:42:15 +05301777 QDF_TIMER_STATE_STOPPED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001778 }
1779 }
1780#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1781 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1782#endif
1783
1784 cfg80211_del_sta(dev,
1785 (const u8 *)&pSapEvent->sapevt.
1786 sapStationDisassocCompleteEvent.staMac.
1787 bytes[0], GFP_KERNEL);
1788
1789 /* Update the beacon Interval if it is P2P GO */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301790 qdf_status = cds_change_mcc_go_beacon_interval(pHostapdAdapter);
1791 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001792 hdd_err("failed to update Beacon interval %d",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301793 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001794 }
Krunal Soni056ea0f2016-03-10 13:07:10 -08001795 if (pHostapdAdapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001796 /* send peer status indication to oem app */
1797 hdd_send_peer_status_ind_to_oem_app(&pSapEvent->sapevt.
Abhishek Singh1c676222016-05-09 14:20:28 +05301798 sapStationDisassocCompleteEvent.
1799 staMac, ePeerDisconnected,
1800 0,
1801 pHostapdAdapter->sessionId,
1802 NULL,
1803 pHostapdAdapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001804 }
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301805 qdf_status = hdd_remove_peer_object(pHostapdAdapter->hdd_vdev,
1806 pSapEvent->sapevt.
1807 sapStationDisassocCompleteEvent.
1808 staMac.bytes);
1809 if (QDF_IS_STATUS_ERROR(qdf_status))
1810 hdd_err("Peer obj "MAC_ADDRESS_STR" delete fails",
1811 MAC_ADDR_ARRAY(pSapEvent->sapevt.
1812 sapStationDisassocCompleteEvent.
1813 staMac.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001814#ifdef MSM_PLATFORM
1815 /*stop timer in sap/p2p_go */
1816 if (pHddApCtx->bApActive == false) {
1817 spin_lock_bh(&pHddCtx->bus_bw_lock);
1818 pHostapdAdapter->prev_tx_packets = 0;
1819 pHostapdAdapter->prev_rx_packets = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05301820 pHostapdAdapter->prev_fwd_tx_packets = 0;
1821 pHostapdAdapter->prev_fwd_rx_packets = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001822 spin_unlock_bh(&pHddCtx->bus_bw_lock);
1823 hdd_stop_bus_bw_compute_timer(pHostapdAdapter);
1824 }
1825#endif
Jeff Johnsona7e5eed2016-09-28 15:19:13 -07001826 hdd_green_ap_del_sta(pHddCtx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001827 break;
1828
1829 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
1830 {
1831 static const char *message =
1832 "MLMEWPSPBCPROBEREQ.indication";
1833 union iwreq_data wreq;
1834
1835 down(&pHddApCtx->semWpsPBCOverlapInd);
1836 pHddApCtx->WPSPBCProbeReq.probeReqIELen =
1837 pSapEvent->sapevt.sapPBCProbeReqEvent.
1838 WPSPBCProbeReq.probeReqIELen;
1839
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301840 qdf_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001841 pSapEvent->sapevt.sapPBCProbeReqEvent.
1842 WPSPBCProbeReq.probeReqIE,
1843 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
1844
Anurag Chouhanc5548422016-02-24 18:33:27 +05301845 qdf_copy_macaddr(&pHddApCtx->WPSPBCProbeReq.peer_macaddr,
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08001846 &pSapEvent->sapevt.sapPBCProbeReqEvent.
1847 WPSPBCProbeReq.peer_macaddr);
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001848 hdd_notice("WPS PBC probe req " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001849 MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08001850 peer_macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001851 memset(&wreq, 0, sizeof(wreq));
1852 wreq.data.length = strlen(message); /* This is length of message */
1853 wireless_send_event(dev, IWEVCUSTOM, &wreq,
1854 (char *)message);
1855
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301856 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001857 }
1858 case eSAP_ASSOC_STA_CALLBACK_EVENT:
1859 pAssocStasArray =
1860 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
1861 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0) { /* List of associated stations */
1862 for (i = 0;
1863 i <
1864 pSapEvent->sapevt.sapAssocStaListEvent.
1865 noOfAssocSta; i++) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001866 hdd_notice("Associated Sta Num %d:assocId=%d, staId=%d, staMac="
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001867 MAC_ADDRESS_STR, i + 1,
1868 pAssocStasArray->assocId,
1869 pAssocStasArray->staId,
1870 MAC_ADDR_ARRAY(pAssocStasArray->staMac.
1871 bytes));
1872 pAssocStasArray++;
1873 }
1874 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301875 qdf_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas); /* Release caller allocated memory here */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001876 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301877 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001878 case eSAP_REMAIN_CHAN_READY:
1879 hdd_remain_chan_ready_handler(pHostapdAdapter,
1880 pSapEvent->sapevt.sap_roc_ind.scan_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301881 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001882 case eSAP_UNKNOWN_STA_JOIN:
1883 snprintf(unknownSTAEvent, IW_CUSTOM_MAX,
1884 "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
1885 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
1886 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
1887 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
1888 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
1889 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
1890 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
1891 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1892 wrqu.data.pointer = unknownSTAEvent;
1893 wrqu.data.length = strlen(unknownSTAEvent);
1894 we_custom_event_generic = (uint8_t *) unknownSTAEvent;
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001895 hdd_err("%s", unknownSTAEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001896 break;
1897
1898 case eSAP_MAX_ASSOC_EXCEEDED:
1899 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX,
1900 "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
1901 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
1902 " one or more devices to enable the new device connection",
1903 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
1904 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
1905 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
1906 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
1907 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
1908 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.
1909 bytes[5]);
1910 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1911 wrqu.data.pointer = maxAssocExceededEvent;
1912 wrqu.data.length = strlen(maxAssocExceededEvent);
1913 we_custom_event_generic = (uint8_t *) maxAssocExceededEvent;
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001914 hdd_notice("%s", maxAssocExceededEvent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001915 break;
1916 case eSAP_STA_ASSOC_IND:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301917 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001918
1919 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001920 hdd_notice(" Disconnecting all the P2P Clients....");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001921 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301922 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001923
1924 case eSAP_MAC_TRIG_STOP_BSS_EVENT:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301925 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001926 hdd_stop_bss_link(pHostapdAdapter, usrDataForCallback);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301927 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001928 hdd_warn("hdd_stop_bss_link failed %d",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301929 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001930 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301931 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001932
1933 case eSAP_CHANNEL_CHANGE_EVENT:
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001934 hdd_notice("Received eSAP_CHANNEL_CHANGE_EVENT event");
Liangwei Dong5047d512016-10-11 00:24:26 -04001935 if (pHostapdState->bssState != BSS_STOP) {
1936 /* Prevent suspend for new channel */
1937 hdd_hostapd_channel_prevent_suspend(pHostapdAdapter,
1938 pSapEvent->sapevt.sap_ch_selected.pri_ch);
1939 /* Allow suspend for old channel */
1940 hdd_hostapd_channel_allow_suspend(pHostapdAdapter,
1941 pHddApCtx->operatingChannel);
1942 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001943 /* SME/PE is already updated for new operation channel. So update
1944 * HDD layer also here. This resolves issue in AP-AP mode where
1945 * AP1 channel is changed due to RADAR then CAC is going on and
1946 * START_BSS on new channel has not come to HDD. At this case if
1947 * AP2 is start it needs current operation channel for MCC DFS
1948 * restiction
1949 */
1950 pHddApCtx->operatingChannel =
1951 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1952 pHddApCtx->sapConfig.acs_cfg.pri_ch =
1953 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1954 pHddApCtx->sapConfig.acs_cfg.ht_sec_ch =
1955 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
1956 pHddApCtx->sapConfig.acs_cfg.vht_seg0_center_ch =
1957 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
1958 pHddApCtx->sapConfig.acs_cfg.vht_seg1_center_ch =
1959 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
1960 pHddApCtx->sapConfig.acs_cfg.ch_width =
1961 pSapEvent->sapevt.sap_ch_selected.ch_width;
1962
1963 /* Indicate operating channel change to hostapd
1964 * only for non driver override acs
1965 */
Krunal Soni056ea0f2016-03-10 13:07:10 -08001966 if (pHostapdAdapter->device_mode == QDF_SAP_MODE &&
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05301967 pHddCtx->config->force_sap_acs) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301968 return QDF_STATUS_SUCCESS;
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05301969 } else {
1970 chan_change.chan =
1971 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1972 chan_change.chan_params.ch_width =
1973 pSapEvent->sapevt.sap_ch_selected.ch_width;
1974 chan_change.chan_params.sec_ch_offset =
1975 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
1976 chan_change.chan_params.center_freq_seg0 =
1977 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
1978 chan_change.chan_params.center_freq_seg1 =
1979 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
1980
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001981 return hdd_chan_change_notify(pHostapdAdapter, dev,
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05301982 chan_change);
1983 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001984 case eSAP_ACS_SCAN_SUCCESS_EVENT:
Liangwei Dongaef84342016-10-21 05:28:00 -04001985 return hdd_handle_acs_scan_event(pSapEvent, pHostapdAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001986 case eSAP_DFS_NOL_GET:
Jeff Johnsoncfb85832016-06-30 13:46:10 -07001987 hdd_notice("Received eSAP_DFS_NOL_GET event");
Yuanyuan Liu13738502016-04-06 17:41:37 -07001988
1989 /* get the dfs nol from PLD */
1990 ret = pld_wlan_get_dfs_nol(pHddCtx->parent_dev,
1991 pSapEvent->sapevt.sapDfsNolInfo.
1992 pDfsList,
1993 pSapEvent->sapevt.sapDfsNolInfo.
1994 sDfsList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001995
1996 if (ret > 0) {
Yuanyuan Liu13738502016-04-06 17:41:37 -07001997 hdd_info("Get %d bytes of dfs nol from PLD", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301998 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001999 } else {
Yuanyuan Liu13738502016-04-06 17:41:37 -07002000 hdd_info("No dfs nol entry in PLD, ret: %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302001 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002002 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002003 case eSAP_DFS_NOL_SET:
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002004 hdd_notice("Received eSAP_DFS_NOL_SET event");
Yuanyuan Liu13738502016-04-06 17:41:37 -07002005
2006 /* set the dfs nol to PLD */
2007 ret = pld_wlan_set_dfs_nol(pHddCtx->parent_dev,
2008 pSapEvent->sapevt.sapDfsNolInfo.
2009 pDfsList,
2010 pSapEvent->sapevt.sapDfsNolInfo.
2011 sDfsList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002012
2013 if (ret) {
Yuanyuan Liu13738502016-04-06 17:41:37 -07002014 hdd_info("Failed to set dfs nol - ret: %d", ret);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002015 } else {
Yuanyuan Liu13738502016-04-06 17:41:37 -07002016 hdd_info(" Set %d bytes dfs nol to PLD",
2017 pSapEvent->sapevt.sapDfsNolInfo.sDfsList);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302019 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002020 case eSAP_ACS_CHANNEL_SELECTED:
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002021 hdd_notice("ACS Completed for wlan%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002022 pHostapdAdapter->dev->ifindex);
2023 clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
2024 clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);
2025 pHddApCtx->sapConfig.acs_cfg.pri_ch =
2026 pSapEvent->sapevt.sap_ch_selected.pri_ch;
2027 pHddApCtx->sapConfig.acs_cfg.ht_sec_ch =
2028 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
2029 pHddApCtx->sapConfig.acs_cfg.vht_seg0_center_ch =
2030 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
2031 pHddApCtx->sapConfig.acs_cfg.vht_seg1_center_ch =
2032 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
2033 pHddApCtx->sapConfig.acs_cfg.ch_width =
2034 pSapEvent->sapevt.sap_ch_selected.ch_width;
2035 /* send vendor event to hostapd only for hostapd based acs*/
2036 if (!pHddCtx->config->force_sap_acs)
2037 wlan_hdd_cfg80211_acs_ch_select_evt(pHostapdAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302038 return QDF_STATUS_SUCCESS;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302039 case eSAP_ECSA_CHANGE_CHAN_IND:
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002040 hdd_notice("Channel change indication from peer for channel %d",
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302041 pSapEvent->sapevt.sap_chan_cng_ind.new_chan);
2042 if (hdd_softap_set_channel_change(dev,
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302043 pSapEvent->sapevt.sap_chan_cng_ind.new_chan,
2044 CH_WIDTH_MAX))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302045 return QDF_STATUS_E_FAILURE;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302046 else
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302047 return QDF_STATUS_SUCCESS;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302048
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002049 default:
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002050 hdd_notice("SAP message is not handled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002051 goto stopbss;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302052 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002053 }
2054 wireless_send_event(dev, we_event, &wrqu,
2055 (char *)we_custom_event_generic);
Manjeet Singhd295b1d2016-07-28 15:57:38 +05302056
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302057 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002058
2059stopbss:
2060 {
2061 uint8_t we_custom_event[64];
2062 char *stopBssEvent = "STOP-BSS.response"; /* 17 */
2063 int event_len = strlen(stopBssEvent);
2064
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002065 hdd_notice("BSS stop status = %s",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002066 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
2067 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
2068
2069 /* Change the BSS state now since, as we are shutting things down,
2070 * we don't want interfaces to become re-enabled */
2071 pHostapdState->bssState = BSS_STOP;
2072
2073 if (0 !=
2074 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
2075 nAPAutoShutOff) {
Anurag Chouhan210db072016-02-22 18:42:15 +05302076 if (QDF_TIMER_STATE_RUNNING ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002077 pHddApCtx->hdd_ap_inactivity_timer.state) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302078 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05302079 qdf_mc_timer_stop(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002080 hdd_ap_inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302081 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002082 hdd_err("Failed to stop AP inactivity timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002083 }
2084 }
2085
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302086 qdf_status =
Anurag Chouhan210db072016-02-22 18:42:15 +05302087 qdf_mc_timer_destroy(&pHddApCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002088 hdd_ap_inactivity_timer);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302089 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002090 hdd_err("Failed to Destroy AP inactivity timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002091 }
2092#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
2093 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
2094#endif
2095
2096 /* Stop the pkts from n/w stack as we are going to free all of
2097 * the TX WMM queues for all STAID's */
2098 hdd_hostapd_stop(dev);
2099
2100 /* reclaim all resources allocated to the BSS */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302101 qdf_status = hdd_softap_stop_bss(pHostapdAdapter);
2102 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsoncfb85832016-06-30 13:46:10 -07002103 hdd_warn("hdd_softap_stop_bss failed %d",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302104 qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002105 }
2106
2107 /* once the event is set, structure dev/pHostapdAdapter should
2108 * not be touched since they are now subject to being deleted
2109 * by another thread */
2110 if (eSAP_STOP_BSS_EVENT == sapEvent)
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05302111 qdf_event_set(&pHostapdState->qdf_stop_bss_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002112
2113 /* notify userspace that the BSS has stopped */
2114 memset(&we_custom_event, '\0', sizeof(we_custom_event));
2115 memcpy(&we_custom_event, stopBssEvent, event_len);
2116 memset(&wrqu, 0, sizeof(wrqu));
2117 wrqu.data.length = event_len;
2118 we_event = IWEVCUSTOM;
2119 we_custom_event_generic = we_custom_event;
2120 wireless_send_event(dev, we_event, &wrqu,
2121 (char *)we_custom_event_generic);
Krunal Sonib37bb352016-12-20 14:12:21 -08002122 cds_decr_session_set_pcl(pHostapdAdapter->device_mode,
2123 pHostapdAdapter->sessionId);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002124 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002125 /* Send SCC/MCC Switching event to IPA */
2126 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
2127 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302128 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002129}
2130
2131int hdd_softap_unpack_ie(tHalHandle halHandle,
2132 eCsrEncryptionType *pEncryptType,
2133 eCsrEncryptionType *mcEncryptType,
2134 eCsrAuthType *pAuthType,
2135 bool *pMFPCapable,
2136 bool *pMFPRequired,
2137 uint16_t gen_ie_len, uint8_t *gen_ie)
2138{
2139 tDot11fIERSN dot11RSNIE;
2140 tDot11fIEWPA dot11WPAIE;
2141
2142 uint8_t *pRsnIe;
2143 uint16_t RSNIeLen;
2144
2145 if (NULL == halHandle) {
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002146 hdd_err("Error haHandle returned NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002147 return -EINVAL;
2148 }
2149 /* Validity checks */
Anurag Chouhan6d760662016-02-20 16:05:43 +05302150 if ((gen_ie_len < QDF_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002151 || (gen_ie_len >
Anurag Chouhan6d760662016-02-20 16:05:43 +05302152 QDF_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002153 return -EINVAL;
2154 /* Type check */
2155 if (gen_ie[0] == DOT11F_EID_RSN) {
2156 /* Validity checks */
2157 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
2158 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302159 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002160 }
2161 /* Skip past the EID byte and length byte */
2162 pRsnIe = gen_ie + 2;
2163 RSNIeLen = gen_ie_len - 2;
2164 /* Unpack the RSN IE */
2165 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
2166 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
2167 pRsnIe, RSNIeLen, &dot11RSNIE);
2168 /* Copy out the encryption and authentication types */
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002169 hdd_notice("pairwise cipher suite count: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002170 dot11RSNIE.pwise_cipher_suite_count);
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002171 hdd_notice("authentication suite count: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002172 dot11RSNIE.akm_suite_count);
2173 /*Here we have followed the apple base code,
2174 but probably I suspect we can do something different */
2175 /* dot11RSNIE.akm_suite_count */
2176 /* Just translate the FIRST one */
2177 *pAuthType =
2178 hdd_translate_rsn_to_csr_auth_type(dot11RSNIE.akm_suites[0]);
2179 /* dot11RSNIE.pwise_cipher_suite_count */
2180 *pEncryptType =
2181 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
2182 pwise_cipher_suites[0]);
2183 /* dot11RSNIE.gp_cipher_suite_count */
2184 *mcEncryptType =
2185 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
2186 gp_cipher_suite);
2187 /* Set the PMKSA ID Cache for this interface */
2188 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
2189 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
2190 /* Calling csr_roam_set_pmkid_cache to configure the PMKIDs into the cache */
2191 } else if (gen_ie[0] == DOT11F_EID_WPA) {
2192 /* Validity checks */
2193 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
2194 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302195 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002196 }
2197 /* Skip past the EID byte and length byte - and four byte WiFi OUI */
2198 pRsnIe = gen_ie + 2 + 4;
2199 RSNIeLen = gen_ie_len - (2 + 4);
2200 /* Unpack the WPA IE */
2201 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
2202 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
2203 pRsnIe, RSNIeLen, &dot11WPAIE);
2204 /* Copy out the encryption and authentication types */
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002205 hdd_notice("WPA unicast cipher suite count: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002206 dot11WPAIE.unicast_cipher_count);
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002207 hdd_notice("WPA authentication suite count: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002208 dot11WPAIE.auth_suite_count);
2209 /* dot11WPAIE.auth_suite_count */
2210 /* Just translate the FIRST one */
2211 *pAuthType =
2212 hdd_translate_wpa_to_csr_auth_type(dot11WPAIE.auth_suites[0]);
2213 /* dot11WPAIE.unicast_cipher_count */
2214 *pEncryptType =
2215 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
2216 unicast_ciphers[0]);
2217 /* dot11WPAIE.unicast_cipher_count */
2218 *mcEncryptType =
2219 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
2220 multicast_cipher);
2221 *pMFPCapable = false;
2222 *pMFPRequired = false;
2223 } else {
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002224 hdd_warn("gen_ie[0]: %d", gen_ie[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302225 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002226 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302227 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002228}
2229
2230/**
2231 * hdd_softap_set_channel_change() -
2232 * This function to support SAP channel change with CSA IE
2233 * set in the beacons.
2234 *
2235 * @dev: pointer to the net device.
2236 * @target_channel: target channel number.
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302237 * @target_bw: Target bandwidth to move.
2238 * If no bandwidth is specified, the value is CH_WIDTH_MAX
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002239 *
2240 * Return: 0 for success, non zero for failure
2241 */
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302242int hdd_softap_set_channel_change(struct net_device *dev, int target_channel,
Kiran Kumar Lokere13644672016-02-29 15:40:10 -08002243 enum phy_ch_width target_bw)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002244{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302245 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002246 int ret = 0;
2247 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2248 hdd_context_t *pHddCtx = NULL;
Edhar, Mahesh Kumardf2ec122015-11-16 11:33:16 +05302249 hdd_adapter_t *sta_adapter;
2250 hdd_station_ctx_t *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002251
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002252 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2253 ret = wlan_hdd_validate_context(pHddCtx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05302254 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002255 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002256
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +05302257 ret = hdd_validate_channel_and_bandwidth(pHostapdAdapter,
2258 target_channel, target_bw);
2259 if (ret) {
2260 hdd_err("Invalid CH and BW combo");
2261 return ret;
2262 }
2263
Krunal Soni056ea0f2016-03-10 13:07:10 -08002264 sta_adapter = hdd_get_adapter(pHddCtx, QDF_STA_MODE);
Edhar, Mahesh Kumardf2ec122015-11-16 11:33:16 +05302265 /*
2266 * conc_custom_rule1:
2267 * Force SCC for SAP + STA
2268 * if STA is already connected then we shouldn't allow
2269 * channel switch in SAP interface.
2270 */
2271 if (sta_adapter && pHddCtx->config->conc_custom_rule1) {
2272 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
2273 if (hdd_conn_is_connected(sta_ctx)) {
2274 hdd_err("Channel switch not allowed after STA connection with conc_custom_rule1 enabled");
2275 return -EBUSY;
2276 }
2277 }
2278
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002279 /*
2280 * Set the dfs_radar_found flag to mimic channel change
2281 * when a radar is found. This will enable synchronizing
2282 * SAP and HDD states similar to that of radar indication.
2283 * Suspend the netif queues to stop queuing Tx frames
2284 * from upper layers. netif queues will be resumed
2285 * once the channel change is completed and SAP will
2286 * post eSAP_START_BSS_EVENT success event to HDD.
2287 */
Arif Hussain2a7c1f32016-07-18 14:24:36 -07002288 if (qdf_atomic_inc_return(&pHddCtx->dfs_radar_found) > 1) {
2289 hdd_err("Channel switch in progress!!");
2290 return -EBUSY;
2291 }
2292
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002293 /*
2294 * Post the Channel Change request to SAP.
2295 */
2296 status = wlansap_set_channel_change_with_csa(
Dustin Brown5118e8e2016-09-13 15:54:23 -07002297 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
2298 (uint32_t)target_channel,
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302299 target_bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002300
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302301 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002302 hdd_err("SAP set channel failed for channel = %d, bw:%d",
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302303 target_channel, target_bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002304 /*
2305 * If channel change command fails then clear the
2306 * radar found flag and also restart the netif
2307 * queues.
2308 */
Arif Hussain1969ec82016-07-08 10:37:01 -07002309 qdf_atomic_set(&pHddCtx->dfs_radar_found, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002310
2311 ret = -EINVAL;
2312 }
2313
2314 return ret;
2315}
2316
Chandrasekaran Manishekarcde33d72016-04-14 19:03:39 +05302317#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
2318/**
2319 * hdd_sap_restart_with_channel_switch() - SAP channel change with E/CSA
2320 * @ap_adapter: HDD adapter
2321 * @target_channel: Channel to which switch must happen
2322 * @target_bw: Bandwidth of the target channel
2323 *
2324 * Invokes the necessary API to perform channel switch for the SAP or GO
2325 *
2326 * Return: None
2327 */
2328void hdd_sap_restart_with_channel_switch(hdd_adapter_t *ap_adapter,
2329 uint32_t target_channel,
2330 uint32_t target_bw)
2331{
2332 struct net_device *dev = ap_adapter->dev;
2333 int ret;
2334
2335 ENTER();
2336
2337 if (!dev) {
2338 hdd_err("Invalid dev pointer");
2339 return;
2340 }
2341
2342 ret = hdd_softap_set_channel_change(dev, target_channel, target_bw);
2343 if (ret) {
2344 hdd_err("channel switch failed");
2345 return;
2346 }
2347}
2348#endif
2349
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002350int
2351static __iw_softap_set_ini_cfg(struct net_device *dev,
2352 struct iw_request_info *info,
2353 union iwreq_data *wrqu, char *extra)
2354{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302355 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002356 int ret = 0; /* success */
2357 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2358 hdd_context_t *pHddCtx;
2359
Jeff Johnson02050312016-02-11 18:40:28 -08002360 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002361
2362 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2363 ret = wlan_hdd_validate_context(pHddCtx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05302364 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002365 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002366
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002367 hdd_notice("Received data %s", extra);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002368
2369 vstatus = hdd_execute_global_config_command(pHddCtx, extra);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302370 if (QDF_STATUS_SUCCESS != vstatus) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002371 ret = -EINVAL;
2372 }
2373
2374 return ret;
2375}
2376
2377int
2378static iw_softap_set_ini_cfg(struct net_device *dev,
2379 struct iw_request_info *info,
2380 union iwreq_data *wrqu, char *extra)
2381{
2382 int ret;
2383
2384 cds_ssr_protect(__func__);
2385 ret = __iw_softap_set_ini_cfg(dev, info, wrqu, extra);
2386 cds_ssr_unprotect(__func__);
2387
2388 return ret;
2389}
2390
Kai Liubdd5fcb2016-09-28 22:55:44 +08002391static int hdd_sap_get_chan_width(hdd_adapter_t *adapter, int *value)
2392{
2393 void *cds_ctx;
2394 hdd_hostapd_state_t *hostapdstate;
2395
2396 ENTER();
2397 hostapdstate = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
2398
2399 if (hostapdstate->bssState != BSS_START) {
2400 *value = -EINVAL;
2401 return -EINVAL;
2402 }
2403
2404 cds_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
2405
2406 *value = wlansap_get_chan_width(cds_ctx);
2407 hdd_notice("chan_width = %d", *value);
2408
2409 return 0;
2410}
2411
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002412int
2413static __iw_softap_get_ini_cfg(struct net_device *dev,
2414 struct iw_request_info *info,
2415 union iwreq_data *wrqu, char *extra)
2416{
2417 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2418 hdd_context_t *pHddCtx;
2419 int ret = 0;
2420
Jeff Johnson02050312016-02-11 18:40:28 -08002421 ENTER_DEV(dev);
2422
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002423 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2424 ret = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson02050312016-02-11 18:40:28 -08002425 if (ret != 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002426 return ret;
Jeff Johnson02050312016-02-11 18:40:28 -08002427
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002428 hdd_notice("Printing CLD global INI Config");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002429 hdd_cfg_get_global_config(pHddCtx, extra, QCSAP_IOCTL_MAX_STR_LEN);
2430 wrqu->data.length = strlen(extra) + 1;
2431
2432 return 0;
2433}
2434
2435int
2436static iw_softap_get_ini_cfg(struct net_device *dev,
2437 struct iw_request_info *info,
2438 union iwreq_data *wrqu, char *extra)
2439{
2440 int ret;
2441
2442 cds_ssr_protect(__func__);
2443 ret = __iw_softap_get_ini_cfg(dev, info, wrqu, extra);
2444 cds_ssr_unprotect(__func__);
2445
2446 return ret;
2447}
2448
Govind Singha471e5e2015-10-12 17:11:14 +05302449/**
2450 * iw_softap_set_two_ints_getnone() - Generic "set two integer" ioctl handler
2451 * @dev: device upon which the ioctl was received
2452 * @info: ioctl request information
2453 * @wrqu: ioctl request data
2454 * @extra: ioctl extra data
2455 *
2456 * Return: 0 on success, non-zero on error
2457 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002458static int __iw_softap_set_two_ints_getnone(struct net_device *dev,
2459 struct iw_request_info *info,
2460 union iwreq_data *wrqu, char *extra)
2461{
Govind Singha471e5e2015-10-12 17:11:14 +05302462 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2463 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002464 int *value = (int *)extra;
2465 int sub_cmd = value[0];
Govind Singha471e5e2015-10-12 17:11:14 +05302466 hdd_context_t *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002467
Jeff Johnson02050312016-02-11 18:40:28 -08002468 ENTER_DEV(dev);
2469
Govind Singha471e5e2015-10-12 17:11:14 +05302470 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2471 ret = wlan_hdd_validate_context(hdd_ctx);
2472 if (ret != 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002473 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002474
2475 switch (sub_cmd) {
Srinivas Girigowda6147c582016-10-18 12:26:15 -07002476#ifdef WLAN_DEBUG
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002477 case QCSAP_IOCTL_SET_FW_CRASH_INJECT:
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002478 hdd_err("WE_SET_FW_CRASH_INJECT: %d %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002479 value[1], value[2]);
Govind Singha471e5e2015-10-12 17:11:14 +05302480 ret = wma_cli_set2_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002481 GEN_PARAM_CRASH_INJECT,
2482 value[1], value[2],
2483 GEN_CMD);
2484 break;
2485#endif
2486 case QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL:
2487 hdd_info("WE_DUMP_DP_TRACE: %d %d",
2488 value[1], value[2]);
2489 if (value[1] == DUMP_DP_TRACE)
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302490 qdf_dp_trace_dump_all(value[2]);
Nirav Shahda008342016-05-17 18:50:40 +05302491 else if (value[1] == ENABLE_DP_TRACE_LIVE_MODE)
2492 qdf_dp_trace_enable_live_mode();
2493 else if (value[1] == CLEAR_DP_TRACE_BUFFER)
2494 qdf_dp_trace_clear_buffer();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002495 break;
Govind Singha471e5e2015-10-12 17:11:14 +05302496 case QCSAP_ENABLE_FW_PROFILE:
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002497 hdd_notice("QCSAP_ENABLE_FW_PROFILE: %d %d",
Govind Singha471e5e2015-10-12 17:11:14 +05302498 value[1], value[2]);
2499 ret = wma_cli_set2_command(adapter->sessionId,
2500 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
2501 value[1], value[2], DBG_CMD);
2502 break;
2503 case QCSAP_SET_FW_PROFILE_HIST_INTVL:
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002504 hdd_notice("QCSAP_SET_FW_PROFILE_HIST_INTVL: %d %d",
Govind Singha471e5e2015-10-12 17:11:14 +05302505 value[1], value[2]);
2506 ret = wma_cli_set2_command(adapter->sessionId,
2507 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
2508 value[1], value[2], DBG_CMD);
Dustin Brownd95b96b2016-12-09 15:08:26 -08002509 case QCSAP_SET_WLAN_SUSPEND:
2510 ret = hdd_wlan_fake_apps_suspend(hdd_ctx->wiphy, dev);
2511 break;
2512 case QCSAP_SET_WLAN_RESUME:
2513 ret = hdd_wlan_fake_apps_resume(hdd_ctx->wiphy, dev);
2514 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002515 default:
Jeff Johnsonfb33cf52016-06-30 14:06:57 -07002516 hdd_err("Invalid IOCTL command %d", sub_cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002517 break;
2518 }
2519
2520out:
2521 return ret;
2522}
2523
2524static int iw_softap_set_two_ints_getnone(struct net_device *dev,
2525 struct iw_request_info *info,
2526 union iwreq_data *wrqu, char *extra)
2527{
2528 int ret;
2529
2530 cds_ssr_protect(__func__);
2531 ret = __iw_softap_set_two_ints_getnone(dev, info, wrqu, extra);
2532 cds_ssr_unprotect(__func__);
2533
2534 return ret;
2535}
2536
Anurag Chouhan6d760662016-02-20 16:05:43 +05302537static void print_mac_list(struct qdf_mac_addr *macList, uint8_t size)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002538{
2539 int i;
2540 uint8_t *macArray;
2541
2542 for (i = 0; i < size; i++) {
2543 macArray = (macList + i)->bytes;
2544 pr_info("** ACL entry %i - %02x:%02x:%02x:%02x:%02x:%02x \n",
2545 i, MAC_ADDR_ARRAY(macArray));
2546 }
2547 return;
2548}
2549
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302550static QDF_STATUS hdd_print_acl(hdd_adapter_t *pHostapdAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002551{
2552 eSapMacAddrACL acl_mode;
Anurag Chouhan6d760662016-02-20 16:05:43 +05302553 struct qdf_mac_addr MacList[MAX_ACL_MAC_ADDRESS];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002554 uint8_t listnum;
2555 void *p_cds_gctx = NULL;
2556
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002557 p_cds_gctx = WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302558 qdf_mem_zero(&MacList[0], sizeof(MacList));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302559 if (QDF_STATUS_SUCCESS == wlansap_get_acl_mode(p_cds_gctx, &acl_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002560 pr_info("******** ACL MODE *********\n");
2561 switch (acl_mode) {
2562 case eSAP_ACCEPT_UNLESS_DENIED:
2563 pr_info("ACL Mode = ACCEPT_UNLESS_DENIED\n");
2564 break;
2565 case eSAP_DENY_UNLESS_ACCEPTED:
2566 pr_info("ACL Mode = DENY_UNLESS_ACCEPTED\n");
2567 break;
2568 case eSAP_SUPPORT_ACCEPT_AND_DENY:
2569 pr_info("ACL Mode = ACCEPT_AND_DENY\n");
2570 break;
2571 case eSAP_ALLOW_ALL:
2572 pr_info("ACL Mode = ALLOW_ALL\n");
2573 break;
2574 default:
2575 pr_info("Invalid SAP ACL Mode = %d\n", acl_mode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302576 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002577 }
2578 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302579 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002580 }
2581
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302582 if (QDF_STATUS_SUCCESS == wlansap_get_acl_accept_list(p_cds_gctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002583 &MacList[0],
2584 &listnum)) {
2585 pr_info("******* WHITE LIST ***********\n");
2586 if (listnum <= MAX_ACL_MAC_ADDRESS)
2587 print_mac_list(&MacList[0], listnum);
2588 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302589 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002590 }
2591
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302592 if (QDF_STATUS_SUCCESS == wlansap_get_acl_deny_list(p_cds_gctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002593 &MacList[0],
2594 &listnum)) {
2595 pr_info("******* BLACK LIST ***********\n");
2596 if (listnum <= MAX_ACL_MAC_ADDRESS)
2597 print_mac_list(&MacList[0], listnum);
2598 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302599 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002600 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302601 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002602}
2603
2604int
2605static __iw_softap_setparam(struct net_device *dev,
2606 struct iw_request_info *info,
2607 union iwreq_data *wrqu, char *extra)
2608{
2609 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2610 tHalHandle hHal;
2611 int *value = (int *)extra;
2612 int sub_cmd = value[0];
2613 int set_value = value[1];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302614 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002615 int ret = 0; /* success */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002616 hdd_context_t *hdd_ctx;
2617
Jeff Johnson02050312016-02-11 18:40:28 -08002618 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302619
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002620 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2621 ret = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302622 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002623 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002624
2625 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2626 if (!hHal) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002627 hdd_err("Hal ctx is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002628 return -EINVAL;
2629 }
2630
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002631 switch (sub_cmd) {
2632 case QCASAP_SET_RADAR_DBG:
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002633 hdd_notice("QCASAP_SET_RADAR_DBG called with: value: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002634 set_value);
2635 wlan_sap_enable_phy_error_logs(hHal, (bool) set_value);
2636 break;
2637
2638 case QCSAP_PARAM_CLR_ACL:
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302639 if (QDF_STATUS_SUCCESS != wlansap_clear_acl(
Dustin Brown5118e8e2016-09-13 15:54:23 -07002640 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002641 ret = -EIO;
2642 }
2643 break;
2644
2645 case QCSAP_PARAM_ACL_MODE:
2646 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL) set_value) ||
2647 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL) set_value)) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002648 hdd_err("Invalid ACL Mode value %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002649 set_value);
2650 ret = -EINVAL;
2651 } else {
Dustin Brown5118e8e2016-09-13 15:54:23 -07002652 wlansap_set_mode(
2653 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
2654 set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002655 }
2656 break;
2657
2658 case QCSAP_PARAM_SET_CHANNEL_CHANGE:
Krunal Soni056ea0f2016-03-10 13:07:10 -08002659 if ((QDF_SAP_MODE == pHostapdAdapter->device_mode) ||
2660 (QDF_P2P_GO_MODE == pHostapdAdapter->device_mode)) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002661 hdd_notice("SET Channel Change to new channel= %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002662 set_value);
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302663 ret = hdd_softap_set_channel_change(dev, set_value,
2664 CH_WIDTH_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002665 } else {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002666 hdd_err("Channel Change Failed, Device in test mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002667 ret = -EINVAL;
2668 }
2669 break;
2670 case QCSAP_PARAM_AUTO_CHANNEL:
2671 if (set_value == 0 || set_value == 1)
2672 (WLAN_HDD_GET_CTX(
2673 pHostapdAdapter))->config->force_sap_acs =
2674 set_value;
2675 else
2676 ret = -EINVAL;
2677 break;
Manishekar Chandrasekaran97e077d2016-03-23 17:10:31 +05302678 case QCSAP_PARAM_CONC_SYSTEM_PREF:
2679 hdd_info("New preference: %d", set_value);
2680 if (!((set_value >= CFG_CONC_SYSTEM_PREF_MIN) &&
2681 (set_value <= CFG_CONC_SYSTEM_PREF_MAX))) {
2682 hdd_err("Invalid system preference %d", set_value);
2683 return -EINVAL;
2684 }
2685 /* hdd_ctx, hdd_ctx->config are already checked for null */
2686 hdd_ctx->config->conc_system_pref = set_value;
2687 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002688 case QCSAP_PARAM_MAX_ASSOC:
2689 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002690 hdd_err("Invalid setMaxAssoc value %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002691 set_value);
2692 ret = -EINVAL;
2693 } else {
2694 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002695 hdd_warn("setMaxAssoc %d > max allowed %d.",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002696 set_value,
2697 WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002698 hdd_warn("Setting it to max allowed and continuing");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002699 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
2700 }
2701 status = sme_cfg_set_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
2702 set_value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302703 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002704 hdd_err("setMaxAssoc failure, status %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002705 status);
2706 ret = -EIO;
2707 }
2708 }
2709 break;
2710
2711 case QCSAP_PARAM_HIDE_SSID:
2712 {
Selvaraj, Sridhar7231c5f2016-09-28 12:42:33 +05302713 QDF_STATUS status;
2714 status = sme_update_session_param(hHal,
2715 pHostapdAdapter->sessionId,
2716 SIR_PARAM_SSID_HIDDEN, set_value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302717 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002718 hdd_err("QCSAP_PARAM_HIDE_SSID failed");
Selvaraj, Sridhar7231c5f2016-09-28 12:42:33 +05302719 return -EIO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002720 }
2721 break;
2722 }
2723 case QCSAP_PARAM_SET_MC_RATE:
2724 {
2725 tSirRateUpdateInd rateUpdate = {0};
2726 struct hdd_config *pConfig = hdd_ctx->config;
2727
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002728 hdd_notice("MC Target rate %d", set_value);
Anurag Chouhanc5548422016-02-24 18:33:27 +05302729 qdf_copy_macaddr(&rateUpdate.bssid,
Srinivas Girigowdaafede182015-11-18 22:36:12 -08002730 &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002731 rateUpdate.nss = (pConfig->enable2x2 == 0) ? 0 : 1;
2732 rateUpdate.dev_mode = pHostapdAdapter->device_mode;
2733 rateUpdate.mcastDataRate24GHz = set_value;
2734 rateUpdate.mcastDataRate24GHzTxFlag = 1;
2735 rateUpdate.mcastDataRate5GHz = set_value;
2736 rateUpdate.bcastDataRate = -1;
2737 status = sme_send_rate_update_ind(hHal, &rateUpdate);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302738 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002739 hdd_err("SET_MC_RATE failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002740 ret = -1;
2741 }
2742 break;
2743 }
2744
2745 case QCSAP_PARAM_SET_TXRX_FW_STATS:
2746 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002747 hdd_notice("QCSAP_PARAM_SET_TXRX_FW_STATS val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002748 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2749 WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
2750 set_value, VDEV_CMD);
2751 break;
2752 }
2753 /* Firmware debug log */
2754 case QCSAP_DBGLOG_LOG_LEVEL:
2755 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002756 hdd_notice("QCSAP_DBGLOG_LOG_LEVEL val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002757 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2758 WMI_DBGLOG_LOG_LEVEL,
2759 set_value, DBG_CMD);
2760 break;
2761 }
2762
2763 case QCSAP_DBGLOG_VAP_ENABLE:
2764 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002765 hdd_notice("QCSAP_DBGLOG_VAP_ENABLE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002766 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2767 WMI_DBGLOG_VAP_ENABLE,
2768 set_value, DBG_CMD);
2769 break;
2770 }
2771
2772 case QCSAP_DBGLOG_VAP_DISABLE:
2773 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002774 hdd_notice("QCSAP_DBGLOG_VAP_DISABLE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002775 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2776 WMI_DBGLOG_VAP_DISABLE,
2777 set_value, DBG_CMD);
2778 break;
2779 }
2780
2781 case QCSAP_DBGLOG_MODULE_ENABLE:
2782 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002783 hdd_notice("QCSAP_DBGLOG_MODULE_ENABLE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002784 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2785 WMI_DBGLOG_MODULE_ENABLE,
2786 set_value, DBG_CMD);
2787 break;
2788 }
2789
2790 case QCSAP_DBGLOG_MODULE_DISABLE:
2791 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002792 hdd_notice("QCSAP_DBGLOG_MODULE_DISABLE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002793 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2794 WMI_DBGLOG_MODULE_DISABLE,
2795 set_value, DBG_CMD);
2796 break;
2797 }
2798
2799 case QCSAP_DBGLOG_MOD_LOG_LEVEL:
2800 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002801 hdd_notice("QCSAP_DBGLOG_MOD_LOG_LEVEL val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002802 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2803 WMI_DBGLOG_MOD_LOG_LEVEL,
2804 set_value, DBG_CMD);
2805 break;
2806 }
2807
2808 case QCSAP_DBGLOG_TYPE:
2809 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002810 hdd_notice("QCSAP_DBGLOG_TYPE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002811 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2812 WMI_DBGLOG_TYPE,
2813 set_value, DBG_CMD);
2814 break;
2815 }
2816 case QCSAP_DBGLOG_REPORT_ENABLE:
2817 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002818 hdd_notice("QCSAP_DBGLOG_REPORT_ENABLE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002819 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2820 WMI_DBGLOG_REPORT_ENABLE,
2821 set_value, DBG_CMD);
2822 break;
2823 }
2824 case QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY:
2825 {
2826 cds_set_mcc_latency(pHostapdAdapter, set_value);
2827 break;
2828 }
2829
2830 case QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA:
2831 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002832 hdd_notice("iwpriv cmd to set MCC quota value %dms",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002833 set_value);
2834 ret = cds_go_set_mcc_p2p_quota(pHostapdAdapter,
2835 set_value);
2836 break;
2837 }
2838
2839 case QCASAP_TXRX_FWSTATS_RESET:
2840 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002841 hdd_notice("WE_TXRX_FWSTATS_RESET val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002842 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2843 WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
2844 set_value, VDEV_CMD);
2845 break;
2846 }
2847
2848 case QCSAP_PARAM_RTSCTS:
2849 {
2850 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2851 WMI_VDEV_PARAM_ENABLE_RTSCTS,
2852 set_value, VDEV_CMD);
2853 if (ret) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002854 hdd_err("FAILED TO SET RTSCTS at SAP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002855 ret = -EIO;
2856 }
2857 break;
2858 }
2859 case QCASAP_SET_11N_RATE:
2860 {
2861 uint8_t preamble = 0, nss = 0, rix = 0;
2862 tsap_Config_t *pConfig =
2863 &pHostapdAdapter->sessionCtx.ap.sapConfig;
2864
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002865 hdd_notice("SET_HT_RATE val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002866
2867 if (set_value != 0xff) {
2868 rix = RC_2_RATE_IDX(set_value);
2869 if (set_value & 0x80) {
2870 if (pConfig->SapHw_mode ==
2871 eCSR_DOT11_MODE_11b
2872 || pConfig->SapHw_mode ==
2873 eCSR_DOT11_MODE_11b_ONLY
2874 || pConfig->SapHw_mode ==
2875 eCSR_DOT11_MODE_11g
2876 || pConfig->SapHw_mode ==
2877 eCSR_DOT11_MODE_11g_ONLY
2878 || pConfig->SapHw_mode ==
2879 eCSR_DOT11_MODE_abg
2880 || pConfig->SapHw_mode ==
2881 eCSR_DOT11_MODE_11a) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002882 hdd_err("Not valid mode for HT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002883 ret = -EIO;
2884 break;
2885 }
2886 preamble = WMI_RATE_PREAMBLE_HT;
2887 nss = HT_RC_2_STREAMS(set_value) - 1;
2888 } else if (set_value & 0x10) {
2889 if (pConfig->SapHw_mode ==
2890 eCSR_DOT11_MODE_11a) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002891 hdd_err("Not valid for cck");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002892 ret = -EIO;
2893 break;
2894 }
2895 preamble = WMI_RATE_PREAMBLE_CCK;
2896 /* Enable Short preamble always
2897 * for CCK except 1mbps
2898 */
2899 if (rix != 0x3)
2900 rix |= 0x4;
2901 } else {
2902 if (pConfig->SapHw_mode ==
2903 eCSR_DOT11_MODE_11b
2904 || pConfig->SapHw_mode ==
2905 eCSR_DOT11_MODE_11b_ONLY) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002906 hdd_err("Not valid for OFDM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002907 ret = -EIO;
2908 break;
2909 }
2910 preamble = WMI_RATE_PREAMBLE_OFDM;
2911 }
2912 set_value = (preamble << 6) | (nss << 4) | rix;
2913 }
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002914 hdd_notice("SET_HT_RATE val %d rix %d preamble %x nss %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002915 set_value, rix, preamble, nss);
2916 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2917 WMI_VDEV_PARAM_FIXED_RATE,
2918 set_value, VDEV_CMD);
2919 break;
2920 }
2921
2922 case QCASAP_SET_VHT_RATE:
2923 {
2924 uint8_t preamble = 0, nss = 0, rix = 0;
2925 tsap_Config_t *pConfig =
2926 &pHostapdAdapter->sessionCtx.ap.sapConfig;
2927
2928 if (pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac &&
2929 pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac_ONLY) {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002930 hdd_err("SET_VHT_RATE error: SapHw_mode= 0x%x, ch = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002931 pConfig->SapHw_mode, pConfig->channel);
2932 ret = -EIO;
2933 break;
2934 }
2935
2936 if (set_value != 0xff) {
2937 rix = RC_2_RATE_IDX_11AC(set_value);
2938 preamble = WMI_RATE_PREAMBLE_VHT;
2939 nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
2940
2941 set_value = (preamble << 6) | (nss << 4) | rix;
2942 }
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002943 hdd_notice("SET_VHT_RATE val %d rix %d preamble %x nss %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002944 set_value, rix, preamble, nss);
2945
2946 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2947 WMI_VDEV_PARAM_FIXED_RATE,
2948 set_value, VDEV_CMD);
2949 break;
2950 }
2951
2952 case QCASAP_SHORT_GI:
2953 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002954 hdd_notice("QCASAP_SET_SHORT_GI val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002955
2956 /* same as 40MHZ */
2957 ret = sme_update_ht_config(hHal, pHostapdAdapter->sessionId,
2958 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
2959 set_value);
2960 if (ret)
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002961 hdd_err("Failed to set ShortGI value ret(%d)", ret);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002962 break;
2963 }
2964
2965 case QCSAP_SET_AMPDU:
2966 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002967 hdd_notice("QCSAP_SET_AMPDU %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002968 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2969 GEN_VDEV_PARAM_AMPDU,
2970 set_value, GEN_CMD);
2971 break;
2972 }
2973
2974 case QCSAP_SET_AMSDU:
2975 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002976 hdd_notice("QCSAP_SET_AMSDU %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002977 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2978 GEN_VDEV_PARAM_AMSDU,
2979 set_value, GEN_CMD);
2980 break;
2981 }
2982 case QCSAP_GTX_HT_MCS:
2983 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002984 hdd_notice("WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002985 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2986 WMI_VDEV_PARAM_GTX_HT_MCS,
2987 set_value, GTX_CMD);
2988 break;
2989 }
2990
2991 case QCSAP_GTX_VHT_MCS:
2992 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07002993 hdd_notice("WMI_VDEV_PARAM_GTX_VHT_MCS %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002994 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2995 WMI_VDEV_PARAM_GTX_VHT_MCS,
2996 set_value, GTX_CMD);
2997 break;
2998 }
2999
3000 case QCSAP_GTX_USRCFG:
3001 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003002 hdd_notice("WMI_VDEV_PARAM_GTX_USR_CFG %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003003 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3004 WMI_VDEV_PARAM_GTX_USR_CFG,
3005 set_value, GTX_CMD);
3006 break;
3007 }
3008
3009 case QCSAP_GTX_THRE:
3010 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003011 hdd_notice("WMI_VDEV_PARAM_GTX_THRE %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003012 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3013 WMI_VDEV_PARAM_GTX_THRE,
3014 set_value, GTX_CMD);
3015 break;
3016 }
3017
3018 case QCSAP_GTX_MARGIN:
3019 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003020 hdd_notice("WMI_VDEV_PARAM_GTX_MARGIN %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003021 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3022 WMI_VDEV_PARAM_GTX_MARGIN,
3023 set_value, GTX_CMD);
3024 break;
3025 }
3026
3027 case QCSAP_GTX_STEP:
3028 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003029 hdd_notice("WMI_VDEV_PARAM_GTX_STEP %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003030 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3031 WMI_VDEV_PARAM_GTX_STEP,
3032 set_value, GTX_CMD);
3033 break;
3034 }
3035
3036 case QCSAP_GTX_MINTPC:
3037 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003038 hdd_notice("WMI_VDEV_PARAM_GTX_MINTPC %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003039 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3040 WMI_VDEV_PARAM_GTX_MINTPC,
3041 set_value, GTX_CMD);
3042 break;
3043 }
3044
3045 case QCSAP_GTX_BWMASK:
3046 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003047 hdd_notice("WMI_VDEV_PARAM_GTX_BWMASK %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003048 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3049 WMI_VDEV_PARAM_GTX_BW_MASK,
3050 set_value, GTX_CMD);
3051 break;
3052 }
3053
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003054 case QCASAP_SET_TM_LEVEL:
3055 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003056 hdd_notice("Set Thermal Mitigation Level %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003057 (void)sme_set_thermal_level(hHal, set_value);
3058 break;
3059 }
3060
3061 case QCASAP_SET_DFS_IGNORE_CAC:
3062 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003063 hdd_notice("Set Dfs ignore CAC %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003064
Krunal Soni056ea0f2016-03-10 13:07:10 -08003065 if (pHostapdAdapter->device_mode != QDF_SAP_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003066 return -EINVAL;
3067
3068 ret = wlansap_set_dfs_ignore_cac(hHal, set_value);
3069 break;
3070 }
3071
3072 case QCASAP_SET_DFS_TARGET_CHNL:
3073 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003074 hdd_notice("Set Dfs target channel %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003075
Krunal Soni056ea0f2016-03-10 13:07:10 -08003076 if (pHostapdAdapter->device_mode != QDF_SAP_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003077 return -EINVAL;
3078
3079 ret = wlansap_set_dfs_target_chnl(hHal, set_value);
3080 break;
3081 }
3082
3083 case QCASAP_SET_DFS_NOL:
3084 wlansap_set_dfs_nol(
Dustin Brown5118e8e2016-09-13 15:54:23 -07003085 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003086 (eSapDfsNolType) set_value);
3087 break;
3088
3089 case QCASAP_SET_RADAR_CMD:
3090 {
3091 hdd_context_t *pHddCtx =
3092 WLAN_HDD_GET_CTX(pHostapdAdapter);
3093 uint8_t ch =
3094 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
3095 operatingChannel;
3096 bool isDfsch;
Arif Hussain2a7c1f32016-07-18 14:24:36 -07003097 int32_t dfs_radar_found;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003098
3099 isDfsch = (CHANNEL_STATE_DFS ==
3100 cds_get_channel_state(ch));
3101
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003102 hdd_notice("Set QCASAP_SET_RADAR_CMD val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003103
Arif Hussain2a7c1f32016-07-18 14:24:36 -07003104 dfs_radar_found = qdf_atomic_read(&pHddCtx->dfs_radar_found);
3105 if (!dfs_radar_found && isDfsch) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003106 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3107 WMA_VDEV_DFS_CONTROL_CMDID,
3108 set_value, VDEV_CMD);
3109 } else {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003110 hdd_err("Ignore, radar_found: %d, dfs_channel: %d",
Arif Hussain2a7c1f32016-07-18 14:24:36 -07003111 dfs_radar_found, isDfsch);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003112 }
3113 break;
3114 }
3115 case QCASAP_TX_CHAINMASK_CMD:
3116 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003117 hdd_notice("QCASAP_TX_CHAINMASK_CMD val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003118 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3119 WMI_PDEV_PARAM_TX_CHAIN_MASK,
3120 set_value, PDEV_CMD);
3121 break;
3122 }
3123
3124 case QCASAP_RX_CHAINMASK_CMD:
3125 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003126 hdd_notice("QCASAP_RX_CHAINMASK_CMD val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003127 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3128 WMI_PDEV_PARAM_RX_CHAIN_MASK,
3129 set_value, PDEV_CMD);
3130 break;
3131 }
3132
3133 case QCASAP_NSS_CMD:
3134 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003135 hdd_notice("QCASAP_NSS_CMD val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003136 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3137 WMI_VDEV_PARAM_NSS,
3138 set_value, VDEV_CMD);
3139 break;
3140 }
3141
3142 case QCSAP_IPA_UC_STAT:
3143 {
3144 /* If input value is non-zero get stats */
3145 switch (set_value) {
3146 case 1:
3147 hdd_ipa_uc_stat_request(pHostapdAdapter, set_value);
3148 break;
3149 case 3:
Yun Parkb187d542016-11-14 18:10:04 -08003150 hdd_ipa_uc_rt_debug_host_dump(hdd_ctx);
3151 break;
3152 case 4:
3153 hdd_ipa_dump_info(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003154 break;
3155 default:
3156 /* place holder for stats clean up
Yun Parkb187d542016-11-14 18:10:04 -08003157 * Stats clean not implemented yet on FW and IPA
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003158 */
3159 break;
3160 }
3161 return ret;
3162 }
3163
3164 case QCASAP_SET_PHYMODE:
3165 {
3166 hdd_context_t *phddctx =
3167 WLAN_HDD_GET_CTX(pHostapdAdapter);
3168
3169 ret =
3170 wlan_hdd_update_phymode(dev, hHal, set_value,
3171 phddctx);
3172 break;
3173 }
3174 case QCASAP_DUMP_STATS:
3175 {
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003176 hdd_notice("QCASAP_DUMP_STATS val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003177 hdd_wlan_dump_stats(pHostapdAdapter, set_value);
3178 break;
3179 }
3180 case QCASAP_CLEAR_STATS:
3181 {
3182 hdd_context_t *hdd_ctx =
3183 WLAN_HDD_GET_CTX(pHostapdAdapter);
Leo Changfdb45c32016-10-28 11:09:23 -07003184 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
3185
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003186 hdd_notice("QCASAP_CLEAR_STATS val %d", set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003187 switch (set_value) {
3188 case WLAN_HDD_STATS:
3189 memset(&pHostapdAdapter->stats, 0,
3190 sizeof(pHostapdAdapter->stats));
3191 memset(&pHostapdAdapter->hdd_stats, 0,
3192 sizeof(pHostapdAdapter->hdd_stats));
3193 break;
3194 case WLAN_TXRX_HIST_STATS:
3195 wlan_hdd_clear_tx_rx_histogram(hdd_ctx);
3196 break;
3197 case WLAN_HDD_NETIF_OPER_HISTORY:
3198 wlan_hdd_clear_netif_queue_history(hdd_ctx);
3199 break;
Nirav Shahbf1b0332016-05-25 14:27:39 +05303200 case WLAN_HIF_STATS:
3201 hdd_clear_hif_stats();
3202 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003203 default:
Leo Changfdb45c32016-10-28 11:09:23 -07003204 if (soc)
3205 cdp_clear_stats(soc, set_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003206 }
3207 break;
3208 }
Govind Singha471e5e2015-10-12 17:11:14 +05303209 case QCSAP_START_FW_PROFILING:
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003210 hdd_notice("QCSAP_START_FW_PROFILING %d", set_value);
Govind Singha471e5e2015-10-12 17:11:14 +05303211 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3212 WMI_WLAN_PROFILE_TRIGGER_CMDID,
3213 set_value, DBG_CMD);
3214 break;
Manjeet Singhe80d6d82016-09-02 19:04:41 +05303215 case QCASAP_PARAM_LDPC:
3216 ret = hdd_set_ldpc(pHostapdAdapter, set_value);
3217 break;
3218 case QCASAP_PARAM_TX_STBC:
3219 ret = hdd_set_tx_stbc(pHostapdAdapter, set_value);
3220 break;
3221 case QCASAP_PARAM_RX_STBC:
3222 ret = hdd_set_rx_stbc(pHostapdAdapter, set_value);
3223 break;
3224
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003225 default:
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003226 hdd_err("Invalid setparam command %d value %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003227 sub_cmd, set_value);
3228 ret = -EINVAL;
3229 break;
3230 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303231 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003232 return ret;
3233}
3234
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07003235/**
3236 * __iw_softap_get_three() - return three value to upper layer.
3237 * @dev: pointer of net_device of this wireless card
3238 * @info: meta data about Request sent
3239 * @wrqu: include request info
3240 * @extra: buf used for in/out
3241 *
3242 * Return: execute result
3243 */
3244static int __iw_softap_get_three(struct net_device *dev,
3245 struct iw_request_info *info,
3246 union iwreq_data *wrqu, char *extra)
3247{
3248 uint32_t *value = (uint32_t *)extra;
3249 uint32_t sub_cmd = value[0];
3250 int ret = 0; /* success */
3251 struct hdd_context_s *hdd_ctx;
3252 struct hdd_adapter_s *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3253
3254 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3255 ret = wlan_hdd_validate_context(hdd_ctx);
3256 if (ret != 0)
3257 return ret;
3258
3259 switch (sub_cmd) {
3260 case QCSAP_GET_TSF:
3261 ret = hdd_indicate_tsf(adapter, value, 3);
3262 break;
3263 default:
Jeff Johnsonedff0d92016-06-30 14:35:19 -07003264 hdd_err("Invalid getparam command %d", sub_cmd);
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07003265 ret = -EINVAL;
3266 break;
3267 }
3268 return ret;
3269}
3270
3271
3272/**
3273 * iw_softap_get_three() - return three value to upper layer.
3274 *
3275 * @dev: pointer of net_device of this wireless card
3276 * @info: meta data about Request sent
3277 * @wrqu: include request info
3278 * @extra: buf used for in/Output
3279 *
3280 * Return: execute result
3281 */
3282static int iw_softap_get_three(struct net_device *dev,
3283 struct iw_request_info *info,
3284 union iwreq_data *wrqu, char *extra)
3285{
3286 int ret;
3287
3288 cds_ssr_protect(__func__);
3289 ret = __iw_softap_get_three(dev, info, wrqu, extra);
3290 cds_ssr_unprotect(__func__);
3291
3292 return ret;
3293}
3294
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003295int
3296static iw_softap_setparam(struct net_device *dev,
3297 struct iw_request_info *info,
3298 union iwreq_data *wrqu, char *extra)
3299{
3300 int ret;
3301
3302 cds_ssr_protect(__func__);
3303 ret = __iw_softap_setparam(dev, info, wrqu, extra);
3304 cds_ssr_unprotect(__func__);
3305
3306 return ret;
3307}
3308
3309int
3310static __iw_softap_getparam(struct net_device *dev,
3311 struct iw_request_info *info,
3312 union iwreq_data *wrqu, char *extra)
3313{
3314 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3315 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3316 int *value = (int *)extra;
3317 int sub_cmd = value[0];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303318 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003319 int ret;
3320 hdd_context_t *hdd_ctx;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05303321 uint8_t nol[QDF_MAX_NUM_CHAN];
3322 uint32_t nol_len = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003323
Jeff Johnson02050312016-02-11 18:40:28 -08003324 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303325
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003326 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3327 ret = wlan_hdd_validate_context(hdd_ctx);
3328 if (0 != ret)
3329 return ret;
3330
3331 switch (sub_cmd) {
3332 case QCSAP_PARAM_MAX_ASSOC:
3333 status =
3334 sme_cfg_get_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
3335 (uint32_t *) value);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303336 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003337 hdd_err("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003338 status);
3339 ret = -EIO;
3340 }
3341 break;
3342
3343 case QCSAP_PARAM_AUTO_CHANNEL:
3344 *value = (WLAN_HDD_GET_CTX
3345 (pHostapdAdapter))->config->force_sap_acs;
3346 break;
3347
3348 case QCSAP_PARAM_GET_WLAN_DBG:
3349 {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303350 qdf_trace_display();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003351 *value = 0;
3352 break;
3353 }
3354
3355 case QCSAP_PARAM_RTSCTS:
3356 {
3357 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3358 WMI_VDEV_PARAM_ENABLE_RTSCTS,
3359 VDEV_CMD);
3360 break;
3361 }
3362
3363 case QCASAP_SHORT_GI:
3364 {
3365 *value = (int)sme_get_ht_config(hHal,
3366 pHostapdAdapter->
3367 sessionId,
3368 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
3369 break;
3370 }
3371
3372 case QCSAP_GTX_HT_MCS:
3373 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003374 hdd_notice("GET WMI_VDEV_PARAM_GTX_HT_MCS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003375 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3376 WMI_VDEV_PARAM_GTX_HT_MCS,
3377 GTX_CMD);
3378 break;
3379 }
3380
3381 case QCSAP_GTX_VHT_MCS:
3382 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003383 hdd_notice("GET WMI_VDEV_PARAM_GTX_VHT_MCS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003384 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3385 WMI_VDEV_PARAM_GTX_VHT_MCS,
3386 GTX_CMD);
3387 break;
3388 }
3389
3390 case QCSAP_GTX_USRCFG:
3391 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003392 hdd_notice("GET WMI_VDEV_PARAM_GTX_USR_CFG");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003393 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3394 WMI_VDEV_PARAM_GTX_USR_CFG,
3395 GTX_CMD);
3396 break;
3397 }
3398
3399 case QCSAP_GTX_THRE:
3400 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003401 hdd_notice("GET WMI_VDEV_PARAM_GTX_THRE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003402 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3403 WMI_VDEV_PARAM_GTX_THRE,
3404 GTX_CMD);
3405 break;
3406 }
3407
3408 case QCSAP_GTX_MARGIN:
3409 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003410 hdd_notice("GET WMI_VDEV_PARAM_GTX_MARGIN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003411 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3412 WMI_VDEV_PARAM_GTX_MARGIN,
3413 GTX_CMD);
3414 break;
3415 }
3416
3417 case QCSAP_GTX_STEP:
3418 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003419 hdd_notice("GET WMI_VDEV_PARAM_GTX_STEP");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003420 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3421 WMI_VDEV_PARAM_GTX_STEP,
3422 GTX_CMD);
3423 break;
3424 }
3425
3426 case QCSAP_GTX_MINTPC:
3427 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003428 hdd_notice("GET WMI_VDEV_PARAM_GTX_MINTPC");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003429 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3430 WMI_VDEV_PARAM_GTX_MINTPC,
3431 GTX_CMD);
3432 break;
3433 }
3434
3435 case QCSAP_GTX_BWMASK:
3436 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003437 hdd_notice("GET WMI_VDEV_PARAM_GTX_BW_MASK");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003438 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3439 WMI_VDEV_PARAM_GTX_BW_MASK,
3440 GTX_CMD);
3441 break;
3442 }
3443
3444 case QCASAP_GET_DFS_NOL:
3445 {
3446 wlansap_get_dfs_nol(
Dustin Brown5118e8e2016-09-13 15:54:23 -07003447 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
3448 nol, &nol_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003449 }
3450 break;
3451
3452 case QCSAP_GET_ACL:
3453 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003454 hdd_notice("QCSAP_GET_ACL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003455 if (hdd_print_acl(pHostapdAdapter) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303456 QDF_STATUS_SUCCESS) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003457 hdd_err("QCSAP_GET_ACL returned Error: not completed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003458 }
3459 *value = 0;
3460 break;
3461 }
3462
3463 case QCASAP_TX_CHAINMASK_CMD:
3464 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003465 hdd_notice("QCASAP_TX_CHAINMASK_CMD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003466 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3467 WMI_PDEV_PARAM_TX_CHAIN_MASK,
3468 PDEV_CMD);
3469 break;
3470 }
3471
3472 case QCASAP_RX_CHAINMASK_CMD:
3473 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003474 hdd_notice("QCASAP_RX_CHAINMASK_CMD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003475 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3476 WMI_PDEV_PARAM_RX_CHAIN_MASK,
3477 PDEV_CMD);
3478 break;
3479 }
3480
3481 case QCASAP_NSS_CMD:
3482 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003483 hdd_notice("QCASAP_NSS_CMD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003484 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3485 WMI_VDEV_PARAM_NSS,
3486 VDEV_CMD);
3487 break;
3488 }
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07003489 case QCSAP_CAP_TSF:
3490 ret = hdd_capture_tsf(pHostapdAdapter, (uint32_t *)value, 1);
3491 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003492 case QCASAP_GET_TEMP_CMD:
3493 {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003494 hdd_notice("QCASAP_GET_TEMP_CMD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003495 ret = wlan_hdd_get_temperature(pHostapdAdapter, value);
3496 break;
3497 }
Govind Singha471e5e2015-10-12 17:11:14 +05303498 case QCSAP_GET_FW_PROFILE_DATA:
Jeff Johnsonb8491892016-06-30 14:44:04 -07003499 hdd_notice("QCSAP_GET_FW_PROFILE_DATA");
Govind Singha471e5e2015-10-12 17:11:14 +05303500 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3501 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
3502 0, DBG_CMD);
3503 break;
Manjeet Singhe80d6d82016-09-02 19:04:41 +05303504 case QCASAP_PARAM_LDPC:
3505 {
3506 ret = hdd_get_ldpc(pHostapdAdapter, value);
3507 break;
3508 }
3509 case QCASAP_PARAM_TX_STBC:
3510 {
3511 ret = hdd_get_tx_stbc(pHostapdAdapter, value);
3512 break;
3513 }
3514 case QCASAP_PARAM_RX_STBC:
3515 {
3516 ret = hdd_get_rx_stbc(pHostapdAdapter, value);
3517 break;
3518 }
Kai Liubdd5fcb2016-09-28 22:55:44 +08003519 case QCSAP_PARAM_CHAN_WIDTH:
3520 {
3521 ret = hdd_sap_get_chan_width(pHostapdAdapter, value);
3522 break;
3523 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003524 default:
Jeff Johnsonb8491892016-06-30 14:44:04 -07003525 hdd_err("Invalid getparam command %d", sub_cmd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003526 ret = -EINVAL;
3527 break;
3528
3529 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303530 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003531 return ret;
3532}
3533
3534int
3535static iw_softap_getparam(struct net_device *dev,
3536 struct iw_request_info *info,
3537 union iwreq_data *wrqu, char *extra)
3538{
3539 int ret;
3540
3541 cds_ssr_protect(__func__);
3542 ret = __iw_softap_getparam(dev, info, wrqu, extra);
3543 cds_ssr_unprotect(__func__);
3544
3545 return ret;
3546}
3547
3548/* Usage:
3549 BLACK_LIST = 0
3550 WHITE_LIST = 1
3551 ADD MAC = 0
3552 REMOVE MAC = 1
3553
3554 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
3555 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
3556 while using this ioctl
3557
3558 Syntax:
3559 iwpriv softap.0 modify_acl
3560 <6 octet mac addr> <list type> <cmd type>
3561
3562 Examples:
3563 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
3564 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
3565 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
3566 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
3567 */
3568static
3569int __iw_softap_modify_acl(struct net_device *dev,
3570 struct iw_request_info *info,
3571 union iwreq_data *wrqu, char *extra)
3572{
3573 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003574 uint8_t *value = (uint8_t *) extra;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303575 uint8_t pPeerStaMac[QDF_MAC_ADDR_SIZE];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003576 int listType, cmd, i;
3577 int ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303578 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003579 hdd_context_t *hdd_ctx;
3580
Jeff Johnson02050312016-02-11 18:40:28 -08003581 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003582
3583 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3584 ret = wlan_hdd_validate_context(hdd_ctx);
3585 if (0 != ret)
3586 return ret;
3587
Anurag Chouhan6d760662016-02-20 16:05:43 +05303588 for (i = 0; i < QDF_MAC_ADDR_SIZE; i++)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003589 pPeerStaMac[i] = *(value + i);
3590
3591 listType = (int)(*(value + i));
3592 i++;
3593 cmd = (int)(*(value + i));
3594
Jeff Johnsonb8491892016-06-30 14:44:04 -07003595 hdd_notice("Modify ACL mac:" MAC_ADDRESS_STR " type: %d cmd: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003596 MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
3597
Dustin Brown5118e8e2016-09-13 15:54:23 -07003598 qdf_status = wlansap_modify_acl(
3599 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
3600 pPeerStaMac, (eSapACLType) listType, (eSapACLCmdType) cmd);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303601 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003602 hdd_err("Modify ACL failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003603 ret = -EIO;
3604 }
3605 EXIT();
3606 return ret;
3607}
3608
3609static
3610int iw_softap_modify_acl(struct net_device *dev,
3611 struct iw_request_info *info,
3612 union iwreq_data *wrqu, char *extra)
3613{
3614 int ret;
3615
3616 cds_ssr_protect(__func__);
3617 ret = __iw_softap_modify_acl(dev, info, wrqu, extra);
3618 cds_ssr_unprotect(__func__);
3619
3620 return ret;
3621}
3622
3623int
3624static __iw_softap_getchannel(struct net_device *dev,
3625 struct iw_request_info *info,
3626 union iwreq_data *wrqu, char *extra)
3627{
3628 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3629 hdd_context_t *hdd_ctx;
3630 int *value = (int *)extra;
3631 int ret;
3632
Jeff Johnson02050312016-02-11 18:40:28 -08003633 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303634
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003635 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3636 ret = wlan_hdd_validate_context(hdd_ctx);
3637 if (0 != ret)
3638 return ret;
3639
3640 *value = 0;
3641 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
3642 *value = (WLAN_HDD_GET_AP_CTX_PTR(
3643 pHostapdAdapter))->operatingChannel;
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303644 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003645 return 0;
3646}
3647
3648int
3649static iw_softap_getchannel(struct net_device *dev,
3650 struct iw_request_info *info,
3651 union iwreq_data *wrqu, char *extra)
3652{
3653 int ret;
3654
3655 cds_ssr_protect(__func__);
3656 ret = __iw_softap_getchannel(dev, info, wrqu, extra);
3657 cds_ssr_unprotect(__func__);
3658
3659 return ret;
3660}
3661
3662int
3663static __iw_softap_set_max_tx_power(struct net_device *dev,
3664 struct iw_request_info *info,
3665 union iwreq_data *wrqu, char *extra)
3666{
3667 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3668 hdd_context_t *hdd_ctx;
3669 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3670 int *value = (int *)extra;
3671 int set_value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003672 int ret;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303673 struct qdf_mac_addr bssid = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
3674 struct qdf_mac_addr selfMac = QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003675
Jeff Johnson02050312016-02-11 18:40:28 -08003676 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303677
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003678 if (NULL == value)
3679 return -ENOMEM;
3680
3681 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3682 ret = wlan_hdd_validate_context(hdd_ctx);
3683 if (0 != ret)
3684 return ret;
3685
3686 /* Assign correct slef MAC address */
Anurag Chouhanc5548422016-02-24 18:33:27 +05303687 qdf_copy_macaddr(&bssid, &pHostapdAdapter->macAddressCurrent);
3688 qdf_copy_macaddr(&selfMac, &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003689
3690 set_value = value[0];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303691 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003692 sme_set_max_tx_power(hHal, bssid, selfMac, set_value)) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003693 hdd_err("Setting maximum tx power failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003694 return -EIO;
3695 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303696 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003697 return 0;
3698}
3699
3700int
3701static iw_softap_set_max_tx_power(struct net_device *dev,
3702 struct iw_request_info *info,
3703 union iwreq_data *wrqu, char *extra)
3704{
3705 int ret;
3706
3707 cds_ssr_protect(__func__);
3708 ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
3709 cds_ssr_unprotect(__func__);
3710
3711 return ret;
3712}
3713
3714int
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08003715static __iw_softap_set_pktlog(struct net_device *dev,
3716 struct iw_request_info *info,
3717 union iwreq_data *wrqu, char *extra)
3718{
3719 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
3720 hdd_context_t *hdd_ctx;
3721 int *value = (int *)extra;
3722
3723 ENTER_DEV(dev);
3724
3725 if (NULL == value)
3726 return -ENOMEM;
3727
Poddar, Siddarth176c4362016-10-03 12:25:00 +05303728 if (wrqu->data.length < 1 || wrqu->data.length > 2) {
3729 hdd_err("pktlog: either 1 or 2 parameters are required");
3730 return -EINVAL;
3731 }
3732
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08003733 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Poddar, Siddarth176c4362016-10-03 12:25:00 +05303734 return hdd_process_pktlog_command(hdd_ctx, value[0], value[1]);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08003735}
3736
3737int
3738static iw_softap_set_pktlog(struct net_device *dev,
3739 struct iw_request_info *info,
3740 union iwreq_data *wrqu, char *extra)
3741{
3742 int ret;
3743
3744 cds_ssr_protect(__func__);
3745 ret = __iw_softap_set_pktlog(dev, info, wrqu, extra);
3746 cds_ssr_unprotect(__func__);
3747
3748 return ret;
3749}
3750
3751
3752int
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003753static __iw_softap_set_tx_power(struct net_device *dev,
3754 struct iw_request_info *info,
3755 union iwreq_data *wrqu, char *extra)
3756{
3757 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3758 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3759 hdd_context_t *hdd_ctx;
3760 int *value = (int *)extra;
3761 int set_value;
Anurag Chouhan6d760662016-02-20 16:05:43 +05303762 struct qdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003763 int ret;
3764
Jeff Johnson02050312016-02-11 18:40:28 -08003765 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303766
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003767 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3768 ret = wlan_hdd_validate_context(hdd_ctx);
3769 if (0 != ret)
3770 return ret;
3771
3772 if (NULL == value)
3773 return -ENOMEM;
3774
Anurag Chouhanc5548422016-02-24 18:33:27 +05303775 qdf_copy_macaddr(&bssid, &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003776
3777 set_value = value[0];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303778 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003779 sme_set_tx_power(hHal, pHostapdAdapter->sessionId, bssid,
3780 pHostapdAdapter->device_mode, set_value)) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003781 hdd_err("Setting tx power failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003782 return -EIO;
3783 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303784 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003785 return 0;
3786}
3787
3788int
3789static iw_softap_set_tx_power(struct net_device *dev,
3790 struct iw_request_info *info,
3791 union iwreq_data *wrqu, char *extra)
3792{
3793 int ret;
3794
3795 cds_ssr_protect(__func__);
3796 ret = __iw_softap_set_tx_power(dev, info, wrqu, extra);
3797 cds_ssr_unprotect(__func__);
3798
3799 return ret;
3800}
3801
3802#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
3803
3804int
3805static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
3806 struct iw_request_info *info,
3807 union iwreq_data *wrqu, char *extra)
3808{
3809 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3810 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
3811 hdd_context_t *hdd_ctx;
3812 char *buf;
3813 int cnt = 0;
3814 int left;
3815 int ret;
3816 /* maclist_index must be u32 to match userspace */
3817 u32 maclist_index;
3818
Jeff Johnson02050312016-02-11 18:40:28 -08003819 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303820
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003821 /*
3822 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
3823 * number, and even numbered iocts are supposed to have "set"
3824 * semantics. Hence the wireless extensions support in the kernel
3825 * won't correctly copy the result to userspace, so the ioctl
3826 * handler itself must copy the data. Output format is 32-bit
3827 * record length, followed by 0 or more 6-byte STA MAC addresses.
3828 *
3829 * Further note that due to the incorrect semantics, the "iwpriv"
3830 * userspace application is unable to correctly invoke this API,
3831 * hence it is not registered in the hostapd_private_args. This
3832 * API can only be invoked by directly invoking the ioctl() system
3833 * call.
3834 */
3835
3836 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3837 ret = wlan_hdd_validate_context(hdd_ctx);
3838 if (0 != ret)
3839 return ret;
3840
3841 /* make sure userspace allocated a reasonable buffer size */
3842 if (wrqu->data.length < sizeof(maclist_index)) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003843 hdd_notice("invalid userspace buffer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003844 return -EINVAL;
3845 }
3846
3847 /* allocate local buffer to build the response */
3848 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
3849 if (!buf) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003850 hdd_notice("failed to allocate response buffer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003851 return -ENOMEM;
3852 }
3853
3854 /* start indexing beyond where the record count will be written */
3855 maclist_index = sizeof(maclist_index);
3856 left = wrqu->data.length - maclist_index;
3857
3858 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303859 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= QDF_MAC_ADDR_SIZE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003860 if ((pStaInfo[cnt].isUsed) &&
3861 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
3862 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
Anurag Chouhan6d760662016-02-20 16:05:43 +05303863 QDF_MAC_ADDR_SIZE);
3864 maclist_index += QDF_MAC_ADDR_SIZE;
3865 left -= QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003866 }
3867 cnt++;
3868 }
3869 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
3870
3871 *((u32 *) buf) = maclist_index;
3872 wrqu->data.length = maclist_index;
3873 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003874 hdd_notice("failed to copy response to user buffer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003875 ret = -EFAULT;
3876 }
3877 kfree(buf);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303878 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003879 return ret;
3880}
3881
3882int
3883static iw_softap_getassoc_stamacaddr(struct net_device *dev,
3884 struct iw_request_info *info,
3885 union iwreq_data *wrqu, char *extra)
3886{
3887 int ret;
3888
3889 cds_ssr_protect(__func__);
3890 ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
3891 cds_ssr_unprotect(__func__);
3892
3893 return ret;
3894}
3895
3896/* Usage:
3897 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
3898 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
3899 while using this ioctl
3900
3901 Syntax:
3902 iwpriv softap.0 disassoc_sta <6 octet mac address>
3903
3904 e.g.
3905 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
3906 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
3907 */
3908
3909int
3910static __iw_softap_disassoc_sta(struct net_device *dev,
3911 struct iw_request_info *info,
3912 union iwreq_data *wrqu, char *extra)
3913{
3914 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3915 hdd_context_t *hdd_ctx;
3916 uint8_t *peerMacAddr;
3917 int ret;
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +05303918 struct tagCsrDelStaParams del_sta_params;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003919
Jeff Johnson02050312016-02-11 18:40:28 -08003920 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003921
Mukul Sharma744420f2015-11-02 19:49:13 +05303922 if (!capable(CAP_NET_ADMIN)) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07003923 hdd_err("permission check failed");
Mukul Sharma744420f2015-11-02 19:49:13 +05303924 return -EPERM;
3925 }
3926
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003927 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3928 ret = wlan_hdd_validate_context(hdd_ctx);
3929 if (0 != ret)
3930 return ret;
3931
3932 /* iwpriv tool or framework calls this ioctl with
3933 * data passed in extra (less than 16 octets);
3934 */
3935 peerMacAddr = (uint8_t *) (extra);
3936
Jeff Johnsonb8491892016-06-30 14:44:04 -07003937 hdd_notice("data " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003938 MAC_ADDR_ARRAY(peerMacAddr));
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +05303939 wlansap_populate_del_sta_params(peerMacAddr,
3940 eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
3941 (SIR_MAC_MGMT_DISASSOC >> 4),
3942 &del_sta_params);
3943 hdd_softap_sta_disassoc(pHostapdAdapter, &del_sta_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003944 EXIT();
3945 return 0;
3946}
3947
3948int
3949static iw_softap_disassoc_sta(struct net_device *dev,
3950 struct iw_request_info *info,
3951 union iwreq_data *wrqu, char *extra)
3952{
3953 int ret;
3954
3955 cds_ssr_protect(__func__);
3956 ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
3957 cds_ssr_unprotect(__func__);
3958
3959 return ret;
3960}
3961
Govind Singha471e5e2015-10-12 17:11:14 +05303962/**
3963 * iw_get_char_setnone() - Generic "get char" private ioctl handler
3964 * @dev: device upon which the ioctl was received
3965 * @info: ioctl request information
3966 * @wrqu: ioctl request data
3967 * @extra: ioctl extra data
3968 *
3969 * Return: 0 on success, non-zero on error
3970 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003971static int __iw_get_char_setnone(struct net_device *dev,
3972 struct iw_request_info *info,
3973 union iwreq_data *wrqu, char *extra)
3974{
3975 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Govind Singha471e5e2015-10-12 17:11:14 +05303976 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003977 int sub_cmd = wrqu->data.flags;
3978 hdd_context_t *hdd_ctx;
3979
Jeff Johnson02050312016-02-11 18:40:28 -08003980 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003981
3982 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Govind Singha471e5e2015-10-12 17:11:14 +05303983 ret = wlan_hdd_validate_context(hdd_ctx);
3984 if (ret != 0)
3985 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003986
3987 switch (sub_cmd) {
3988 case QCSAP_GET_STATS:
3989 hdd_wlan_get_stats(adapter, &(wrqu->data.length),
3990 extra, WE_MAX_STR_LEN);
3991 break;
Govind Singha471e5e2015-10-12 17:11:14 +05303992 case QCSAP_LIST_FW_PROFILE:
3993 hdd_wlan_list_fw_profile(&(wrqu->data.length),
3994 extra, WE_MAX_STR_LEN);
3995 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003996 }
3997
3998 EXIT();
Govind Singha471e5e2015-10-12 17:11:14 +05303999 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004000}
4001
4002static int iw_get_char_setnone(struct net_device *dev,
4003 struct iw_request_info *info,
4004 union iwreq_data *wrqu, char *extra)
4005{
4006 int ret;
4007
4008 cds_ssr_protect(__func__);
4009 ret = __iw_get_char_setnone(dev, info, wrqu, extra);
4010 cds_ssr_unprotect(__func__);
4011
4012 return ret;
4013}
4014
4015static int wlan_hdd_set_force_acs_ch_range(struct net_device *dev,
4016 struct iw_request_info *info,
4017 union iwreq_data *wrqu, char *extra)
4018{
4019 hdd_adapter_t *adapter = (netdev_priv(dev));
4020 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4021 int *value = (int *)extra;
4022
Jeff Johnson02050312016-02-11 18:40:28 -08004023 ENTER_DEV(dev);
4024
Hanumantha Reddy Pothula3b8c0a52015-11-05 10:59:21 +05304025 if (!capable(CAP_NET_ADMIN)) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07004026 hdd_err("permission check failed");
Hanumantha Reddy Pothula3b8c0a52015-11-05 10:59:21 +05304027 return -EPERM;
4028 }
4029
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004030 if (wlan_hdd_validate_operation_channel(adapter, value[0]) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304031 QDF_STATUS_SUCCESS ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004032 wlan_hdd_validate_operation_channel(adapter, value[1]) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304033 QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004034 return -EINVAL;
4035 } else {
4036 hdd_ctx->config->force_sap_acs_st_ch = value[0];
4037 hdd_ctx->config->force_sap_acs_end_ch = value[1];
4038 }
4039
4040 return 0;
4041}
4042
4043static int iw_softap_set_force_acs_ch_range(struct net_device *dev,
4044 struct iw_request_info *info,
4045 union iwreq_data *wrqu, char *extra)
4046{
4047 int ret;
4048 cds_ssr_protect(__func__);
4049 ret = wlan_hdd_set_force_acs_ch_range(dev, info, wrqu, extra);
4050 cds_ssr_unprotect(__func__);
4051 return ret;
4052}
4053
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05304054static int __iw_get_channel_list(struct net_device *dev,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004055 struct iw_request_info *info,
4056 union iwreq_data *wrqu, char *extra)
4057{
4058 uint32_t num_channels = 0;
4059 uint8_t i = 0;
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05304060 uint8_t band_start_channel = CHAN_ENUM_1;
4061 uint8_t band_end_channel = CHAN_ENUM_184;
4062 hdd_adapter_t *hostapd_adapter = (netdev_priv(dev));
4063 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(hostapd_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004064 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05304065 eCsrBand cur_band = eCSR_BAND_ALL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004066 hdd_context_t *hdd_ctx;
4067 int ret;
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05304068 bool is_dfs_mode_enabled = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004069
Jeff Johnson02050312016-02-11 18:40:28 -08004070 ENTER_DEV(dev);
4071
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05304072 hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004073 ret = wlan_hdd_validate_context(hdd_ctx);
4074 if (0 != ret)
4075 return ret;
4076
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05304077 if (QDF_STATUS_SUCCESS != sme_get_freq_band(hal, &cur_band)) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07004078 hdd_err("not able get the current frequency band");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004079 return -EIO;
4080 }
4081 wrqu->data.length = sizeof(tChannelListInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004082
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05304083 if (eCSR_BAND_24 == cur_band) {
4084 band_start_channel = CHAN_ENUM_1;
4085 band_end_channel = CHAN_ENUM_14;
4086 } else if (eCSR_BAND_5G == cur_band) {
4087 band_start_channel = CHAN_ENUM_36;
4088 band_end_channel = CHAN_ENUM_184;
4089 }
4090 if (cur_band != eCSR_BAND_24) {
4091 if (hdd_ctx->config->dot11p_mode)
4092 band_end_channel = CHAN_ENUM_184;
4093 else
4094 band_end_channel = CHAN_ENUM_165;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004095 }
4096
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05304097 if (hostapd_adapter->device_mode == QDF_STA_MODE &&
4098 hdd_ctx->config->enableDFSChnlScan) {
4099 is_dfs_mode_enabled = true;
4100 } else if (hostapd_adapter->device_mode == QDF_SAP_MODE &&
4101 hdd_ctx->config->enableDFSMasterCap) {
4102 is_dfs_mode_enabled = true;
4103 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004104
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05304105 hdd_notice("curBand = %d, StartChannel = %hu, EndChannel = %hu is_dfs_mode_enabled = %d ",
4106 cur_band, band_start_channel, band_end_channel,
4107 is_dfs_mode_enabled);
4108
4109 for (i = band_start_channel; i <= band_end_channel; i++) {
Amar Singhal7a1726a2015-10-14 16:28:11 -07004110 if ((CHANNEL_STATE_ENABLE == CDS_CHANNEL_STATE(i)) ||
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05304111 (is_dfs_mode_enabled &&
4112 CHANNEL_STATE_DFS == CDS_CHANNEL_STATE(i))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004113 channel_list->channels[num_channels] =
Amar Singhal7a1726a2015-10-14 16:28:11 -07004114 CDS_CHANNEL_NUM(i);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004115 num_channels++;
4116 }
4117 }
4118
Jeff Johnsonb8491892016-06-30 14:44:04 -07004119 hdd_notice(" number of channels %d", num_channels);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004120
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004121 channel_list->num_channels = num_channels;
4122 EXIT();
4123
4124 return 0;
4125}
4126
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05304127int iw_get_channel_list(struct net_device *dev,
4128 struct iw_request_info *info,
4129 union iwreq_data *wrqu, char *extra)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004130{
4131 int ret;
4132
4133 cds_ssr_protect(__func__);
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05304134 ret = __iw_get_channel_list(dev, info, wrqu, extra);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004135 cds_ssr_unprotect(__func__);
4136
4137 return ret;
4138}
4139
4140static
4141int __iw_get_genie(struct net_device *dev,
4142 struct iw_request_info *info,
4143 union iwreq_data *wrqu, char *extra)
4144{
4145 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4146 hdd_context_t *hdd_ctx;
4147 int ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304148 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004149 uint32_t length = DOT11F_IE_RSN_MAX_LEN;
4150 uint8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
4151
Jeff Johnson02050312016-02-11 18:40:28 -08004152 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004153
4154 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4155 ret = wlan_hdd_validate_context(hdd_ctx);
4156 if (0 != ret)
4157 return ret;
4158
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004159 /*
4160 * Actually retrieve the RSN IE from CSR.
4161 * (We previously sent it down in the CSR Roam Profile.)
4162 */
4163 status = wlan_sap_getstation_ie_information(
Dustin Brown5118e8e2016-09-13 15:54:23 -07004164 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004165 &length, genIeBytes);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304166 if (status == QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004167 wrqu->data.length = length;
Manjeet Singhfde0c042016-09-03 12:08:09 +05304168 if (length > DOT11F_IE_RSN_MAX_LEN) {
4169 hdd_notice("invalid buffer length length:%d", length);
4170 return -E2BIG;
4171 }
4172 qdf_mem_copy(extra, genIeBytes, length);
Jeff Johnsonb8491892016-06-30 14:44:04 -07004173 hdd_notice(" RSN IE of %d bytes returned",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004174 wrqu->data.length);
4175 } else {
4176 wrqu->data.length = 0;
Jeff Johnsonb8491892016-06-30 14:44:04 -07004177 hdd_notice(" RSN IE failed to populate");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004178 }
4179
4180 EXIT();
4181 return 0;
4182}
4183
4184static
4185int iw_get_genie(struct net_device *dev,
4186 struct iw_request_info *info,
4187 union iwreq_data *wrqu, char *extra)
4188{
4189 int ret;
4190
4191 cds_ssr_protect(__func__);
4192 ret = __iw_get_genie(dev, info, wrqu, extra);
4193 cds_ssr_unprotect(__func__);
4194
4195 return ret;
4196}
4197
4198static
4199int __iw_get_wpspbc_probe_req_ies(struct net_device *dev,
4200 struct iw_request_info *info,
4201 union iwreq_data *wrqu, char *extra)
4202{
4203 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4204 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
4205 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
4206 hdd_context_t *hdd_ctx;
4207 int ret;
4208
Jeff Johnson02050312016-02-11 18:40:28 -08004209 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004210
4211 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4212 ret = wlan_hdd_validate_context(hdd_ctx);
4213 if (0 != ret)
4214 return ret;
4215
Jeff Johnsonb8491892016-06-30 14:44:04 -07004216 hdd_notice("get_WPSPBCProbeReqIEs ioctl");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004217 memset((void *)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
4218
4219 WPSPBCProbeReqIEs.probeReqIELen =
4220 pHddApCtx->WPSPBCProbeReq.probeReqIELen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304221 qdf_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004222 pHddApCtx->WPSPBCProbeReq.probeReqIE,
4223 WPSPBCProbeReqIEs.probeReqIELen);
Anurag Chouhanc5548422016-02-24 18:33:27 +05304224 qdf_copy_macaddr(&WPSPBCProbeReqIEs.macaddr,
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08004225 &pHddApCtx->WPSPBCProbeReq.peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004226 if (copy_to_user(wrqu->data.pointer,
4227 (void *)&WPSPBCProbeReqIEs,
4228 sizeof(WPSPBCProbeReqIEs))) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07004229 hdd_notice("failed to copy data to user buffer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004230 return -EFAULT;
4231 }
4232 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08004233 hdd_info("Macaddress : " MAC_ADDRESS_STR,
4234 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004235 up(&pHddApCtx->semWpsPBCOverlapInd);
4236 EXIT();
4237 return 0;
4238}
4239
4240static
4241int iw_get_wpspbc_probe_req_ies(struct net_device *dev,
4242 struct iw_request_info *info,
4243 union iwreq_data *wrqu, char *extra)
4244{
4245 int ret;
4246
4247 cds_ssr_protect(__func__);
4248 ret = __iw_get_wpspbc_probe_req_ies(dev, info, wrqu, extra);
4249 cds_ssr_unprotect(__func__);
4250
4251 return ret;
4252}
4253
4254/**
4255 * __iw_set_auth_hostap() -
4256 * This function sets the auth type received from the wpa_supplicant.
4257 *
4258 * @dev: pointer to the net device.
4259 * @info: pointer to the iw_request_info.
4260 * @wrqu: pointer to the iwreq_data.
4261 * @extra: pointer to the data.
4262 *
4263 * Return: 0 for success, non zero for failure
4264 */
4265static
4266int __iw_set_auth_hostap(struct net_device *dev, struct iw_request_info *info,
4267 union iwreq_data *wrqu, char *extra)
4268{
4269 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4270 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4271 hdd_context_t *hdd_ctx;
4272 int ret;
4273
Jeff Johnson651f9f22016-02-11 18:16:11 -08004274 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004275
4276 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4277 ret = wlan_hdd_validate_context(hdd_ctx);
4278 if (0 != ret)
4279 return ret;
4280
4281 switch (wrqu->param.flags & IW_AUTH_INDEX) {
4282 case IW_AUTH_TKIP_COUNTERMEASURES:
4283 {
4284 if (wrqu->param.value) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07004285 hdd_info("Counter Measure started %d",
4286 wrqu->param.value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004287 pWextState->mTKIPCounterMeasures =
4288 TKIP_COUNTER_MEASURE_STARTED;
4289 } else {
Jeff Johnsonb8491892016-06-30 14:44:04 -07004290 hdd_info("Counter Measure stopped=%d",
4291 wrqu->param.value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004292 pWextState->mTKIPCounterMeasures =
4293 TKIP_COUNTER_MEASURE_STOPED;
4294 }
4295
4296 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
4297 wrqu->param.
4298 value);
4299 }
4300 break;
4301
4302 default:
4303
Jeff Johnsonb8491892016-06-30 14:44:04 -07004304 hdd_warn("called with unsupported auth type %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004305 wrqu->param.flags & IW_AUTH_INDEX);
4306 break;
4307 }
4308
4309 EXIT();
4310 return 0;
4311}
4312
4313/**
4314 * iw_set_auth_hostap() - Wrapper function to protect __iw_set_auth_hostap
4315 * from the SSR.
4316 *
4317 * @dev - Pointer to the net device.
4318 * @info - Pointer to the iw_request_info.
4319 * @wrqu - Pointer to the iwreq_data.
4320 * @extra - Pointer to the data.
4321 *
4322 * Return: 0 for success, non zero for failure.
4323 */
4324static int
4325iw_set_auth_hostap(struct net_device *dev,
4326 struct iw_request_info *info,
4327 union iwreq_data *wrqu, char *extra)
4328{
4329 int ret;
4330
4331 cds_ssr_protect(__func__);
4332 ret = __iw_set_auth_hostap(dev, info, wrqu, extra);
4333 cds_ssr_unprotect(__func__);
4334
4335 return ret;
4336}
4337
4338/**
4339 * __iw_set_ap_encodeext() - set ap encode
4340 *
4341 * @dev - Pointer to the net device.
4342 * @info - Pointer to the iw_request_info.
4343 * @wrqu - Pointer to the iwreq_data.
4344 * @extra - Pointer to the data.
4345 *
4346 * Return: 0 for success, non zero for failure.
4347 */
4348static int __iw_set_ap_encodeext(struct net_device *dev,
4349 struct iw_request_info *info,
4350 union iwreq_data *wrqu, char *extra)
4351{
4352 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004353 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
4354 hdd_context_t *hdd_ctx;
4355 int ret;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304356 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004357 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
4358 int key_index;
4359 struct iw_point *encoding = &wrqu->encoding;
4360 tCsrRoamSetKey setKey;
4361 int i;
4362
Jeff Johnson651f9f22016-02-11 18:16:11 -08004363 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004364
4365 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4366 ret = wlan_hdd_validate_context(hdd_ctx);
4367 if (0 != ret)
4368 return ret;
4369
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004370 key_index = encoding->flags & IW_ENCODE_INDEX;
4371
4372 if (key_index > 0) {
4373 /*Convert from 1-based to 0-based keying */
4374 key_index--;
4375 }
4376 if (!ext->key_len)
4377 return ret;
4378
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304379 qdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004380
4381 setKey.keyId = key_index;
4382 setKey.keyLength = ext->key_len;
4383
4384 if (ext->key_len <= CSR_MAX_KEY_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304385 qdf_mem_copy(&setKey.Key[0], ext->key, ext->key_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004386 }
4387
4388 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
4389 /*Key direction for group is RX only */
4390 setKey.keyDirection = eSIR_RX_ONLY;
Anurag Chouhanc5548422016-02-24 18:33:27 +05304391 qdf_set_macaddr_broadcast(&setKey.peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004392 } else {
4393
4394 setKey.keyDirection = eSIR_TX_RX;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304395 qdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304396 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004397 }
4398 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
4399 setKey.keyDirection = eSIR_TX_DEFAULT;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304400 qdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304401 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004402 }
4403
4404 /*For supplicant pae role is zero */
4405 setKey.paeRole = 0;
4406
4407 switch (ext->alg) {
4408 case IW_ENCODE_ALG_NONE:
4409 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4410 break;
4411
4412 case IW_ENCODE_ALG_WEP:
4413 setKey.encType =
4414 (ext->key_len ==
4415 5) ? eCSR_ENCRYPT_TYPE_WEP40 : eCSR_ENCRYPT_TYPE_WEP104;
4416 pHddApCtx->uPrivacy = 1;
Jeff Johnsonb8491892016-06-30 14:44:04 -07004417 hdd_notice("uPrivacy=%d", pHddApCtx->uPrivacy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004418 break;
4419
4420 case IW_ENCODE_ALG_TKIP:
4421 {
4422 uint8_t *pKey = &setKey.Key[0];
4423
4424 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
4425
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304426 qdf_mem_zero(pKey, CSR_MAX_KEY_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004427
4428 /*Supplicant sends the 32bytes key in this order
4429
4430 |--------------|----------|----------|
4431 | Tk1 |TX-MIC | RX Mic |
4432 |||--------------|----------|----------|
4433 <---16bytes---><--8bytes--><--8bytes-->
4434
4435 */
4436 /*Sme expects the 32 bytes key to be in the below order
4437
4438 |--------------|----------|----------|
4439 | Tk1 |RX-MIC | TX Mic |
4440 |||--------------|----------|----------|
4441 <---16bytes---><--8bytes--><--8bytes-->
4442 */
4443 /* Copy the Temporal Key 1 (TK1) */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304444 qdf_mem_copy(pKey, ext->key, 16);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004445
4446 /*Copy the rx mic first */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304447 qdf_mem_copy(&pKey[16], &ext->key[24], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004448
4449 /*Copy the tx mic */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304450 qdf_mem_copy(&pKey[24], &ext->key[16], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004451
4452 }
4453 break;
4454
4455 case IW_ENCODE_ALG_CCMP:
4456 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
4457 break;
4458
4459 default:
4460 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4461 break;
4462 }
4463
Jeff Johnsonb8491892016-06-30 14:44:04 -07004464 hdd_notice(":EncryptionType:%d key_len:%d, KeyId:%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004465 setKey.encType, setKey.keyLength, setKey.keyId);
4466 for (i = 0; i < ext->key_len; i++)
Jeff Johnsonb8491892016-06-30 14:44:04 -07004467 hdd_notice("%02x", setKey.Key[i]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004468
Dustin Brown5118e8e2016-09-13 15:54:23 -07004469 vstatus = wlansap_set_key_sta(
4470 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter), &setKey);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004471
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304472 if (vstatus != QDF_STATUS_SUCCESS) {
Jeff Johnsonb8491892016-06-30 14:44:04 -07004473 hdd_err("wlansap_set_key_sta failed, status= %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004474 vstatus);
4475 ret = -EINVAL;
4476 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304477 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004478 return ret;
4479}
4480
4481/**
4482 * iw_set_ap_encodeext() - Wrapper function to protect __iw_set_ap_encodeext
4483 * from the SSR.
4484 *
4485 * @dev - Pointer to the net device.
4486 * @info - Pointer to the iw_request_info.
4487 * @wrqu - Pointer to the iwreq_data.
4488 * @extra - Pointer to the data.
4489 *
4490 * Return: 0 for success, non zero for failure.
4491 */
4492static int iw_set_ap_encodeext(struct net_device *dev,
4493 struct iw_request_info *info,
4494 union iwreq_data *wrqu, char *extra)
4495{
4496 int ret;
4497
4498 cds_ssr_protect(__func__);
4499 ret = __iw_set_ap_encodeext(dev, info, wrqu, extra);
4500 cds_ssr_unprotect(__func__);
4501
4502 return ret;
4503}
4504
4505/**
4506 * __iw_set_ap_mlme() - set ap mlme
4507 * @dev: pointer to net_device
4508 * @info: pointer to iw_request_info
4509 * @wrqu; pointer to iwreq_data
4510 * @extra: extra
4511 *
4512 * Return; 0 on success, error number otherwise
4513 */
4514static int __iw_set_ap_mlme(struct net_device *dev,
4515 struct iw_request_info *info,
4516 union iwreq_data *wrqu, char *extra)
4517{
Jeff Johnson651f9f22016-02-11 18:16:11 -08004518 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004519 return 0;
4520}
4521
4522/**
4523 * iw_set_ap_mlme() - SSR wrapper for __iw_set_ap_mlme
4524 * @dev: pointer to net_device
4525 * @info: pointer to iw_request_info
4526 * @wrqu; pointer to iwreq_data
4527 * @extra: extra
4528 *
4529 * Return; 0 on success, error number otherwise
4530 */
4531static int iw_set_ap_mlme(struct net_device *dev,
4532 struct iw_request_info *info,
4533 union iwreq_data *wrqu,
4534 char *extra)
4535{
4536 int ret;
4537
4538 cds_ssr_protect(__func__);
4539 ret = __iw_set_ap_mlme(dev, info, wrqu, extra);
4540 cds_ssr_unprotect(__func__);
4541
4542 return ret;
4543}
4544
4545/**
4546 * __iw_get_ap_rts_threshold() - get ap rts threshold
4547 * @dev - Pointer to the net device.
4548 * @info - Pointer to the iw_request_info.
4549 * @wrqu - Pointer to the iwreq_data.
4550 * @extra - Pointer to the data.
4551 *
4552 * Return: 0 for success, non zero for failure.
4553 */
4554static int __iw_get_ap_rts_threshold(struct net_device *dev,
4555 struct iw_request_info *info,
4556 union iwreq_data *wrqu, char *extra) {
4557
4558 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
4559 int ret;
4560 hdd_context_t *hdd_ctx;
4561
Jeff Johnson651f9f22016-02-11 18:16:11 -08004562 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004563
4564 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4565 ret = wlan_hdd_validate_context(hdd_ctx);
4566 if (0 != ret)
4567 return ret;
4568 ret = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
4569
4570 return ret;
4571}
4572
4573/**
4574 * iw_get_ap_rts_threshold() - Wrapper function to protect
4575 * __iw_get_ap_rts_threshold from the SSR.
4576 * @dev - Pointer to the net device.
4577 * @info - Pointer to the iw_request_info.
4578 * @wrqu - Pointer to the iwreq_data.
4579 * @extra - Pointer to the data.
4580 *
4581 * Return: 0 for success, non zero for failure.
4582 */
4583static int iw_get_ap_rts_threshold(struct net_device *dev,
4584 struct iw_request_info *info,
4585 union iwreq_data *wrqu, char *extra)
4586{
4587 int ret;
4588
4589 cds_ssr_protect(__func__);
4590 ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra);
4591 cds_ssr_unprotect(__func__);
4592
4593 return ret;
4594}
4595
4596/**
4597 * __iw_get_ap_frag_threshold() - get ap fragmentation threshold
4598 * @dev - Pointer to the net device.
4599 * @info - Pointer to the iw_request_info.
4600 * @wrqu - Pointer to the iwreq_data.
4601 * @extra - Pointer to the data.
4602 *
4603 * Return: 0 for success, non zero for failure.
4604 */
4605static int __iw_get_ap_frag_threshold(struct net_device *dev,
4606 struct iw_request_info *info,
4607 union iwreq_data *wrqu, char *extra) {
4608
4609 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
4610 hdd_context_t *hdd_ctx;
4611 int ret = 0;
4612
Jeff Johnson651f9f22016-02-11 18:16:11 -08004613 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004614
4615 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4616 ret = wlan_hdd_validate_context(hdd_ctx);
4617 if (0 != ret)
4618 return ret;
4619
4620 ret = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
4621
4622 return ret;
4623}
4624
4625/**
4626 * iw_get_ap_frag_threshold() - Wrapper function to protect
4627 * __iw_get_ap_frag_threshold from the SSR.
4628 * @dev - Pointer to the net device.
4629 * @info - Pointer to the iw_request_info.
4630 * @wrqu - Pointer to the iwreq_data.
4631 * @extra - Pointer to the data.
4632 *
4633 * Return: 0 for success, non zero for failure.
4634 */
4635static int iw_get_ap_frag_threshold(struct net_device *dev,
4636 struct iw_request_info *info,
4637 union iwreq_data *wrqu, char *extra)
4638{
4639 int ret;
4640
4641 cds_ssr_protect(__func__);
4642 ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra);
4643 cds_ssr_unprotect(__func__);
4644
4645 return ret;
4646}
4647
4648/**
4649 * __iw_get_ap_freq() - get ap frequency
4650 * @dev - Pointer to the net device.
4651 * @info - Pointer to the iw_request_info.
4652 * @wrqu - Pointer to the iwreq_data.
4653 * @extra - Pointer to the data.
4654 *
4655 * Return: 0 for success, non zero for failure.
4656 */
4657static int __iw_get_ap_freq(struct net_device *dev,
4658 struct iw_request_info *info, struct iw_freq *fwrq,
4659 char *extra) {
4660 uint32_t status = false, channel = 0, freq = 0;
4661 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4662 hdd_context_t *hdd_ctx;
4663 tHalHandle hHal;
4664 hdd_hostapd_state_t *pHostapdState;
4665 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
4666 int ret;
4667
Jeff Johnson651f9f22016-02-11 18:16:11 -08004668 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004669
4670 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4671 ret = wlan_hdd_validate_context(hdd_ctx);
4672 if (0 != ret)
4673 return ret;
4674
4675 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
4676 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
4677
4678 if (pHostapdState->bssState == BSS_STOP) {
4679 if (sme_cfg_get_int(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304680 != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004681 return -EIO;
4682 } else {
4683 status = hdd_wlan_get_freq(channel, &freq);
4684 if (true == status) {
4685 /* Set Exponent parameter as 6 (MHZ) in struct
4686 * iw_freq * iwlist & iwconfig command
4687 * shows frequency into proper
4688 * format (2.412 GHz instead of 246.2 MHz)
4689 */
4690 fwrq->m = freq;
4691 fwrq->e = MHZ;
4692 }
4693 }
4694 } else {
4695 channel = pHddApCtx->operatingChannel;
4696 status = hdd_wlan_get_freq(channel, &freq);
4697 if (true == status) {
4698 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
4699 * iwlist & iwconfig command shows frequency into proper
4700 * format (2.412 GHz instead of 246.2 MHz)*/
4701 fwrq->m = freq;
4702 fwrq->e = MHZ;
4703 }
4704 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304705 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004706 return 0;
4707}
4708
4709/**
4710 * iw_get_ap_freq() - Wrapper function to protect
4711 * __iw_get_ap_freq from the SSR.
4712 * @dev - Pointer to the net device.
4713 * @info - Pointer to the iw_request_info.
4714 * @wrqu - Pointer to the iwreq_data.
4715 * @extra - Pointer to the data.
4716 *
4717 * Return: 0 for success, non zero for failure.
4718 */
4719static int iw_get_ap_freq(struct net_device *dev,
4720 struct iw_request_info *info,
4721 struct iw_freq *wrqu, char *extra)
4722{
4723 int ret;
4724
4725 cds_ssr_protect(__func__);
4726 ret = __iw_get_ap_freq(dev, info, wrqu, extra);
4727 cds_ssr_unprotect(__func__);
4728
4729 return ret;
4730}
4731
4732/**
4733 * __iw_get_mode() - get mode
4734 * @dev - Pointer to the net device.
4735 * @info - Pointer to the iw_request_info.
4736 * @wrqu - Pointer to the iwreq_data.
4737 * @extra - Pointer to the data.
4738 *
4739 * Return: 0 for success, non zero for failure.
4740 */
4741static int __iw_get_mode(struct net_device *dev,
4742 struct iw_request_info *info,
4743 union iwreq_data *wrqu, char *extra) {
4744
4745 hdd_adapter_t *adapter;
4746 hdd_context_t *hdd_ctx;
4747 int ret;
4748
Jeff Johnson651f9f22016-02-11 18:16:11 -08004749 ENTER_DEV(dev);
4750
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004751 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4752 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4753 ret = wlan_hdd_validate_context(hdd_ctx);
4754 if (0 != ret)
4755 return ret;
4756
4757 wrqu->mode = IW_MODE_MASTER;
4758
4759 return ret;
4760}
4761
4762/**
4763 * iw_get_mode() - Wrapper function to protect __iw_get_mode from the SSR.
4764 * @dev - Pointer to the net device.
4765 * @info - Pointer to the iw_request_info.
4766 * @wrqu - Pointer to the iwreq_data.
4767 * @extra - Pointer to the data.
4768 *
4769 * Return: 0 for success, non zero for failure.
4770 */
4771static int iw_get_mode(struct net_device *dev,
4772 struct iw_request_info *info,
4773 union iwreq_data *wrqu, char *extra)
4774{
4775 int ret;
4776
4777 cds_ssr_protect(__func__);
4778 ret = __iw_get_mode(dev, info, wrqu, extra);
4779 cds_ssr_unprotect(__func__);
4780
4781 return ret;
4782}
4783
4784static int
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004785__iw_softap_stopbss(struct net_device *dev,
4786 struct iw_request_info *info,
4787 union iwreq_data *wrqu, char *extra)
4788{
4789 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304790 QDF_STATUS status = QDF_STATUS_SUCCESS;
Anurag Chouhance0dc992016-02-16 18:18:03 +05304791 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004792 hdd_context_t *hdd_ctx;
4793
Jeff Johnson02050312016-02-11 18:40:28 -08004794 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004795
4796 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4797 status = wlan_hdd_validate_context(hdd_ctx);
4798 if (0 != status)
4799 return status;
4800
4801 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
4802 hdd_hostapd_state_t *pHostapdState =
4803 WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
4804
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304805 qdf_event_reset(&pHostapdState->qdf_stop_bss_event);
Dustin Brown5118e8e2016-09-13 15:54:23 -07004806 status = wlansap_stop_bss(
4807 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304808 if (QDF_IS_STATUS_SUCCESS(status)) {
Anurag Chouhance0dc992016-02-16 18:18:03 +05304809 qdf_status =
4810 qdf_wait_single_event(&pHostapdState->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304811 qdf_stop_bss_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004812 10000);
4813
Anurag Chouhance0dc992016-02-16 18:18:03 +05304814 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07004815 hdd_err("wait for single_event failed!!");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304816 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004817 }
4818 }
4819 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08004820 cds_decr_session_set_pcl(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004821 pHostapdAdapter->sessionId);
4822 }
4823 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304824 return (status == QDF_STATUS_SUCCESS) ? 0 : -EBUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004825}
4826
4827static int iw_softap_stopbss(struct net_device *dev,
4828 struct iw_request_info *info,
4829 union iwreq_data *wrqu,
4830 char *extra)
4831{
4832 int ret;
4833
4834 cds_ssr_protect(__func__);
4835 ret = __iw_softap_stopbss(dev, info, wrqu, extra);
4836 cds_ssr_unprotect(__func__);
4837
4838 return ret;
4839}
4840
4841static int
4842__iw_softap_version(struct net_device *dev,
4843 struct iw_request_info *info,
4844 union iwreq_data *wrqu, char *extra)
4845{
4846 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
4847 hdd_context_t *hdd_ctx;
4848 int ret;
4849
Jeff Johnson02050312016-02-11 18:40:28 -08004850 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004851
4852 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4853 ret = wlan_hdd_validate_context(hdd_ctx);
4854 if (0 != ret)
4855 return ret;
4856
Arun Khandavallia96c2c02016-05-17 19:15:34 +05304857 hdd_wlan_get_version(hdd_ctx, wrqu, extra);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004858 EXIT();
4859 return 0;
4860}
4861
4862static int iw_softap_version(struct net_device *dev,
4863 struct iw_request_info *info,
4864 union iwreq_data *wrqu,
4865 char *extra)
4866{
4867 int ret;
4868
4869 cds_ssr_protect(__func__);
4870 ret = __iw_softap_version(dev, info, wrqu, extra);
4871 cds_ssr_unprotect(__func__);
4872
4873 return ret;
4874}
4875
4876static
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304877QDF_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, uint8_t *pBuf,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004878 int buf_len) {
4879 uint8_t i;
4880 uint8_t maxSta = 0;
4881 int len = 0;
4882 const char sta_info_header[] = "staId staAddress";
4883 hdd_context_t *hdd_ctx;
4884
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304885 ENTER();
4886
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004887 if (NULL == pAdapter) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07004888 hdd_err("Adapter is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004889 return -EINVAL;
4890 }
4891
4892 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4893 if (0 != wlan_hdd_validate_context(hdd_ctx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304894 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004895
4896 len = scnprintf(pBuf, buf_len, sta_info_header);
4897 pBuf += len;
4898 buf_len -= len;
4899
4900 maxSta = hdd_ctx->config->maxNumberOfPeers;
4901
4902 for (i = 0; i <= maxSta; i++) {
4903 if (pAdapter->aStaInfo[i].isUsed) {
4904 len =
4905 scnprintf(pBuf, buf_len,
4906 "%5d .%02x:%02x:%02x:%02x:%02x:%02x",
4907 pAdapter->aStaInfo[i].ucSTAId,
4908 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
4909 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
4910 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
4911 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
4912 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
4913 pAdapter->aStaInfo[i].macAddrSTA.
4914 bytes[5]);
4915 pBuf += len;
4916 buf_len -= len;
4917 }
4918 if (WE_GET_STA_INFO_SIZE > buf_len) {
4919 break;
4920 }
4921 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304922 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304923 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004924}
4925
4926static int __iw_softap_get_sta_info(struct net_device *dev,
4927 struct iw_request_info *info,
4928 union iwreq_data *wrqu, char *extra)
4929{
4930 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304931 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004932 hdd_context_t *hdd_ctx;
4933 int ret;
4934
Jeff Johnson02050312016-02-11 18:40:28 -08004935 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004936
4937 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4938 ret = wlan_hdd_validate_context(hdd_ctx);
4939 if (0 != ret)
4940 return ret;
4941
4942 status =
4943 hdd_softap_get_sta_info(pHostapdAdapter, extra,
4944 WE_SAP_MAX_STA_INFO);
4945
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304946 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07004947 hdd_err("Failed to get sta info: %d", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004948 return -EINVAL;
4949 }
4950 wrqu->data.length = strlen(extra);
4951 EXIT();
4952 return 0;
4953}
4954
4955static int iw_softap_get_sta_info(struct net_device *dev,
4956 struct iw_request_info *info,
4957 union iwreq_data *wrqu,
4958 char *extra)
4959{
4960 int ret;
4961
4962 cds_ssr_protect(__func__);
4963 ret = __iw_softap_get_sta_info(dev, info, wrqu, extra);
4964 cds_ssr_unprotect(__func__);
4965
4966 return ret;
4967}
4968
4969/**
4970 * __iw_set_ap_genie() - set ap wpa/rsn ie
4971 *
4972 * @dev - Pointer to the net device.
4973 * @info - Pointer to the iw_request_info.
4974 * @wrqu - Pointer to the iwreq_data.
4975 * @extra - Pointer to the data.
4976 *
4977 * Return: 0 for success, non zero for failure.
4978 */
4979static int __iw_set_ap_genie(struct net_device *dev,
4980 struct iw_request_info *info,
4981 union iwreq_data *wrqu, char *extra) {
4982
4983 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004984 hdd_context_t *hdd_ctx;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304985 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004986 uint8_t *genie = (uint8_t *)extra;
4987 int ret;
4988
Jeff Johnson651f9f22016-02-11 18:16:11 -08004989 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004990
4991 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4992 ret = wlan_hdd_validate_context(hdd_ctx);
4993 if (0 != ret)
4994 return ret;
4995
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004996 if (!wrqu->data.length) {
4997 EXIT();
4998 return 0;
4999 }
5000
5001 switch (genie[0]) {
5002 case DOT11F_EID_WPA:
5003 case DOT11F_EID_RSN:
5004 if ((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0) {
5005 hdd_softap_deregister_bc_sta(pHostapdAdapter);
5006 hdd_softap_register_bc_sta(pHostapdAdapter, 1);
5007 }
5008 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
Dustin Brown5118e8e2016-09-13 15:54:23 -07005009 qdf_ret_status = wlansap_set_wparsn_ies(
5010 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
5011 genie, wrqu->data.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005012 break;
5013
5014 default:
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005015 hdd_err("Set UNKNOWN IE %X", genie[0]);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305016 qdf_ret_status = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005017 }
5018
5019 EXIT();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305020 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005021}
5022
5023/**
5024 * iw_set_ap_genie() - Wrapper function to protect __iw_set_ap_genie
5025 * from the SSR.
5026 *
5027 * @dev - Pointer to the net device.
5028 * @info - Pointer to the iw_request_info.
5029 * @wrqu - Pointer to the iwreq_data.
5030 * @extra - Pointer to the data.
5031 *
5032 * Return: 0 for success, non zero for failure.
5033 */
5034static int
5035iw_set_ap_genie(struct net_device *dev,
5036 struct iw_request_info *info,
5037 union iwreq_data *wrqu, char *extra)
5038{
5039 int ret;
5040
5041 cds_ssr_protect(__func__);
5042 ret = __iw_set_ap_genie(dev, info, wrqu, extra);
5043 cds_ssr_unprotect(__func__);
5044
5045 return ret;
5046}
5047
5048static
5049int __iw_get_softap_linkspeed(struct net_device *dev,
5050 struct iw_request_info *info,
5051 union iwreq_data *wrqu, char *extra)
5052{
5053 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
5054 hdd_context_t *hdd_ctx;
5055 char *pLinkSpeed = (char *)extra;
5056 uint32_t link_speed = 0;
5057 int len = sizeof(uint32_t) + 1;
Anurag Chouhan6d760662016-02-20 16:05:43 +05305058 struct qdf_mac_addr macAddress;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005059 char pmacAddress[MAC_ADDRESS_STR_LEN + 1];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305060 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005061 int rc, valid, i;
5062
Jeff Johnson02050312016-02-11 18:40:28 -08005063 ENTER_DEV(dev);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305064
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005065 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5066 valid = wlan_hdd_validate_context(hdd_ctx);
5067 if (0 != valid)
5068 return valid;
5069
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005070 hdd_notice("wrqu->data.length(%d)", wrqu->data.length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005071
Nitesh Shah4e2d5eb2016-09-06 19:45:13 +05305072 /* Linkspeed is allowed only for P2P mode */
5073 if (pHostapdAdapter->device_mode != QDF_P2P_GO_MODE) {
5074 hdd_err("Link Speed is not allowed in Device mode %s(%d)",
5075 hdd_device_mode_to_string(
5076 pHostapdAdapter->device_mode),
5077 pHostapdAdapter->device_mode);
5078 return -ENOTSUPP;
5079 }
5080
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005081 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) {
5082 if (copy_from_user((void *)pmacAddress,
5083 wrqu->data.pointer, MAC_ADDRESS_STR_LEN)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005084 hdd_notice("failed to copy data to user buffer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005085 return -EFAULT;
5086 }
Manjeet Singh75c2f972016-09-02 13:50:45 +05305087 pmacAddress[MAC_ADDRESS_STR_LEN - 1] = '\0';
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005088
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08005089 if (!mac_pton(pmacAddress, macAddress.bytes)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005090 hdd_err("String to Hex conversion Failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005091 return -EINVAL;
5092 }
5093 }
5094 /* If no mac address is passed and/or its length is less than 17,
5095 * link speed for first connected client will be returned.
5096 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305097 if (wrqu->data.length < 17 || !QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005098 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
5099 if (pHostapdAdapter->aStaInfo[i].isUsed &&
Anurag Chouhanc5548422016-02-24 18:33:27 +05305100 (!qdf_is_macaddr_broadcast
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005101 (&pHostapdAdapter->aStaInfo[i].macAddrSTA))) {
Anurag Chouhanc5548422016-02-24 18:33:27 +05305102 qdf_copy_macaddr(
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08005103 &macAddress,
5104 &pHostapdAdapter->aStaInfo[i].
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005105 macAddrSTA);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305106 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005107 break;
5108 }
5109 }
5110 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305111 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005112 hdd_err("Invalid peer macaddress");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005113 return -EINVAL;
5114 }
5115 status = wlan_hdd_get_linkspeed_for_peermac(pHostapdAdapter,
5116 macAddress);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305117 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005118 hdd_err("Unable to retrieve SME linkspeed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005119 return -EINVAL;
5120 }
5121
5122 link_speed = pHostapdAdapter->ls_stats.estLinkSpeed;
5123
5124 /* linkspeed in units of 500 kbps */
5125 link_speed = link_speed / 500;
5126 wrqu->data.length = len;
5127 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
5128 if ((rc < 0) || (rc >= len)) {
5129 /* encoding or length error? */
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005130 hdd_err("Unable to encode link speed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005131 return -EIO;
5132 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305133 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005134 return 0;
5135}
5136
5137static int
5138iw_get_softap_linkspeed(struct net_device *dev,
5139 struct iw_request_info *info,
5140 union iwreq_data *wrqu,
5141 char *extra)
5142{
5143 int ret;
5144
5145 cds_ssr_protect(__func__);
5146 ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
5147 cds_ssr_unprotect(__func__);
5148
5149 return ret;
5150}
5151
5152static const iw_handler hostapd_handler[] = {
5153 (iw_handler) NULL, /* SIOCSIWCOMMIT */
5154 (iw_handler) NULL, /* SIOCGIWNAME */
5155 (iw_handler) NULL, /* SIOCSIWNWID */
5156 (iw_handler) NULL, /* SIOCGIWNWID */
5157 (iw_handler) NULL, /* SIOCSIWFREQ */
5158 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
5159 (iw_handler) NULL, /* SIOCSIWMODE */
5160 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
5161 (iw_handler) NULL, /* SIOCSIWSENS */
5162 (iw_handler) NULL, /* SIOCGIWSENS */
5163 (iw_handler) NULL, /* SIOCSIWRANGE */
5164 (iw_handler) NULL, /* SIOCGIWRANGE */
5165 (iw_handler) NULL, /* SIOCSIWPRIV */
5166 (iw_handler) NULL, /* SIOCGIWPRIV */
5167 (iw_handler) NULL, /* SIOCSIWSTATS */
5168 (iw_handler) NULL, /* SIOCGIWSTATS */
5169 (iw_handler) NULL, /* SIOCSIWSPY */
5170 (iw_handler) NULL, /* SIOCGIWSPY */
5171 (iw_handler) NULL, /* SIOCSIWTHRSPY */
5172 (iw_handler) NULL, /* SIOCGIWTHRSPY */
5173 (iw_handler) NULL, /* SIOCSIWAP */
5174 (iw_handler) NULL, /* SIOCGIWAP */
5175 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
5176 (iw_handler) NULL, /* SIOCGIWAPLIST */
5177 (iw_handler) NULL, /* SIOCSIWSCAN */
5178 (iw_handler) NULL, /* SIOCGIWSCAN */
5179 (iw_handler) NULL, /* SIOCSIWESSID */
5180 (iw_handler) NULL, /* SIOCGIWESSID */
5181 (iw_handler) NULL, /* SIOCSIWNICKN */
5182 (iw_handler) NULL, /* SIOCGIWNICKN */
5183 (iw_handler) NULL, /* -- hole -- */
5184 (iw_handler) NULL, /* -- hole -- */
5185 (iw_handler) NULL, /* SIOCSIWRATE */
5186 (iw_handler) NULL, /* SIOCGIWRATE */
5187 (iw_handler) NULL, /* SIOCSIWRTS */
5188 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
5189 (iw_handler) NULL, /* SIOCSIWFRAG */
5190 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
5191 (iw_handler) NULL, /* SIOCSIWTXPOW */
5192 (iw_handler) NULL, /* SIOCGIWTXPOW */
5193 (iw_handler) NULL, /* SIOCSIWRETRY */
5194 (iw_handler) NULL, /* SIOCGIWRETRY */
5195 (iw_handler) NULL, /* SIOCSIWENCODE */
5196 (iw_handler) NULL, /* SIOCGIWENCODE */
5197 (iw_handler) NULL, /* SIOCSIWPOWER */
5198 (iw_handler) NULL, /* SIOCGIWPOWER */
5199 (iw_handler) NULL, /* -- hole -- */
5200 (iw_handler) NULL, /* -- hole -- */
5201 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
5202 (iw_handler) NULL, /* SIOCGIWGENIE */
5203 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
5204 (iw_handler) NULL, /* SIOCGIWAUTH */
5205 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
5206 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
5207 (iw_handler) NULL, /* SIOCSIWPMKSA */
5208};
5209
5210/*
5211 * Note that the following ioctls were defined with semantics which
5212 * cannot be handled by the "iwpriv" userspace application and hence
5213 * they are not included in the hostapd_private_args array
5214 * QCSAP_IOCTL_ASSOC_STA_MACADDR
5215 */
5216
5217static const struct iw_priv_args hostapd_private_args[] = {
5218 {
5219 QCSAP_IOCTL_SETPARAM,
5220 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam"
5221 }, {
5222 QCSAP_IOCTL_SETPARAM,
5223 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""
5224 }, {
5225 QCSAP_PARAM_MAX_ASSOC,
5226 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5227 "setMaxAssoc"
5228 }, {
5229 QCSAP_PARAM_HIDE_SSID,
5230 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID"
5231 }, {
5232 QCSAP_PARAM_SET_MC_RATE,
5233 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate"
5234 },
5235 {
5236 QCSAP_PARAM_SET_TXRX_FW_STATS,
5237 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5238 "txrx_fw_stats"
5239 }, {
5240 QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY,
5241 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5242 "setMccLatency"
5243 }, {
5244 QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA,
5245 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5246 "setMccQuota"
5247 }, {
5248 QCSAP_PARAM_SET_CHANNEL_CHANGE,
5249 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5250 "setChanChange"
5251 }, {
5252 QCSAP_PARAM_AUTO_CHANNEL,
5253 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5254 "setAutoChannel"
Manishekar Chandrasekaran97e077d2016-03-23 17:10:31 +05305255 }, {
5256 QCSAP_PARAM_CONC_SYSTEM_PREF,
5257 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5258 "setConcSysPref"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005259 },
5260 /* Sub-cmds DBGLOG specific commands */
5261 {
5262 QCSAP_DBGLOG_LOG_LEVEL,
5263 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5264 0, "dl_loglevel"
5265 }, {
5266 QCSAP_DBGLOG_VAP_ENABLE,
5267 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_vapon"
5268 }, {
5269 QCSAP_DBGLOG_VAP_DISABLE,
5270 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5271 0, "dl_vapoff"
5272 }, {
5273 QCSAP_DBGLOG_MODULE_ENABLE,
5274 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_modon"
5275 }, {
5276 QCSAP_DBGLOG_MODULE_DISABLE,
5277 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5278 0, "dl_modoff"
5279 }, {
5280 QCSAP_DBGLOG_MOD_LOG_LEVEL,
5281 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5282 0, "dl_mod_loglevel"
5283 }, {
5284 QCSAP_DBGLOG_TYPE,
5285 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_type"
5286 }, {
5287 QCSAP_DBGLOG_REPORT_ENABLE,
5288 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5289 0, "dl_report"
5290 }, {
5291 QCASAP_TXRX_FWSTATS_RESET,
5292 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5293 0, "txrx_fw_st_rst"
5294 }, {
5295 QCSAP_PARAM_RTSCTS,
5296 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5297 0, "enablertscts"
5298 }, {
5299 QCASAP_SET_11N_RATE,
5300 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5301 0, "set11NRates"
5302 }, {
5303 QCASAP_SET_VHT_RATE,
5304 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5305 0, "set11ACRates"
5306 }, {
5307 QCASAP_SHORT_GI,
5308 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5309 0, "enable_short_gi"
5310 }, {
5311 QCSAP_SET_AMPDU,
5312 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ampdu"
5313 }, {
5314 QCSAP_SET_AMSDU,
5315 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "amsdu"
5316 }, {
5317 QCSAP_GTX_HT_MCS,
5318 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxHTMcs"
5319 }, {
5320 QCSAP_GTX_VHT_MCS,
5321 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5322 0, "gtxVHTMcs"
5323 }, {
5324 QCSAP_GTX_USRCFG,
5325 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5326 0, "gtxUsrCfg"
5327 }, {
5328 QCSAP_GTX_THRE,
5329 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxThre"
5330 }, {
5331 QCSAP_GTX_MARGIN,
5332 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5333 0, "gtxMargin"
5334 }, {
5335 QCSAP_GTX_STEP,
5336 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxStep"
5337 }, {
5338 QCSAP_GTX_MINTPC,
5339 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5340 0, "gtxMinTpc"
5341 }, {
5342 QCSAP_GTX_BWMASK,
5343 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5344 0, "gtxBWMask"
5345 }, {
5346 QCSAP_PARAM_CLR_ACL,
5347 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5348 0, "setClearAcl"
5349 }, {
5350 QCSAP_PARAM_ACL_MODE,
5351 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode"
5352 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005353 {
5354 QCASAP_SET_TM_LEVEL,
5355 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5356 0, "setTmLevel"
5357 }, {
5358 QCASAP_SET_DFS_IGNORE_CAC,
5359 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5360 0, "setDfsIgnoreCAC"
5361 }, {
5362 QCASAP_SET_DFS_NOL,
5363 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5364 0, "setdfsnol"
5365 }, {
5366 QCASAP_SET_DFS_TARGET_CHNL,
5367 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5368 0, "setNextChnl"
5369 }, {
5370 QCASAP_SET_RADAR_CMD,
5371 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setRadar"
5372 },
5373 {
5374 QCSAP_IPA_UC_STAT,
5375 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ipaucstat"
5376 },
5377 {
5378 QCASAP_TX_CHAINMASK_CMD,
5379 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5380 0, "set_txchainmask"
5381 }, {
5382 QCASAP_RX_CHAINMASK_CMD,
5383 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5384 0, "set_rxchainmask"
5385 }, {
5386 QCASAP_NSS_CMD,
5387 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_nss"
5388 }, {
5389 QCASAP_SET_PHYMODE,
5390 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5391 0, "setphymode"
5392 }, {
5393 QCASAP_DUMP_STATS,
5394 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5395 0, "dumpStats"
5396 }, {
5397 QCASAP_CLEAR_STATS,
5398 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5399 0, "clearStats"
5400 }, {
Govind Singha471e5e2015-10-12 17:11:14 +05305401 QCSAP_START_FW_PROFILING,
5402 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5403 0, "startProfile"
5404 }, {
Manjeet Singhe80d6d82016-09-02 19:04:41 +05305405 QCASAP_PARAM_LDPC,
5406 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5407 0, "set_ldpc"
5408 }, {
5409 QCASAP_PARAM_TX_STBC,
5410 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5411 0, "set_tx_stbc"
5412 }, {
5413 QCASAP_PARAM_RX_STBC,
5414 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5415 0, "set_rx_stbc"
5416 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005417 QCSAP_IOCTL_GETPARAM, 0,
5418 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam"
5419 }, {
5420 QCSAP_IOCTL_GETPARAM, 0,
5421 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""
5422 }, {
5423 QCSAP_PARAM_MAX_ASSOC, 0,
5424 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc"
5425 }, {
5426 QCSAP_PARAM_GET_WLAN_DBG, 0,
5427 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg"
5428 }, {
5429 QCSAP_PARAM_AUTO_CHANNEL, 0,
5430 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel"
5431 }, {
5432 QCSAP_GTX_BWMASK, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5433 "get_gtxBWMask"
5434 }, {
5435 QCSAP_GTX_MINTPC, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5436 "get_gtxMinTpc"
5437 }, {
5438 QCSAP_GTX_STEP, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5439 "get_gtxStep"
5440 }, {
5441 QCSAP_GTX_MARGIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5442 "get_gtxMargin"
5443 }, {
5444 QCSAP_GTX_THRE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5445 "get_gtxThre"
5446 }, {
5447 QCSAP_GTX_USRCFG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5448 "get_gtxUsrCfg"
5449 }, {
5450 QCSAP_GTX_VHT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5451 "get_gtxVHTMcs"
5452 }, {
5453 QCSAP_GTX_HT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5454 "get_gtxHTMcs"
5455 }, {
5456 QCASAP_SHORT_GI, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5457 "get_short_gi"
5458 }, {
5459 QCSAP_PARAM_RTSCTS, 0,
5460 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rtscts"
5461 }, {
5462 QCASAP_GET_DFS_NOL, 0,
5463 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdfsnol"
5464 }, {
5465 QCSAP_GET_ACL, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5466 "get_acl_list"
5467 }, {
Manjeet Singhe80d6d82016-09-02 19:04:41 +05305468 QCASAP_PARAM_LDPC, 0,
5469 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5470 "get_ldpc"
5471 }, {
5472 QCASAP_PARAM_TX_STBC, 0,
5473 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5474 "get_tx_stbc"
5475 }, {
5476 QCASAP_PARAM_RX_STBC, 0,
5477 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5478 "get_rx_stbc"
5479 }, {
Kai Liubdd5fcb2016-09-28 22:55:44 +08005480 QCSAP_PARAM_CHAN_WIDTH, 0,
5481 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5482 "get_chwidth"
5483 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005484 QCASAP_TX_CHAINMASK_CMD, 0,
5485 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5486 "get_txchainmask"
5487 }, {
5488 QCASAP_RX_CHAINMASK_CMD, 0,
5489 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5490 "get_rxchainmask"
5491 }, {
5492 QCASAP_NSS_CMD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5493 "get_nss"
5494 }, {
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07005495 QCSAP_CAP_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5496 "cap_tsf"
5497 }, {
5498 QCSAP_IOCTL_SET_NONE_GET_THREE, 0, IW_PRIV_TYPE_INT |
5499 IW_PRIV_SIZE_FIXED | 3, ""
5500 }, {
5501 QCSAP_GET_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
5502 "get_tsf"
5503 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005504 QCASAP_GET_TEMP_CMD, 0,
5505 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_temp"
5506 }, {
Govind Singha471e5e2015-10-12 17:11:14 +05305507 QCSAP_GET_FW_PROFILE_DATA, 0,
5508 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getProfileData"
5509 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005510 QCSAP_IOCTL_GET_STAWPAIE,
Manjeet Singhfde0c042016-09-03 12:08:09 +05305511 0, IW_PRIV_TYPE_BYTE | DOT11F_IE_RSN_MAX_LEN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005512 "get_staWPAIE"
5513 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005514 QCSAP_IOCTL_STOPBSS, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0,
5515 "stopbss"
5516 }, {
Mukul Sharmadd93cbc2016-09-03 13:31:44 +05305517 QCSAP_IOCTL_VERSION, 0, IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005518 "version"
5519 }, {
5520 QCSAP_IOCTL_GET_STA_INFO, 0,
5521 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info"
5522 }, {
5523 QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
5524 IW_PRIV_TYPE_BYTE |
5525 sizeof(sQcSapreq_WPSPBCProbeReqIES_t) |
5526 IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs"
5527 }
5528 , {
5529 QCSAP_IOCTL_GET_CHANNEL, 0,
5530 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
5531 }
5532 , {
5533 QCSAP_IOCTL_DISASSOC_STA,
5534 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6, 0,
5535 "disassoc_sta"
5536 }
5537 /* handler for main ioctl */
5538 , {
5539 QCSAP_PRIV_GET_CHAR_SET_NONE, 0,
5540 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, ""
5541 }
5542 /* handler for sub-ioctl */
5543 , {
5544 QCSAP_GET_STATS, 0,
5545 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getStats"
5546 }
5547 , {
Govind Singha471e5e2015-10-12 17:11:14 +05305548 QCSAP_LIST_FW_PROFILE, 0,
5549 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "listProfile"
5550 }
5551 , {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005552 QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
5553 IW_PRIV_TYPE_CHAR | 18,
5554 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
5555 }
5556 , {
5557 QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
5558 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""
5559 }
5560 ,
5561 /* handlers for sub-ioctl */
5562 {
5563 WE_SET_WLAN_DBG,
5564 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setwlandbg"
5565 }, {
5566 WE_SET_SAP_CHANNELS,
5567 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setsapchannels"
5568 }
5569 ,
5570 /* handlers for sub-ioctl */
5571 {
5572 WE_SET_DP_TRACE,
5573 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_dp_trace"
5574 }
5575 ,
5576 /* handlers for main ioctl */
5577 {
5578 QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
5579 IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, ""
5580 }
5581 , {
5582 WE_P2P_NOA_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, "SetP2pPs"
5583 }
5584 , {
5585 WE_UNIT_TEST_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0,
5586 "setUnitTestCmd"
5587 }
5588 ,
5589 /* handlers for main ioctl */
5590 {
5591 QCSAP_IOCTL_MODIFY_ACL,
5592 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8, 0, "modify_acl"
5593 }
5594 ,
5595 /* handlers for main ioctl */
5596 {
5597 QCSAP_IOCTL_GET_CHANNEL_LIST,
5598 0,
5599 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
5600 "getChannelList"
5601 }
5602 ,
5603 /* handlers for main ioctl */
5604 {
5605 QCSAP_IOCTL_SET_TX_POWER,
5606 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setTxPower"
5607 }
5608 ,
5609 /* handlers for main ioctl */
5610 {
5611 QCSAP_IOCTL_SET_MAX_TX_POWER,
5612 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5613 0, "setTxMaxPower"
5614 }
5615 ,
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08005616 {
5617 QCSAP_IOCTL_SET_PKTLOG,
Poddar, Siddarth176c4362016-10-03 12:25:00 +05305618 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08005619 0, "pktlog"
5620 }
5621 ,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005622 /* Set HDD CFG Ini param */
5623 {
5624 QCSAP_IOCTL_SET_INI_CFG,
5625 IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, 0, "setConfig"
5626 }
5627 ,
5628 /* Get HDD CFG Ini param */
5629 {
5630 QCSAP_IOCTL_GET_INI_CFG,
5631 0, IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, "getConfig"
5632 }
5633 ,
5634 /* handlers for main ioctl */
5635 {
5636 /* handlers for main ioctl */
5637 QCSAP_IOCTL_SET_TWO_INT_GET_NONE,
5638 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""
5639 }
5640 ,
5641 /* handlers for sub-ioctl */
Srinivas Girigowda6147c582016-10-18 12:26:15 -07005642#ifdef WLAN_DEBUG
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005643 {
5644 QCSAP_IOCTL_SET_FW_CRASH_INJECT,
5645 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5646 0, "crash_inject"
5647 }
5648 ,
5649#endif
5650 {
5651 QCASAP_SET_RADAR_DBG,
5652 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5653 0, "setRadarDbg"
5654 }
5655 ,
5656 /* dump dp trace - descriptor or dp trace records */
5657 {
5658 QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL,
5659 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5660 0, "dump_dp_trace"
5661 }
5662 ,
Govind Singha471e5e2015-10-12 17:11:14 +05305663 {
5664 QCSAP_ENABLE_FW_PROFILE,
5665 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5666 0, "enableProfile"
5667 }
5668 ,
5669 {
5670 QCSAP_SET_FW_PROFILE_HIST_INTVL,
5671 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5672 0, "set_hist_intvl"
5673 }
Dustin Brownd95b96b2016-12-09 15:08:26 -08005674 ,
5675#ifdef WLAN_SUSPEND_RESUME_TEST
5676 {
5677 QCSAP_SET_WLAN_SUSPEND,
5678 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5679 0, "wlan_suspend"
5680 }
5681 ,
5682 {
5683 QCSAP_SET_WLAN_RESUME,
5684 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5685 0, "wlan_resume"
5686 }
5687 ,
5688#endif
5689
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005690};
5691
5692static const iw_handler hostapd_private[] = {
5693 /* set priv ioctl */
5694 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam,
5695 /* get priv ioctl */
5696 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam,
Manikandan Mohandcc21ba2016-03-15 14:31:56 -07005697 [QCSAP_IOCTL_SET_NONE_GET_THREE - SIOCIWFIRSTPRIV] =
5698 iw_softap_get_three,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005699 /* get station genIE */
5700 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005701 /* stop bss */
5702 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss,
5703 /* get driver version */
5704 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version,
5705 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] =
5706 iw_get_wpspbc_probe_req_ies,
5707 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] =
5708 iw_softap_getchannel,
5709 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] =
5710 iw_softap_getassoc_stamacaddr,
5711 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] =
5712 iw_softap_disassoc_sta,
5713 [QCSAP_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] =
5714 iw_get_char_setnone,
5715 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE -
5716 SIOCIWFIRSTPRIV] =
5717 iw_set_three_ints_getnone,
5718 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE -
5719 SIOCIWFIRSTPRIV] =
5720 iw_set_var_ints_getnone,
5721 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] =
5722 iw_softap_set_force_acs_ch_range,
5723 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] =
5724 iw_softap_modify_acl,
5725 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] =
Agrawal Ashish6c9bca72016-09-04 13:37:59 +05305726 iw_get_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005727 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] =
5728 iw_softap_get_sta_info,
5729 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED -
5730 SIOCIWFIRSTPRIV] =
5731 iw_get_softap_linkspeed,
5732 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] =
5733 iw_softap_set_tx_power,
5734 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] =
5735 iw_softap_set_max_tx_power,
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08005736 [QCSAP_IOCTL_SET_PKTLOG - SIOCIWFIRSTPRIV] =
5737 iw_softap_set_pktlog,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005738 [QCSAP_IOCTL_SET_INI_CFG - SIOCIWFIRSTPRIV] =
5739 iw_softap_set_ini_cfg,
5740 [QCSAP_IOCTL_GET_INI_CFG - SIOCIWFIRSTPRIV] =
5741 iw_softap_get_ini_cfg,
5742 [QCSAP_IOCTL_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
5743 iw_softap_set_two_ints_getnone,
5744};
5745const struct iw_handler_def hostapd_handler_def = {
Anurag Chouhan6d760662016-02-20 16:05:43 +05305746 .num_standard = QDF_ARRAY_SIZE(hostapd_handler),
5747 .num_private = QDF_ARRAY_SIZE(hostapd_private),
5748 .num_private_args = QDF_ARRAY_SIZE(hostapd_private_args),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005749 .standard = (iw_handler *) hostapd_handler,
5750 .private = (iw_handler *) hostapd_private,
5751 .private_args = hostapd_private_args,
5752 .get_wireless_stats = NULL,
5753};
5754
5755struct net_device_ops net_ops_struct = {
5756 .ndo_open = hdd_hostapd_open,
5757 .ndo_stop = hdd_hostapd_stop,
5758 .ndo_uninit = hdd_hostapd_uninit,
5759 .ndo_start_xmit = hdd_softap_hard_start_xmit,
5760 .ndo_tx_timeout = hdd_softap_tx_timeout,
5761 .ndo_get_stats = hdd_get_stats,
5762 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
5763 .ndo_do_ioctl = hdd_ioctl,
5764 .ndo_change_mtu = hdd_hostapd_change_mtu,
5765 .ndo_select_queue = hdd_hostapd_select_queue,
5766};
5767
5768static int hdd_set_hostapd(hdd_adapter_t *pAdapter)
5769{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305770 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005771}
5772
5773void hdd_set_ap_ops(struct net_device *pWlanHostapdDev)
5774{
5775 pWlanHostapdDev->netdev_ops = &net_ops_struct;
5776}
5777
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305778QDF_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005779{
5780 hdd_hostapd_state_t *phostapdBuf;
5781 struct net_device *dev = pAdapter->dev;
5782 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305783 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005784 v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(pAdapter))->pcds_context;
5785 v_CONTEXT_t sapContext = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005786 int ret;
Peng Xu66162de2016-02-11 17:01:20 -08005787 enum tQDF_ADAPTER_MODE mode;
5788 uint32_t session_id = CSR_SESSION_ID_INVALID;
Agrawal Ashish65634612016-08-18 13:24:32 +05305789 enum dfs_mode acs_dfs_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005790
5791 ENTER();
5792
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005793 sapContext = wlansap_open(p_cds_context);
5794 if (sapContext == NULL) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005795 hdd_err("ERROR: wlansap_open failed!!");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305796 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005797 }
5798
5799 pAdapter->sessionCtx.ap.sapContext = sapContext;
Agrawal Ashish65634612016-08-18 13:24:32 +05305800 pAdapter->sessionCtx.ap.sapConfig.channel =
5801 pHddCtx->acs_policy.acs_channel;
5802 acs_dfs_mode = pHddCtx->acs_policy.acs_dfs_mode;
5803 pAdapter->sessionCtx.ap.sapConfig.acs_dfs_mode =
5804 wlan_hdd_get_dfs_mode(acs_dfs_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005805
Krunal Soni056ea0f2016-03-10 13:07:10 -08005806 if (pAdapter->device_mode == QDF_P2P_GO_MODE) {
Peng Xu66162de2016-02-11 17:01:20 -08005807 mode = QDF_P2P_GO_MODE;
Krunal Soni056ea0f2016-03-10 13:07:10 -08005808 } else if (pAdapter->device_mode == QDF_SAP_MODE) {
Peng Xu66162de2016-02-11 17:01:20 -08005809 mode = QDF_SAP_MODE;
5810 } else {
5811 hdd_err("Invalid mode for AP: %d", pAdapter->device_mode);
5812 return QDF_STATUS_E_FAULT;
5813 }
5814
5815 status = wlansap_start(sapContext, mode,
5816 pAdapter->macAddressCurrent.bytes,
5817 &session_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305818 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005819 hdd_err("ERROR: wlansap_start failed!!");
Peng Xu66162de2016-02-11 17:01:20 -08005820 pAdapter->sessionCtx.ap.sapContext = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005821 return status;
5822 }
Peng Xu66162de2016-02-11 17:01:20 -08005823 pAdapter->sessionId = session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005824
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05305825 status = hdd_create_and_store_vdev(pHddCtx->hdd_pdev, pAdapter);
5826 if (QDF_IS_STATUS_ERROR(status))
5827 goto error_vdev_create;
5828
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005829 /* Allocate the Wireless Extensions state structure */
5830 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
5831
5832 sme_set_curr_device_mode(pHddCtx->hHal, pAdapter->device_mode);
5833
5834 /* Zero the memory. This zeros the profile structure. */
5835 memset(phostapdBuf, 0, sizeof(hdd_hostapd_state_t));
5836
5837 /* Set up the pointer to the Wireless Extensions state structure */
5838 /* NOP */
5839 status = hdd_set_hostapd(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305840 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005841 hdd_err("ERROR: hdd_set_hostapd failed!!");
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05305842 goto error_init_ap_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005843 }
5844
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05305845 status = qdf_event_create(&phostapdBuf->qdf_event);
5846 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005847 hdd_err("ERROR: Hostapd HDD qdf event init failed!!");
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05305848 goto error_init_ap_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005849 }
5850
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05305851 status = qdf_event_create(&phostapdBuf->qdf_stop_bss_event);
5852 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005853 hdd_err("ERROR: Hostapd HDD stop bss event init failed!!");
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05305854 goto error_init_ap_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005855 }
5856
Wei Song2f76f642016-11-18 16:32:53 +08005857 status = qdf_event_create(&phostapdBuf->qdf_sta_disassoc_event);
5858 if (!QDF_IS_STATUS_SUCCESS(status)) {
5859 hdd_err("ERROR: Hostapd HDD sta disassoc event init failed!!");
5860 wlansap_close(sapContext);
5861 pAdapter->sessionCtx.ap.sapContext = NULL;
5862 return status;
5863 }
5864
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005865 init_completion(&pAdapter->session_close_comp_var);
5866 init_completion(&pAdapter->session_open_comp_var);
5867
5868 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
5869
5870 /* Register as a wireless device */
5871 dev->wireless_handlers = (struct iw_handler_def *)&hostapd_handler_def;
5872
5873 /* Initialize the data path module */
5874 status = hdd_softap_init_tx_rx(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305875 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005876 hdd_alert("hdd_softap_init_tx_rx failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005877 }
5878
5879 status = hdd_wmm_adapter_init(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305880 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005881 hdd_err("hdd_wmm_adapter_init() failed code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005882 status, status);
5883 goto error_wmm_init;
5884 }
5885
5886 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5887
5888 ret = wma_cli_set_command(pAdapter->sessionId,
5889 WMI_PDEV_PARAM_BURST_ENABLE,
5890 pHddCtx->config->enableSifsBurst,
5891 PDEV_CMD);
5892
5893 if (0 != ret) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005894 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005895 }
5896 pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305897 qdf_mem_free(pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
5898 qdf_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005899 sizeof(struct sap_acs_cfg));
5900 return status;
5901
5902error_wmm_init:
5903 hdd_softap_deinit_tx_rx(pAdapter);
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05305904error_init_ap_mode:
Rajeev Kumarba778852017-01-06 13:23:04 -08005905 status = hdd_release_and_destroy_vdev(pAdapter);
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05305906 if (QDF_IS_STATUS_ERROR(status))
5907 hdd_err("vdev delete failed");
5908error_vdev_create:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005909 wlansap_close(sapContext);
Peng Xu66162de2016-02-11 17:01:20 -08005910 pAdapter->sessionCtx.ap.sapContext = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005911 EXIT();
5912 return status;
5913}
5914
5915/**
5916 * hdd_wlan_create_ap_dev() - create an AP-mode device
5917 * @pHddCtx: Global HDD context
5918 * @macAddr: MAC address to assign to the interface
Ryan Hsu07495ea2016-01-21 15:25:39 -08005919 * @name_assign_type: the name of assign type of the netdev
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005920 * @iface_name: User-visible name of the interface
5921 *
5922 * This function will allocate a Linux net_device and configuration it
5923 * for an AP mode of operation. Note that the device is NOT actually
5924 * registered with the kernel at this time.
5925 *
5926 * Return: A pointer to the private data portion of the net_device if
5927 * the allocation and initialization was successful, NULL otherwise.
5928 */
5929hdd_adapter_t *hdd_wlan_create_ap_dev(hdd_context_t *pHddCtx,
5930 tSirMacAddr macAddr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08005931 unsigned char name_assign_type,
5932 uint8_t *iface_name)
5933{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005934 struct net_device *pWlanHostapdDev = NULL;
5935 hdd_adapter_t *pHostapdAdapter = NULL;
5936
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005937 hdd_info("iface_name = %s", iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005938
Ryan Hsu07495ea2016-01-21 15:25:39 -08005939 pWlanHostapdDev = alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name,
5940#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
5941 name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005942#endif
Ryan Hsu07495ea2016-01-21 15:25:39 -08005943 ether_setup, NUM_TX_QUEUES);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005944
5945 if (pWlanHostapdDev != NULL) {
5946 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
5947
5948 /* Init the net_device structure */
5949 ether_setup(pWlanHostapdDev);
5950
5951 /* Initialize the adapter context to zeros. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305952 qdf_mem_zero(pHostapdAdapter, sizeof(hdd_adapter_t));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005953 pHostapdAdapter->dev = pWlanHostapdDev;
5954 pHostapdAdapter->pHddCtx = pHddCtx;
5955 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Arun Khandavalli9ad88f02016-09-01 19:03:37 +05305956 pHostapdAdapter->sessionId = HDD_SESSION_ID_INVALID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005957
Jeff Johnsonecd884e2016-06-30 14:52:25 -07005958 hdd_info("pWlanHostapdDev = %p, pHostapdAdapter = %p, concurrency_mode=0x%x",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005959 pWlanHostapdDev,
5960 pHostapdAdapter,
5961 (int)cds_get_concurrency_mode());
5962
5963 /* Init the net_device structure */
5964 strlcpy(pWlanHostapdDev->name, (const char *)iface_name,
5965 IFNAMSIZ);
5966
5967 hdd_set_ap_ops(pHostapdAdapter->dev);
5968
5969 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
5970 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
Mohit Khannaee9e80f2015-11-10 11:32:49 -08005971 pWlanHostapdDev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005972
jge3e6f6382016-09-29 13:28:28 +08005973 if (pHddCtx->config->enable_ip_tcp_udp_checksum_offload)
5974 pWlanHostapdDev->features |=
5975 NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
5976 pWlanHostapdDev->features |= NETIF_F_RXCSUM;
5977
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305978 qdf_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005979 sizeof(tSirMacAddr));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305980 qdf_mem_copy(pHostapdAdapter->macAddressCurrent.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005981 (void *)macAddr, sizeof(tSirMacAddr));
5982
5983 pHostapdAdapter->offloads_configured = false;
5984 pWlanHostapdDev->destructor = free_netdev;
5985 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev;
5986 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
5987 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
Dhanashri Atre83d373d2015-07-28 16:45:59 -07005988 hdd_set_tso_flags(pHddCtx, pWlanHostapdDev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005989 init_completion(&pHostapdAdapter->tx_action_cnf_event);
5990 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
5991 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
5992 init_completion(&pHostapdAdapter->sta_authorized_event);
5993 init_completion(&pHostapdAdapter->offchannel_tx_event);
5994 init_completion(&pHostapdAdapter->scan_info.
5995 abortscan_event_var);
5996
5997 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
5998 spin_lock_init(&pHostapdAdapter->pause_map_lock);
Nirav Shah617cff92016-04-25 10:24:24 +05305999 pHostapdAdapter->start_time =
6000 pHostapdAdapter->last_time = qdf_system_ticks();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006001 }
6002 return pHostapdAdapter;
6003}
6004
6005/**
6006 * hdd_register_hostapd() - register hostapd
6007 * @pAdapter: Pointer to hostapd adapter
6008 * @rtnl_lock_held: RTNL lock held
6009 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05306010 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006011 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306012QDF_STATUS hdd_register_hostapd(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006013 uint8_t rtnl_lock_held) {
6014 struct net_device *dev = pAdapter->dev;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306015 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006016
6017 ENTER();
6018
6019 if (rtnl_lock_held) {
6020 if (strnchr(dev->name, strlen(dev->name), '%')) {
6021 if (dev_alloc_name(dev, dev->name) < 0) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006022 hdd_err("Failed:dev_alloc_name");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306023 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006024 }
6025 }
6026 if (register_netdevice(dev)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006027 hdd_err("Failed:register_netdevice");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306028 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006029 }
6030 } else {
6031 if (register_netdev(dev)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006032 hdd_err("Failed:register_netdev");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306033 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006034 }
6035 }
6036 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6037
6038 EXIT();
6039 return status;
6040}
6041
6042/**
6043 * hdd_unregister_hostapd() - unregister hostapd
6044 * @pAdapter: Pointer to hostapd adapter
6045 * @rtnl_held: true if rtnl lock held; false otherwise
6046 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306047 * Return: QDF_STATUS enumaration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006048 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306049QDF_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006050{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306051 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006052 void *sapContext = WLAN_HDD_GET_SAP_CTX_PTR(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006053
6054 ENTER();
6055
6056 hdd_softap_deinit_tx_rx(pAdapter);
6057
6058 /* if we are being called during driver unload,
6059 * then the dev has already been invalidated.
6060 * if we are being called at other times, then we can
6061 * detach the wireless device handlers
6062 */
6063 if (pAdapter->dev) {
6064 if (rtnl_held)
6065 pAdapter->dev->wireless_handlers = NULL;
6066 else {
6067 rtnl_lock();
6068 pAdapter->dev->wireless_handlers = NULL;
6069 rtnl_unlock();
6070 }
6071 }
6072
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006073 status = wlansap_stop(sapContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306074 if (!QDF_IS_STATUS_SUCCESS(status))
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006075 hdd_err("Failed:wlansap_stop");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006076
6077 status = wlansap_close(sapContext);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306078 if (!QDF_IS_STATUS_SUCCESS(status))
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006079 hdd_err("Failed:WLANSAP_close");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006080 pAdapter->sessionCtx.ap.sapContext = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006081
Rajeev Kumarba778852017-01-06 13:23:04 -08006082 status = hdd_release_and_destroy_vdev(pAdapter);
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05306083 if (QDF_IS_STATUS_ERROR(status))
6084 hdd_err("vdev delete failed");
6085
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006086 EXIT();
6087 return 0;
6088}
6089
6090/**
6091 * wlan_hdd_rate_is_11g() - check if rate is 11g rate or not
6092 * @rate: Rate to be checked
6093 *
6094 * Return: true if rate if 11g else false
6095 */
6096static bool wlan_hdd_rate_is_11g(u8 rate)
6097{
6098 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72,
6099 96, 108}; /* actual rate * 2 */
6100 u8 i;
6101 for (i = 0; i < 8; i++) {
6102 if (rate == gRateArray[i])
6103 return true;
6104 }
6105 return false;
6106}
6107
6108#ifdef QCA_HT_2040_COEX
6109/**
6110 * wlan_hdd_get_sap_obss() - Get SAP OBSS enable config based on HT_CAPAB IE
6111 * @pHostapdAdapter: Pointer to hostapd adapter
6112 *
6113 * Return: HT support channel width config value
6114 */
6115static bool wlan_hdd_get_sap_obss(hdd_adapter_t *pHostapdAdapter)
6116{
6117 uint8_t ht_cap_ie[DOT11F_IE_HTCAPS_MAX_LEN];
6118 tDot11fIEHTCaps dot11_ht_cap_ie = {0};
6119 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
6120 beacon_data_t *beacon = pHostapdAdapter->sessionCtx.ap.beacon;
6121 uint8_t *ie = NULL;
6122
6123 ie = wlan_hdd_cfg80211_get_ie_ptr(beacon->tail, beacon->tail_len,
6124 WLAN_EID_HT_CAPABILITY);
6125 if (ie && ie[1]) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306126 qdf_mem_copy(ht_cap_ie, &ie[2], DOT11F_IE_HTCAPS_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006127 dot11f_unpack_ie_ht_caps((tpAniSirGlobal)hdd_ctx->hHal,
6128 ht_cap_ie, ie[1], &dot11_ht_cap_ie);
6129 return dot11_ht_cap_ie.supportedChannelWidthSet;
6130 }
6131
6132 return false;
6133}
6134#else
6135static bool wlan_hdd_get_sap_obss(hdd_adapter_t *pHostapdAdapter)
6136{
6137 return false;
6138}
6139#endif
6140/**
6141 * wlan_hdd_set_channel() - set channel in sap mode
6142 * @wiphy: Pointer to wiphy structure
6143 * @dev: Pointer to net_device structure
6144 * @chandef: Pointer to channel definition structure
6145 * @channel_type: Channel type
6146 *
6147 * Return: 0 for success non-zero for failure
6148 */
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05306149int wlan_hdd_set_channel(struct wiphy *wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006150 struct net_device *dev,
6151 struct cfg80211_chan_def *chandef,
6152 enum nl80211_channel_type channel_type)
6153{
6154 hdd_adapter_t *pAdapter = NULL;
6155 uint32_t num_ch = 0;
6156 int channel = 0;
6157 int channel_seg2 = 0;
6158 hdd_context_t *pHddCtx;
6159 int status;
6160
Manjeet Singhaec78b52016-11-03 15:43:56 +05306161 tSmeConfigParams *sme_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006162 tsap_Config_t *sap_config;
6163
6164 ENTER();
6165
6166
6167 if (NULL == dev) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006168 hdd_err("Called with dev = NULL.");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006169 return -ENODEV;
6170 }
6171 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6172
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05306173 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006174 TRACE_CODE_HDD_CFG80211_SET_CHANNEL,
6175 pAdapter->sessionId, channel_type));
6176
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006177 hdd_notice("Device_mode %s(%d) freq = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006178 hdd_device_mode_to_string(pAdapter->device_mode),
6179 pAdapter->device_mode, chandef->chan->center_freq);
6180
6181 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6182 status = wlan_hdd_validate_context(pHddCtx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306183 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006184 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05306185
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006186
6187 /*
6188 * Do freq to chan conversion
6189 * TODO: for 11a
6190 */
6191
6192 channel = ieee80211_frequency_to_channel(chandef->chan->center_freq);
Arif Hussain174c3fc2016-07-28 11:19:42 -07006193
Kiran Kumar Lokeref1f5e992016-06-20 16:48:50 -07006194 if (NL80211_CHAN_WIDTH_80P80 == chandef->width ||
Arif Hussain174c3fc2016-07-28 11:19:42 -07006195 NL80211_CHAN_WIDTH_160 == chandef->width) {
6196 if (chandef->center_freq2)
6197 channel_seg2 = ieee80211_frequency_to_channel(
6198 chandef->center_freq2);
6199 else
6200 hdd_err("Invalid center_freq2");
6201 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006202
6203 /* Check freq range */
6204 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6205 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006206 hdd_err("Channel [%d] is outside valid range from %d to %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006207 channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6208 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6209 return -EINVAL;
6210 }
6211
6212 /* Check freq range */
6213
6214 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel_seg2) ||
6215 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel_seg2)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006216 hdd_err("Channel [%d] is outside valid range from %d to %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006217 channel_seg2, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6218 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6219 return -EINVAL;
6220 }
6221
6222 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6223
Krunal Soni056ea0f2016-03-10 13:07:10 -08006224 if ((QDF_SAP_MODE != pAdapter->device_mode) &&
6225 (QDF_P2P_GO_MODE != pAdapter->device_mode)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306226 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006227 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006228 hdd_err("Invalid Channel [%d]", channel);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006229 return -EINVAL;
6230 }
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006231 hdd_info("set channel to [%d] for device mode %s(%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006232 channel,
6233 hdd_device_mode_to_string(pAdapter->device_mode),
6234 pAdapter->device_mode);
6235 }
6236
Krunal Soni056ea0f2016-03-10 13:07:10 -08006237 if ((pAdapter->device_mode == QDF_STA_MODE)
6238 || (pAdapter->device_mode == QDF_P2P_CLIENT_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006239 ) {
6240 hdd_wext_state_t *pWextState =
6241 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6242 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
6243 hdd_station_ctx_t *pHddStaCtx =
6244 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6245
6246 if (eConnectionState_IbssConnected ==
6247 pHddStaCtx->conn_info.connState) {
6248 /* Link is up then return cant set channel */
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006249 hdd_err("IBSS Associated, can't set the channel");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006250 return -EINVAL;
6251 }
6252
6253 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6254 pHddStaCtx->conn_info.operationChannel = channel;
6255 pRoamProfile->ChannelInfo.ChannelList =
6256 &pHddStaCtx->conn_info.operationChannel;
Krunal Soni056ea0f2016-03-10 13:07:10 -08006257 } else if ((pAdapter->device_mode == QDF_SAP_MODE)
6258 || (pAdapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006259 ) {
6260 sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig);
Krunal Soni056ea0f2016-03-10 13:07:10 -08006261 if (QDF_P2P_GO_MODE == pAdapter->device_mode) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306262 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006263 wlan_hdd_validate_operation_channel(pAdapter,
6264 channel)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006265 hdd_err("Invalid Channel [%d]", channel);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006266 return -EINVAL;
6267 }
6268 sap_config->channel = channel;
6269 sap_config->ch_params.center_freq_seg1 = channel_seg2;
6270 } else {
6271 /* set channel to what hostapd configured */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306272 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006273 wlan_hdd_validate_operation_channel(pAdapter,
6274 channel)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006275 hdd_err("Invalid Channel [%d]", channel);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006276 return -EINVAL;
6277 }
6278
6279 sap_config->channel = channel;
6280 sap_config->ch_params.center_freq_seg1 = channel_seg2;
6281
Manjeet Singhaec78b52016-11-03 15:43:56 +05306282 sme_config = qdf_mem_malloc(sizeof(*sme_config));
6283
6284 if (!sme_config) {
6285 hdd_err("Unable to allocate memory for smeconfig!");
6286 return -ENOMEM;
6287 }
6288 sme_get_config_param(pHddCtx->hHal, sme_config);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006289 switch (channel_type) {
6290 case NL80211_CHAN_HT20:
6291 case NL80211_CHAN_NO_HT:
Manjeet Singhaec78b52016-11-03 15:43:56 +05306292 sme_config->csrConfig.obssEnabled = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006293 sap_config->sec_ch = 0;
6294 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006295 case NL80211_CHAN_HT40MINUS:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006296 sap_config->sec_ch = sap_config->channel - 4;
6297 break;
6298 case NL80211_CHAN_HT40PLUS:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006299 sap_config->sec_ch = sap_config->channel + 4;
6300 break;
6301 default:
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006302 hdd_err("Error!!! Invalid HT20/40 mode !");
Manjeet Singhaec78b52016-11-03 15:43:56 +05306303 qdf_mem_free(sme_config);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006304 return -EINVAL;
6305 }
Manjeet Singhaec78b52016-11-03 15:43:56 +05306306 sme_config->csrConfig.obssEnabled =
6307 wlan_hdd_get_sap_obss(pAdapter);
6308
6309 sme_update_config(pHddCtx->hHal, sme_config);
6310 qdf_mem_free(sme_config);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006311 }
6312 } else {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006313 hdd_err("Invalid device mode failed to set valid channel");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006314 return -EINVAL;
6315 }
6316 EXIT();
6317 return status;
6318}
6319
6320/**
6321 * wlan_hdd_check_11gmode() - check for 11g mode
6322 * @pIe: Pointer to IE
6323 * @require_ht: Pointer to require ht
6324 * @require_vht: Pointer to require vht
6325 * @pCheckRatesfor11g: Pointer to check rates for 11g mode
6326 * @pSapHw_mode: SAP HW mode
6327 *
6328 * Check for 11g rate and set proper 11g only mode
6329 *
6330 * Return: none
6331 */
6332static void wlan_hdd_check_11gmode(u8 *pIe, u8 *require_ht, u8 *require_vht,
6333 u8 *pCheckRatesfor11g,
6334 eCsrPhyMode *pSapHw_mode)
6335{
6336 u8 i, num_rates = pIe[0];
6337
6338 pIe += 1;
6339 for (i = 0; i < num_rates; i++) {
6340 if (*pCheckRatesfor11g
6341 && (true == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK))) {
6342 /* If rate set have 11g rate than change the mode
6343 * to 11G
6344 */
6345 *pSapHw_mode = eCSR_DOT11_MODE_11g;
6346 if (pIe[i] & BASIC_RATE_MASK) {
6347 /* If we have 11g rate as basic rate, it
6348 * means mode is 11g only mode.
6349 */
6350 *pSapHw_mode = eCSR_DOT11_MODE_11g_ONLY;
6351 *pCheckRatesfor11g = false;
6352 }
6353 } else {
6354 if ((BASIC_RATE_MASK |
6355 WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6356 *require_ht = true;
6357 else if ((BASIC_RATE_MASK |
6358 WLAN_BSS_MEMBERSHIP_SELECTOR_VHT_PHY) == pIe[i])
6359 *require_vht = true;
6360 }
6361 }
6362 return;
6363}
6364
6365/**
6366 * wlan_hdd_add_ie() - add ie
6367 * @pHostapdAdapter: Pointer to hostapd adapter
6368 * @genie: Pointer to ie to be added
6369 * @total_ielen: Pointer to store total ie length
6370 * @oui: Pointer to oui
6371 * @oui_size: Size of oui
6372 *
6373 * Return: 0 for success non-zero for failure
6374 */
6375static int wlan_hdd_add_ie(hdd_adapter_t *pHostapdAdapter, uint8_t *genie,
Liangwei Dongec9be932016-10-19 05:59:13 -04006376 uint16_t *total_ielen, uint8_t *oui,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006377 uint8_t oui_size)
6378{
6379 uint16_t ielen = 0;
6380 uint8_t *pIe = NULL;
6381 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6382
6383 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6384 pBeacon->tail, pBeacon->tail_len);
6385
6386 if (pIe) {
6387 ielen = pIe[1] + 2;
6388 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306389 qdf_mem_copy(&genie[*total_ielen], pIe, ielen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006390 } else {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006391 hdd_err("**Ie Length is too big***");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006392 return -EINVAL;
6393 }
6394 *total_ielen += ielen;
6395 }
6396 return 0;
6397}
6398
6399/**
6400 * wlan_hdd_add_hostapd_conf_vsie() - configure vsie in sap mode
6401 * @pHostapdAdapter: Pointer to hostapd adapter
6402 * @genie: Pointer to vsie
6403 * @total_ielen: Pointer to store total ie length
6404 *
6405 * Return: none
6406 */
6407static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t *pHostapdAdapter,
6408 uint8_t *genie,
Liangwei Dongec9be932016-10-19 05:59:13 -04006409 uint16_t *total_ielen)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006410{
6411 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6412 int left = pBeacon->tail_len;
6413 uint8_t *ptr = pBeacon->tail;
6414 uint8_t elem_id, elem_len;
6415 uint16_t ielen = 0;
6416
6417 if (NULL == ptr || 0 == left)
6418 return;
6419
6420 while (left >= 2) {
6421 elem_id = ptr[0];
6422 elem_len = ptr[1];
6423 left -= 2;
6424 if (elem_len > left) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006425 hdd_err("****Invalid IEs eid = %d elem_len=%d left=%d*****",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006426 elem_id, elem_len, left);
6427 return;
6428 }
6429 if (IE_EID_VENDOR == elem_id) {
6430 /* skipping the VSIE's which we don't want to include or
6431 * it will be included by existing code
6432 */
6433 if ((memcmp(&ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) !=
6434 0) &&
6435#ifdef WLAN_FEATURE_WFD
6436 (memcmp(&ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) !=
6437 0) &&
6438#endif
6439 (memcmp
6440 (&ptr[2], WHITELIST_OUI_TYPE,
6441 WPA_OUI_TYPE_SIZE) != 0)
6442 &&
6443 (memcmp
6444 (&ptr[2], BLACKLIST_OUI_TYPE,
6445 WPA_OUI_TYPE_SIZE) != 0)
6446 &&
6447 (memcmp
6448 (&ptr[2], "\x00\x50\xf2\x02",
6449 WPA_OUI_TYPE_SIZE) != 0)
6450 && (memcmp(&ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE)
6451 != 0)
6452 && (memcmp(&ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE)
6453 != 0)) {
6454 ielen = ptr[1] + 2;
6455 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306456 qdf_mem_copy(&genie[*total_ielen], ptr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006457 ielen);
6458 *total_ielen += ielen;
6459 } else {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006460 hdd_err("IE Length is too big IEs eid=%d elem_len=%d total_ie_lent=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006461 elem_id, elem_len, *total_ielen);
6462 }
6463 }
6464 }
6465
6466 left -= elem_len;
6467 ptr += (elem_len + 2);
6468 }
6469 return;
6470}
6471
6472/**
6473 * wlan_hdd_add_extra_ie() - add extra ies in beacon
6474 * @pHostapdAdapter: Pointer to hostapd adapter
6475 * @genie: Pointer to extra ie
6476 * @total_ielen: Pointer to store total ie length
6477 * @temp_ie_id: ID of extra ie
6478 *
6479 * Return: none
6480 */
6481static void wlan_hdd_add_extra_ie(hdd_adapter_t *pHostapdAdapter,
Liangwei Dongec9be932016-10-19 05:59:13 -04006482 uint8_t *genie, uint16_t *total_ielen,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006483 uint8_t temp_ie_id)
6484{
6485 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6486 int left = pBeacon->tail_len;
6487 uint8_t *ptr = pBeacon->tail;
6488 uint8_t elem_id, elem_len;
6489 uint16_t ielen = 0;
6490
6491 if (NULL == ptr || 0 == left)
6492 return;
6493
6494 while (left >= 2) {
6495 elem_id = ptr[0];
6496 elem_len = ptr[1];
6497 left -= 2;
6498 if (elem_len > left) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006499 hdd_err("****Invalid IEs eid = %d elem_len=%d left=%d*****",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006500 elem_id, elem_len, left);
6501 return;
6502 }
6503
6504 if (temp_ie_id == elem_id) {
6505 ielen = ptr[1] + 2;
6506 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306507 qdf_mem_copy(&genie[*total_ielen], ptr, ielen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006508 *total_ielen += ielen;
6509 } else {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006510 hdd_err("IE Length is too big IEs eid=%d elem_len=%d total_ie_lent=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006511 elem_id, elem_len, *total_ielen);
6512 }
6513 }
6514
6515 left -= elem_len;
6516 ptr += (elem_len + 2);
6517 }
6518 return;
6519}
6520
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006521/**
6522 * wlan_hdd_cfg80211_alloc_new_beacon() - alloc beacon in ap mode
6523 * @pAdapter: Pointer to hostapd adapter
6524 * @ppBeacon: Pointer to pointer to beacon data
6525 * @params: Pointer to beacon parameters
6526 * @dtim_period: DTIM period
6527 *
6528 * Return: 0 for success non-zero for failure
6529 */
Jeff Johnsone4090f72016-10-05 16:00:23 -07006530static int
6531wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
6532 beacon_data_t **ppBeacon,
6533 struct cfg80211_beacon_data *params,
6534 int dtim_period)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006535{
6536 int size;
6537 beacon_data_t *beacon = NULL;
6538 beacon_data_t *old = NULL;
6539 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
6540 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
6541
6542 ENTER();
6543 if (params->head && !params->head_len) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006544 hdd_err("head_len is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006545 return -EINVAL;
6546 }
6547
6548 old = pAdapter->sessionCtx.ap.beacon;
6549
6550 if (!params->head && !old) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006551 hdd_err("session(%d) old and new heads points to NULL",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006552 pAdapter->sessionId);
6553 return -EINVAL;
6554 }
6555
6556 if (params->head) {
6557 head_len = params->head_len;
6558 head = params->head;
6559 } else {
6560 head_len = old->head_len;
6561 head = old->head;
6562 }
6563
6564 if (params->tail || !old) {
6565 tail_len = params->tail_len;
6566 tail = params->tail;
6567 } else {
6568 tail_len = old->tail_len;
6569 tail = old->tail;
6570 }
6571
6572 if (params->proberesp_ies || !old) {
6573 proberesp_ies_len = params->proberesp_ies_len;
6574 proberesp_ies = params->proberesp_ies;
6575 } else {
6576 proberesp_ies_len = old->proberesp_ies_len;
6577 proberesp_ies = old->proberesp_ies;
6578 }
6579
6580 if (params->assocresp_ies || !old) {
6581 assocresp_ies_len = params->assocresp_ies_len;
6582 assocresp_ies = params->assocresp_ies;
6583 } else {
6584 assocresp_ies_len = old->assocresp_ies_len;
6585 assocresp_ies = old->assocresp_ies;
6586 }
6587
6588 size = sizeof(beacon_data_t) + head_len + tail_len +
6589 proberesp_ies_len + assocresp_ies_len;
6590
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05306591 beacon = qdf_mem_malloc(size);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006592
6593 if (beacon == NULL) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006594 hdd_err("Mem allocation for beacon failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006595 return -ENOMEM;
6596 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006597 if (dtim_period)
6598 beacon->dtim_period = dtim_period;
6599 else if (old)
6600 beacon->dtim_period = old->dtim_period;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006601 /* -----------------------------------------------
6602 * | head | tail | proberesp_ies | assocresp_ies |
6603 * -----------------------------------------------
6604 */
6605 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6606 beacon->tail = beacon->head + head_len;
6607 beacon->proberesp_ies = beacon->tail + tail_len;
6608 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
6609
6610 beacon->head_len = head_len;
6611 beacon->tail_len = tail_len;
6612 beacon->proberesp_ies_len = proberesp_ies_len;
6613 beacon->assocresp_ies_len = assocresp_ies_len;
6614
6615 if (head && head_len)
6616 memcpy(beacon->head, head, head_len);
6617 if (tail && tail_len)
6618 memcpy(beacon->tail, tail, tail_len);
6619 if (proberesp_ies && proberesp_ies_len)
6620 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
6621 if (assocresp_ies && assocresp_ies_len)
6622 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
6623
6624 *ppBeacon = beacon;
6625
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05306626 pAdapter->sessionCtx.ap.beacon = NULL;
6627 qdf_mem_free(old);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006628
6629 return 0;
6630
6631}
6632
Liangwei Dongec9be932016-10-19 05:59:13 -04006633#ifdef QCA_HT_2040_COEX
6634static void wlan_hdd_add_sap_obss_scan_ie(
6635 hdd_adapter_t *hostapd_adapter, uint8_t *ie_buf, uint16_t *ie_len)
6636{
6637 if (QDF_SAP_MODE == hostapd_adapter->device_mode) {
6638 if (wlan_hdd_get_sap_obss(hostapd_adapter))
6639 wlan_hdd_add_extra_ie(hostapd_adapter, ie_buf, ie_len,
6640 WLAN_EID_OVERLAP_BSS_SCAN_PARAM);
6641 }
6642}
6643#else
6644static void wlan_hdd_add_sap_obss_scan_ie(
6645 hdd_adapter_t *hostapd_adapter, uint8_t *ie_buf, uint16_t *ie_len)
6646{
6647}
6648#endif
6649
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006650/**
6651 * wlan_hdd_cfg80211_update_apies() - update ap mode ies
6652 * @adapter: Pointer to hostapd adapter
6653 *
6654 * Return: 0 for success non-zero for failure
6655 */
6656int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *adapter)
6657{
6658 uint8_t *genie;
Liangwei Dongec9be932016-10-19 05:59:13 -04006659 uint16_t total_ielen = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006660 int ret = 0;
6661 tsap_Config_t *pConfig;
6662 tSirUpdateIE updateIE;
6663 beacon_data_t *beacon = NULL;
Liangwei Dongec9be932016-10-19 05:59:13 -04006664 uint16_t proberesp_ies_len;
6665 uint8_t *proberesp_ies = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006666
6667 pConfig = &adapter->sessionCtx.ap.sapConfig;
6668 beacon = adapter->sessionCtx.ap.beacon;
6669
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306670 genie = qdf_mem_malloc(MAX_GENIE_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006671
6672 if (genie == NULL)
6673 return -ENOMEM;
6674
Edhar, Mahesh Kumar14846232016-06-30 15:03:23 +05306675 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
6676 WLAN_EID_VHT_TX_POWER_ENVELOPE);
6677
Vidyullatha Kanchanapally518c5d72016-09-30 11:04:16 +05306678 /* Extract and add the extended capabilities and interworking IE */
6679 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
6680 WLAN_EID_EXT_CAPABILITY);
6681
6682 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
6683 WLAN_EID_INTERWORKING);
6684
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006685 if (0 != wlan_hdd_add_ie(adapter, genie,
6686 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006687 hdd_err("Adding WPS IE failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006688 ret = -EINVAL;
6689 goto done;
6690 }
6691#ifdef WLAN_FEATURE_WFD
6692 if (0 != wlan_hdd_add_ie(adapter, genie,
6693 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006694 hdd_err("Adding WFD IE failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006695 ret = -EINVAL;
6696 goto done;
6697 }
6698#endif
6699
6700#ifdef FEATURE_WLAN_WAPI
Krunal Soni056ea0f2016-03-10 13:07:10 -08006701 if (QDF_SAP_MODE == adapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006702 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
6703 WLAN_EID_WAPI);
6704 }
6705#endif
6706
Krunal Soni056ea0f2016-03-10 13:07:10 -08006707 if (adapter->device_mode == QDF_SAP_MODE ||
6708 adapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006709 wlan_hdd_add_hostapd_conf_vsie(adapter, genie,
6710 &total_ielen);
6711
6712 if (wlan_hdd_add_ie(adapter, genie,
6713 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006714 hdd_err("Adding P2P IE failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006715 ret = -EINVAL;
6716 goto done;
6717 }
6718
Liangwei Dongec9be932016-10-19 05:59:13 -04006719 wlan_hdd_add_sap_obss_scan_ie(adapter, genie, &total_ielen);
6720
Anurag Chouhanc5548422016-02-24 18:33:27 +05306721 qdf_copy_macaddr(&updateIE.bssid, &adapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006722 updateIE.smeSessionId = adapter->sessionId;
6723
6724 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6725 updateIE.ieBufferlength = total_ielen;
6726 updateIE.pAdditionIEBuffer = genie;
6727 updateIE.append = false;
6728 updateIE.notify = true;
6729 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6730 &updateIE,
6731 eUPDATE_IE_PROBE_BCN) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306732 QDF_STATUS_E_FAILURE) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006733 hdd_err("Could not pass on Add Ie probe beacon data");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006734 ret = -EINVAL;
6735 goto done;
6736 }
6737 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_BCN);
6738 } else {
6739 wlansap_update_sap_config_add_ie(pConfig,
6740 genie,
6741 total_ielen,
6742 eUPDATE_IE_PROBE_BCN);
6743 }
6744
6745 /* Added for Probe Response IE */
Liangwei Dongec9be932016-10-19 05:59:13 -04006746 proberesp_ies = qdf_mem_malloc(beacon->proberesp_ies_len +
6747 MAX_GENIE_LEN);
6748 if (proberesp_ies == NULL) {
6749 hdd_err("mem alloc failed for probe resp ies %d",
6750 proberesp_ies_len);
6751 ret = -EINVAL;
6752 goto done;
6753 }
6754 qdf_mem_copy(proberesp_ies, beacon->proberesp_ies,
6755 beacon->proberesp_ies_len);
6756 proberesp_ies_len = beacon->proberesp_ies_len;
6757
6758 wlan_hdd_add_sap_obss_scan_ie(adapter, proberesp_ies,
6759 &proberesp_ies_len);
6760
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006761 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Liangwei Dongec9be932016-10-19 05:59:13 -04006762 updateIE.ieBufferlength = proberesp_ies_len;
6763 updateIE.pAdditionIEBuffer = proberesp_ies;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006764 updateIE.append = false;
6765 updateIE.notify = false;
6766 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6767 &updateIE,
6768 eUPDATE_IE_PROBE_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306769 QDF_STATUS_E_FAILURE) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006770 hdd_err("Could not pass on PROBE_RESP add Ie data");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006771 ret = -EINVAL;
6772 goto done;
6773 }
6774 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_RESP);
6775 } else {
6776 wlansap_update_sap_config_add_ie(pConfig,
Liangwei Dongec9be932016-10-19 05:59:13 -04006777 proberesp_ies,
6778 proberesp_ies_len,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006779 eUPDATE_IE_PROBE_RESP);
6780 }
6781
6782 /* Assoc resp Add ie Data */
6783 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6784 updateIE.ieBufferlength = beacon->assocresp_ies_len;
6785 updateIE.pAdditionIEBuffer = (uint8_t *) beacon->assocresp_ies;
6786 updateIE.append = false;
6787 updateIE.notify = false;
6788 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6789 &updateIE,
6790 eUPDATE_IE_ASSOC_RESP) ==
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306791 QDF_STATUS_E_FAILURE) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006792 hdd_err("Could not pass on Add Ie Assoc Response data");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006793 ret = -EINVAL;
6794 goto done;
6795 }
6796 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ASSOC_RESP);
6797 } else {
6798 wlansap_update_sap_config_add_ie(pConfig,
6799 beacon->assocresp_ies,
6800 beacon->assocresp_ies_len,
6801 eUPDATE_IE_ASSOC_RESP);
6802 }
6803
6804done:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05306805 qdf_mem_free(genie);
Liangwei Dongec9be932016-10-19 05:59:13 -04006806 qdf_mem_free(proberesp_ies);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006807 return ret;
6808}
6809
6810/**
6811 * wlan_hdd_set_sap_hwmode() - set sap hw mode
6812 * @pHostapdAdapter: Pointer to hostapd adapter
6813 *
6814 * Return: none
6815 */
6816static void wlan_hdd_set_sap_hwmode(hdd_adapter_t *pHostapdAdapter)
6817{
6818 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6819 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6820 struct ieee80211_mgmt *pMgmt_frame =
6821 (struct ieee80211_mgmt *)pBeacon->head;
6822 u8 checkRatesfor11g = true;
6823 u8 require_ht = false, require_vht = false;
6824 u8 *pIe = NULL;
6825
6826 pConfig->SapHw_mode = eCSR_DOT11_MODE_11b;
6827
6828 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6829 pBeacon->head_len,
6830 WLAN_EID_SUPP_RATES);
6831 if (pIe != NULL) {
6832 pIe += 1;
6833 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
6834 &checkRatesfor11g, &pConfig->SapHw_mode);
6835 }
6836
6837 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6838 WLAN_EID_EXT_SUPP_RATES);
6839 if (pIe != NULL) {
6840 pIe += 1;
6841 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
6842 &checkRatesfor11g, &pConfig->SapHw_mode);
6843 }
6844
6845 if (pConfig->channel > 14)
6846 pConfig->SapHw_mode = eCSR_DOT11_MODE_11a;
6847
6848 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6849 WLAN_EID_HT_CAPABILITY);
6850
6851 if (pIe) {
6852 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n;
6853 if (require_ht)
6854 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n_ONLY;
6855 }
6856
6857 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6858 WLAN_EID_VHT_CAPABILITY);
6859
6860 if (pIe) {
6861 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac;
6862 if (require_vht)
6863 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac_ONLY;
6864 }
6865}
6866
6867/**
6868 * wlan_hdd_config_acs() - config ACS needed parameters
6869 * @hdd_ctx: HDD context
6870 * @adapter: Adapter pointer
6871 *
6872 * This function get ACS related INI paramters and populated
6873 * sap config and smeConfig for ACS needed configurations.
6874 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306875 * Return: The QDF_STATUS code associated with performing the operation.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006876 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306877QDF_STATUS wlan_hdd_config_acs(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006878{
6879 tsap_Config_t *sap_config;
6880 struct hdd_config *ini_config;
6881 tHalHandle hal;
6882
6883 hal = WLAN_HDD_GET_HAL_CTX(adapter);
6884 sap_config = &adapter->sessionCtx.ap.sapConfig;
6885 ini_config = hdd_ctx->config;
6886
6887 sap_config->enOverLapCh = !!hdd_ctx->config->gEnableOverLapCh;
6888
Dustin Brown5118e8e2016-09-13 15:54:23 -07006889#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006890 hdd_notice("HDD_ACS_SKIP_STATUS = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006891 hdd_ctx->skip_acs_scan_status);
6892 if (hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) {
6893 hdd_adapter_t *con_sap_adapter;
6894 tsap_Config_t *con_sap_config = NULL;
6895
6896 con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);
6897
6898 if (con_sap_adapter)
6899 con_sap_config =
6900 &con_sap_adapter->sessionCtx.ap.sapConfig;
6901
6902 sap_config->acs_cfg.skip_scan_status = eSAP_DO_NEW_ACS_SCAN;
6903
6904 if (con_sap_config &&
6905 con_sap_config->acs_cfg.acs_mode == true &&
6906 hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN &&
6907 con_sap_config->acs_cfg.hw_mode ==
6908 sap_config->acs_cfg.hw_mode) {
6909 uint8_t con_sap_st_ch, con_sap_end_ch;
6910 uint8_t cur_sap_st_ch, cur_sap_end_ch;
6911 uint8_t bandStartChannel, bandEndChannel;
6912
6913 con_sap_st_ch =
6914 con_sap_config->acs_cfg.start_ch;
6915 con_sap_end_ch =
6916 con_sap_config->acs_cfg.end_ch;
6917 cur_sap_st_ch = sap_config->acs_cfg.start_ch;
6918 cur_sap_end_ch = sap_config->acs_cfg.end_ch;
6919
6920 wlansap_extend_to_acs_range(
6921 &cur_sap_st_ch, &cur_sap_end_ch,
6922 &bandStartChannel, &bandEndChannel);
6923
6924 wlansap_extend_to_acs_range(
6925 &con_sap_st_ch, &con_sap_end_ch,
6926 &bandStartChannel, &bandEndChannel);
6927
6928 if (con_sap_st_ch <= cur_sap_st_ch &&
6929 con_sap_end_ch >= cur_sap_end_ch) {
6930 sap_config->acs_cfg.skip_scan_status =
6931 eSAP_SKIP_ACS_SCAN;
6932
6933 } else if (con_sap_st_ch >= cur_sap_st_ch &&
6934 con_sap_end_ch >= cur_sap_end_ch) {
6935 sap_config->acs_cfg.skip_scan_status =
6936 eSAP_DO_PAR_ACS_SCAN;
6937
6938 sap_config->acs_cfg.skip_scan_range1_stch =
6939 cur_sap_st_ch;
6940 sap_config->acs_cfg.skip_scan_range1_endch =
6941 con_sap_st_ch - 1;
6942 sap_config->acs_cfg.skip_scan_range2_stch =
6943 0;
6944 sap_config->acs_cfg.skip_scan_range2_endch =
6945 0;
6946
6947 } else if (con_sap_st_ch <= cur_sap_st_ch &&
6948 con_sap_end_ch <= cur_sap_end_ch) {
6949 sap_config->acs_cfg.skip_scan_status =
6950 eSAP_DO_PAR_ACS_SCAN;
6951
6952 sap_config->acs_cfg.skip_scan_range1_stch =
6953 con_sap_end_ch + 1;
6954 sap_config->acs_cfg.skip_scan_range1_endch =
6955 cur_sap_end_ch;
6956 sap_config->acs_cfg.skip_scan_range2_stch =
6957 0;
6958 sap_config->acs_cfg.skip_scan_range2_endch =
6959 0;
6960
6961 } else if (con_sap_st_ch >= cur_sap_st_ch &&
6962 con_sap_end_ch <= cur_sap_end_ch) {
6963 sap_config->acs_cfg.skip_scan_status =
6964 eSAP_DO_PAR_ACS_SCAN;
6965
6966 sap_config->acs_cfg.skip_scan_range1_stch =
6967 cur_sap_st_ch;
6968 sap_config->acs_cfg.skip_scan_range1_endch =
6969 con_sap_st_ch - 1;
6970 sap_config->acs_cfg.skip_scan_range2_stch =
6971 con_sap_end_ch;
6972 sap_config->acs_cfg.skip_scan_range2_endch =
6973 cur_sap_end_ch + 1;
6974
6975 } else
6976 sap_config->acs_cfg.skip_scan_status =
6977 eSAP_DO_NEW_ACS_SCAN;
6978
6979
Jeff Johnsonecd884e2016-06-30 14:52:25 -07006980 hdd_notice(FL(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006981 "SecAP ACS Skip=%d, ACS CH RANGE=%d-%d, %d-%d"),
6982 sap_config->acs_cfg.skip_scan_status,
6983 sap_config->acs_cfg.skip_scan_range1_stch,
6984 sap_config->acs_cfg.skip_scan_range1_endch,
6985 sap_config->acs_cfg.skip_scan_range2_stch,
6986 sap_config->acs_cfg.skip_scan_range2_endch);
6987 }
6988 }
6989#endif
6990
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306991 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006992}
6993
6994/**
6995 * wlan_hdd_setup_driver_overrides : Overrides SAP / P2P GO Params
6996 * @adapter: pointer to adapter struct
6997 *
6998 * This function overrides SAP / P2P Go configuration based on driver INI
6999 * parameters for 11AC override and ACS. This overrides are done to support
7000 * android legacy configuration method.
7001 *
7002 * NOTE: Non android platform supports concurrency and these overrides shall
7003 * not be used. Also future driver based overrides shall be consolidated in this
7004 * function only. Avoid random overrides in other location based on ini.
7005 *
7006 * Return: 0 for Success or Negative error codes.
7007 */
Jeff Johnsone4090f72016-10-05 16:00:23 -07007008static int wlan_hdd_setup_driver_overrides(hdd_adapter_t *ap_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007009{
7010 tsap_Config_t *sap_cfg = &ap_adapter->sessionCtx.ap.sapConfig;
7011 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007012
Krunal Soni056ea0f2016-03-10 13:07:10 -08007013 if (ap_adapter->device_mode == QDF_SAP_MODE &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007014 hdd_ctx->config->force_sap_acs)
7015 goto setup_acs_overrides;
7016
7017 /* Fixed channel 11AC override:
7018 * 11AC override in qcacld is introduced for following reasons:
7019 * 1. P2P GO also follows start_bss and since p2p GO could not be
7020 * configured to setup VHT channel width in wpa_supplicant
7021 * 2. Android UI does not provide advanced configuration options for SAP
7022 *
7023 * Default override enabled (for android). MDM shall disable this in ini
7024 */
7025 if (hdd_ctx->config->sap_p2p_11ac_override &&
7026 (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
7027 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
Rajeev Kumar Sirasanagandlab79b5462016-09-06 18:33:17 +05307028 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY) &&
7029 !hdd_ctx->config->sap_force_11n_for_11ac) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007030 hdd_notice("** Driver force 11AC override for SAP/Go **");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007031
7032 /* 11n only shall not be overridden since it may be on purpose*/
7033 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n)
7034 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
7035
7036 if (sap_cfg->channel >= 36)
7037 sap_cfg->ch_width_orig =
7038 hdd_ctx->config->vhtChannelWidth;
7039 else
7040 sap_cfg->ch_width_orig =
7041 hdd_ctx->config->nChannelBondingMode24GHz ?
7042 eHT_CHANNEL_WIDTH_40MHZ :
7043 eHT_CHANNEL_WIDTH_20MHZ;
7044 }
7045 sap_cfg->ch_params.ch_width = sap_cfg->ch_width_orig;
Sandeep Puligilla1cc23f62016-04-27 16:52:49 -07007046 cds_set_channel_params(sap_cfg->channel,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007047 sap_cfg->sec_ch, &sap_cfg->ch_params);
7048
7049 return 0;
7050
7051setup_acs_overrides:
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007052 hdd_err("** Driver force ACS override **");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007053
7054 sap_cfg->channel = AUTO_CHANNEL_SELECT;
7055 sap_cfg->acs_cfg.acs_mode = true;
7056 sap_cfg->acs_cfg.start_ch = hdd_ctx->config->force_sap_acs_st_ch;
7057 sap_cfg->acs_cfg.end_ch = hdd_ctx->config->force_sap_acs_end_ch;
7058
7059 if (sap_cfg->acs_cfg.start_ch > sap_cfg->acs_cfg.end_ch) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007060 hdd_err("Driver force ACS start ch (%d) > end ch (%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007061 sap_cfg->acs_cfg.start_ch, sap_cfg->acs_cfg.end_ch);
7062 return -EINVAL;
7063 }
7064
7065 /* Derive ACS HW mode */
7066 sap_cfg->SapHw_mode = hdd_cfg_xlate_to_csr_phy_mode(
7067 hdd_ctx->config->dot11Mode);
7068 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_AUTO)
7069 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
7070
Rajeev Kumar Sirasanagandlab79b5462016-09-06 18:33:17 +05307071 if (hdd_ctx->config->sap_force_11n_for_11ac) {
7072 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
7073 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY)
7074 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11n;
7075 }
7076
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007077 if ((sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11b ||
7078 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11g ||
7079 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11g_ONLY) &&
7080 sap_cfg->acs_cfg.start_ch > 14) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007081 hdd_err("Invalid ACS HW Mode %d + CH range <%d - %d>",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007082 sap_cfg->SapHw_mode, sap_cfg->acs_cfg.start_ch,
7083 sap_cfg->acs_cfg.end_ch);
7084 return -EINVAL;
7085 }
7086 sap_cfg->acs_cfg.hw_mode = sap_cfg->SapHw_mode;
7087
7088 /* Derive ACS BW */
7089 sap_cfg->ch_width_orig = eHT_CHANNEL_WIDTH_20MHZ;
7090 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
7091 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY) {
7092
7093 sap_cfg->ch_width_orig = hdd_ctx->config->vhtChannelWidth;
7094 /* VHT in 2.4G depends on gChannelBondingMode24GHz INI param */
7095 if (sap_cfg->acs_cfg.end_ch <= 14)
7096 sap_cfg->ch_width_orig =
7097 hdd_ctx->config->nChannelBondingMode24GHz ?
7098 eHT_CHANNEL_WIDTH_40MHZ :
7099 eHT_CHANNEL_WIDTH_20MHZ;
7100 }
7101
7102 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
7103 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n_ONLY) {
7104 if (sap_cfg->acs_cfg.end_ch <= 14)
7105 sap_cfg->ch_width_orig =
7106 hdd_ctx->config->nChannelBondingMode24GHz ?
7107 eHT_CHANNEL_WIDTH_40MHZ :
7108 eHT_CHANNEL_WIDTH_20MHZ;
7109 else
7110 sap_cfg->ch_width_orig =
7111 hdd_ctx->config->nChannelBondingMode5GHz ?
7112 eHT_CHANNEL_WIDTH_40MHZ :
7113 eHT_CHANNEL_WIDTH_20MHZ;
7114 }
7115 sap_cfg->acs_cfg.ch_width = sap_cfg->ch_width_orig;
7116
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007117 hdd_notice("Force ACS Config: HW_MODE: %d ACS_BW: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007118 sap_cfg->acs_cfg.hw_mode, sap_cfg->acs_cfg.ch_width);
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007119 hdd_notice("Force ACS Config: ST_CH: %d END_CH: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007120 sap_cfg->acs_cfg.start_ch, sap_cfg->acs_cfg.end_ch);
7121
7122 return 0;
7123}
7124
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007125/**
7126 * wlan_hdd_cfg80211_start_bss() - start bss
7127 * @pHostapdAdapter: Pointer to hostapd adapter
7128 * @params: Pointer to start bss beacon parameters
7129 * @ssid: Pointer ssid
7130 * @ssid_len: Length of ssid
7131 * @hidden_ssid: Hidden SSID parameter
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05307132 * @check_for_concurrency: Flag to indicate if check for concurrency is needed
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007133 *
7134 * Return: 0 for success non-zero for failure
7135 */
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05307136int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007137 struct cfg80211_beacon_data *params,
7138 const u8 *ssid, size_t ssid_len,
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05307139 enum nl80211_hidden_ssid hidden_ssid,
Archana Ramachandran1a5b6042016-11-08 16:36:50 -08007140 bool check_for_concurrency,
7141 bool update_beacon)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007142{
7143 tsap_Config_t *pConfig;
7144 beacon_data_t *pBeacon = NULL;
7145 struct ieee80211_mgmt *pMgmt_frame;
7146 uint8_t *pIe = NULL;
7147 uint16_t capab_info;
7148 eCsrAuthType RSNAuthType;
7149 eCsrEncryptionType RSNEncryptType;
7150 eCsrEncryptionType mcRSNEncryptType;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307151 int status = QDF_STATUS_SUCCESS, ret;
Anurag Chouhance0dc992016-02-16 18:18:03 +05307152 int qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007153 tpWLAN_SAPEventCB pSapEventCallback;
7154 hdd_hostapd_state_t *pHostapdState;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007155 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
7156 struct qc_mac_acl_entry *acl_entry = NULL;
7157 int32_t i;
7158 struct hdd_config *iniConfig;
7159 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
7160 tSmeConfigParams sme_config;
7161 bool MFPCapable = false;
7162 bool MFPRequired = false;
7163 uint16_t prev_rsn_length = 0;
Agrawal Ashish65634612016-08-18 13:24:32 +05307164 enum dfs_mode mode;
7165
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007166 ENTER();
7167
Archana Ramachandran1a5b6042016-11-08 16:36:50 -08007168 if (!update_beacon && cds_is_connection_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007169 hdd_err("Can't start BSS: connection is in progress");
7170 return -EINVAL;
7171 }
7172
7173 iniConfig = pHddCtx->config;
7174 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7175
7176 clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
7177 clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);
7178
7179 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7180
7181 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7182
7183 pMgmt_frame = (struct ieee80211_mgmt *)pBeacon->head;
7184
7185 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7186
7187 pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch;
7188
7189 /* channel is already set in the set_channel Call back */
7190 /* pConfig->channel = pCommitConfig->channel; */
7191
7192 /* Protection parameter to enable or disable */
7193 pConfig->protEnabled = iniConfig->apProtEnabled;
7194
Arif Hussain1b21e812016-08-16 16:08:28 -07007195 pConfig->enOverLapCh = iniConfig->gEnableOverLapCh;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007196 pConfig->dtim_period = pBeacon->dtim_period;
Kondabattini, Ganeshc846f3a2016-10-05 15:01:18 +05307197 hdd_info("acs_mode %d", pConfig->acs_cfg.acs_mode);
7198
7199 if (pConfig->acs_cfg.acs_mode == true) {
7200 hdd_info("acs_channel %d, acs_dfs_mode %d",
7201 pHddCtx->acs_policy.acs_channel,
7202 pHddCtx->acs_policy.acs_dfs_mode);
7203
7204 if (pHddCtx->acs_policy.acs_channel)
7205 pConfig->channel = pHddCtx->acs_policy.acs_channel;
7206 mode = pHddCtx->acs_policy.acs_dfs_mode;
7207 pConfig->acs_dfs_mode = wlan_hdd_get_dfs_mode(mode);
7208 }
7209
7210 hdd_info("pConfig->channel %d, pConfig->acs_dfs_mode %d",
7211 pConfig->channel, pConfig->acs_dfs_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007212
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007213 hdd_info("****pConfig->dtim_period=%d***",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007214 pConfig->dtim_period);
7215
Krunal Soni056ea0f2016-03-10 13:07:10 -08007216 if (pHostapdAdapter->device_mode == QDF_SAP_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007217 pIe =
7218 wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail,
7219 pBeacon->tail_len,
7220 WLAN_EID_COUNTRY);
7221 if (pIe) {
7222 pConfig->ieee80211d = 1;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307223 qdf_mem_copy(pConfig->countryCode, &pIe[2], 3);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007224 sme_set_reg_info(hHal, pConfig->countryCode);
7225 sme_apply_channel_power_info_to_fw(hHal);
7226 } else {
7227 pConfig->countryCode[0] = pHddCtx->reg.alpha2[0];
7228 pConfig->countryCode[1] = pHddCtx->reg.alpha2[1];
7229 pConfig->ieee80211d = 0;
7230 }
7231
7232 ret = wlan_hdd_sap_cfg_dfs_override(pHostapdAdapter);
7233 if (ret < 0) {
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05307234 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007235 } else {
7236 if (ret == 0) {
7237 if (CDS_IS_DFS_CH(pConfig->channel))
7238 pHddCtx->dev_dfs_cac_status =
7239 DFS_CAC_NEVER_DONE;
7240 }
7241 }
7242
Rajeev Kumar Sirasanagandlaa0006022016-09-09 16:24:31 +05307243 /*
7244 * If auto channel is configured i.e. channel is 0,
7245 * so skip channel validation.
7246 */
7247 if (AUTO_CHANNEL_SELECT != pConfig->channel) {
7248 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007249 wlan_hdd_validate_operation_channel(pHostapdAdapter,
7250 pConfig->channel)) {
Rajeev Kumar Sirasanagandlaa0006022016-09-09 16:24:31 +05307251 hdd_err("Invalid Channel [%d]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007252 pConfig->channel);
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05307253 ret = -EINVAL;
7254 goto error;
Rajeev Kumar Sirasanagandlaa0006022016-09-09 16:24:31 +05307255 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007256
Rajeev Kumar Sirasanagandlaa0006022016-09-09 16:24:31 +05307257 /* reject SAP if DFS channel scan is not allowed */
7258 if (!(pHddCtx->config->enableDFSChnlScan) &&
7259 (CHANNEL_STATE_DFS == cds_get_channel_state(
7260 pConfig->channel))) {
7261 hdd_err("No SAP start on DFS channel");
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05307262 ret = -EOPNOTSUPP;
7263 goto error;
Rajeev Kumar Sirasanagandlaa0006022016-09-09 16:24:31 +05307264 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007265 }
7266 wlansap_set_dfs_ignore_cac(hHal, iniConfig->ignoreCAC);
7267 wlansap_set_dfs_restrict_japan_w53(hHal,
7268 iniConfig->gDisableDfsJapanW53);
7269 wlansap_set_dfs_preferred_channel_location(hHal,
7270 iniConfig->gSapPreferredChanLocation);
7271#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
7272 wlan_sap_set_channel_avoidance(hHal,
7273 iniConfig->sap_channel_avoidance);
7274#endif
Krunal Soni056ea0f2016-03-10 13:07:10 -08007275 } else if (pHostapdAdapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007276 pConfig->countryCode[0] = pHddCtx->reg.alpha2[0];
7277 pConfig->countryCode[1] = pHddCtx->reg.alpha2[1];
7278 pConfig->ieee80211d = 0;
7279 } else {
7280 pConfig->ieee80211d = 0;
7281 }
7282
Yingying Tangb4832f72016-10-20 13:44:55 +08007283 wlansap_set_tx_leakage_threshold(hHal,
7284 iniConfig->sap_tx_leakage_threshold);
7285
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007286 capab_info = pMgmt_frame->u.beacon.capab_info;
7287
7288 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
7289 WLAN_CAPABILITY_PRIVACY) ? true : false;
7290
7291 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7292
7293 /*Set wps station to configured */
7294 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7295
7296 if (pIe) {
7297 if (pIe[1] < (2 + WPS_OUI_TYPE_SIZE)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007298 hdd_err("**Wps Ie Length is too small***");
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05307299 ret = -EINVAL;
7300 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007301 } else if (memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) ==
7302 0) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007303 hdd_notice("** WPS IE(len %d) ***", (pIe[1] + 2));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007304 /* Check 15 bit of WPS IE as it contain information for
7305 * wps state
7306 */
7307 if (SAP_WPS_ENABLED_UNCONFIGURED == pIe[15]) {
7308 pConfig->wps_state =
7309 SAP_WPS_ENABLED_UNCONFIGURED;
7310 } else if (SAP_WPS_ENABLED_CONFIGURED == pIe[15]) {
7311 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7312 }
7313 }
7314 } else {
7315 hdd_info("WPS disabled");
7316 pConfig->wps_state = SAP_WPS_DISABLED;
7317 }
7318 /* Forward WPS PBC probe request frame up */
7319 pConfig->fwdWPSPBCProbeReq = 1;
7320
7321 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7322 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7323 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7324 eCSR_ENCRYPT_TYPE_NONE;
7325
7326 pConfig->RSNWPAReqIELength = 0;
7327 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
7328 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7329 WLAN_EID_RSN);
7330 if (pIe && pIe[1]) {
7331 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7332 if (pConfig->RSNWPAReqIELength < sizeof(pConfig->RSNWPAReqIE))
7333 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
7334 pConfig->RSNWPAReqIELength);
7335 else
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007336 hdd_err("RSNWPA IE MAX Length exceeded; length =%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007337 pConfig->RSNWPAReqIELength);
7338 /* The actual processing may eventually be more extensive than
7339 * this. Right now, just consume any PMKIDs that are sent in
7340 * by the app.
7341 * */
7342 status =
7343 hdd_softap_unpack_ie(cds_get_context
Anurag Chouhan6d760662016-02-20 16:05:43 +05307344 (QDF_MODULE_ID_SME),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007345 &RSNEncryptType, &mcRSNEncryptType,
7346 &RSNAuthType, &MFPCapable,
7347 &MFPRequired,
7348 pConfig->RSNWPAReqIE[1] + 2,
7349 pConfig->RSNWPAReqIE);
7350
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307351 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007352 /* Now copy over all the security attributes you have
7353 * parsed out. Use the cipher type in the RSN IE
7354 */
7355 pConfig->RSNEncryptType = RSNEncryptType;
7356 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7357 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
7358 ucEncryptType = RSNEncryptType;
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007359 hdd_notice("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007360 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7361 }
7362 }
7363
7364 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7365 pBeacon->tail, pBeacon->tail_len);
7366
7367 if (pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA)) {
7368 if (pConfig->RSNWPAReqIE[0]) {
7369 /*Mixed mode WPA/WPA2 */
7370 prev_rsn_length = pConfig->RSNWPAReqIELength;
7371 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7372 if (pConfig->RSNWPAReqIELength <
7373 sizeof(pConfig->RSNWPAReqIE))
7374 memcpy(&pConfig->RSNWPAReqIE[0] +
7375 prev_rsn_length, pIe, pIe[1] + 2);
7376 else
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007377 hdd_err("RSNWPA IE MAX Length exceeded; length =%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007378 pConfig->RSNWPAReqIELength);
7379 } else {
7380 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7381 if (pConfig->RSNWPAReqIELength <
7382 sizeof(pConfig->RSNWPAReqIE))
7383 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
7384 pConfig->RSNWPAReqIELength);
7385 else
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007386 hdd_err("RSNWPA IE MAX Length exceeded; length =%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007387 pConfig->RSNWPAReqIELength);
7388 status = hdd_softap_unpack_ie
Anurag Chouhan6d760662016-02-20 16:05:43 +05307389 (cds_get_context(QDF_MODULE_ID_SME),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007390 &RSNEncryptType,
7391 &mcRSNEncryptType, &RSNAuthType,
7392 &MFPCapable, &MFPRequired,
7393 pConfig->RSNWPAReqIE[1] + 2,
7394 pConfig->RSNWPAReqIE);
7395
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307396 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007397 /* Now copy over all the security attributes
7398 * you have parsed out. Use the cipher type
7399 * in the RSN IE
7400 */
7401 pConfig->RSNEncryptType = RSNEncryptType;
7402 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7403 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
7404 ucEncryptType = RSNEncryptType;
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007405 hdd_notice("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007406 RSNAuthType, RSNEncryptType,
7407 mcRSNEncryptType);
7408 }
7409 }
7410 }
7411
7412 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007413 hdd_err("**RSNWPAReqIELength is too large***");
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05307414 ret = -EINVAL;
7415 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007416 }
7417
7418 pConfig->SSIDinfo.ssidHidden = false;
7419
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007420 if (ssid != NULL) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307421 qdf_mem_copy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007422 pConfig->SSIDinfo.ssid.length = ssid_len;
7423
7424 switch (hidden_ssid) {
7425 case NL80211_HIDDEN_SSID_NOT_IN_USE:
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007426 hdd_notice("HIDDEN_SSID_NOT_IN_USE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007427 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE;
7428 break;
7429 case NL80211_HIDDEN_SSID_ZERO_LEN:
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007430 hdd_notice("HIDDEN_SSID_ZERO_LEN");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007431 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN;
7432 break;
7433 case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007434 hdd_notice("HIDDEN_SSID_ZERO_CONTENTS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007435 pConfig->SSIDinfo.ssidHidden =
7436 eHIDDEN_SSID_ZERO_CONTENTS;
7437 break;
7438 default:
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007439 hdd_err("Wrong hidden_ssid param %d", hidden_ssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007440 break;
7441 }
7442 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007443
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307444 qdf_mem_copy(pConfig->self_macaddr.bytes,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007445 pHostapdAdapter->macAddressCurrent.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05307446 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007447
7448 /* default value */
7449 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7450 pConfig->num_accept_mac = 0;
7451 pConfig->num_deny_mac = 0;
7452#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
7453 /*
7454 * We don't want P2PGO to follow STA's channel
7455 * so lets limit the logic for SAP only.
7456 * Later if we decide to make p2pgo follow STA's
7457 * channel then remove this check.
7458 */
7459 if ((0 == pHddCtx->config->conc_custom_rule1) ||
7460 (pHddCtx->config->conc_custom_rule1 &&
Krunal Soni056ea0f2016-03-10 13:07:10 -08007461 QDF_SAP_MODE == pHostapdAdapter->device_mode))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007462 pConfig->cc_switch_mode = iniConfig->WlanMccToSccSwitchMode;
7463#endif
7464
7465 pIe =
7466 wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE,
7467 WPA_OUI_TYPE_SIZE, pBeacon->tail,
7468 pBeacon->tail_len);
7469
7470 /* pIe for black list is following form:
7471 * type : 1 byte
7472 * length : 1 byte
7473 * OUI : 4 bytes
7474 * acl type : 1 byte
7475 * no of mac addr in black list: 1 byte
7476 * list of mac_acl_entries: variable, 6 bytes per mac
7477 * address + sizeof(int) for vlan id
7478 */
7479 if ((pIe != NULL) && (pIe[1] != 0)) {
7480 pConfig->SapMacaddr_acl = pIe[6];
7481 pConfig->num_deny_mac = pIe[7];
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007482 hdd_notice("acl type = %d no deny mac = %d", pIe[6], pIe[7]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007483 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7484 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
7485 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7486 for (i = 0; i < pConfig->num_deny_mac; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307487 qdf_mem_copy(&pConfig->deny_mac[i], acl_entry->addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007488 sizeof(qcmacaddr));
7489 acl_entry++;
7490 }
7491 }
7492 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE,
7493 WPA_OUI_TYPE_SIZE, pBeacon->tail,
7494 pBeacon->tail_len);
7495
7496 /* pIe for white list is following form:
7497 * type : 1 byte
7498 * length : 1 byte
7499 * OUI : 4 bytes
7500 * acl type : 1 byte
7501 * no of mac addr in white list: 1 byte
7502 * list of mac_acl_entries: variable, 6 bytes per mac
7503 * address + sizeof(int) for vlan id
7504 */
7505 if ((pIe != NULL) && (pIe[1] != 0)) {
7506 pConfig->SapMacaddr_acl = pIe[6];
7507 pConfig->num_accept_mac = pIe[7];
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007508 hdd_notice("acl type = %d no accept mac = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007509 pIe[6], pIe[7]);
7510 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7511 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
7512 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7513 for (i = 0; i < pConfig->num_accept_mac; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307514 qdf_mem_copy(&pConfig->accept_mac[i], acl_entry->addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007515 sizeof(qcmacaddr));
7516 acl_entry++;
7517 }
7518 }
Krunal Soni8f8507c2016-12-20 13:54:34 -08007519 if (!pHddCtx->config->force_sap_acs &&
7520 (0 != qdf_mem_cmp(ssid, PRE_CAC_SSID, ssid_len))) {
Agrawal Ashish06e76d22016-08-18 16:44:48 +05307521 pIe = wlan_hdd_cfg80211_get_ie_ptr(
7522 &pMgmt_frame->u.beacon.variable[0],
7523 pBeacon->head_len, WLAN_EID_SUPP_RATES);
7524
7525 if (pIe != NULL) {
7526 pIe++;
7527 pConfig->supported_rates.numRates = pIe[0];
7528 pIe++;
7529 for (i = 0;
7530 i < pConfig->supported_rates.numRates; i++) {
7531 if (pIe[i]) {
7532 pConfig->supported_rates.rate[i] = pIe[i];
7533 hdd_info("Configured Supported rate is %2x",
7534 pConfig->supported_rates.rate[i]);
7535 }
7536 }
7537 }
7538 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail,
7539 pBeacon->tail_len,
7540 WLAN_EID_EXT_SUPP_RATES);
7541 if (pIe != NULL) {
7542 pIe++;
7543 pConfig->extended_rates.numRates = pIe[0];
7544 pIe++;
7545 for (i = 0; i < pConfig->extended_rates.numRates; i++) {
7546 if (pIe[i]) {
7547 pConfig->extended_rates.rate[i] = pIe[i];
7548 hdd_info("Configured ext Supported rate is %2x",
7549 pConfig->extended_rates.rate[i]);
7550 }
7551 }
7552 }
7553 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007554
7555 wlan_hdd_set_sap_hwmode(pHostapdAdapter);
Rajeev Kumar Sirasanagandlab79b5462016-09-06 18:33:17 +05307556 if (pHddCtx->config->sap_force_11n_for_11ac) {
7557 if (pConfig->SapHw_mode == eCSR_DOT11_MODE_11ac ||
7558 pConfig->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY)
7559 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n;
7560 }
7561
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307562 qdf_mem_zero(&sme_config, sizeof(tSmeConfigParams));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007563 sme_get_config_param(pHddCtx->hHal, &sme_config);
7564 /* Override hostapd.conf wmm_enabled only for 11n and 11AC configs (IOT)
7565 * As per spec 11N/AC STA are QOS STA and may not connect or throughput
7566 * may not be good with non QOS 11N AP
7567 * Default: enable QOS for SAP unless WMM IE not present for 11bga
7568 */
7569 sme_config.csrConfig.WMMSupportMode = eCsrRoamWmmAuto;
7570 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE,
7571 pBeacon->tail, pBeacon->tail_len);
7572 if (!pIe && (pConfig->SapHw_mode == eCSR_DOT11_MODE_11a ||
7573 pConfig->SapHw_mode == eCSR_DOT11_MODE_11g ||
7574 pConfig->SapHw_mode == eCSR_DOT11_MODE_11b))
7575 sme_config.csrConfig.WMMSupportMode = eCsrRoamWmmNoQos;
7576 sme_update_config(pHddCtx->hHal, &sme_config);
7577
Rajeev Kumar Sirasanagandlab79b5462016-09-06 18:33:17 +05307578 if (!pHddCtx->config->sap_force_11n_for_11ac) {
Amar Singhal4f22ccd2016-08-15 15:01:45 -07007579 pConfig->ch_width_orig =
7580 hdd_map_nl_chan_width(pConfig->ch_width_orig);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007581 } else {
Rajeev Kumar Sirasanagandlab79b5462016-09-06 18:33:17 +05307582 if (pConfig->ch_width_orig >= NL80211_CHAN_WIDTH_40)
7583 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7584 else
7585 pConfig->ch_width_orig = CH_WIDTH_20MHZ;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007586 }
7587
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05307588 if (wlan_hdd_setup_driver_overrides(pHostapdAdapter)) {
7589 ret = -EINVAL;
7590 goto error;
7591 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007592
7593 /* ht_capab is not what the name conveys,this is used for protection
7594 * bitmap */
7595 pConfig->ht_capab = iniConfig->apProtection;
7596
7597 if (0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007598 hdd_err("SAP Not able to set AP IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007599 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05307600 ret = -EINVAL;
7601 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007602 }
7603 /* Uapsd Enabled Bit */
7604 pConfig->UapsdEnable = iniConfig->apUapsdEnabled;
7605 /* Enable OBSS protection */
7606 pConfig->obssProtEnabled = iniConfig->apOBSSProtEnabled;
7607
Krunal Soni056ea0f2016-03-10 13:07:10 -08007608 if (pHostapdAdapter->device_mode == QDF_SAP_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007609 pConfig->sap_dot11mc =
7610 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->sap_dot11mc;
7611 else /* for P2P-Go case */
7612 pConfig->sap_dot11mc = 1;
7613
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007614 hdd_notice("11MC Support Enabled : %d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007615 pConfig->sap_dot11mc);
7616
7617#ifdef WLAN_FEATURE_11W
7618 pConfig->mfpCapable = MFPCapable;
7619 pConfig->mfpRequired = MFPRequired;
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007620 hdd_notice("Soft AP MFP capable %d, MFP required %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007621 pConfig->mfpCapable, pConfig->mfpRequired);
7622#endif
7623
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007624 hdd_warn("SOftAP macaddress : " MAC_ADDRESS_STR,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007625 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007626 hdd_warn("ssid =%s, beaconint=%d, channel=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007627 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7628 (int)pConfig->channel);
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007629 hdd_warn("hw_mode=%x, privacy=%d, authType=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007630 pConfig->SapHw_mode, pConfig->privacy, pConfig->authType);
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007631 hdd_warn("RSN/WPALen=%d, Uapsd = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007632 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007633 hdd_warn("ProtEnabled = %d, OBSSProtEnabled = %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007634 pConfig->protEnabled, pConfig->obssProtEnabled);
7635
7636 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
7637 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7638 /* Bss already started. just return. */
7639 /* TODO Probably it should update some beacon params. */
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007640 hdd_err("Bss Already started...Ignore the request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007641 EXIT();
7642 return 0;
7643 }
7644
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05307645 if (check_for_concurrency) {
7646 if (!cds_allow_concurrency(
7647 cds_convert_device_mode_to_qdf_type(
7648 pHostapdAdapter->device_mode),
7649 pConfig->channel, HW_MODE_20_MHZ)) {
7650 hdd_warn("This concurrency combination is not allowed");
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05307651 ret = -EINVAL;
7652 goto error;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05307653 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007654 }
7655
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007656 if (!cds_set_connection_in_progress(true)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007657 hdd_err("Can't start BSS: set connnection in progress failed");
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05307658 ret = -EINVAL;
7659 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007660 }
7661
7662 pConfig->persona = pHostapdAdapter->device_mode;
7663
7664 pSapEventCallback = hdd_hostapd_sap_event_cb;
7665
7666 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->dfs_cac_block_tx = true;
7667
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307668 qdf_event_reset(&pHostapdState->qdf_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007669 status = wlansap_start_bss(
Dustin Brown5118e8e2016-09-13 15:54:23 -07007670 WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
7671 pSapEventCallback, pConfig, pHostapdAdapter->dev);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307672 if (!QDF_IS_STATUS_SUCCESS(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007673 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007674 cds_set_connection_in_progress(false);
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007675 hdd_err("SAP Start Bss fail");
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05307676 ret = -EINVAL;
7677 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007678 }
7679
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007680 hdd_notice("Waiting for Scan to complete(auto mode) and BSS to start");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007681
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307682 qdf_status = qdf_wait_single_event(&pHostapdState->qdf_event, 10000);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007683
7684 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7685
Anurag Chouhance0dc992016-02-16 18:18:03 +05307686 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007687 hdd_err("ERROR: HDD qdf wait for single_event failed!!");
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007688 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007689 sme_get_command_q_status(hHal);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007690 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307691 QDF_ASSERT(0);
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05307692 ret = -EINVAL;
7693 goto error;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007694 }
7695 /* Succesfully started Bss update the state bit. */
7696 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
7697 /* Initialize WMM configuation */
7698 hdd_wmm_init(pHostapdAdapter);
Krunal Sonib37bb352016-12-20 14:12:21 -08007699 if (pHostapdState->bssState == BSS_START)
7700 cds_incr_active_session(pHostapdAdapter->device_mode,
7701 pHostapdAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007702#ifdef DHCP_SERVER_OFFLOAD
7703 if (iniConfig->enableDHCPServerOffload)
7704 wlan_hdd_set_dhcp_server_offload(pHostapdAdapter);
7705#endif /* DHCP_SERVER_OFFLOAD */
7706
7707#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Soni056ea0f2016-03-10 13:07:10 -08007708 if (pHostapdAdapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007709 if (global_p2p_connection_status == P2P_GO_NEG_COMPLETED) {
7710 global_p2p_connection_status = P2P_GO_COMPLETED_STATE;
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007711 hdd_err("[P2P State] From Go nego completed to Non-autonomous Group started");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007712 } else if (global_p2p_connection_status == P2P_NOT_ACTIVE) {
7713 global_p2p_connection_status = P2P_GO_COMPLETED_STATE;
Jeff Johnsonecd884e2016-06-30 14:52:25 -07007714 hdd_err("[P2P State] From Inactive to Autonomous Group started");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007715 }
7716 }
7717#endif
7718
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007719 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007720 pHostapdState->bCommit = true;
7721 EXIT();
7722
7723 return 0;
Masti, Narayanraddi96d62ab2016-08-22 14:58:33 +05307724
7725error:
7726 if (pHostapdAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list) {
7727 qdf_mem_free(pHostapdAdapter->sessionCtx.ap.sapConfig.
7728 acs_cfg.ch_list);
7729 pHostapdAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list = NULL;
7730 }
7731 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007732}
7733
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007734/**
7735 * __wlan_hdd_cfg80211_stop_ap() - stop soft ap
7736 * @wiphy: Pointer to wiphy structure
7737 * @dev: Pointer to net_device structure
7738 *
7739 * Return: 0 for success non-zero for failure
7740 */
7741static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7742 struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007743{
7744 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7745 hdd_context_t *pHddCtx = NULL;
7746 hdd_scaninfo_t *pScanInfo = NULL;
7747 hdd_adapter_t *staAdapter = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307748 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Anurag Chouhance0dc992016-02-16 18:18:03 +05307749 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007750 tSirUpdateIE updateIE;
7751 beacon_data_t *old;
7752 int ret;
7753 unsigned long rc;
7754 hdd_adapter_list_node_t *pAdapterNode = NULL;
7755 hdd_adapter_list_node_t *pNext = NULL;
7756
7757 ENTER();
7758
Anurag Chouhan6d760662016-02-20 16:05:43 +05307759 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07007760 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007761 return -EINVAL;
7762 }
7763
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +05307764 if (wlan_hdd_validate_session_id(pAdapter->sessionId)) {
7765 hdd_err("invalid session id: %d", pAdapter->sessionId);
7766 return -EINVAL;
7767 }
7768
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307769 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007770 TRACE_CODE_HDD_CFG80211_STOP_AP,
7771 pAdapter->sessionId, pAdapter->device_mode));
7772
Krunal Soni056ea0f2016-03-10 13:07:10 -08007773 if (!(pAdapter->device_mode == QDF_SAP_MODE ||
7774 pAdapter->device_mode == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007775 return -EOPNOTSUPP;
7776 }
7777
Jeff Johnsonb90586c2016-06-30 15:00:38 -07007778 hdd_notice("Device_mode %s(%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007779 hdd_device_mode_to_string(pAdapter->device_mode),
7780 pAdapter->device_mode);
7781
Ganesh Kondabattiniff050662016-08-05 12:21:23 +05307782 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7783 ret = wlan_hdd_validate_context(pHddCtx);
Liangwei Dong8baf7c82016-10-11 01:26:59 -04007784 if (0 != ret)
Ganesh Kondabattiniff050662016-08-05 12:21:23 +05307785 return ret;
Ganesh Kondabattiniff050662016-08-05 12:21:23 +05307786
bings612b9c42016-11-07 10:52:03 +08007787 if (QDF_SAP_MODE == pAdapter->device_mode)
7788 hdd_green_ap_stop_bss(pHddCtx);
7789
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007790 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307791 while (NULL != pAdapterNode && QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007792 staAdapter = pAdapterNode->pAdapter;
7793
Krunal Soni056ea0f2016-03-10 13:07:10 -08007794 if (QDF_STA_MODE == staAdapter->device_mode ||
7795 (QDF_P2P_CLIENT_MODE == staAdapter->device_mode) ||
7796 (QDF_P2P_GO_MODE == staAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007797 pScanInfo = &staAdapter->scan_info;
7798
7799 if (pScanInfo && pScanInfo->mScanPending) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07007800 hdd_notice("Aborting pending scan for device mode:%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007801 staAdapter->device_mode);
7802 INIT_COMPLETION(pScanInfo->abortscan_event_var);
7803 hdd_abort_mac_scan(staAdapter->pHddCtx,
7804 staAdapter->sessionId,
7805 eCSR_SCAN_ABORT_DEFAULT);
7806 rc = wait_for_completion_timeout(
7807 &pScanInfo->abortscan_event_var,
7808 msecs_to_jiffies(
7809 WLAN_WAIT_TIME_ABORTSCAN));
7810 if (!rc) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07007811 hdd_err("Timeout occurred while waiting for abortscan");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307812 QDF_ASSERT(pScanInfo->mScanPending);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007813 }
7814 }
7815 }
7816
7817 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
7818 pAdapterNode = pNext;
7819 }
7820 /*
7821 * When ever stop ap adapter gets called, we need to check
7822 * whether any restart AP work is pending. If any restart is pending
7823 * then lets finish it and go ahead from there.
7824 */
7825 if (pHddCtx->config->conc_custom_rule1 &&
Krunal Soni056ea0f2016-03-10 13:07:10 -08007826 (QDF_SAP_MODE == pAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007827 cds_flush_work(&pHddCtx->sap_start_work);
Jeff Johnsonb90586c2016-06-30 15:00:38 -07007828 hdd_warn("Canceled the pending restart work");
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307829 qdf_spin_lock(&pHddCtx->sap_update_info_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007830 pHddCtx->is_sap_restart_required = false;
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307831 qdf_spin_unlock(&pHddCtx->sap_update_info_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007832 }
7833 pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
Liangwei Dong8baf7c82016-10-11 01:26:59 -04007834 wlan_hdd_undo_acs(pAdapter);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307835 qdf_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007836 sizeof(struct sap_acs_cfg));
7837 hdd_hostapd_stop(dev);
7838
7839 old = pAdapter->sessionCtx.ap.beacon;
7840 if (!old) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07007841 hdd_err("Session(%d) beacon data points to NULL",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007842 pAdapter->sessionId);
7843 return -EINVAL;
7844 }
7845
7846 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Kapil Gupta139c3302016-09-22 16:48:12 +05307847 wlan_hdd_cleanup_remain_on_channel_ctx(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007848
7849 mutex_lock(&pHddCtx->sap_lock);
7850 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) {
7851 hdd_hostapd_state_t *pHostapdState =
7852 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7853
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307854 qdf_event_reset(&pHostapdState->qdf_stop_bss_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007855 status = wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307856 if (QDF_IS_STATUS_SUCCESS(status)) {
Anurag Chouhance0dc992016-02-16 18:18:03 +05307857 qdf_status =
7858 qdf_wait_single_event(&pHostapdState->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307859 qdf_stop_bss_event,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007860 10000);
7861
Anurag Chouhance0dc992016-02-16 18:18:03 +05307862 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07007863 hdd_err("HDD qdf wait for single_event failed!!");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05307864 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007865 }
7866 }
7867 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7868 /*BSS stopped, clear the active sessions for this device mode*/
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08007869 cds_decr_session_set_pcl(pAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007870 pAdapter->sessionId);
7871 pAdapter->sessionCtx.ap.beacon = NULL;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05307872 qdf_mem_free(old);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007873 }
7874 mutex_unlock(&pHddCtx->sap_lock);
7875
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05307876 if (wlan_sap_is_pre_cac_active(pHddCtx->hHal))
7877 hdd_clean_up_pre_cac_interface(pHddCtx);
7878
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307879 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07007880 hdd_err("Stopping the BSS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007881 return -EINVAL;
7882 }
7883
Anurag Chouhanc5548422016-02-24 18:33:27 +05307884 qdf_copy_macaddr(&updateIE.bssid, &pAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007885 updateIE.smeSessionId = pAdapter->sessionId;
7886 updateIE.ieBufferlength = 0;
7887 updateIE.pAdditionIEBuffer = NULL;
7888 updateIE.append = true;
7889 updateIE.notify = true;
7890 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
7891 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307892 eUPDATE_IE_PROBE_BCN) == QDF_STATUS_E_FAILURE) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07007893 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007894 }
7895
7896 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
7897 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307898 eUPDATE_IE_ASSOC_RESP) == QDF_STATUS_E_FAILURE) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07007899 hdd_err("Could not pass on ASSOC_RSP data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007900 }
7901 /* Reset WNI_CFG_PROBE_RSP Flags */
7902 wlan_hdd_reset_prob_rspies(pAdapter);
7903
7904#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Soni056ea0f2016-03-10 13:07:10 -08007905 if ((pAdapter->device_mode == QDF_P2P_GO_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007906 (global_p2p_connection_status == P2P_GO_COMPLETED_STATE)) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07007907 hdd_err("[P2P State] From GO completed to Inactive state GO got removed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007908 global_p2p_connection_status = P2P_NOT_ACTIVE;
7909 }
7910#endif
Hanumanth Reddy Pothula33702122016-10-07 17:27:04 +05307911 pAdapter->sessionId = HDD_SESSION_ID_INVALID;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007912 EXIT();
7913 return ret;
7914}
7915
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007916/**
7917 * wlan_hdd_get_channel_bw() - get channel bandwidth
7918 * @width: input channel width in nl80211_chan_width value
7919 *
7920 * Return: channel width value defined by driver
7921 */
7922static enum hw_mode_bandwidth wlan_hdd_get_channel_bw(
7923 enum nl80211_chan_width width)
7924{
7925 enum hw_mode_bandwidth ch_bw = HW_MODE_20_MHZ;
7926
7927 switch (width) {
7928 case NL80211_CHAN_WIDTH_20_NOHT:
7929 case NL80211_CHAN_WIDTH_20:
7930 ch_bw = HW_MODE_20_MHZ;
7931 break;
7932 case NL80211_CHAN_WIDTH_40:
7933 ch_bw = HW_MODE_40_MHZ;
7934 break;
7935 case NL80211_CHAN_WIDTH_80:
7936 ch_bw = HW_MODE_80_MHZ;
7937 break;
7938 case NL80211_CHAN_WIDTH_80P80:
7939 ch_bw = HW_MODE_80_PLUS_80_MHZ;
7940 break;
7941 case NL80211_CHAN_WIDTH_160:
7942 ch_bw = HW_MODE_160_MHZ;
7943 break;
7944 default:
7945 hdd_err("Invalid width: %d, using default 20MHz", width);
7946 break;
7947 }
7948
7949 return ch_bw;
7950}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007951
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007952/**
7953 * wlan_hdd_cfg80211_stop_ap() - stop sap
7954 * @wiphy: Pointer to wiphy
7955 * @dev: Pointer to netdev
7956 *
7957 * Return: zero for success non-zero for failure
7958 */
7959int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7960 struct net_device *dev)
7961{
7962 int ret;
7963
7964 cds_ssr_protect(__func__);
7965 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7966 cds_ssr_unprotect(__func__);
7967
7968 return ret;
7969}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007970
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007971/**
7972 * __wlan_hdd_cfg80211_start_ap() - start soft ap mode
7973 * @wiphy: Pointer to wiphy structure
7974 * @dev: Pointer to net_device structure
7975 * @params: Pointer to AP settings parameters
7976 *
7977 * Return: 0 for success non-zero for failure
7978 */
7979static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7980 struct net_device *dev,
7981 struct cfg80211_ap_settings *params)
7982{
7983 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7984 hdd_context_t *pHddCtx;
Chandrasekaran, Manishekar96c90962015-11-20 16:47:45 +05307985 enum hw_mode_bandwidth channel_width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007986 int status;
Agrawal, Ashish4e5fa1c2016-09-21 19:03:43 +05307987 struct sme_sta_inactivity_timeout *sta_inactivity_timer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007988 uint8_t channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007989
7990 ENTER();
7991
Anurag Chouhan6d760662016-02-20 16:05:43 +05307992 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07007993 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007994 return -EINVAL;
7995 }
7996
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +05307997 if (wlan_hdd_validate_session_id(pAdapter->sessionId)) {
7998 hdd_err("invalid session id: %d", pAdapter->sessionId);
7999 return -EINVAL;
8000 }
8001
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308002 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008003 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8004 params->beacon_interval));
8005 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07008006 hdd_err("HDD adapter magic is invalid");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008007 return -ENODEV;
8008 }
8009
8010 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8011 status = wlan_hdd_validate_context(pHddCtx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308012 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008013 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008014
Jeff Johnsonb90586c2016-06-30 15:00:38 -07008015 hdd_info("pAdapter = %p, Device mode %s(%d)", pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008016 hdd_device_mode_to_string(pAdapter->device_mode),
8017 pAdapter->device_mode);
8018
Sandeep Puligillab913b392016-10-25 16:31:46 -07008019
8020 if (cds_is_connection_in_progress()) {
8021 hdd_err("Can't start BSS: connection is in progress");
8022 return -EBUSY;
8023 }
8024
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008025 channel_width = wlan_hdd_get_channel_bw(params->chandef.width);
8026 channel = ieee80211_frequency_to_channel(
8027 params->chandef.chan->center_freq);
Amar Singhal01098f72015-10-08 11:55:32 -07008028
Naveen Rawat64e477e2016-05-20 10:34:56 -07008029 if (cds_is_sub_20_mhz_enabled()) {
8030 enum channel_state ch_state;
8031 enum phy_ch_width sub_20_ch_width = CH_WIDTH_INVALID;
8032 /* Avoid ACS/DFS, and overwrite ch wd to 20 */
8033 if (channel == 0) {
8034 hdd_err("Can't start SAP-ACS (channel=0) with sub 20 MHz ch width.");
8035 return -EINVAL;
8036 }
8037 if (CHANNEL_STATE_DFS == cds_get_channel_state(channel)) {
8038 hdd_err("Can't start SAP-DFS (channel=%d)with sub 20 MHz ch wd",
8039 channel);
8040 return -EINVAL;
8041 }
8042 if (channel_width != HW_MODE_20_MHZ) {
8043 hdd_err("Hostapd (20+ MHz) conflits with config.ini (sub 20 MHz)");
8044 return -EINVAL;
8045 }
8046 if (cds_is_5_mhz_enabled())
8047 sub_20_ch_width = CH_WIDTH_5MHZ;
8048 if (cds_is_10_mhz_enabled())
8049 sub_20_ch_width = CH_WIDTH_10MHZ;
8050 if (CDS_IS_CHANNEL_5GHZ(channel))
8051 ch_state = cds_get_5g_bonded_channel_state(channel,
8052 sub_20_ch_width);
8053 else
8054 ch_state = cds_get_2g_bonded_channel_state(channel,
8055 sub_20_ch_width, 0);
8056 if (CHANNEL_STATE_DISABLE == ch_state) {
8057 hdd_err("Given ch width not supported by reg domain.");
8058 return -EINVAL;
8059 }
8060 }
8061
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008062 /* check if concurrency is allowed */
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08008063 if (!cds_allow_concurrency(
Krunal Soni056ea0f2016-03-10 13:07:10 -08008064 cds_convert_device_mode_to_qdf_type(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008065 pAdapter->device_mode),
8066 channel,
8067 channel_width)) {
8068 hdd_err("Connection failed due to concurrency check failure");
8069 return -EINVAL;
8070 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008071
Krunal Soni3091bcc2016-06-23 12:28:21 -07008072 status = qdf_reset_connection_update();
8073 if (!QDF_IS_STATUS_SUCCESS(status))
8074 hdd_err("ERR: clear event failed");
8075
8076 status = cds_current_connections_update(pAdapter->sessionId,
8077 channel,
8078 SIR_UPDATE_REASON_START_AP);
8079 if (QDF_STATUS_E_FAILURE == status) {
8080 hdd_err("ERROR: connections update failed!!");
8081 return -EINVAL;
8082 }
8083
8084 if (QDF_STATUS_SUCCESS == status) {
8085 status = qdf_wait_for_connection_update();
8086 if (!QDF_IS_STATUS_SUCCESS(status)) {
8087 hdd_err("ERROR: qdf wait for event failed!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008088 return -EINVAL;
8089 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008090 }
bings612b9c42016-11-07 10:52:03 +08008091
8092 if (QDF_SAP_MODE == pAdapter->device_mode)
8093 hdd_green_ap_start_bss(pHddCtx);
8094
Liangwei Dongb3f26cc2016-10-11 04:37:00 -04008095 if (pAdapter->device_mode == QDF_P2P_GO_MODE) {
8096 hdd_adapter_t *p2p_adapter;
8097 p2p_adapter = hdd_get_adapter(pHddCtx, QDF_P2P_DEVICE_MODE);
8098 if (p2p_adapter) {
8099 hdd_info("cancel active p2p device ROC before GO "
8100 "starting");
8101 wlan_hdd_cancel_existing_remain_on_channel(
8102 p2p_adapter);
8103 }
8104 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008105
Krunal Soni056ea0f2016-03-10 13:07:10 -08008106 if ((pAdapter->device_mode == QDF_SAP_MODE)
8107 || (pAdapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008108 ) {
8109 beacon_data_t *old, *new;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008110 enum nl80211_channel_type channel_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008111
8112 old = pAdapter->sessionCtx.ap.beacon;
8113
8114 if (old)
8115 return -EALREADY;
8116
8117 status =
8118 wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new,
8119 &params->beacon,
8120 params->dtim_period);
8121
8122 if (status != 0) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07008123 hdd_err("Error!!! Allocating the new beacon");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008124 return -EINVAL;
8125 }
8126 pAdapter->sessionCtx.ap.beacon = new;
8127
8128 if (params->chandef.width < NL80211_CHAN_WIDTH_80)
8129 channel_type = cfg80211_get_chandef_type(
8130 &(params->chandef));
8131 else
8132 channel_type = NL80211_CHAN_HT40PLUS;
8133
8134
8135 wlan_hdd_set_channel(wiphy, dev,
8136 &params->chandef,
8137 channel_type);
8138
8139 /* set authentication type */
8140 switch (params->auth_type) {
8141 case NL80211_AUTHTYPE_OPEN_SYSTEM:
8142 pAdapter->sessionCtx.ap.sapConfig.authType =
8143 eSAP_OPEN_SYSTEM;
8144 break;
8145 case NL80211_AUTHTYPE_SHARED_KEY:
8146 pAdapter->sessionCtx.ap.sapConfig.authType =
8147 eSAP_SHARED_KEY;
8148 break;
8149 default:
8150 pAdapter->sessionCtx.ap.sapConfig.authType =
8151 eSAP_AUTO_SWITCH;
8152 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008153 pAdapter->sessionCtx.ap.sapConfig.ch_width_orig =
8154 params->chandef.width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008155 status =
8156 wlan_hdd_cfg80211_start_bss(pAdapter,
8157 &params->beacon,
8158 params->ssid, params->ssid_len,
Archana Ramachandran1a5b6042016-11-08 16:36:50 -08008159 params->hidden_ssid, true, false);
Agrawal, Ashish4e5fa1c2016-09-21 19:03:43 +05308160
8161 if (pHddCtx->config->sap_max_inactivity_override) {
8162 sta_inactivity_timer = qdf_mem_malloc(
8163 sizeof(*sta_inactivity_timer));
8164 if (!sta_inactivity_timer) {
8165 hdd_err("Failed to allocate Memory");
8166 return QDF_STATUS_E_FAILURE;
8167 }
8168 sta_inactivity_timer->session_id = pAdapter->sessionId;
8169 sta_inactivity_timer->sta_inactivity_timeout =
8170 params->inactivity_timeout;
8171 sme_update_sta_inactivity_timeout(WLAN_HDD_GET_HAL_CTX
8172 (pAdapter), sta_inactivity_timer);
8173 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008174 }
8175
8176 EXIT();
8177 return status;
8178}
8179
8180/**
8181 * wlan_hdd_cfg80211_start_ap() - start sap
8182 * @wiphy: Pointer to wiphy
8183 * @dev: Pointer to netdev
8184 * @params: Pointer to start ap configuration parameters
8185 *
8186 * Return: zero for success non-zero for failure
8187 */
8188int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8189 struct net_device *dev,
8190 struct cfg80211_ap_settings *params)
8191{
8192 int ret;
8193
8194 cds_ssr_protect(__func__);
8195 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8196 cds_ssr_unprotect(__func__);
8197
8198 return ret;
8199}
8200
8201/**
8202 * __wlan_hdd_cfg80211_change_beacon() - change beacon for sofatap/p2p go
8203 * @wiphy: Pointer to wiphy structure
8204 * @dev: Pointer to net_device structure
8205 * @params: Pointer to change beacon parameters
8206 *
8207 * Return: 0 for success non-zero for failure
8208 */
8209static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8210 struct net_device *dev,
8211 struct cfg80211_beacon_data *params)
8212{
8213 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8214 hdd_context_t *pHddCtx;
8215 beacon_data_t *old, *new;
8216 int status;
Archana Ramachandran1a5b6042016-11-08 16:36:50 -08008217 bool update_beacon;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008218
8219 ENTER();
8220
Anurag Chouhan6d760662016-02-20 16:05:43 +05308221 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07008222 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008223 return -EINVAL;
8224 }
8225
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +05308226 if (wlan_hdd_validate_session_id(pAdapter->sessionId)) {
8227 hdd_err("invalid session id: %d", pAdapter->sessionId);
8228 return -EINVAL;
8229 }
8230
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05308231 MTRACE(qdf_trace(QDF_MODULE_ID_HDD,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008232 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8233 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnsonb90586c2016-06-30 15:00:38 -07008234 hdd_notice("Device_mode %s(%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008235 hdd_device_mode_to_string(pAdapter->device_mode),
8236 pAdapter->device_mode);
8237
8238 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8239 status = wlan_hdd_validate_context(pHddCtx);
8240
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308241 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008242 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008243
Krunal Soni056ea0f2016-03-10 13:07:10 -08008244 if (!(pAdapter->device_mode == QDF_SAP_MODE ||
8245 pAdapter->device_mode == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008246 return -EOPNOTSUPP;
8247 }
8248
8249 old = pAdapter->sessionCtx.ap.beacon;
8250
8251 if (!old) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07008252 hdd_err("session(%d) beacon data points to NULL",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008253 pAdapter->sessionId);
8254 return -EINVAL;
8255 }
8256
8257 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8258
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308259 if (status != QDF_STATUS_SUCCESS) {
Jeff Johnsonb90586c2016-06-30 15:00:38 -07008260 hdd_err("new beacon alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008261 return -EINVAL;
8262 }
8263
8264 pAdapter->sessionCtx.ap.beacon = new;
Archana Ramachandran1a5b6042016-11-08 16:36:50 -08008265 update_beacon = (pAdapter->device_mode ==
8266 QDF_P2P_GO_MODE) ? true : false;
8267 hdd_info("update beacon for P2P GO: %d", update_beacon);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05308268 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL,
Archana Ramachandran1a5b6042016-11-08 16:36:50 -08008269 0, 0, false, update_beacon);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008270
8271 EXIT();
8272 return status;
8273}
8274
8275/**
8276 * wlan_hdd_cfg80211_change_beacon() - change beacon content in sap mode
8277 * @wiphy: Pointer to wiphy
8278 * @dev: Pointer to netdev
8279 * @params: Pointer to change beacon parameters
8280 *
8281 * Return: zero for success non-zero for failure
8282 */
8283int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8284 struct net_device *dev,
8285 struct cfg80211_beacon_data *params)
8286{
8287 int ret;
8288
8289 cds_ssr_protect(__func__);
8290 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8291 cds_ssr_unprotect(__func__);
8292
8293 return ret;
8294}