blob: 0e69738968e524d39093d403d0dc1e6e05881981 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002 * Copyright (c) 2012-2016 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>
43#include <cds_api.h>
44#include <cds_sched.h>
45#include <linux/etherdevice.h>
46#include <wlan_hdd_includes.h>
47#include <qc_sap_ioctl.h>
48#include <wlan_hdd_hostapd.h>
49#include <sap_api.h>
50#include <sap_internal.h>
51#include <wlan_hdd_softap_tx_rx.h>
52#include <wlan_hdd_main.h>
53#include <wlan_hdd_ioctl.h>
54#include <wlan_hdd_stats.h>
55#include <linux/netdevice.h>
56#include <linux/rtnetlink.h>
57#include <linux/mmc/sdio_func.h>
58#include "wlan_hdd_p2p.h"
59#include <wlan_hdd_ipa.h>
60#include "cfg_api.h"
61#include "wni_cfg.h"
62#include "wlan_hdd_misc.h"
63#include <cds_utils.h>
64#if defined CONFIG_CNSS
65#include <net/cnss.h>
66#endif
67
68#include "wma.h"
69#ifdef DEBUG
70#include "wma_api.h"
71#endif
72#include "wlan_hdd_trace.h"
73#include "cdf_types.h"
74#include "cdf_trace.h"
75#include "wlan_hdd_cfg.h"
76#include "cds_concurrency.h"
77#include "wlan_hdd_green_ap.h"
78
79#define IS_UP(_dev) \
80 (((_dev)->flags & (IFF_RUNNING|IFF_UP)) == (IFF_RUNNING|IFF_UP))
81#define IS_UP_AUTO(_ic) \
82 (IS_UP((_ic)->ic_dev) && (_ic)->ic_roaming == IEEE80211_ROAMING_AUTO)
83#define WE_WLAN_VERSION 1
84#define WE_GET_STA_INFO_SIZE 30
85/* WEXT limitation: MAX allowed buf len for any *
86 * IW_PRIV_TYPE_CHAR is 2Kbytes *
87 */
88#define WE_SAP_MAX_STA_INFO 0x7FF
89
90#define RC_2_RATE_IDX(_rc) ((_rc) & 0x7)
91#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1)
92#define RC_2_RATE_IDX_11AC(_rc) ((_rc) & 0xf)
93#define HT_RC_2_STREAMS_11AC(_rc) ((((_rc) & 0x30) >> 4) + 1)
94
95#define SAP_24GHZ_CH_COUNT (14)
96#define ACS_SCAN_EXPIRY_TIMEOUT_S 4
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080097
98#define DUMP_DP_TRACE 0
99
100/* Function definitions */
101
102/**
103 * hdd_hostapd_channel_wakelock_init() - init the channel wakelock
104 * @pHddCtx: pointer to hdd context
105 *
106 * Return: None
107 */
108void hdd_hostapd_channel_wakelock_init(hdd_context_t *pHddCtx)
109{
110 /* Initialize the wakelock */
111 cdf_wake_lock_init(&pHddCtx->sap_dfs_wakelock, "sap_dfs_wakelock");
112 atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0);
113}
114
115/**
116 * hdd_hostapd_channel_allow_suspend() - allow suspend in a channel.
117 * Called when, 1. bss stopped, 2. channel switch
118 *
119 * @pAdapter: pointer to hdd adapter
120 * @channel: current channel
121 *
122 * Return: None
123 */
124void hdd_hostapd_channel_allow_suspend(hdd_adapter_t *pAdapter,
125 uint8_t channel)
126{
127
128 hdd_context_t *pHddCtx = (hdd_context_t *) (pAdapter->pHddCtx);
129 hdd_hostapd_state_t *pHostapdState =
130 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
131
132 hddLog(LOG1, FL("bssState: %d, channel: %d, dfs_ref_cnt: %d"),
133 pHostapdState->bssState, channel,
134 atomic_read(&pHddCtx->sap_dfs_ref_cnt));
135
136 /* Return if BSS is already stopped */
137 if (pHostapdState->bssState == BSS_STOP)
138 return;
139
140 /* Release wakelock when no more DFS channels are used */
141 if (CHANNEL_STATE_DFS == cds_get_channel_state(channel)) {
142 if (atomic_dec_and_test(&pHddCtx->sap_dfs_ref_cnt)) {
143 hddLog(LOGE, FL("DFS: allowing suspend (chan %d)"),
144 channel);
145 cdf_wake_lock_release(&pHddCtx->sap_dfs_wakelock,
146 WIFI_POWER_EVENT_WAKELOCK_DFS);
147 }
148 }
149}
150
151/**
152 * hdd_hostapd_channel_prevent_suspend() - prevent suspend in a channel.
153 * Called when, 1. bss started, 2. channel switch
154 *
155 * @pAdapter: pointer to hdd adapter
156 * @channel: current channel
157 *
158 * Return - None
159 */
160void hdd_hostapd_channel_prevent_suspend(hdd_adapter_t *pAdapter,
161 uint8_t channel)
162{
163 hdd_context_t *pHddCtx = (hdd_context_t *) (pAdapter->pHddCtx);
164 hdd_hostapd_state_t *pHostapdState =
165 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
166
167 hddLog(LOG1, FL("bssState: %d, channel: %d, dfs_ref_cnt: %d"),
168 pHostapdState->bssState, channel,
169 atomic_read(&pHddCtx->sap_dfs_ref_cnt));
170
171 /* Return if BSS is already started && wakelock is acquired */
172 if ((pHostapdState->bssState == BSS_START) &&
173 (atomic_read(&pHddCtx->sap_dfs_ref_cnt) >= 1))
174 return;
175
176 /* Acquire wakelock if we have at least one DFS channel in use */
177 if (CHANNEL_STATE_DFS == cds_get_channel_state(channel)) {
178 if (atomic_inc_return(&pHddCtx->sap_dfs_ref_cnt) == 1) {
179 hddLog(LOGE, FL("DFS: preventing suspend (chan %d)"),
180 channel);
181 cdf_wake_lock_acquire(&pHddCtx->sap_dfs_wakelock,
182 WIFI_POWER_EVENT_WAKELOCK_DFS);
183 }
184 }
185}
186
187/**
188 * hdd_hostapd_channel_wakelock_deinit() - destroy the channel wakelock
189 *
190 * @pHddCtx: pointer to hdd context
191 *
192 * Return: None
193 */
194void hdd_hostapd_channel_wakelock_deinit(hdd_context_t *pHddCtx)
195{
196 if (atomic_read(&pHddCtx->sap_dfs_ref_cnt)) {
197 /* Release wakelock */
198 cdf_wake_lock_release(&pHddCtx->sap_dfs_wakelock,
199 WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT);
200 /* Reset the reference count */
201 atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0);
202 hddLog(LOGE, FL("DFS: allowing suspend"));
203 }
204
205 /* Destroy lock */
206 cdf_wake_lock_destroy(&pHddCtx->sap_dfs_wakelock);
207}
208
209/**
210 * __hdd_hostapd_open() - hdd open function for hostapd interface
211 * This is called in response to ifconfig up
212 * @dev: pointer to net_device structure
213 *
214 * Return - 0 for success non-zero for failure
215 */
216static int __hdd_hostapd_open(struct net_device *dev)
217{
218 hdd_adapter_t *pAdapter = netdev_priv(dev);
219
220 ENTER();
221
222 MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
223 TRACE_CODE_HDD_HOSTAPD_OPEN_REQUEST, NO_SESSION, 0));
224
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800225 if (cds_is_load_unload_in_progress()) {
226 hdd_err("Driver load/unload in progress, ignore, state: 0x%x",
227 cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800228 goto done;
229 }
Prashanth Bhatta9e143052015-12-04 11:56:47 -0800230
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800231 /* Enable all Tx queues */
232 hddLog(LOG1, FL("Enabling queues"));
233 wlan_hdd_netif_queue_control(pAdapter,
234 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
235 WLAN_CONTROL_PATH);
236done:
237 EXIT();
238 return 0;
239}
240
241/**
242 * hdd_hostapd_open() - SSR wrapper for __hdd_hostapd_open
243 * @dev: pointer to net device
244 *
245 * Return: 0 on success, error number otherwise
246 */
247static int hdd_hostapd_open(struct net_device *dev)
248{
249 int ret;
250
251 cds_ssr_protect(__func__);
252 ret = __hdd_hostapd_open(dev);
253 cds_ssr_unprotect(__func__);
254
255 return ret;
256}
257
258/**
259 * __hdd_hostapd_stop() - hdd stop function for hostapd interface
260 * This is called in response to ifconfig down
261 *
262 * @dev: pointer to net_device structure
263 *
264 * Return - 0 for success non-zero for failure
265 */
266static int __hdd_hostapd_stop(struct net_device *dev)
267{
268 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
269 ENTER();
270
271 /* Stop all tx queues */
272 hddLog(LOG1, FL("Disabling queues"));
273 wlan_hdd_netif_queue_control(adapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
274 WLAN_CONTROL_PATH);
275
276 EXIT();
277 return 0;
278}
279
280/**
281 * hdd_hostapd_stop() - SSR wrapper for__hdd_hostapd_stop
282 * @dev: pointer to net_device
283 *
284 * This is called in response to ifconfig down
285 *
286 * Return: 0 on success, error number otherwise
287 */
288int hdd_hostapd_stop(struct net_device *dev)
289{
290 int ret;
291
292 cds_ssr_protect(__func__);
293 ret = __hdd_hostapd_stop(dev);
294 cds_ssr_unprotect(__func__);
295
296 return ret;
297}
298
299/**
300 * __hdd_hostapd_uninit() - hdd uninit function
301 * This is called during the netdev unregister to uninitialize all data
302 * associated with the device.
303 *
304 * @dev: pointer to net_device structure
305 *
306 * Return: None
307 */
308static void __hdd_hostapd_uninit(struct net_device *dev)
309{
310 hdd_adapter_t *adapter = netdev_priv(dev);
311 hdd_context_t *hdd_ctx;
312
313 ENTER();
314
315 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
316 hddLog(LOGE, FL("Invalid magic"));
317 return;
318 }
319
320 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
321 if (NULL == hdd_ctx) {
322 hddLog(LOGE, FL("NULL hdd_ctx"));
323 return;
324 }
325
326 hdd_deinit_adapter(hdd_ctx, adapter, true);
327
328 /* after uninit our adapter structure will no longer be valid */
329 adapter->dev = NULL;
330 adapter->magic = 0;
331
332 EXIT();
333}
334
335/**
336 * hdd_hostapd_uninit() - SSR wrapper for __hdd_hostapd_uninit
337 * @dev: pointer to net_device
338 *
339 * Return: 0 on success, error number otherwise
340 */
341static void hdd_hostapd_uninit(struct net_device *dev)
342{
343 cds_ssr_protect(__func__);
344 __hdd_hostapd_uninit(dev);
345 cds_ssr_unprotect(__func__);
346}
347
348/**
349 * __hdd_hostapd_change_mtu() - change mtu
350 * @dev: pointer to net_device
351 * @new_mtu: new mtu
352 *
353 * Return: 0 on success, error number otherwise
354 */
355static int __hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
356{
357 return 0;
358}
359
360/**
361 * hdd_hostapd_change_mtu() - SSR wrapper for __hdd_hostapd_change_mtu
362 * @dev: pointer to net_device
363 * @new_mtu: new mtu
364 *
365 * Return: 0 on success, error number otherwise
366 */
367static int hdd_hostapd_change_mtu(struct net_device *dev, int new_mtu)
368{
369 int ret;
370
371 cds_ssr_protect(__func__);
372 ret = __hdd_hostapd_change_mtu(dev, new_mtu);
373 cds_ssr_unprotect(__func__);
374
375 return ret;
376}
377
378#ifdef QCA_HT_2040_COEX
379CDF_STATUS hdd_set_sap_ht2040_mode(hdd_adapter_t *pHostapdAdapter,
380 uint8_t channel_type)
381{
382 CDF_STATUS cdf_ret_status = CDF_STATUS_E_FAILURE;
383 void *hHal = NULL;
384
385 hddLog(LOGE, FL("change HT20/40 mode"));
386
387 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) {
388 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
389 if (NULL == hHal) {
390 hddLog(LOGE, FL("Hal ctx is null"));
391 return CDF_STATUS_E_FAULT;
392 }
393 cdf_ret_status =
394 sme_set_ht2040_mode(hHal, pHostapdAdapter->sessionId,
395 channel_type, true);
396 if (cdf_ret_status == CDF_STATUS_E_FAILURE) {
397 hddLog(LOGE, FL("Failed to change HT20/40 mode"));
398 return CDF_STATUS_E_FAILURE;
399 }
400 }
401 return CDF_STATUS_SUCCESS;
402}
403#endif
404
405/**
406 * __hdd_hostapd_set_mac_address() -
407 * This function sets the user specified mac address using
408 * the command ifconfig wlanX hw ether <mac address>.
409 *
410 * @dev: pointer to the net device.
411 * @addr: pointer to the sockaddr.
412 *
413 * Return: 0 for success, non zero for failure
414 */
415static int __hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
416{
417 struct sockaddr *psta_mac_addr = addr;
418 hdd_adapter_t *adapter;
419 hdd_context_t *hdd_ctx;
420 int ret = 0;
421
422 ENTER();
423
424 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
425 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
426 ret = wlan_hdd_validate_context(hdd_ctx);
427 if (0 != ret)
428 return ret;
429
430 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
431 EXIT();
432 return 0;
433}
434
435/**
436 * hdd_hostapd_set_mac_address() - set mac address
437 * @dev: pointer to net_device
438 * @addr: mac address
439 *
440 * Return: 0 on success, error number otherwise
441 */
442static int hdd_hostapd_set_mac_address(struct net_device *dev, void *addr)
443{
444 int ret;
445
446 cds_ssr_protect(__func__);
447 ret = __hdd_hostapd_set_mac_address(dev, addr);
448 cds_ssr_unprotect(__func__);
449
450 return ret;
451}
452
453void hdd_hostapd_inactivity_timer_cb(void *usrDataForCallback)
454{
455 struct net_device *dev = (struct net_device *)usrDataForCallback;
456 uint8_t we_custom_event[64];
457 union iwreq_data wrqu;
458#ifdef DISABLE_CONCURRENCY_AUTOSAVE
459 CDF_STATUS cdf_status;
460 hdd_adapter_t *pHostapdAdapter;
461 hdd_ap_ctx_t *pHddApCtx;
462#endif /* DISABLE_CONCURRENCY_AUTOSAVE */
463
464 /* event_name space-delimiter driver_module_name
465 * Format of the event is "AUTO-SHUT.indication" " " "module_name"
466 */
467 char *autoShutEvent = "AUTO-SHUT.indication" " " KBUILD_MODNAME;
468
469 /* For the NULL at the end */
470 int event_len = strlen(autoShutEvent) + 1;
471
472 ENTER();
473
474#ifdef DISABLE_CONCURRENCY_AUTOSAVE
475 if (cds_concurrent_open_sessions_running()) {
476 /*
477 * This timer routine is going to be called only when AP
478 * persona is up.
479 * If there are concurrent sessions running we do not want
480 * to shut down the Bss.Instead we run the timer again so
481 * that if Autosave is enabled next time and other session
482 was down only then we bring down AP
483 */
484 pHostapdAdapter = netdev_priv(dev);
485 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
486 cdf_status =
487 cdf_mc_timer_start(&pHddApCtx->hdd_ap_inactivity_timer,
488 (WLAN_HDD_GET_CTX(pHostapdAdapter))->
489 config->nAPAutoShutOff * 1000);
490 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
491 hddLog(LOGE, FL("Failed to init AP inactivity timer"));
492 }
493 EXIT();
494 return;
495 }
496#endif /* DISABLE_CONCURRENCY_AUTOSAVE */
497 memset(&we_custom_event, '\0', sizeof(we_custom_event));
498 memcpy(&we_custom_event, autoShutEvent, event_len);
499
500 memset(&wrqu, 0, sizeof(wrqu));
501 wrqu.data.length = event_len;
502
503 hddLog(LOG1, FL("Shutting down AP interface due to inactivity"));
504 wireless_send_event(dev, IWEVCUSTOM, &wrqu, (char *)we_custom_event);
505
506 EXIT();
507}
508
509void hdd_clear_all_sta(hdd_adapter_t *pHostapdAdapter,
510 void *usrDataForCallback)
511{
512 uint8_t staId = 0;
513 struct net_device *dev;
514 dev = (struct net_device *)usrDataForCallback;
515
516 hddLog(LOGE, FL("Clearing all the STA entry...."));
517 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++) {
518 if (pHostapdAdapter->aStaInfo[staId].isUsed &&
519 (staId !=
520 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uBCStaId)) {
521 /* Disconnect all the stations */
522 hdd_softap_sta_disassoc(pHostapdAdapter,
523 &pHostapdAdapter->
524 aStaInfo[staId].macAddrSTA.
525 bytes[0]);
526 }
527 }
528}
529
530static int hdd_stop_bss_link(hdd_adapter_t *pHostapdAdapter,
531 void *usrDataForCallback)
532{
533 struct net_device *dev;
534 hdd_context_t *pHddCtx = NULL;
535 CDF_STATUS status = CDF_STATUS_SUCCESS;
536 dev = (struct net_device *)usrDataForCallback;
537 ENTER();
538
539 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
540 status = wlan_hdd_validate_context(pHddCtx);
541
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +0530542 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800543 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800544
545 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
546#ifdef WLAN_FEATURE_MBSSID
547 status =
548 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(
549 pHostapdAdapter));
550#else
551 status =
552 wlansap_stop_bss((WLAN_HDD_GET_CTX(pHostapdAdapter))->
553 pcds_context);
554#endif
555 if (CDF_IS_STATUS_SUCCESS(status))
556 hddLog(LOGE, FL("Deleting SAP/P2P link!!!!!!"));
557
558 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -0800559 cds_decr_session_set_pcl(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560 pHostapdAdapter->sessionId);
561 }
562 EXIT();
563 return (status == CDF_STATUS_SUCCESS) ? 0 : -EBUSY;
564}
565
566/**
567 * hdd_issue_stored_joinreq() - This function will trigger stations's
568 * cached connect request to proceed.
569 * @hdd_ctx: pointer to hdd context.
570 * @sta_adater: pointer to station adapter.
571 *
572 * This function will call SME to release station's stored/cached connect
573 * request to proceed.
574 *
575 * Return: none.
576 */
577static void hdd_issue_stored_joinreq(hdd_adapter_t *sta_adapter,
578 hdd_context_t *hdd_ctx)
579{
580 tHalHandle hal_handle;
581 uint32_t roam_id;
582
583 if (NULL == sta_adapter) {
584 hddLog(LOGE,
585 FL
586 ("Invalid station adapter, ignore issueing join req"));
587 return;
588 }
589 hal_handle = WLAN_HDD_GET_HAL_CTX(sta_adapter);
590
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800591 if (true == cds_is_sta_connection_pending()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
593 TRACE_CODE_HDD_ISSUE_JOIN_REQ,
594 sta_adapter->sessionId, roam_id));
595 if (CDF_STATUS_SUCCESS !=
596 sme_issue_stored_joinreq(hal_handle,
597 &roam_id,
598 sta_adapter->sessionId)) {
599 /* change back to NotAssociated */
600 hdd_conn_set_connection_state(sta_adapter,
601 eConnectionState_NotConnected);
602 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800603 cds_change_sta_conn_pending_status(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800604 }
605}
606
607/**
608 * hdd_chan_change_notify() - Function to notify hostapd about channel change
609 * @hostapd_adapter hostapd adapter
610 * @dev: Net device structure
611 * @oper_chan: New operating channel
612 *
613 * This function is used to notify hostapd about the channel change
614 *
615 * Return: Success on intimating userspace
616 *
617 */
618CDF_STATUS hdd_chan_change_notify(hdd_adapter_t *hostapd_adapter,
619 struct net_device *dev,
620 uint8_t oper_chan)
621{
622 struct ieee80211_channel *chan;
623 struct cfg80211_chan_def chandef;
624 enum nl80211_channel_type channel_type;
625 eCsrPhyMode phy_mode;
626 ePhyChanBondState cb_mode;
627 uint32_t freq;
628 tHalHandle hal = WLAN_HDD_GET_HAL_CTX(hostapd_adapter);
629
630 if (NULL == hal) {
631 hdd_err("hal is NULL");
632 return CDF_STATUS_E_FAILURE;
633 }
634
635 freq = cds_chan_to_freq(oper_chan);
636
637 chan = __ieee80211_get_channel(hostapd_adapter->wdev.wiphy, freq);
638
639 if (!chan) {
640 hdd_err("Invalid input frequency for channel conversion");
641 return CDF_STATUS_E_FAILURE;
642 }
643
644 phy_mode = sme_get_phy_mode(hal);
645
646 if (oper_chan <= 14)
647 cb_mode = sme_get_cb_phy_state_from_cb_ini_value(
648 sme_get_channel_bonding_mode24_g(hal));
649 else
650 cb_mode = sme_get_cb_phy_state_from_cb_ini_value(
651 sme_get_channel_bonding_mode5_g(hal));
652
653 switch (phy_mode) {
654 case eCSR_DOT11_MODE_11n:
655 case eCSR_DOT11_MODE_11n_ONLY:
656 case eCSR_DOT11_MODE_11ac:
657 case eCSR_DOT11_MODE_11ac_ONLY:
658 if (cb_mode == PHY_SINGLE_CHANNEL_CENTERED)
659 channel_type = NL80211_CHAN_HT20;
660 else if (cb_mode == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
661 channel_type = NL80211_CHAN_HT40MINUS;
662 else if (cb_mode == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
663 channel_type = NL80211_CHAN_HT40PLUS;
664 else
665 channel_type = NL80211_CHAN_HT40PLUS;
666 break;
667 default:
668 channel_type = NL80211_CHAN_NO_HT;
669 break;
670 }
671
672 cfg80211_chandef_create(&chandef, chan, channel_type);
673
674 cfg80211_ch_switch_notify(dev, &chandef);
675
676 return CDF_STATUS_SUCCESS;
677}
678
679/**
680 * hdd_send_radar_event() - Function to send radar events to user space
681 * @hdd_context: HDD context
682 * @event: Type of radar event
683 * @dfs_info: Structure containing DFS channel and country
684 * @wdev: Wireless device structure
685 *
686 * This function is used to send radar events such as CAC start, CAC
687 * end etc., to userspace
688 *
689 * Return: Success on sending notifying userspace
690 *
691 */
692CDF_STATUS hdd_send_radar_event(hdd_context_t *hdd_context,
693 eSapHddEvent event,
694 struct wlan_dfs_info dfs_info,
695 struct wireless_dev *wdev)
696{
697
698 struct sk_buff *vendor_event;
699 enum qca_nl80211_vendor_subcmds_index index;
700 uint32_t freq, ret;
701 uint32_t data_size;
702
703 if (!hdd_context) {
704 hddLog(LOGE, FL("HDD context is NULL"));
705 return CDF_STATUS_E_FAILURE;
706 }
707
708 freq = cds_chan_to_freq(dfs_info.channel);
709
710 switch (event) {
711 case eSAP_DFS_CAC_START:
712 index =
713 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED_INDEX;
714 data_size = sizeof(uint32_t);
715 break;
716 case eSAP_DFS_CAC_END:
717 index =
718 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED_INDEX;
719 data_size = sizeof(uint32_t);
720 break;
721 case eSAP_DFS_RADAR_DETECT:
722 index =
723 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED_INDEX;
724 data_size = sizeof(uint32_t);
725 break;
726 default:
727 return CDF_STATUS_E_FAILURE;
728 }
729
730 vendor_event = cfg80211_vendor_event_alloc(hdd_context->wiphy,
731 wdev,
732 data_size + NLMSG_HDRLEN,
733 index,
734 GFP_KERNEL);
735 if (!vendor_event) {
736 hddLog(LOGE,
737 FL("cfg80211_vendor_event_alloc failed for %d"), index);
738 return CDF_STATUS_E_FAILURE;
739 }
740
741 ret = nla_put_u32(vendor_event, NL80211_ATTR_WIPHY_FREQ, freq);
742
743 if (ret) {
744 hddLog(LOGE, FL("NL80211_ATTR_WIPHY_FREQ put fail"));
745 kfree_skb(vendor_event);
746 return CDF_STATUS_E_FAILURE;
747 }
748
749 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
750 return CDF_STATUS_SUCCESS;
751}
752
753CDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
754 void *usrDataForCallback)
755{
756 hdd_adapter_t *pHostapdAdapter;
757 hdd_ap_ctx_t *pHddApCtx;
758 hdd_hostapd_state_t *pHostapdState;
759 struct net_device *dev;
760 eSapHddEvent sapEvent;
761 union iwreq_data wrqu;
762 uint8_t *we_custom_event_generic = NULL;
763 int we_event = 0;
764 int i = 0;
765 uint8_t staId;
766 CDF_STATUS cdf_status;
767 bool bWPSState;
768 bool bAuthRequired = true;
769 tpSap_AssocMacAddr pAssocStasArray = NULL;
770 char unknownSTAEvent[IW_CUSTOM_MAX + 1];
771 char maxAssocExceededEvent[IW_CUSTOM_MAX + 1];
772 uint8_t we_custom_start_event[64];
773 char *startBssEvent;
774 hdd_context_t *pHddCtx;
775 hdd_scaninfo_t *pScanInfo = NULL;
776 struct iw_michaelmicfailure msg;
777 uint8_t ignoreCAC = 0;
778 struct hdd_config *cfg = NULL;
779 struct wlan_dfs_info dfs_info;
780 uint8_t cc_len = WLAN_SVC_COUNTRY_CODE_LEN;
781 hdd_adapter_t *con_sap_adapter;
782 CDF_STATUS status = CDF_STATUS_SUCCESS;
783#if defined CONFIG_CNSS
784 int ret = 0;
785#endif
786
787 dev = (struct net_device *)usrDataForCallback;
788 if (!dev) {
789 hddLog(LOGE, FL("usrDataForCallback is null"));
790 return CDF_STATUS_E_FAILURE;
791 }
792
793 pHostapdAdapter = netdev_priv(dev);
794
795 if ((NULL == pHostapdAdapter) ||
796 (WLAN_HDD_ADAPTER_MAGIC != pHostapdAdapter->magic)) {
797 hddLog(LOGE, "invalid adapter or adapter has invalid magic");
798 return CDF_STATUS_E_FAILURE;
799 }
800
801 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
802 pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
803
804 if (!pSapEvent) {
805 hddLog(LOGE, FL("pSapEvent is null"));
806 return CDF_STATUS_E_FAILURE;
807 }
808
809 sapEvent = pSapEvent->sapHddEventCode;
810 memset(&wrqu, '\0', sizeof(wrqu));
811 pHddCtx = (hdd_context_t *) (pHostapdAdapter->pHddCtx);
812
813 if (!pHddCtx) {
814 hddLog(LOGE, FL("HDD context is null"));
815 return CDF_STATUS_E_FAILURE;
816 }
817
818 cfg = pHddCtx->config;
819
820 if (!cfg) {
821 hddLog(LOGE, FL("HDD config is null"));
822 return CDF_STATUS_E_FAILURE;
823 }
824
825 dfs_info.channel = pHddApCtx->operatingChannel;
826 sme_get_country_code(pHddCtx->hHal, dfs_info.country_code, &cc_len);
827
828 switch (sapEvent) {
829 case eSAP_START_BSS_EVENT:
830 hddLog(LOG1,
831 FL("BSS status = %s, channel = %u, bc sta Id = %d"),
832 pSapEvent->sapevt.sapStartBssCompleteEvent.
833 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS",
834 pSapEvent->sapevt.sapStartBssCompleteEvent.
835 operatingChannel,
836 pSapEvent->sapevt.sapStartBssCompleteEvent.staId);
837
838 pHostapdAdapter->sessionId =
839 pSapEvent->sapevt.sapStartBssCompleteEvent.sessionId;
840
841 pHostapdState->cdf_status =
842 pSapEvent->sapevt.sapStartBssCompleteEvent.status;
843 cdf_status = cdf_event_set(&pHostapdState->cdf_event);
844
845 if (!CDF_IS_STATUS_SUCCESS(cdf_status)
846 || pHostapdState->cdf_status) {
847 hddLog(LOGE, ("ERROR: startbss event failed!!"));
848 goto stopbss;
849 } else {
850 sme_ch_avoid_update_req(pHddCtx->hHal);
851
852 pHddApCtx->uBCStaId =
853 pSapEvent->sapevt.sapStartBssCompleteEvent.staId;
854
855 hdd_register_tx_flow_control(pHostapdAdapter,
856 hdd_softap_tx_resume_timer_expired_handler,
857 hdd_softap_tx_resume_cb);
858
859 /* @@@ need wep logic here to set privacy bit */
860 cdf_status =
861 hdd_softap_register_bc_sta(pHostapdAdapter,
862 pHddApCtx->uPrivacy);
863 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
864 hddLog(LOGW, FL("Failed to register BC STA %d"),
865 cdf_status);
866 hdd_stop_bss_link(pHostapdAdapter,
867 usrDataForCallback);
868 }
869 }
870
871 if (hdd_ipa_is_enabled(pHddCtx)) {
872 status = hdd_ipa_wlan_evt(pHostapdAdapter,
873 pHddApCtx->uBCStaId,
874 WLAN_AP_CONNECT,
875 pHostapdAdapter->dev->dev_addr);
876 if (status) {
877 hddLog(LOGE,
878 ("WLAN_AP_CONNECT event failed!!"));
879 goto stopbss;
880 }
881 }
882
883 if (0 !=
884 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
885 nAPAutoShutOff) {
886 /* AP Inactivity timer init and start */
887 cdf_status =
888 cdf_mc_timer_init(&pHddApCtx->
889 hdd_ap_inactivity_timer,
890 CDF_TIMER_TYPE_SW,
891 hdd_hostapd_inactivity_timer_cb,
892 dev);
893 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
894 hddLog(LOGE,
895 FL("Failed to init inactivity timer"));
896
897 cdf_status =
898 cdf_mc_timer_start(&pHddApCtx->
899 hdd_ap_inactivity_timer,
900 (WLAN_HDD_GET_CTX
901 (pHostapdAdapter))->config->
902 nAPAutoShutOff * 1000);
903 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
904 hddLog(LOGE,
905 FL("Failed to init inactivity timer"));
906
907 }
908#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
909 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
910#endif
911 pHddApCtx->operatingChannel =
912 pSapEvent->sapevt.sapStartBssCompleteEvent.operatingChannel;
913
914 hdd_hostapd_channel_prevent_suspend(pHostapdAdapter,
915 pHddApCtx->
916 operatingChannel);
917
918 pHostapdState->bssState = BSS_START;
919 hdd_wlan_green_ap_start_bss(pHddCtx);
920
921 /* Set group key / WEP key every time when BSS is restarted */
922 if (pHddApCtx->groupKey.keyLength) {
923 status = wlansap_set_key_sta(
924#ifdef WLAN_FEATURE_MBSSID
925 WLAN_HDD_GET_SAP_CTX_PTR
926 (pHostapdAdapter),
927#else
928 (WLAN_HDD_GET_CTX
929 (pHostapdAdapter))->
930 pcds_context,
931#endif
932 &pHddApCtx->groupKey);
933 if (!CDF_IS_STATUS_SUCCESS(status))
934 hddLog(LOGE, FL("wlansap_set_key_sta failed"));
935 } else {
936 for (i = 0; i < CSR_MAX_NUM_KEY; i++) {
937 if (!pHddApCtx->wepKey[i].keyLength)
938 continue;
939
940 status = wlansap_set_key_sta(
941#ifdef WLAN_FEATURE_MBSSID
942 WLAN_HDD_GET_SAP_CTX_PTR
943 (pHostapdAdapter),
944#else
945 (WLAN_HDD_GET_CTX(pHostapdAdapter))->
946 pcds_context,
947#endif
948 &pHddApCtx->
949 wepKey[i]);
950 if (!CDF_IS_STATUS_SUCCESS(status)) {
951 hddLog(LOGE,
952 FL("set_key failed idx %d"), i);
953 }
954 }
955 }
956
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +0530957 mutex_lock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800958 pHddCtx->dfs_radar_found = false;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +0530959 mutex_unlock(&pHddCtx->dfs_lock);
960
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800961 wlansap_get_dfs_ignore_cac(pHddCtx->hHal, &ignoreCAC);
962
963 /* DFS requirement: DO NOT transmit during CAC. */
964 if ((CHANNEL_STATE_DFS !=
965 cds_get_channel_state(pHddApCtx->operatingChannel))
966 || ignoreCAC
967 || pHddCtx->dev_dfs_cac_status == DFS_CAC_ALREADY_DONE)
968 pHddApCtx->dfs_cac_block_tx = false;
969 else
970 pHddApCtx->dfs_cac_block_tx = true;
971
972 hddLog(LOG3, "The value of dfs_cac_block_tx[%d] for ApCtx[%p]",
973 pHddApCtx->dfs_cac_block_tx, pHddApCtx);
974
975 if ((CHANNEL_STATE_DFS ==
976 cds_get_channel_state(pHddApCtx->operatingChannel))
977 && (pHddCtx->config->IsSapDfsChSifsBurstEnabled == 0)) {
978
979 hddLog(LOG1,
980 FL("Set SIFS Burst disable for DFS channel %d"),
981 pHddApCtx->operatingChannel);
982
983 if (wma_cli_set_command(pHostapdAdapter->sessionId,
984 WMI_PDEV_PARAM_BURST_ENABLE,
985 0, PDEV_CMD)) {
986 hddLog(LOGE,
987 FL("Failed to Set SIFS Burst %d"),
988 pHddApCtx->operatingChannel);
989 }
990 }
991 /* Fill the params for sending IWEVCUSTOM Event with SOFTAP.enabled */
992 startBssEvent = "SOFTAP.enabled";
993 memset(&we_custom_start_event, '\0',
994 sizeof(we_custom_start_event));
995 memcpy(&we_custom_start_event, startBssEvent,
996 strlen(startBssEvent));
997 memset(&wrqu, 0, sizeof(wrqu));
998 wrqu.data.length = strlen(startBssEvent);
999 we_event = IWEVCUSTOM;
1000 we_custom_event_generic = we_custom_start_event;
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001001 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001002 /* Send SCC/MCC Switching event to IPA */
1003 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
1004 break; /* Event will be sent after Switch-Case stmt */
1005
1006 case eSAP_STOP_BSS_EVENT:
1007 hddLog(LOG1, FL("BSS stop status = %s"),
1008 pSapEvent->sapevt.sapStopBssCompleteEvent.
1009 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1010
1011 hdd_hostapd_channel_allow_suspend(pHostapdAdapter,
1012 pHddApCtx->operatingChannel);
1013
1014 hdd_wlan_green_ap_stop_bss(pHddCtx);
1015
1016 /* Free up Channel List incase if it is set */
1017#ifdef WLAN_FEATURE_MBSSID
1018 sap_cleanup_channel_list(WLAN_HDD_GET_SAP_CTX_PTR
1019 (pHostapdAdapter));
1020#else
1021 sap_cleanup_channel_list();
1022#endif
1023 /* Invalidate the channel info. */
1024 pHddApCtx->operatingChannel = 0;
1025 if (hdd_ipa_is_enabled(pHddCtx)) {
1026 status = hdd_ipa_wlan_evt(pHostapdAdapter,
1027 pHddApCtx->uBCStaId,
1028 WLAN_AP_DISCONNECT,
1029 pHostapdAdapter->dev->dev_addr);
1030 if (status) {
1031 hddLog(LOGE,
1032 ("WLAN_AP_DISCONNECT event failed!!"));
1033 goto stopbss;
1034 }
1035 }
1036
1037 /* reset the dfs_cac_status and dfs_cac_block_tx flag only when
1038 * the last BSS is stopped
1039 */
1040 con_sap_adapter = hdd_get_con_sap_adapter(pHostapdAdapter, true);
1041 if (!con_sap_adapter) {
1042 pHddApCtx->dfs_cac_block_tx = true;
1043 pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
1044 }
1045 if (pHddCtx->config->conc_custom_rule2 &&
1046 (WLAN_HDD_P2P_GO == pHostapdAdapter->device_mode)) {
1047 hdd_adapter_t *sta_adapter = hdd_get_adapter(pHddCtx,
1048 WLAN_HDD_INFRA_STATION);
1049 hddLog(LOG2,
1050 FL("P2PGO is going down now"));
1051 hdd_issue_stored_joinreq(sta_adapter, pHddCtx);
1052 }
1053 goto stopbss;
1054
1055 case eSAP_DFS_CAC_START:
1056 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_CAC_START_IND,
1057 &dfs_info,
1058 sizeof(struct wlan_dfs_info));
1059 pHddCtx->dev_dfs_cac_status = DFS_CAC_IN_PROGRESS;
1060 if (CDF_STATUS_SUCCESS !=
1061 hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_START,
1062 dfs_info, &pHostapdAdapter->wdev)) {
1063 hddLog(LOGE, FL("Unable to indicate CAC start NL event"));
1064 } else {
1065 hdd_info("Sent CAC start to user space");
1066 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301067
1068 mutex_lock(&pHddCtx->dfs_lock);
1069 pHddCtx->dfs_radar_found = false;
1070 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001071 break;
1072 case eSAP_DFS_CAC_INTERRUPTED:
1073 /*
1074 * The CAC timer did not run completely and a radar was detected
1075 * during the CAC time. This new state will keep the tx path
1076 * blocked since we do not want any transmission on the DFS
1077 * channel. CAC end will only be reported here since the user
1078 * space applications are waiting on CAC end for their state
1079 * management.
1080 */
1081 if (CDF_STATUS_SUCCESS !=
1082 hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_END,
1083 dfs_info, &pHostapdAdapter->wdev)) {
1084 hdd_err("Unable to indicate CAC end (interrupted) event");
1085 } else {
1086 hdd_info("Sent CAC end (interrupted) to user space");
1087 }
1088 break;
1089 case eSAP_DFS_CAC_END:
1090 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_CAC_END_IND,
1091 &dfs_info,
1092 sizeof(struct wlan_dfs_info));
1093 pHddApCtx->dfs_cac_block_tx = false;
1094 pHddCtx->dev_dfs_cac_status = DFS_CAC_ALREADY_DONE;
1095 if (CDF_STATUS_SUCCESS !=
1096 hdd_send_radar_event(pHddCtx, eSAP_DFS_CAC_END,
1097 dfs_info, &pHostapdAdapter->wdev)) {
1098 hddLog(LOGE, FL("Unable to indicate CAC end NL event"));
1099 } else {
1100 hdd_info("Sent CAC end to user space");
1101 }
1102 break;
1103
1104 case eSAP_DFS_RADAR_DETECT:
1105 wlan_hdd_send_svc_nlink_msg(WLAN_SVC_DFS_RADAR_DETECT_IND,
1106 &dfs_info,
1107 sizeof(struct wlan_dfs_info));
1108 pHddCtx->dev_dfs_cac_status = DFS_CAC_NEVER_DONE;
1109 if (CDF_STATUS_SUCCESS !=
1110 hdd_send_radar_event(pHddCtx, eSAP_DFS_RADAR_DETECT,
1111 dfs_info, &pHostapdAdapter->wdev)) {
1112 hddLog(LOGE, FL("Unable to indicate Radar detect NL event"));
1113 } else {
1114 hdd_info("Sent radar detected to user space");
1115 }
1116 break;
1117
1118 case eSAP_DFS_NO_AVAILABLE_CHANNEL:
1119 wlan_hdd_send_svc_nlink_msg
1120 (WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND, &dfs_info,
1121 sizeof(struct wlan_dfs_info));
1122 break;
1123
1124 case eSAP_STA_SET_KEY_EVENT:
1125 /* TODO:
1126 * forward the message to hostapd once implementation
1127 * is done for now just print
1128 */
1129 hddLog(LOG1, FL("SET Key: configured status = %s"),
1130 pSapEvent->sapevt.sapStationSetKeyCompleteEvent.
1131 status ? "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1132 return CDF_STATUS_SUCCESS;
1133 case eSAP_STA_MIC_FAILURE_EVENT:
1134 {
1135 memset(&msg, '\0', sizeof(msg));
1136 msg.src_addr.sa_family = ARPHRD_ETHER;
1137 memcpy(msg.src_addr.sa_data,
1138 &pSapEvent->sapevt.sapStationMICFailureEvent.
1139 staMac, CDF_MAC_ADDR_SIZE);
1140 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
1141 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
1142 if (pSapEvent->sapevt.sapStationMICFailureEvent.
1143 multicast == eSAP_TRUE)
1144 msg.flags = IW_MICFAILURE_GROUP;
1145 else
1146 msg.flags = IW_MICFAILURE_PAIRWISE;
1147 memset(&wrqu, 0, sizeof(wrqu));
1148 wrqu.data.length = sizeof(msg);
1149 we_event = IWEVMICHAELMICFAILURE;
1150 we_custom_event_generic = (uint8_t *) &msg;
1151 }
1152 /* inform mic failure to nl80211 */
1153 cfg80211_michael_mic_failure(dev,
1154 pSapEvent->
1155 sapevt.sapStationMICFailureEvent.
1156 staMac.bytes,
1157 ((pSapEvent->sapevt.
1158 sapStationMICFailureEvent.
1159 multicast ==
1160 eSAP_TRUE) ?
1161 NL80211_KEYTYPE_GROUP :
1162 NL80211_KEYTYPE_PAIRWISE),
1163 pSapEvent->sapevt.
1164 sapStationMICFailureEvent.keyId,
1165 pSapEvent->sapevt.
1166 sapStationMICFailureEvent.TSC,
1167 GFP_KERNEL);
1168 break;
1169
1170 case eSAP_STA_ASSOC_EVENT:
1171 case eSAP_STA_REASSOC_EVENT:
1172 wrqu.addr.sa_family = ARPHRD_ETHER;
1173 memcpy(wrqu.addr.sa_data,
1174 &pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.
1175 staMac, CDF_MAC_ADDR_SIZE);
1176 hddLog(LOG1, " associated " MAC_ADDRESS_STR,
1177 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1178 we_event = IWEVREGISTERED;
1179
1180#ifdef WLAN_FEATURE_MBSSID
1181 wlansap_get_wps_state(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
1182 &bWPSState);
1183#else
1184 wlansap_get_wps_state((WLAN_HDD_GET_CTX(pHostapdAdapter))->
1185 pcds_context, &bWPSState);
1186#endif
1187
1188 if ((eCSR_ENCRYPT_TYPE_NONE == pHddApCtx->ucEncryptType) ||
1189 (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
1190 pHddApCtx->ucEncryptType)
1191 || (eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
1192 pHddApCtx->ucEncryptType)) {
1193 bAuthRequired = false;
1194 }
1195
1196 if (bAuthRequired || bWPSState == true) {
1197 cdf_status = hdd_softap_register_sta(
1198 pHostapdAdapter,
1199 true,
1200 pHddApCtx->uPrivacy,
1201 pSapEvent->sapevt.
1202 sapStationAssocReassocCompleteEvent.
1203 staId, 0, 0,
1204 (struct cdf_mac_addr *)
1205 wrqu.addr.sa_data,
1206 pSapEvent->sapevt.
1207 sapStationAssocReassocCompleteEvent.
1208 wmmEnabled);
1209 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
1210 hddLog(LOGW,
1211 FL("Failed to register STA %d "
1212 MAC_ADDRESS_STR ""), cdf_status,
1213 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1214 } else {
1215 cdf_status = hdd_softap_register_sta(
1216 pHostapdAdapter,
1217 false,
1218 pHddApCtx->uPrivacy,
1219 pSapEvent->sapevt.
1220 sapStationAssocReassocCompleteEvent.
1221 staId, 0, 0,
1222 (struct cdf_mac_addr *)
1223 wrqu.addr.sa_data,
1224 pSapEvent->sapevt.
1225 sapStationAssocReassocCompleteEvent.
1226 wmmEnabled);
1227 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
1228 hddLog(LOGW,
1229 FL("Failed to register STA %d "
1230 MAC_ADDRESS_STR ""), cdf_status,
1231 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1232 }
1233
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05301234 staId =
1235 pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staId;
1236 if (CDF_IS_STATUS_SUCCESS(cdf_status)) {
1237 pHostapdAdapter->aStaInfo[staId].nss =
1238 pSapEvent->sapevt.
1239 sapStationAssocReassocCompleteEvent.
1240 chan_info.nss;
1241 pHostapdAdapter->aStaInfo[staId].rate_flags =
1242 pSapEvent->sapevt.
1243 sapStationAssocReassocCompleteEvent.
1244 chan_info.rate_flags;
1245 }
1246
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001247 if (hdd_ipa_is_enabled(pHddCtx)) {
1248 status = hdd_ipa_wlan_evt(pHostapdAdapter,
1249 pSapEvent->sapevt.
1250 sapStationAssocReassocCompleteEvent.
1251 staId, WLAN_CLIENT_CONNECT_EX,
1252 pSapEvent->sapevt.
1253 sapStationAssocReassocCompleteEvent.
1254 staMac.bytes);
1255 if (status) {
1256 hddLog(LOGE,
1257 FL("WLAN_CLIENT_CONNECT_EX event failed"));
1258 goto stopbss;
1259 }
1260 }
1261
1262#ifdef QCA_PKT_PROTO_TRACE
1263 /* Peer associated, update into trace buffer */
1264 if (pHddCtx->config->gEnableDebugLog) {
1265 cds_pkt_trace_buf_update("HA:ASSOC");
1266 }
1267#endif /* QCA_PKT_PROTO_TRACE */
1268
1269#ifdef MSM_PLATFORM
1270 /* start timer in sap/p2p_go */
1271 if (pHddApCtx->bApActive == false) {
1272 spin_lock_bh(&pHddCtx->bus_bw_lock);
1273 pHostapdAdapter->prev_tx_packets =
1274 pHostapdAdapter->stats.tx_packets;
1275 pHostapdAdapter->prev_rx_packets =
1276 pHostapdAdapter->stats.rx_packets;
1277 spin_unlock_bh(&pHddCtx->bus_bw_lock);
1278 hdd_start_bus_bw_compute_timer(pHostapdAdapter);
1279 }
1280#endif
1281 pHddApCtx->bApActive = true;
1282 /* Stop AP inactivity timer */
1283 if (pHddApCtx->hdd_ap_inactivity_timer.state ==
1284 CDF_TIMER_STATE_RUNNING) {
1285 cdf_status =
1286 cdf_mc_timer_stop(&pHddApCtx->
1287 hdd_ap_inactivity_timer);
1288 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1289 hddLog(LOGE,
1290 FL("Failed to start inactivity timer"));
1291 }
1292 }
1293#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1294 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1295#endif
1296 cdf_wake_lock_timeout_acquire(&pHddCtx->sap_wake_lock,
1297 HDD_SAP_WAKE_LOCK_DURATION,
1298 WIFI_POWER_EVENT_WAKELOCK_SAP);
1299 {
1300 struct station_info staInfo;
1301 uint16_t iesLen =
1302 pSapEvent->sapevt.
1303 sapStationAssocReassocCompleteEvent.iesLen;
1304
1305 memset(&staInfo, 0, sizeof(staInfo));
1306 if (iesLen <= MAX_ASSOC_IND_IE_LEN) {
1307 staInfo.assoc_req_ies =
1308 (const u8 *)&pSapEvent->sapevt.
1309 sapStationAssocReassocCompleteEvent.ies[0];
1310 staInfo.assoc_req_ies_len = iesLen;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001311 staInfo.filled |= STATION_INFO_ASSOC_REQ_IES;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001312 cfg80211_new_sta(dev,
1313 (const u8 *)&pSapEvent->sapevt.
1314 sapStationAssocReassocCompleteEvent.
1315 staMac.bytes[0], &staInfo,
1316 GFP_KERNEL);
1317 } else {
1318 hddLog(LOGE,
1319 FL("Assoc Ie length is too long"));
1320 }
1321 }
1322
1323 pScanInfo = &pHostapdAdapter->scan_info;
1324 /* Lets do abort scan to ensure smooth authentication for client */
1325 if ((pScanInfo != NULL) && pScanInfo->mScanPending) {
1326 hdd_abort_mac_scan(pHddCtx, pHostapdAdapter->sessionId,
1327 eCSR_SCAN_ABORT_DEFAULT);
1328 }
1329 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
1330 /* send peer status indication to oem app */
1331 hdd_send_peer_status_ind_to_oem_app(&pSapEvent->sapevt.
1332 sapStationAssocReassocCompleteEvent.
1333 staMac, ePeerConnected,
1334 pSapEvent->sapevt.
1335 sapStationAssocReassocCompleteEvent.
1336 timingMeasCap,
1337 pHostapdAdapter->
1338 sessionId,
1339 &pSapEvent->sapevt.
1340 sapStationAssocReassocCompleteEvent.
1341 chan_info);
1342 }
1343 hdd_wlan_green_ap_add_sta(pHddCtx);
1344 break;
1345
1346 case eSAP_STA_DISASSOC_EVENT:
1347 memcpy(wrqu.addr.sa_data,
1348 &pSapEvent->sapevt.sapStationDisassocCompleteEvent.
1349 staMac, CDF_MAC_ADDR_SIZE);
1350 hddLog(LOG1, " disassociated " MAC_ADDRESS_STR,
1351 MAC_ADDR_ARRAY(wrqu.addr.sa_data));
1352
1353 cdf_status = cdf_event_set(&pHostapdState->cdf_event);
1354 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
1355 hddLog(LOGE, "ERR: Station Deauth event Set failed");
1356
1357 if (pSapEvent->sapevt.sapStationDisassocCompleteEvent.reason ==
1358 eSAP_USR_INITATED_DISASSOC)
1359 hddLog(LOG1, " User initiated disassociation");
1360 else
1361 hddLog(LOG1, " MAC initiated disassociation");
1362 we_event = IWEVEXPIRED;
1363 cdf_status =
1364 hdd_softap_get_sta_id(pHostapdAdapter,
1365 &pSapEvent->sapevt.
1366 sapStationDisassocCompleteEvent.staMac,
1367 &staId);
1368 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1369 hddLog(LOGE, FL("ERROR: HDD Failed to find sta id!!"));
1370 return CDF_STATUS_E_FAILURE;
1371 }
1372#ifdef IPA_OFFLOAD
1373 if (hdd_ipa_is_enabled(pHddCtx)) {
1374 status = hdd_ipa_wlan_evt(pHostapdAdapter, staId,
1375 WLAN_CLIENT_DISCONNECT,
1376 pSapEvent->sapevt.
1377 sapStationDisassocCompleteEvent.
1378 staMac.bytes);
1379
1380 if (status) {
1381 hddLog(LOGE,
1382 ("ERROR: WLAN_CLIENT_DISCONNECT event failed!!"));
1383 goto stopbss;
1384 }
1385 }
1386#endif
1387#ifdef QCA_PKT_PROTO_TRACE
1388 /* Peer dis-associated, update into trace buffer */
1389 if (pHddCtx->config->gEnableDebugLog) {
1390 cds_pkt_trace_buf_update("HA:DISASC");
1391 }
1392#endif /* QCA_PKT_PROTO_TRACE */
1393 hdd_softap_deregister_sta(pHostapdAdapter, staId);
1394
1395 pHddApCtx->bApActive = false;
1396 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
1397 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
1398 if (pHostapdAdapter->aStaInfo[i].isUsed
1399 && i !=
1400 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
1401 uBCStaId) {
1402 pHddApCtx->bApActive = true;
1403 break;
1404 }
1405 }
1406 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
1407
1408 /* Start AP inactivity timer if no stations associated with it */
1409 if ((0 !=
1410 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
1411 nAPAutoShutOff)) {
1412 if (pHddApCtx->bApActive == false) {
1413 if (pHddApCtx->hdd_ap_inactivity_timer.state ==
1414 CDF_TIMER_STATE_STOPPED) {
1415 cdf_status =
1416 cdf_mc_timer_start(&pHddApCtx->
1417 hdd_ap_inactivity_timer,
1418 (WLAN_HDD_GET_CTX
1419 (pHostapdAdapter))->
1420 config->
1421 nAPAutoShutOff *
1422 1000);
1423 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
1424 hddLog(LOGE,
1425 FL("Failed to init AP inactivity timer"));
1426 } else
1427 CDF_ASSERT
1428 (cdf_mc_timer_get_current_state
1429 (&pHddApCtx->
1430 hdd_ap_inactivity_timer) ==
1431 CDF_TIMER_STATE_STOPPED);
1432 }
1433 }
1434#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1435 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1436#endif
1437
1438 cfg80211_del_sta(dev,
1439 (const u8 *)&pSapEvent->sapevt.
1440 sapStationDisassocCompleteEvent.staMac.
1441 bytes[0], GFP_KERNEL);
1442
1443 /* Update the beacon Interval if it is P2P GO */
1444 cdf_status = cds_change_mcc_go_beacon_interval(pHostapdAdapter);
1445 if (CDF_STATUS_SUCCESS != cdf_status) {
1446 hddLog(LOGE, FL("failed to update Beacon interval %d"),
1447 cdf_status);
1448 }
1449 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
1450 /* send peer status indication to oem app */
1451 hdd_send_peer_status_ind_to_oem_app(&pSapEvent->sapevt.
1452 sapStationDisassocCompleteEvent.
1453 staMac, ePeerDisconnected,
1454 0,
1455 pHostapdAdapter->
1456 sessionId, NULL);
1457 }
1458#ifdef MSM_PLATFORM
1459 /*stop timer in sap/p2p_go */
1460 if (pHddApCtx->bApActive == false) {
1461 spin_lock_bh(&pHddCtx->bus_bw_lock);
1462 pHostapdAdapter->prev_tx_packets = 0;
1463 pHostapdAdapter->prev_rx_packets = 0;
1464 spin_unlock_bh(&pHddCtx->bus_bw_lock);
1465 hdd_stop_bus_bw_compute_timer(pHostapdAdapter);
1466 }
1467#endif
1468 hdd_wlan_green_ap_del_sta(pHddCtx);
1469 break;
1470
1471 case eSAP_WPS_PBC_PROBE_REQ_EVENT:
1472 {
1473 static const char *message =
1474 "MLMEWPSPBCPROBEREQ.indication";
1475 union iwreq_data wreq;
1476
1477 down(&pHddApCtx->semWpsPBCOverlapInd);
1478 pHddApCtx->WPSPBCProbeReq.probeReqIELen =
1479 pSapEvent->sapevt.sapPBCProbeReqEvent.
1480 WPSPBCProbeReq.probeReqIELen;
1481
1482 cdf_mem_copy(pHddApCtx->WPSPBCProbeReq.probeReqIE,
1483 pSapEvent->sapevt.sapPBCProbeReqEvent.
1484 WPSPBCProbeReq.probeReqIE,
1485 pHddApCtx->WPSPBCProbeReq.probeReqIELen);
1486
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08001487 cdf_copy_macaddr(&pHddApCtx->WPSPBCProbeReq.peer_macaddr,
1488 &pSapEvent->sapevt.sapPBCProbeReqEvent.
1489 WPSPBCProbeReq.peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001490 hddLog(LOG1, "WPS PBC probe req " MAC_ADDRESS_STR,
1491 MAC_ADDR_ARRAY(pHddApCtx->WPSPBCProbeReq.
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08001492 peer_macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001493 memset(&wreq, 0, sizeof(wreq));
1494 wreq.data.length = strlen(message); /* This is length of message */
1495 wireless_send_event(dev, IWEVCUSTOM, &wreq,
1496 (char *)message);
1497
1498 return CDF_STATUS_SUCCESS;
1499 }
1500 case eSAP_ASSOC_STA_CALLBACK_EVENT:
1501 pAssocStasArray =
1502 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas;
1503 if (pSapEvent->sapevt.sapAssocStaListEvent.noOfAssocSta != 0) { /* List of associated stations */
1504 for (i = 0;
1505 i <
1506 pSapEvent->sapevt.sapAssocStaListEvent.
1507 noOfAssocSta; i++) {
1508 hddLog(LOG1,
1509 "Associated Sta Num %d:assocId=%d, staId=%d, staMac="
1510 MAC_ADDRESS_STR, i + 1,
1511 pAssocStasArray->assocId,
1512 pAssocStasArray->staId,
1513 MAC_ADDR_ARRAY(pAssocStasArray->staMac.
1514 bytes));
1515 pAssocStasArray++;
1516 }
1517 }
1518 cdf_mem_free(pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas); /* Release caller allocated memory here */
1519 pSapEvent->sapevt.sapAssocStaListEvent.pAssocStas = NULL;
1520 return CDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001521 case eSAP_REMAIN_CHAN_READY:
1522 hdd_remain_chan_ready_handler(pHostapdAdapter,
1523 pSapEvent->sapevt.sap_roc_ind.scan_id);
1524 return CDF_STATUS_SUCCESS;
1525 case eSAP_SEND_ACTION_CNF:
1526 hdd_send_action_cnf(pHostapdAdapter,
1527 (eSAP_STATUS_SUCCESS ==
1528 pSapEvent->sapevt.sapActionCnf.
1529 actionSendSuccess) ? true : false);
1530 return CDF_STATUS_SUCCESS;
1531 case eSAP_UNKNOWN_STA_JOIN:
1532 snprintf(unknownSTAEvent, IW_CUSTOM_MAX,
1533 "JOIN_UNKNOWN_STA-%02x:%02x:%02x:%02x:%02x:%02x",
1534 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[0],
1535 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[1],
1536 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[2],
1537 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[3],
1538 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[4],
1539 pSapEvent->sapevt.sapUnknownSTAJoin.macaddr.bytes[5]);
1540 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1541 wrqu.data.pointer = unknownSTAEvent;
1542 wrqu.data.length = strlen(unknownSTAEvent);
1543 we_custom_event_generic = (uint8_t *) unknownSTAEvent;
1544 hddLog(LOGE, "%s", unknownSTAEvent);
1545 break;
1546
1547 case eSAP_MAX_ASSOC_EXCEEDED:
1548 snprintf(maxAssocExceededEvent, IW_CUSTOM_MAX,
1549 "Peer %02x:%02x:%02x:%02x:%02x:%02x denied"
1550 " assoc due to Maximum Mobile Hotspot connections reached. Please disconnect"
1551 " one or more devices to enable the new device connection",
1552 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[0],
1553 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[1],
1554 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[2],
1555 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[3],
1556 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.bytes[4],
1557 pSapEvent->sapevt.sapMaxAssocExceeded.macaddr.
1558 bytes[5]);
1559 we_event = IWEVCUSTOM; /* Discovered a new node (AP mode). */
1560 wrqu.data.pointer = maxAssocExceededEvent;
1561 wrqu.data.length = strlen(maxAssocExceededEvent);
1562 we_custom_event_generic = (uint8_t *) maxAssocExceededEvent;
1563 hddLog(LOG1, "%s", maxAssocExceededEvent);
1564 break;
1565 case eSAP_STA_ASSOC_IND:
1566 return CDF_STATUS_SUCCESS;
1567
1568 case eSAP_DISCONNECT_ALL_P2P_CLIENT:
1569 hddLog(LOG1, FL(" Disconnecting all the P2P Clients...."));
1570 hdd_clear_all_sta(pHostapdAdapter, usrDataForCallback);
1571 return CDF_STATUS_SUCCESS;
1572
1573 case eSAP_MAC_TRIG_STOP_BSS_EVENT:
1574 cdf_status =
1575 hdd_stop_bss_link(pHostapdAdapter, usrDataForCallback);
1576 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1577 hddLog(LOGW, FL("hdd_stop_bss_link failed %d"),
1578 cdf_status);
1579 }
1580 return CDF_STATUS_SUCCESS;
1581
1582 case eSAP_CHANNEL_CHANGE_EVENT:
1583 hddLog(LOG1, FL("Received eSAP_CHANNEL_CHANGE_EVENT event"));
1584 /* Prevent suspend for new channel */
1585 hdd_hostapd_channel_prevent_suspend(pHostapdAdapter,
1586 pSapEvent->sapevt.sap_ch_selected.pri_ch);
1587 /* Allow suspend for old channel */
1588 hdd_hostapd_channel_allow_suspend(pHostapdAdapter,
1589 pHddApCtx->operatingChannel);
1590 /* SME/PE is already updated for new operation channel. So update
1591 * HDD layer also here. This resolves issue in AP-AP mode where
1592 * AP1 channel is changed due to RADAR then CAC is going on and
1593 * START_BSS on new channel has not come to HDD. At this case if
1594 * AP2 is start it needs current operation channel for MCC DFS
1595 * restiction
1596 */
1597 pHddApCtx->operatingChannel =
1598 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1599 pHddApCtx->sapConfig.acs_cfg.pri_ch =
1600 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1601 pHddApCtx->sapConfig.acs_cfg.ht_sec_ch =
1602 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
1603 pHddApCtx->sapConfig.acs_cfg.vht_seg0_center_ch =
1604 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
1605 pHddApCtx->sapConfig.acs_cfg.vht_seg1_center_ch =
1606 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
1607 pHddApCtx->sapConfig.acs_cfg.ch_width =
1608 pSapEvent->sapevt.sap_ch_selected.ch_width;
1609
1610 /* Indicate operating channel change to hostapd
1611 * only for non driver override acs
1612 */
1613 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP &&
1614 pHddCtx->config->force_sap_acs)
1615 return CDF_STATUS_SUCCESS;
1616 else
1617 return hdd_chan_change_notify(pHostapdAdapter, dev,
1618 pSapEvent->sapevt.sap_ch_selected.pri_ch);
1619
1620#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
1621 case eSAP_ACS_SCAN_SUCCESS_EVENT:
1622 pHddCtx->skip_acs_scan_status = eSAP_SKIP_ACS_SCAN;
1623 hddLog(LOG1, FL("Reusing Last ACS scan result for %d sec"),
1624 ACS_SCAN_EXPIRY_TIMEOUT_S);
1625 cdf_mc_timer_stop(&pHddCtx->skip_acs_scan_timer);
1626 cdf_status = cdf_mc_timer_start(&pHddCtx->skip_acs_scan_timer,
1627 ACS_SCAN_EXPIRY_TIMEOUT_S *
1628 1000);
1629 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
1630 hddLog(LOGE,
1631 FL("Failed to start ACS scan expiry timer"));
1632 return CDF_STATUS_SUCCESS;
1633#endif
1634
1635 case eSAP_DFS_NOL_GET:
1636 hddLog(LOG1,
1637 FL("Received eSAP_DFS_NOL_GET event"));
1638#if defined CONFIG_CNSS
1639 /* get the dfs nol from cnss */
1640 ret =
1641 cnss_wlan_get_dfs_nol(pSapEvent->sapevt.sapDfsNolInfo.
1642 pDfsList,
1643 pSapEvent->sapevt.sapDfsNolInfo.
1644 sDfsList);
1645
1646 if (ret > 0) {
1647 hddLog(LOG2,
1648 FL("Get %d bytes of dfs nol from cnss"), ret);
1649 return CDF_STATUS_SUCCESS;
1650 } else {
1651 hddLog(LOG2,
1652 FL("No dfs nol entry in CNSS, ret: %d"), ret);
1653 return CDF_STATUS_E_FAULT;
1654 }
1655#else
1656 return CDF_STATUS_E_FAILURE;
1657#endif
1658 case eSAP_DFS_NOL_SET:
1659 hddLog(LOG1, FL("Received eSAP_DFS_NOL_SET event"));
1660#if defined CONFIG_CNSS
1661 /* set the dfs nol to cnss */
1662 ret =
1663 cnss_wlan_set_dfs_nol(pSapEvent->sapevt.sapDfsNolInfo.
1664 pDfsList,
1665 pSapEvent->sapevt.sapDfsNolInfo.
1666 sDfsList);
1667
1668 if (ret) {
1669 hddLog(LOG2,
1670 FL("Failed to set dfs nol - ret: %d"),
1671 ret);
1672 } else {
1673 hddLog(LOG2, FL(" Set %d bytes dfs nol to cnss"),
1674 pSapEvent->sapevt.sapDfsNolInfo.sDfsList);
1675 }
1676#else
1677 return CDF_STATUS_E_FAILURE;
1678#endif
1679 return CDF_STATUS_SUCCESS;
1680 case eSAP_ACS_CHANNEL_SELECTED:
1681 hddLog(LOG1, FL("ACS Completed for wlan%d"),
1682 pHostapdAdapter->dev->ifindex);
1683 clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
1684 clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);
1685 pHddApCtx->sapConfig.acs_cfg.pri_ch =
1686 pSapEvent->sapevt.sap_ch_selected.pri_ch;
1687 pHddApCtx->sapConfig.acs_cfg.ht_sec_ch =
1688 pSapEvent->sapevt.sap_ch_selected.ht_sec_ch;
1689 pHddApCtx->sapConfig.acs_cfg.vht_seg0_center_ch =
1690 pSapEvent->sapevt.sap_ch_selected.vht_seg0_center_ch;
1691 pHddApCtx->sapConfig.acs_cfg.vht_seg1_center_ch =
1692 pSapEvent->sapevt.sap_ch_selected.vht_seg1_center_ch;
1693 pHddApCtx->sapConfig.acs_cfg.ch_width =
1694 pSapEvent->sapevt.sap_ch_selected.ch_width;
1695 /* send vendor event to hostapd only for hostapd based acs*/
1696 if (!pHddCtx->config->force_sap_acs)
1697 wlan_hdd_cfg80211_acs_ch_select_evt(pHostapdAdapter);
1698 return CDF_STATUS_SUCCESS;
Abhishek Singh1bdb1572015-10-16 16:24:19 +05301699 case eSAP_ECSA_CHANGE_CHAN_IND:
1700 hddLog(LOG1,
1701 FL("Channel change indication from peer for channel %d"),
1702 pSapEvent->sapevt.sap_chan_cng_ind.new_chan);
1703 if (hdd_softap_set_channel_change(dev,
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301704 pSapEvent->sapevt.sap_chan_cng_ind.new_chan,
1705 CH_WIDTH_MAX))
Abhishek Singh1bdb1572015-10-16 16:24:19 +05301706 return CDF_STATUS_E_FAILURE;
1707 else
1708 return CDF_STATUS_SUCCESS;
1709
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001710 default:
1711 hddLog(LOG1, "SAP message is not handled");
1712 goto stopbss;
1713 return CDF_STATUS_SUCCESS;
1714 }
1715 wireless_send_event(dev, we_event, &wrqu,
1716 (char *)we_custom_event_generic);
1717 return CDF_STATUS_SUCCESS;
1718
1719stopbss:
1720 {
1721 uint8_t we_custom_event[64];
1722 char *stopBssEvent = "STOP-BSS.response"; /* 17 */
1723 int event_len = strlen(stopBssEvent);
1724
1725 hddLog(LOG1, FL("BSS stop status = %s"),
1726 pSapEvent->sapevt.sapStopBssCompleteEvent.status ?
1727 "eSAP_STATUS_FAILURE" : "eSAP_STATUS_SUCCESS");
1728
1729 /* Change the BSS state now since, as we are shutting things down,
1730 * we don't want interfaces to become re-enabled */
1731 pHostapdState->bssState = BSS_STOP;
1732
1733 if (0 !=
1734 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->
1735 nAPAutoShutOff) {
1736 if (CDF_TIMER_STATE_RUNNING ==
1737 pHddApCtx->hdd_ap_inactivity_timer.state) {
1738 cdf_status =
1739 cdf_mc_timer_stop(&pHddApCtx->
1740 hdd_ap_inactivity_timer);
1741 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1742 hddLog(LOGE,
1743 FL("Failed to stop AP inactivity timer"));
1744 }
1745 }
1746
1747 cdf_status =
1748 cdf_mc_timer_destroy(&pHddApCtx->
1749 hdd_ap_inactivity_timer);
1750 if (!CDF_IS_STATUS_SUCCESS(cdf_status))
1751 hddLog(LOGE, FL("Failed to Destroy AP inactivity timer"));
1752 }
1753#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1754 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1755#endif
1756
1757 /* Stop the pkts from n/w stack as we are going to free all of
1758 * the TX WMM queues for all STAID's */
1759 hdd_hostapd_stop(dev);
1760
1761 /* reclaim all resources allocated to the BSS */
1762 cdf_status = hdd_softap_stop_bss(pHostapdAdapter);
1763 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
1764 hddLog(LOGW,
1765 FL("hdd_softap_stop_bss failed %d"),
1766 cdf_status);
1767 }
1768
1769 /* once the event is set, structure dev/pHostapdAdapter should
1770 * not be touched since they are now subject to being deleted
1771 * by another thread */
1772 if (eSAP_STOP_BSS_EVENT == sapEvent)
1773 cdf_event_set(&pHostapdState->cdf_stop_bss_event);
1774
1775 /* notify userspace that the BSS has stopped */
1776 memset(&we_custom_event, '\0', sizeof(we_custom_event));
1777 memcpy(&we_custom_event, stopBssEvent, event_len);
1778 memset(&wrqu, 0, sizeof(wrqu));
1779 wrqu.data.length = event_len;
1780 we_event = IWEVCUSTOM;
1781 we_custom_event_generic = we_custom_event;
1782 wireless_send_event(dev, we_event, &wrqu,
1783 (char *)we_custom_event_generic);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001784 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001785 /* Send SCC/MCC Switching event to IPA */
1786 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
1787 }
1788 return CDF_STATUS_SUCCESS;
1789}
1790
1791int hdd_softap_unpack_ie(tHalHandle halHandle,
1792 eCsrEncryptionType *pEncryptType,
1793 eCsrEncryptionType *mcEncryptType,
1794 eCsrAuthType *pAuthType,
1795 bool *pMFPCapable,
1796 bool *pMFPRequired,
1797 uint16_t gen_ie_len, uint8_t *gen_ie)
1798{
1799 tDot11fIERSN dot11RSNIE;
1800 tDot11fIEWPA dot11WPAIE;
1801
1802 uint8_t *pRsnIe;
1803 uint16_t RSNIeLen;
1804
1805 if (NULL == halHandle) {
1806 hddLog(LOGE, FL("Error haHandle returned NULL"));
1807 return -EINVAL;
1808 }
1809 /* Validity checks */
1810 if ((gen_ie_len < CDF_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN))
1811 || (gen_ie_len >
1812 CDF_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)))
1813 return -EINVAL;
1814 /* Type check */
1815 if (gen_ie[0] == DOT11F_EID_RSN) {
1816 /* Validity checks */
1817 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
1818 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
1819 return CDF_STATUS_E_FAILURE;
1820 }
1821 /* Skip past the EID byte and length byte */
1822 pRsnIe = gen_ie + 2;
1823 RSNIeLen = gen_ie_len - 2;
1824 /* Unpack the RSN IE */
1825 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
1826 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
1827 pRsnIe, RSNIeLen, &dot11RSNIE);
1828 /* Copy out the encryption and authentication types */
1829 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
1830 dot11RSNIE.pwise_cipher_suite_count);
1831 hddLog(LOG1, FL("authentication suite count: %d"),
1832 dot11RSNIE.akm_suite_count);
1833 /*Here we have followed the apple base code,
1834 but probably I suspect we can do something different */
1835 /* dot11RSNIE.akm_suite_count */
1836 /* Just translate the FIRST one */
1837 *pAuthType =
1838 hdd_translate_rsn_to_csr_auth_type(dot11RSNIE.akm_suites[0]);
1839 /* dot11RSNIE.pwise_cipher_suite_count */
1840 *pEncryptType =
1841 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
1842 pwise_cipher_suites[0]);
1843 /* dot11RSNIE.gp_cipher_suite_count */
1844 *mcEncryptType =
1845 hdd_translate_rsn_to_csr_encryption_type(dot11RSNIE.
1846 gp_cipher_suite);
1847 /* Set the PMKSA ID Cache for this interface */
1848 *pMFPCapable = 0 != (dot11RSNIE.RSN_Cap[0] & 0x80);
1849 *pMFPRequired = 0 != (dot11RSNIE.RSN_Cap[0] & 0x40);
1850 /* Calling csr_roam_set_pmkid_cache to configure the PMKIDs into the cache */
1851 } else if (gen_ie[0] == DOT11F_EID_WPA) {
1852 /* Validity checks */
1853 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
1854 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
1855 return CDF_STATUS_E_FAILURE;
1856 }
1857 /* Skip past the EID byte and length byte - and four byte WiFi OUI */
1858 pRsnIe = gen_ie + 2 + 4;
1859 RSNIeLen = gen_ie_len - (2 + 4);
1860 /* Unpack the WPA IE */
1861 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
1862 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
1863 pRsnIe, RSNIeLen, &dot11WPAIE);
1864 /* Copy out the encryption and authentication types */
1865 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
1866 dot11WPAIE.unicast_cipher_count);
1867 hddLog(LOG1, FL("WPA authentication suite count: %d"),
1868 dot11WPAIE.auth_suite_count);
1869 /* dot11WPAIE.auth_suite_count */
1870 /* Just translate the FIRST one */
1871 *pAuthType =
1872 hdd_translate_wpa_to_csr_auth_type(dot11WPAIE.auth_suites[0]);
1873 /* dot11WPAIE.unicast_cipher_count */
1874 *pEncryptType =
1875 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
1876 unicast_ciphers[0]);
1877 /* dot11WPAIE.unicast_cipher_count */
1878 *mcEncryptType =
1879 hdd_translate_wpa_to_csr_encryption_type(dot11WPAIE.
1880 multicast_cipher);
1881 *pMFPCapable = false;
1882 *pMFPRequired = false;
1883 } else {
1884 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
1885 return CDF_STATUS_E_FAILURE;
1886 }
1887 return CDF_STATUS_SUCCESS;
1888}
1889
1890/**
1891 * hdd_softap_set_channel_change() -
1892 * This function to support SAP channel change with CSA IE
1893 * set in the beacons.
1894 *
1895 * @dev: pointer to the net device.
1896 * @target_channel: target channel number.
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301897 * @target_bw: Target bandwidth to move.
1898 * If no bandwidth is specified, the value is CH_WIDTH_MAX
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001899 *
1900 * Return: 0 for success, non zero for failure
1901 */
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301902int hdd_softap_set_channel_change(struct net_device *dev, int target_channel,
1903 phy_ch_width target_bw)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001904{
1905 CDF_STATUS status;
1906 int ret = 0;
1907 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
1908 hdd_context_t *pHddCtx = NULL;
Edhar, Mahesh Kumardf2ec122015-11-16 11:33:16 +05301909 hdd_adapter_t *sta_adapter;
1910 hdd_station_ctx_t *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001911
1912#ifndef WLAN_FEATURE_MBSSID
1913 v_CONTEXT_t p_cds_context =
1914 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pcds_context;
1915#endif
1916
1917 pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
1918 ret = wlan_hdd_validate_context(pHddCtx);
1919 if (ret) {
1920 hddLog(LOGE, FL("invalid HDD context"));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001921 return ret;
1922 }
1923
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +05301924 ret = hdd_validate_channel_and_bandwidth(pHostapdAdapter,
1925 target_channel, target_bw);
1926 if (ret) {
1927 hdd_err("Invalid CH and BW combo");
1928 return ret;
1929 }
1930
Edhar, Mahesh Kumardf2ec122015-11-16 11:33:16 +05301931 sta_adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
1932 /*
1933 * conc_custom_rule1:
1934 * Force SCC for SAP + STA
1935 * if STA is already connected then we shouldn't allow
1936 * channel switch in SAP interface.
1937 */
1938 if (sta_adapter && pHddCtx->config->conc_custom_rule1) {
1939 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter);
1940 if (hdd_conn_is_connected(sta_ctx)) {
1941 hdd_err("Channel switch not allowed after STA connection with conc_custom_rule1 enabled");
1942 return -EBUSY;
1943 }
1944 }
1945
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301946 mutex_lock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001947 if (pHddCtx->dfs_radar_found == true) {
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301948 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001949 hddLog(LOGE, FL("Channel switch in progress!!"));
1950 return -EBUSY;
1951 }
1952 /*
1953 * Set the dfs_radar_found flag to mimic channel change
1954 * when a radar is found. This will enable synchronizing
1955 * SAP and HDD states similar to that of radar indication.
1956 * Suspend the netif queues to stop queuing Tx frames
1957 * from upper layers. netif queues will be resumed
1958 * once the channel change is completed and SAP will
1959 * post eSAP_START_BSS_EVENT success event to HDD.
1960 */
1961 pHddCtx->dfs_radar_found = true;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301962 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001963 /*
1964 * Post the Channel Change request to SAP.
1965 */
1966 status = wlansap_set_channel_change_with_csa(
1967#ifdef WLAN_FEATURE_MBSSID
1968 WLAN_HDD_GET_SAP_CTX_PTR
1969 (pHostapdAdapter),
1970#else
1971 p_cds_context,
1972#endif
1973 (uint32_t)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301974 target_channel,
1975 target_bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001976
1977 if (CDF_STATUS_SUCCESS != status) {
1978 hddLog(LOGE,
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301979 FL("SAP set channel failed for channel = %d, bw:%d"),
1980 target_channel, target_bw);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001981 /*
1982 * If channel change command fails then clear the
1983 * radar found flag and also restart the netif
1984 * queues.
1985 */
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301986 mutex_lock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001987 pHddCtx->dfs_radar_found = false;
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05301988 mutex_unlock(&pHddCtx->dfs_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001989
1990 ret = -EINVAL;
1991 }
1992
1993 return ret;
1994}
1995
1996int
1997static __iw_softap_set_ini_cfg(struct net_device *dev,
1998 struct iw_request_info *info,
1999 union iwreq_data *wrqu, char *extra)
2000{
2001 CDF_STATUS vstatus;
2002 int ret = 0; /* success */
2003 hdd_adapter_t *pAdapter = (netdev_priv(dev));
2004 hdd_context_t *pHddCtx;
2005
2006 if (pAdapter == NULL) {
2007 hddLog(LOGE, FL("pAdapter is NULL!"));
2008 return -EINVAL;
2009 }
2010
2011 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2012 ret = wlan_hdd_validate_context(pHddCtx);
2013 if (ret != 0) {
2014 hddLog(LOGE, FL("HDD context is not valid"));
2015 return ret;
2016 }
2017
2018 hddLog(LOG1, FL("Received data %s"), extra);
2019
2020 vstatus = hdd_execute_global_config_command(pHddCtx, extra);
2021 if (CDF_STATUS_SUCCESS != vstatus) {
2022 ret = -EINVAL;
2023 }
2024
2025 return ret;
2026}
2027
2028int
2029static iw_softap_set_ini_cfg(struct net_device *dev,
2030 struct iw_request_info *info,
2031 union iwreq_data *wrqu, char *extra)
2032{
2033 int ret;
2034
2035 cds_ssr_protect(__func__);
2036 ret = __iw_softap_set_ini_cfg(dev, info, wrqu, extra);
2037 cds_ssr_unprotect(__func__);
2038
2039 return ret;
2040}
2041
2042int
2043static __iw_softap_get_ini_cfg(struct net_device *dev,
2044 struct iw_request_info *info,
2045 union iwreq_data *wrqu, char *extra)
2046{
2047 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2048 hdd_context_t *pHddCtx;
2049 int ret = 0;
2050
2051 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2052 ret = wlan_hdd_validate_context(pHddCtx);
2053 if (ret != 0) {
2054 hddLog(LOGE, FL("HDD context is not valid"));
2055 return ret;
2056 }
2057 hddLog(LOG1, FL("Printing CLD global INI Config"));
2058 hdd_cfg_get_global_config(pHddCtx, extra, QCSAP_IOCTL_MAX_STR_LEN);
2059 wrqu->data.length = strlen(extra) + 1;
2060
2061 return 0;
2062}
2063
2064int
2065static iw_softap_get_ini_cfg(struct net_device *dev,
2066 struct iw_request_info *info,
2067 union iwreq_data *wrqu, char *extra)
2068{
2069 int ret;
2070
2071 cds_ssr_protect(__func__);
2072 ret = __iw_softap_get_ini_cfg(dev, info, wrqu, extra);
2073 cds_ssr_unprotect(__func__);
2074
2075 return ret;
2076}
2077
Govind Singha471e5e2015-10-12 17:11:14 +05302078/**
2079 * iw_softap_set_two_ints_getnone() - Generic "set two integer" ioctl handler
2080 * @dev: device upon which the ioctl was received
2081 * @info: ioctl request information
2082 * @wrqu: ioctl request data
2083 * @extra: ioctl extra data
2084 *
2085 * Return: 0 on success, non-zero on error
2086 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002087static int __iw_softap_set_two_ints_getnone(struct net_device *dev,
2088 struct iw_request_info *info,
2089 union iwreq_data *wrqu, char *extra)
2090{
Govind Singha471e5e2015-10-12 17:11:14 +05302091 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2092 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002093 int *value = (int *)extra;
2094 int sub_cmd = value[0];
Govind Singha471e5e2015-10-12 17:11:14 +05302095 hdd_context_t *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002096
Govind Singha471e5e2015-10-12 17:11:14 +05302097 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2098 ret = wlan_hdd_validate_context(hdd_ctx);
2099 if (ret != 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002100 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002101
2102 switch (sub_cmd) {
2103#ifdef DEBUG
2104 case QCSAP_IOCTL_SET_FW_CRASH_INJECT:
2105 hddLog(LOGE, "WE_SET_FW_CRASH_INJECT: %d %d",
2106 value[1], value[2]);
Govind Singha471e5e2015-10-12 17:11:14 +05302107 ret = wma_cli_set2_command(adapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002108 GEN_PARAM_CRASH_INJECT,
2109 value[1], value[2],
2110 GEN_CMD);
2111 break;
2112#endif
2113 case QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL:
2114 hdd_info("WE_DUMP_DP_TRACE: %d %d",
2115 value[1], value[2]);
2116 if (value[1] == DUMP_DP_TRACE)
2117 cdf_dp_trace_dump_all(value[2]);
2118 break;
Govind Singha471e5e2015-10-12 17:11:14 +05302119 case QCSAP_ENABLE_FW_PROFILE:
2120 hddLog(LOG1, "QCSAP_ENABLE_FW_PROFILE: %d %d",
2121 value[1], value[2]);
2122 ret = wma_cli_set2_command(adapter->sessionId,
2123 WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID,
2124 value[1], value[2], DBG_CMD);
2125 break;
2126 case QCSAP_SET_FW_PROFILE_HIST_INTVL:
2127 hddLog(LOG1, "QCSAP_SET_FW_PROFILE_HIST_INTVL: %d %d",
2128 value[1], value[2]);
2129 ret = wma_cli_set2_command(adapter->sessionId,
2130 WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID,
2131 value[1], value[2], DBG_CMD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002132 default:
2133 hddLog(LOGE, FL("Invalid IOCTL command %d"), sub_cmd);
2134 break;
2135 }
2136
2137out:
2138 return ret;
2139}
2140
2141static int iw_softap_set_two_ints_getnone(struct net_device *dev,
2142 struct iw_request_info *info,
2143 union iwreq_data *wrqu, char *extra)
2144{
2145 int ret;
2146
2147 cds_ssr_protect(__func__);
2148 ret = __iw_softap_set_two_ints_getnone(dev, info, wrqu, extra);
2149 cds_ssr_unprotect(__func__);
2150
2151 return ret;
2152}
2153
2154static void print_mac_list(struct cdf_mac_addr *macList, uint8_t size)
2155{
2156 int i;
2157 uint8_t *macArray;
2158
2159 for (i = 0; i < size; i++) {
2160 macArray = (macList + i)->bytes;
2161 pr_info("** ACL entry %i - %02x:%02x:%02x:%02x:%02x:%02x \n",
2162 i, MAC_ADDR_ARRAY(macArray));
2163 }
2164 return;
2165}
2166
2167static CDF_STATUS hdd_print_acl(hdd_adapter_t *pHostapdAdapter)
2168{
2169 eSapMacAddrACL acl_mode;
2170 struct cdf_mac_addr MacList[MAX_ACL_MAC_ADDRESS];
2171 uint8_t listnum;
2172 void *p_cds_gctx = NULL;
2173
2174#ifdef WLAN_FEATURE_MBSSID
2175 p_cds_gctx = WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter);
2176#else
2177 p_cds_gctx = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pcds_context;
2178#endif
2179 cdf_mem_zero(&MacList[0], sizeof(MacList));
2180 if (CDF_STATUS_SUCCESS == wlansap_get_acl_mode(p_cds_gctx, &acl_mode)) {
2181 pr_info("******** ACL MODE *********\n");
2182 switch (acl_mode) {
2183 case eSAP_ACCEPT_UNLESS_DENIED:
2184 pr_info("ACL Mode = ACCEPT_UNLESS_DENIED\n");
2185 break;
2186 case eSAP_DENY_UNLESS_ACCEPTED:
2187 pr_info("ACL Mode = DENY_UNLESS_ACCEPTED\n");
2188 break;
2189 case eSAP_SUPPORT_ACCEPT_AND_DENY:
2190 pr_info("ACL Mode = ACCEPT_AND_DENY\n");
2191 break;
2192 case eSAP_ALLOW_ALL:
2193 pr_info("ACL Mode = ALLOW_ALL\n");
2194 break;
2195 default:
2196 pr_info("Invalid SAP ACL Mode = %d\n", acl_mode);
2197 return CDF_STATUS_E_FAILURE;
2198 }
2199 } else {
2200 return CDF_STATUS_E_FAILURE;
2201 }
2202
2203 if (CDF_STATUS_SUCCESS == wlansap_get_acl_accept_list(p_cds_gctx,
2204 &MacList[0],
2205 &listnum)) {
2206 pr_info("******* WHITE LIST ***********\n");
2207 if (listnum <= MAX_ACL_MAC_ADDRESS)
2208 print_mac_list(&MacList[0], listnum);
2209 } else {
2210 return CDF_STATUS_E_FAILURE;
2211 }
2212
2213 if (CDF_STATUS_SUCCESS == wlansap_get_acl_deny_list(p_cds_gctx,
2214 &MacList[0],
2215 &listnum)) {
2216 pr_info("******* BLACK LIST ***********\n");
2217 if (listnum <= MAX_ACL_MAC_ADDRESS)
2218 print_mac_list(&MacList[0], listnum);
2219 } else {
2220 return CDF_STATUS_E_FAILURE;
2221 }
2222 return CDF_STATUS_SUCCESS;
2223}
2224
2225int
2226static __iw_softap_setparam(struct net_device *dev,
2227 struct iw_request_info *info,
2228 union iwreq_data *wrqu, char *extra)
2229{
2230 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2231 tHalHandle hHal;
2232 int *value = (int *)extra;
2233 int sub_cmd = value[0];
2234 int set_value = value[1];
2235 CDF_STATUS status;
2236 int ret = 0; /* success */
2237 v_CONTEXT_t p_cds_context;
2238 hdd_context_t *hdd_ctx;
2239
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302240 ENTER();
2241
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002242 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2243 ret = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302244 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002245 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002246
2247 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2248 if (!hHal) {
2249 hddLog(LOGE, FL("Hal ctx is null"));
2250 return -EINVAL;
2251 }
2252
2253 p_cds_context = hdd_ctx->pcds_context;
2254 if (!p_cds_context) {
2255 hddLog(LOGE, FL("cds ctx is null"));
2256 return -ENOENT;
2257 }
2258
2259 switch (sub_cmd) {
2260 case QCASAP_SET_RADAR_DBG:
2261 hddLog(LOG1, FL("QCASAP_SET_RADAR_DBG called with: value: %d"),
2262 set_value);
2263 wlan_sap_enable_phy_error_logs(hHal, (bool) set_value);
2264 break;
2265
2266 case QCSAP_PARAM_CLR_ACL:
2267 if (CDF_STATUS_SUCCESS != wlansap_clear_acl(
2268#ifdef WLAN_FEATURE_MBSSID
2269 WLAN_HDD_GET_SAP_CTX_PTR
2270 (pHostapdAdapter)
2271#else
2272 p_cds_context
2273#endif
2274 )) {
2275 ret = -EIO;
2276 }
2277 break;
2278
2279 case QCSAP_PARAM_ACL_MODE:
2280 if ((eSAP_ALLOW_ALL < (eSapMacAddrACL) set_value) ||
2281 (eSAP_ACCEPT_UNLESS_DENIED > (eSapMacAddrACL) set_value)) {
2282 hddLog(LOGE, FL("Invalid ACL Mode value %d"),
2283 set_value);
2284 ret = -EINVAL;
2285 } else {
2286#ifdef WLAN_FEATURE_MBSSID
2287 wlansap_set_mode(WLAN_HDD_GET_SAP_CTX_PTR
2288 (pHostapdAdapter), set_value);
2289#else
2290 wlansap_set_mode(p_cds_context, set_value);
2291#endif
2292
2293 }
2294 break;
2295
2296 case QCSAP_PARAM_SET_CHANNEL_CHANGE:
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302297 if ((WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode) ||
2298 (WLAN_HDD_P2P_GO == pHostapdAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002299 hddLog(LOG1,
Abhishek Singh1bdb1572015-10-16 16:24:19 +05302300 "SET Channel Change to new channel= %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002301 set_value);
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05302302 ret = hdd_softap_set_channel_change(dev, set_value,
2303 CH_WIDTH_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002304 } else {
2305 hddLog(LOGE,
2306 FL("Channel Change Failed, Device in test mode"));
2307 ret = -EINVAL;
2308 }
2309 break;
2310 case QCSAP_PARAM_AUTO_CHANNEL:
2311 if (set_value == 0 || set_value == 1)
2312 (WLAN_HDD_GET_CTX(
2313 pHostapdAdapter))->config->force_sap_acs =
2314 set_value;
2315 else
2316 ret = -EINVAL;
2317 break;
2318
2319 case QCSAP_PARAM_MAX_ASSOC:
2320 if (WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) {
2321 hddLog(LOGE, FL("Invalid setMaxAssoc value %d"),
2322 set_value);
2323 ret = -EINVAL;
2324 } else {
2325 if (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value) {
2326 hddLog(LOGW,
2327 FL("setMaxAssoc %d > max allowed %d."),
2328 set_value,
2329 WNI_CFG_ASSOC_STA_LIMIT_STAMAX);
2330 hddLog(LOGW,
2331 FL("Setting it to max allowed and continuing"));
2332 set_value = WNI_CFG_ASSOC_STA_LIMIT_STAMAX;
2333 }
2334 status = sme_cfg_set_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
2335 set_value);
2336 if (status != CDF_STATUS_SUCCESS) {
2337 hddLog(LOGE,
2338 FL("setMaxAssoc failure, status %d"),
2339 status);
2340 ret = -EIO;
2341 }
2342 }
2343 break;
2344
2345 case QCSAP_PARAM_HIDE_SSID:
2346 {
2347 CDF_STATUS status = CDF_STATUS_SUCCESS;
2348 status =
2349 sme_hide_ssid(hHal, pHostapdAdapter->sessionId,
2350 set_value);
2351 if (CDF_STATUS_SUCCESS != status) {
2352 hddLog(LOGE, FL("QCSAP_PARAM_HIDE_SSID failed"));
2353 return status;
2354 }
2355 break;
2356 }
2357 case QCSAP_PARAM_SET_MC_RATE:
2358 {
2359 tSirRateUpdateInd rateUpdate = {0};
2360 struct hdd_config *pConfig = hdd_ctx->config;
2361
2362 hddLog(LOG1, "MC Target rate %d", set_value);
Srinivas Girigowdaafede182015-11-18 22:36:12 -08002363 cdf_copy_macaddr(&rateUpdate.bssid,
2364 &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002365 rateUpdate.nss = (pConfig->enable2x2 == 0) ? 0 : 1;
2366 rateUpdate.dev_mode = pHostapdAdapter->device_mode;
2367 rateUpdate.mcastDataRate24GHz = set_value;
2368 rateUpdate.mcastDataRate24GHzTxFlag = 1;
2369 rateUpdate.mcastDataRate5GHz = set_value;
2370 rateUpdate.bcastDataRate = -1;
2371 status = sme_send_rate_update_ind(hHal, &rateUpdate);
2372 if (CDF_STATUS_SUCCESS != status) {
2373 hddLog(LOGE, FL("SET_MC_RATE failed"));
2374 ret = -1;
2375 }
2376 break;
2377 }
2378
2379 case QCSAP_PARAM_SET_TXRX_FW_STATS:
2380 {
2381 hddLog(LOG1, "QCSAP_PARAM_SET_TXRX_FW_STATS val %d", set_value);
2382 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2383 WMA_VDEV_TXRX_FWSTATS_ENABLE_CMDID,
2384 set_value, VDEV_CMD);
2385 break;
2386 }
2387 /* Firmware debug log */
2388 case QCSAP_DBGLOG_LOG_LEVEL:
2389 {
2390 hddLog(LOG1, "QCSAP_DBGLOG_LOG_LEVEL val %d", set_value);
2391 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2392 WMI_DBGLOG_LOG_LEVEL,
2393 set_value, DBG_CMD);
2394 break;
2395 }
2396
2397 case QCSAP_DBGLOG_VAP_ENABLE:
2398 {
2399 hddLog(LOG1, "QCSAP_DBGLOG_VAP_ENABLE val %d", set_value);
2400 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2401 WMI_DBGLOG_VAP_ENABLE,
2402 set_value, DBG_CMD);
2403 break;
2404 }
2405
2406 case QCSAP_DBGLOG_VAP_DISABLE:
2407 {
2408 hddLog(LOG1, "QCSAP_DBGLOG_VAP_DISABLE val %d", set_value);
2409 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2410 WMI_DBGLOG_VAP_DISABLE,
2411 set_value, DBG_CMD);
2412 break;
2413 }
2414
2415 case QCSAP_DBGLOG_MODULE_ENABLE:
2416 {
2417 hddLog(LOG1, "QCSAP_DBGLOG_MODULE_ENABLE val %d", set_value);
2418 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2419 WMI_DBGLOG_MODULE_ENABLE,
2420 set_value, DBG_CMD);
2421 break;
2422 }
2423
2424 case QCSAP_DBGLOG_MODULE_DISABLE:
2425 {
2426 hddLog(LOG1, "QCSAP_DBGLOG_MODULE_DISABLE val %d", set_value);
2427 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2428 WMI_DBGLOG_MODULE_DISABLE,
2429 set_value, DBG_CMD);
2430 break;
2431 }
2432
2433 case QCSAP_DBGLOG_MOD_LOG_LEVEL:
2434 {
2435 hddLog(LOG1, "QCSAP_DBGLOG_MOD_LOG_LEVEL val %d", set_value);
2436 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2437 WMI_DBGLOG_MOD_LOG_LEVEL,
2438 set_value, DBG_CMD);
2439 break;
2440 }
2441
2442 case QCSAP_DBGLOG_TYPE:
2443 {
2444 hddLog(LOG1, "QCSAP_DBGLOG_TYPE val %d", set_value);
2445 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2446 WMI_DBGLOG_TYPE,
2447 set_value, DBG_CMD);
2448 break;
2449 }
2450 case QCSAP_DBGLOG_REPORT_ENABLE:
2451 {
2452 hddLog(LOG1, "QCSAP_DBGLOG_REPORT_ENABLE val %d", set_value);
2453 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2454 WMI_DBGLOG_REPORT_ENABLE,
2455 set_value, DBG_CMD);
2456 break;
2457 }
2458 case QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY:
2459 {
2460 cds_set_mcc_latency(pHostapdAdapter, set_value);
2461 break;
2462 }
2463
2464 case QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA:
2465 {
2466 hddLog(LOG1,
2467 FL("iwpriv cmd to set MCC quota value %dms"),
2468 set_value);
2469 ret = cds_go_set_mcc_p2p_quota(pHostapdAdapter,
2470 set_value);
2471 break;
2472 }
2473
2474 case QCASAP_TXRX_FWSTATS_RESET:
2475 {
2476 hddLog(LOG1, "WE_TXRX_FWSTATS_RESET val %d", set_value);
2477 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2478 WMA_VDEV_TXRX_FWSTATS_RESET_CMDID,
2479 set_value, VDEV_CMD);
2480 break;
2481 }
2482
2483 case QCSAP_PARAM_RTSCTS:
2484 {
2485 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2486 WMI_VDEV_PARAM_ENABLE_RTSCTS,
2487 set_value, VDEV_CMD);
2488 if (ret) {
2489 hddLog(LOGE, "FAILED TO SET RTSCTS at SAP");
2490 ret = -EIO;
2491 }
2492 break;
2493 }
2494 case QCASAP_SET_11N_RATE:
2495 {
2496 uint8_t preamble = 0, nss = 0, rix = 0;
2497 tsap_Config_t *pConfig =
2498 &pHostapdAdapter->sessionCtx.ap.sapConfig;
2499
2500 hddLog(LOG1, "SET_HT_RATE val %d", set_value);
2501
2502 if (set_value != 0xff) {
2503 rix = RC_2_RATE_IDX(set_value);
2504 if (set_value & 0x80) {
2505 if (pConfig->SapHw_mode ==
2506 eCSR_DOT11_MODE_11b
2507 || pConfig->SapHw_mode ==
2508 eCSR_DOT11_MODE_11b_ONLY
2509 || pConfig->SapHw_mode ==
2510 eCSR_DOT11_MODE_11g
2511 || pConfig->SapHw_mode ==
2512 eCSR_DOT11_MODE_11g_ONLY
2513 || pConfig->SapHw_mode ==
2514 eCSR_DOT11_MODE_abg
2515 || pConfig->SapHw_mode ==
2516 eCSR_DOT11_MODE_11a) {
2517 hddLog(LOGE,
2518 "Not valid mode for HT");
2519 ret = -EIO;
2520 break;
2521 }
2522 preamble = WMI_RATE_PREAMBLE_HT;
2523 nss = HT_RC_2_STREAMS(set_value) - 1;
2524 } else if (set_value & 0x10) {
2525 if (pConfig->SapHw_mode ==
2526 eCSR_DOT11_MODE_11a) {
2527 hddLog(LOGE, "Not valid for cck");
2528 ret = -EIO;
2529 break;
2530 }
2531 preamble = WMI_RATE_PREAMBLE_CCK;
2532 /* Enable Short preamble always
2533 * for CCK except 1mbps
2534 */
2535 if (rix != 0x3)
2536 rix |= 0x4;
2537 } else {
2538 if (pConfig->SapHw_mode ==
2539 eCSR_DOT11_MODE_11b
2540 || pConfig->SapHw_mode ==
2541 eCSR_DOT11_MODE_11b_ONLY) {
2542 hddLog(LOGE, "Not valid for OFDM");
2543 ret = -EIO;
2544 break;
2545 }
2546 preamble = WMI_RATE_PREAMBLE_OFDM;
2547 }
2548 set_value = (preamble << 6) | (nss << 4) | rix;
2549 }
2550 hddLog(LOG1, "SET_HT_RATE val %d rix %d preamble %x nss %d",
2551 set_value, rix, preamble, nss);
2552 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2553 WMI_VDEV_PARAM_FIXED_RATE,
2554 set_value, VDEV_CMD);
2555 break;
2556 }
2557
2558 case QCASAP_SET_VHT_RATE:
2559 {
2560 uint8_t preamble = 0, nss = 0, rix = 0;
2561 tsap_Config_t *pConfig =
2562 &pHostapdAdapter->sessionCtx.ap.sapConfig;
2563
2564 if (pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac &&
2565 pConfig->SapHw_mode != eCSR_DOT11_MODE_11ac_ONLY) {
2566 hddLog(LOGE,
2567 FL("SET_VHT_RATE error: SapHw_mode= 0x%x, ch = %d"),
2568 pConfig->SapHw_mode, pConfig->channel);
2569 ret = -EIO;
2570 break;
2571 }
2572
2573 if (set_value != 0xff) {
2574 rix = RC_2_RATE_IDX_11AC(set_value);
2575 preamble = WMI_RATE_PREAMBLE_VHT;
2576 nss = HT_RC_2_STREAMS_11AC(set_value) - 1;
2577
2578 set_value = (preamble << 6) | (nss << 4) | rix;
2579 }
2580 hddLog(LOG1, "SET_VHT_RATE val %d rix %d preamble %x nss %d",
2581 set_value, rix, preamble, nss);
2582
2583 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2584 WMI_VDEV_PARAM_FIXED_RATE,
2585 set_value, VDEV_CMD);
2586 break;
2587 }
2588
2589 case QCASAP_SHORT_GI:
2590 {
2591 hddLog(LOG1, "QCASAP_SET_SHORT_GI val %d", set_value);
2592
2593 /* same as 40MHZ */
2594 ret = sme_update_ht_config(hHal, pHostapdAdapter->sessionId,
2595 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ,
2596 set_value);
2597 if (ret)
2598 hddLog(LOGE,
2599 "Failed to set ShortGI value ret(%d)", ret);
2600 break;
2601 }
2602
2603 case QCSAP_SET_AMPDU:
2604 {
2605 hddLog(LOG1, "QCSAP_SET_AMPDU %d", set_value);
2606 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2607 GEN_VDEV_PARAM_AMPDU,
2608 set_value, GEN_CMD);
2609 break;
2610 }
2611
2612 case QCSAP_SET_AMSDU:
2613 {
2614 hddLog(LOG1, "QCSAP_SET_AMSDU %d", set_value);
2615 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2616 GEN_VDEV_PARAM_AMSDU,
2617 set_value, GEN_CMD);
2618 break;
2619 }
2620 case QCSAP_GTX_HT_MCS:
2621 {
2622 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_HT_MCS %d", set_value);
2623 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2624 WMI_VDEV_PARAM_GTX_HT_MCS,
2625 set_value, GTX_CMD);
2626 break;
2627 }
2628
2629 case QCSAP_GTX_VHT_MCS:
2630 {
2631 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_VHT_MCS %d", set_value);
2632 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2633 WMI_VDEV_PARAM_GTX_VHT_MCS,
2634 set_value, GTX_CMD);
2635 break;
2636 }
2637
2638 case QCSAP_GTX_USRCFG:
2639 {
2640 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_USR_CFG %d", set_value);
2641 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2642 WMI_VDEV_PARAM_GTX_USR_CFG,
2643 set_value, GTX_CMD);
2644 break;
2645 }
2646
2647 case QCSAP_GTX_THRE:
2648 {
2649 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_THRE %d", set_value);
2650 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2651 WMI_VDEV_PARAM_GTX_THRE,
2652 set_value, GTX_CMD);
2653 break;
2654 }
2655
2656 case QCSAP_GTX_MARGIN:
2657 {
2658 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MARGIN %d", set_value);
2659 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2660 WMI_VDEV_PARAM_GTX_MARGIN,
2661 set_value, GTX_CMD);
2662 break;
2663 }
2664
2665 case QCSAP_GTX_STEP:
2666 {
2667 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_STEP %d", set_value);
2668 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2669 WMI_VDEV_PARAM_GTX_STEP,
2670 set_value, GTX_CMD);
2671 break;
2672 }
2673
2674 case QCSAP_GTX_MINTPC:
2675 {
2676 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_MINTPC %d", set_value);
2677 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2678 WMI_VDEV_PARAM_GTX_MINTPC,
2679 set_value, GTX_CMD);
2680 break;
2681 }
2682
2683 case QCSAP_GTX_BWMASK:
2684 {
2685 hddLog(LOG1, "WMI_VDEV_PARAM_GTX_BWMASK %d", set_value);
2686 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2687 WMI_VDEV_PARAM_GTX_BW_MASK,
2688 set_value, GTX_CMD);
2689 break;
2690 }
2691
2692#ifdef QCA_PKT_PROTO_TRACE
2693 case QCASAP_SET_DEBUG_LOG:
2694 {
2695 hdd_context_t *pHddCtx =
2696 WLAN_HDD_GET_CTX(pHostapdAdapter);
2697
2698 hddLog(LOG1, "QCASAP_SET_DEBUG_LOG val %d", set_value);
2699 /* Trace buffer dump only */
2700 if (CDS_PKT_TRAC_DUMP_CMD == set_value) {
2701 cds_pkt_trace_buf_dump();
2702 break;
2703 }
2704 pHddCtx->config->gEnableDebugLog = set_value;
2705 break;
2706 }
2707#endif /* QCA_PKT_PROTO_TRACE */
2708
2709 case QCASAP_SET_TM_LEVEL:
2710 {
2711 hddLog(LOG1, "Set Thermal Mitigation Level %d", set_value);
2712 (void)sme_set_thermal_level(hHal, set_value);
2713 break;
2714 }
2715
2716 case QCASAP_SET_DFS_IGNORE_CAC:
2717 {
2718 hddLog(LOG1, "Set Dfs ignore CAC %d", set_value);
2719
2720 if (pHostapdAdapter->device_mode != WLAN_HDD_SOFTAP)
2721 return -EINVAL;
2722
2723 ret = wlansap_set_dfs_ignore_cac(hHal, set_value);
2724 break;
2725 }
2726
2727 case QCASAP_SET_DFS_TARGET_CHNL:
2728 {
2729 hddLog(LOG1, "Set Dfs target channel %d", set_value);
2730
2731 if (pHostapdAdapter->device_mode != WLAN_HDD_SOFTAP)
2732 return -EINVAL;
2733
2734 ret = wlansap_set_dfs_target_chnl(hHal, set_value);
2735 break;
2736 }
2737
2738 case QCASAP_SET_DFS_NOL:
2739 wlansap_set_dfs_nol(
2740#ifdef WLAN_FEATURE_MBSSID
2741 WLAN_HDD_GET_SAP_CTX_PTR
2742 (pHostapdAdapter),
2743#else
2744 p_cds_context,
2745#endif
2746 (eSapDfsNolType) set_value);
2747 break;
2748
2749 case QCASAP_SET_RADAR_CMD:
2750 {
2751 hdd_context_t *pHddCtx =
2752 WLAN_HDD_GET_CTX(pHostapdAdapter);
2753 uint8_t ch =
2754 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
2755 operatingChannel;
2756 bool isDfsch;
2757
2758 isDfsch = (CHANNEL_STATE_DFS ==
2759 cds_get_channel_state(ch));
2760
2761 hddLog(LOG1, FL("Set QCASAP_SET_RADAR_CMD val %d"), set_value);
2762
2763 if (!pHddCtx->dfs_radar_found && isDfsch) {
2764 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2765 WMA_VDEV_DFS_CONTROL_CMDID,
2766 set_value, VDEV_CMD);
2767 } else {
2768 hddLog(LOGE,
2769 FL("Ignore, radar_found: %d, dfs_channel: %d"),
2770 pHddCtx->dfs_radar_found, isDfsch);
2771 }
2772 break;
2773 }
2774 case QCASAP_TX_CHAINMASK_CMD:
2775 {
2776 hddLog(LOG1, "QCASAP_TX_CHAINMASK_CMD val %d", set_value);
2777 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2778 WMI_PDEV_PARAM_TX_CHAIN_MASK,
2779 set_value, PDEV_CMD);
2780 break;
2781 }
2782
2783 case QCASAP_RX_CHAINMASK_CMD:
2784 {
2785 hddLog(LOG1, "QCASAP_RX_CHAINMASK_CMD val %d", set_value);
2786 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2787 WMI_PDEV_PARAM_RX_CHAIN_MASK,
2788 set_value, PDEV_CMD);
2789 break;
2790 }
2791
2792 case QCASAP_NSS_CMD:
2793 {
2794 hddLog(LOG1, "QCASAP_NSS_CMD val %d", set_value);
2795 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2796 WMI_VDEV_PARAM_NSS,
2797 set_value, VDEV_CMD);
2798 break;
2799 }
2800
2801 case QCSAP_IPA_UC_STAT:
2802 {
2803 /* If input value is non-zero get stats */
2804 switch (set_value) {
2805 case 1:
2806 hdd_ipa_uc_stat_request(pHostapdAdapter, set_value);
2807 break;
2808 case 3:
2809 hdd_ipa_uc_rt_debug_host_dump(
2810 WLAN_HDD_GET_CTX(pHostapdAdapter));
2811 break;
2812 default:
2813 /* place holder for stats clean up
2814 * Stats clean not implemented yet on firmware and ipa
2815 */
2816 break;
2817 }
2818 return ret;
2819 }
2820
2821 case QCASAP_SET_PHYMODE:
2822 {
2823 hdd_context_t *phddctx =
2824 WLAN_HDD_GET_CTX(pHostapdAdapter);
2825
2826 ret =
2827 wlan_hdd_update_phymode(dev, hHal, set_value,
2828 phddctx);
2829 break;
2830 }
2831 case QCASAP_DUMP_STATS:
2832 {
2833 hddLog(LOG1, "QCASAP_DUMP_STATS val %d", set_value);
2834 hdd_wlan_dump_stats(pHostapdAdapter, set_value);
2835 break;
2836 }
2837 case QCASAP_CLEAR_STATS:
2838 {
2839 hdd_context_t *hdd_ctx =
2840 WLAN_HDD_GET_CTX(pHostapdAdapter);
2841 hddLog(LOG1, "QCASAP_CLEAR_STATS val %d", set_value);
2842 switch (set_value) {
2843 case WLAN_HDD_STATS:
2844 memset(&pHostapdAdapter->stats, 0,
2845 sizeof(pHostapdAdapter->stats));
2846 memset(&pHostapdAdapter->hdd_stats, 0,
2847 sizeof(pHostapdAdapter->hdd_stats));
2848 break;
2849 case WLAN_TXRX_HIST_STATS:
2850 wlan_hdd_clear_tx_rx_histogram(hdd_ctx);
2851 break;
2852 case WLAN_HDD_NETIF_OPER_HISTORY:
2853 wlan_hdd_clear_netif_queue_history(hdd_ctx);
2854 break;
2855 default:
2856 ol_txrx_clear_stats(set_value);
2857 }
2858 break;
2859 }
Govind Singha471e5e2015-10-12 17:11:14 +05302860 case QCSAP_START_FW_PROFILING:
2861 hddLog(LOG1, "QCSAP_START_FW_PROFILING %d", set_value);
2862 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
2863 WMI_WLAN_PROFILE_TRIGGER_CMDID,
2864 set_value, DBG_CMD);
2865 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002866 default:
2867 hddLog(LOGE, FL("Invalid setparam command %d value %d"),
2868 sub_cmd, set_value);
2869 ret = -EINVAL;
2870 break;
2871 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302872 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002873 return ret;
2874}
2875
2876int
2877static iw_softap_setparam(struct net_device *dev,
2878 struct iw_request_info *info,
2879 union iwreq_data *wrqu, char *extra)
2880{
2881 int ret;
2882
2883 cds_ssr_protect(__func__);
2884 ret = __iw_softap_setparam(dev, info, wrqu, extra);
2885 cds_ssr_unprotect(__func__);
2886
2887 return ret;
2888}
2889
2890int
2891static __iw_softap_getparam(struct net_device *dev,
2892 struct iw_request_info *info,
2893 union iwreq_data *wrqu, char *extra)
2894{
2895 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2896 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2897 int *value = (int *)extra;
2898 int sub_cmd = value[0];
2899 CDF_STATUS status;
2900 int ret;
2901 hdd_context_t *hdd_ctx;
2902
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05302903 ENTER();
2904
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002905 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
2906 ret = wlan_hdd_validate_context(hdd_ctx);
2907 if (0 != ret)
2908 return ret;
2909
2910 switch (sub_cmd) {
2911 case QCSAP_PARAM_MAX_ASSOC:
2912 status =
2913 sme_cfg_get_int(hHal, WNI_CFG_ASSOC_STA_LIMIT,
2914 (uint32_t *) value);
2915 if (CDF_STATUS_SUCCESS != status) {
2916 hddLog(LOGE,
2917 FL("failed to get WNI_CFG_ASSOC_STA_LIMIT from cfg %d"),
2918 status);
2919 ret = -EIO;
2920 }
2921 break;
2922
2923 case QCSAP_PARAM_AUTO_CHANNEL:
2924 *value = (WLAN_HDD_GET_CTX
2925 (pHostapdAdapter))->config->force_sap_acs;
2926 break;
2927
2928 case QCSAP_PARAM_GET_WLAN_DBG:
2929 {
2930 cdf_trace_display();
2931 *value = 0;
2932 break;
2933 }
2934
2935 case QCSAP_PARAM_RTSCTS:
2936 {
2937 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
2938 WMI_VDEV_PARAM_ENABLE_RTSCTS,
2939 VDEV_CMD);
2940 break;
2941 }
2942
2943 case QCASAP_SHORT_GI:
2944 {
2945 *value = (int)sme_get_ht_config(hHal,
2946 pHostapdAdapter->
2947 sessionId,
2948 WNI_CFG_HT_CAP_INFO_SHORT_GI_20MHZ);
2949 break;
2950 }
2951
2952 case QCSAP_GTX_HT_MCS:
2953 {
2954 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_HT_MCS");
2955 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
2956 WMI_VDEV_PARAM_GTX_HT_MCS,
2957 GTX_CMD);
2958 break;
2959 }
2960
2961 case QCSAP_GTX_VHT_MCS:
2962 {
2963 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_VHT_MCS");
2964 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
2965 WMI_VDEV_PARAM_GTX_VHT_MCS,
2966 GTX_CMD);
2967 break;
2968 }
2969
2970 case QCSAP_GTX_USRCFG:
2971 {
2972 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_USR_CFG");
2973 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
2974 WMI_VDEV_PARAM_GTX_USR_CFG,
2975 GTX_CMD);
2976 break;
2977 }
2978
2979 case QCSAP_GTX_THRE:
2980 {
2981 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_THRE");
2982 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
2983 WMI_VDEV_PARAM_GTX_THRE,
2984 GTX_CMD);
2985 break;
2986 }
2987
2988 case QCSAP_GTX_MARGIN:
2989 {
2990 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MARGIN");
2991 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
2992 WMI_VDEV_PARAM_GTX_MARGIN,
2993 GTX_CMD);
2994 break;
2995 }
2996
2997 case QCSAP_GTX_STEP:
2998 {
2999 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_STEP");
3000 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3001 WMI_VDEV_PARAM_GTX_STEP,
3002 GTX_CMD);
3003 break;
3004 }
3005
3006 case QCSAP_GTX_MINTPC:
3007 {
3008 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_MINTPC");
3009 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3010 WMI_VDEV_PARAM_GTX_MINTPC,
3011 GTX_CMD);
3012 break;
3013 }
3014
3015 case QCSAP_GTX_BWMASK:
3016 {
3017 hddLog(LOG1, "GET WMI_VDEV_PARAM_GTX_BW_MASK");
3018 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3019 WMI_VDEV_PARAM_GTX_BW_MASK,
3020 GTX_CMD);
3021 break;
3022 }
3023
3024 case QCASAP_GET_DFS_NOL:
3025 {
3026 wlansap_get_dfs_nol(
3027#ifdef WLAN_FEATURE_MBSSID
3028 WLAN_HDD_GET_SAP_CTX_PTR
3029 (pHostapdAdapter)
3030#else
3031 pHddCtx->pcds_context
3032#endif
3033 );
3034 }
3035 break;
3036
3037 case QCSAP_GET_ACL:
3038 {
3039 hddLog(LOG1, FL("QCSAP_GET_ACL"));
3040 if (hdd_print_acl(pHostapdAdapter) !=
3041 CDF_STATUS_SUCCESS) {
3042 hddLog(LOGE,
3043 FL
3044 ("QCSAP_GET_ACL returned Error: not completed"));
3045 }
3046 *value = 0;
3047 break;
3048 }
3049
3050 case QCASAP_TX_CHAINMASK_CMD:
3051 {
3052 hddLog(LOG1, "QCASAP_TX_CHAINMASK_CMD");
3053 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3054 WMI_PDEV_PARAM_TX_CHAIN_MASK,
3055 PDEV_CMD);
3056 break;
3057 }
3058
3059 case QCASAP_RX_CHAINMASK_CMD:
3060 {
3061 hddLog(LOG1, "QCASAP_RX_CHAINMASK_CMD");
3062 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3063 WMI_PDEV_PARAM_RX_CHAIN_MASK,
3064 PDEV_CMD);
3065 break;
3066 }
3067
3068 case QCASAP_NSS_CMD:
3069 {
3070 hddLog(LOG1, "QCASAP_NSS_CMD");
3071 *value = wma_cli_get_command(pHostapdAdapter->sessionId,
3072 WMI_VDEV_PARAM_NSS,
3073 VDEV_CMD);
3074 break;
3075 }
3076 case QCASAP_GET_TEMP_CMD:
3077 {
3078 hddLog(LOG1, "QCASAP_GET_TEMP_CMD");
3079 ret = wlan_hdd_get_temperature(pHostapdAdapter, value);
3080 break;
3081 }
Govind Singha471e5e2015-10-12 17:11:14 +05303082 case QCSAP_GET_FW_PROFILE_DATA:
3083 hddLog(LOG1, "QCSAP_GET_FW_PROFILE_DATA");
3084 ret = wma_cli_set_command(pHostapdAdapter->sessionId,
3085 WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID,
3086 0, DBG_CMD);
3087 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003088 default:
3089 hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd);
3090 ret = -EINVAL;
3091 break;
3092
3093 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303094 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003095 return ret;
3096}
3097
3098int
3099static iw_softap_getparam(struct net_device *dev,
3100 struct iw_request_info *info,
3101 union iwreq_data *wrqu, char *extra)
3102{
3103 int ret;
3104
3105 cds_ssr_protect(__func__);
3106 ret = __iw_softap_getparam(dev, info, wrqu, extra);
3107 cds_ssr_unprotect(__func__);
3108
3109 return ret;
3110}
3111
3112/* Usage:
3113 BLACK_LIST = 0
3114 WHITE_LIST = 1
3115 ADD MAC = 0
3116 REMOVE MAC = 1
3117
3118 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
3119 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
3120 while using this ioctl
3121
3122 Syntax:
3123 iwpriv softap.0 modify_acl
3124 <6 octet mac addr> <list type> <cmd type>
3125
3126 Examples:
3127 eg 1. to add a mac addr 00:0a:f5:89:89:90 to the black list
3128 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 0 0
3129 eg 2. to delete a mac addr 00:0a:f5:89:89:90 from white list
3130 iwpriv softap.0 modify_acl 0x00 0x0a 0xf5 0x89 0x89 0x90 1 1
3131 */
3132static
3133int __iw_softap_modify_acl(struct net_device *dev,
3134 struct iw_request_info *info,
3135 union iwreq_data *wrqu, char *extra)
3136{
3137 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3138#ifndef WLAN_FEATURE_MBSSID
3139 v_CONTEXT_t cds_ctx;
3140#endif
3141 uint8_t *value = (uint8_t *) extra;
3142 uint8_t pPeerStaMac[CDF_MAC_ADDR_SIZE];
3143 int listType, cmd, i;
3144 int ret;
3145 CDF_STATUS cdf_status = CDF_STATUS_SUCCESS;
3146 hdd_context_t *hdd_ctx;
3147
3148 ENTER();
3149
3150 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3151 ret = wlan_hdd_validate_context(hdd_ctx);
3152 if (0 != ret)
3153 return ret;
3154
3155#ifndef WLAN_FEATURE_MBSSID
3156 cds_ctx = hdd_ctx->pcds_context;
3157 if (NULL == cds_ctx) {
3158 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
3159 "%s: Vos Context is NULL", __func__);
3160 return -EINVAL;
3161 }
3162#endif
3163
3164 for (i = 0; i < CDF_MAC_ADDR_SIZE; i++)
3165 pPeerStaMac[i] = *(value + i);
3166
3167 listType = (int)(*(value + i));
3168 i++;
3169 cmd = (int)(*(value + i));
3170
3171 hddLog(LOG1, FL("Modify ACL mac:" MAC_ADDRESS_STR " type: %d cmd: %d"),
3172 MAC_ADDR_ARRAY(pPeerStaMac), listType, cmd);
3173
3174#ifdef WLAN_FEATURE_MBSSID
3175 cdf_status =
3176 wlansap_modify_acl(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
3177 pPeerStaMac, (eSapACLType) listType,
3178 (eSapACLCmdType) cmd);
3179#else
3180 cdf_status =
3181 wlansap_modify_acl(p_cds_context, pPeerStaMac,
3182 (eSapACLType) listType, (eSapACLCmdType) cmd);
3183#endif
3184 if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
3185 hddLog(LOGE, FL("Modify ACL failed"));
3186 ret = -EIO;
3187 }
3188 EXIT();
3189 return ret;
3190}
3191
3192static
3193int iw_softap_modify_acl(struct net_device *dev,
3194 struct iw_request_info *info,
3195 union iwreq_data *wrqu, char *extra)
3196{
3197 int ret;
3198
3199 cds_ssr_protect(__func__);
3200 ret = __iw_softap_modify_acl(dev, info, wrqu, extra);
3201 cds_ssr_unprotect(__func__);
3202
3203 return ret;
3204}
3205
3206int
3207static __iw_softap_getchannel(struct net_device *dev,
3208 struct iw_request_info *info,
3209 union iwreq_data *wrqu, char *extra)
3210{
3211 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3212 hdd_context_t *hdd_ctx;
3213 int *value = (int *)extra;
3214 int ret;
3215
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303216 ENTER();
3217
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003218 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3219 ret = wlan_hdd_validate_context(hdd_ctx);
3220 if (0 != ret)
3221 return ret;
3222
3223 *value = 0;
3224 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
3225 *value = (WLAN_HDD_GET_AP_CTX_PTR(
3226 pHostapdAdapter))->operatingChannel;
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303227 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003228 return 0;
3229}
3230
3231int
3232static iw_softap_getchannel(struct net_device *dev,
3233 struct iw_request_info *info,
3234 union iwreq_data *wrqu, char *extra)
3235{
3236 int ret;
3237
3238 cds_ssr_protect(__func__);
3239 ret = __iw_softap_getchannel(dev, info, wrqu, extra);
3240 cds_ssr_unprotect(__func__);
3241
3242 return ret;
3243}
3244
3245int
3246static __iw_softap_set_max_tx_power(struct net_device *dev,
3247 struct iw_request_info *info,
3248 union iwreq_data *wrqu, char *extra)
3249{
3250 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3251 hdd_context_t *hdd_ctx;
3252 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3253 int *value = (int *)extra;
3254 int set_value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003255 int ret;
Srinivas Girigowda97215232015-09-24 12:26:28 -07003256 struct cdf_mac_addr bssid = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
3257 struct cdf_mac_addr selfMac = CDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003258
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303259 ENTER();
3260
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003261 if (NULL == value)
3262 return -ENOMEM;
3263
3264 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3265 ret = wlan_hdd_validate_context(hdd_ctx);
3266 if (0 != ret)
3267 return ret;
3268
3269 /* Assign correct slef MAC address */
Srinivas Girigowda97215232015-09-24 12:26:28 -07003270 cdf_copy_macaddr(&bssid, &pHostapdAdapter->macAddressCurrent);
3271 cdf_copy_macaddr(&selfMac, &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003272
3273 set_value = value[0];
3274 if (CDF_STATUS_SUCCESS !=
3275 sme_set_max_tx_power(hHal, bssid, selfMac, set_value)) {
3276 hddLog(LOGE, FL("Setting maximum tx power failed"));
3277 return -EIO;
3278 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303279 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003280 return 0;
3281}
3282
3283int
3284static iw_softap_set_max_tx_power(struct net_device *dev,
3285 struct iw_request_info *info,
3286 union iwreq_data *wrqu, char *extra)
3287{
3288 int ret;
3289
3290 cds_ssr_protect(__func__);
3291 ret = __iw_softap_set_max_tx_power(dev, info, wrqu, extra);
3292 cds_ssr_unprotect(__func__);
3293
3294 return ret;
3295}
3296
3297int
3298static __iw_softap_set_tx_power(struct net_device *dev,
3299 struct iw_request_info *info,
3300 union iwreq_data *wrqu, char *extra)
3301{
3302 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3303 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3304 hdd_context_t *hdd_ctx;
3305 int *value = (int *)extra;
3306 int set_value;
Srinivas Girigowda97215232015-09-24 12:26:28 -07003307 struct cdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003308 int ret;
3309
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303310 ENTER();
3311
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003312 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3313 ret = wlan_hdd_validate_context(hdd_ctx);
3314 if (0 != ret)
3315 return ret;
3316
3317 if (NULL == value)
3318 return -ENOMEM;
3319
Srinivas Girigowda97215232015-09-24 12:26:28 -07003320 cdf_copy_macaddr(&bssid, &pHostapdAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003321
3322 set_value = value[0];
3323 if (CDF_STATUS_SUCCESS !=
3324 sme_set_tx_power(hHal, pHostapdAdapter->sessionId, bssid,
3325 pHostapdAdapter->device_mode, set_value)) {
3326 hddLog(LOGE, FL("Setting tx power failed"));
3327 return -EIO;
3328 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303329 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003330 return 0;
3331}
3332
3333int
3334static iw_softap_set_tx_power(struct net_device *dev,
3335 struct iw_request_info *info,
3336 union iwreq_data *wrqu, char *extra)
3337{
3338 int ret;
3339
3340 cds_ssr_protect(__func__);
3341 ret = __iw_softap_set_tx_power(dev, info, wrqu, extra);
3342 cds_ssr_unprotect(__func__);
3343
3344 return ret;
3345}
3346
3347#define IS_BROADCAST_MAC(x) (((x[0] & x[1] & x[2] & x[3] & x[4] & x[5]) == 0xff) ? 1 : 0)
3348
3349int
3350static __iw_softap_getassoc_stamacaddr(struct net_device *dev,
3351 struct iw_request_info *info,
3352 union iwreq_data *wrqu, char *extra)
3353{
3354 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3355 hdd_station_info_t *pStaInfo = pHostapdAdapter->aStaInfo;
3356 hdd_context_t *hdd_ctx;
3357 char *buf;
3358 int cnt = 0;
3359 int left;
3360 int ret;
3361 /* maclist_index must be u32 to match userspace */
3362 u32 maclist_index;
3363
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303364 ENTER();
3365
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003366 /*
3367 * NOTE WELL: this is a "get" ioctl but it uses an even ioctl
3368 * number, and even numbered iocts are supposed to have "set"
3369 * semantics. Hence the wireless extensions support in the kernel
3370 * won't correctly copy the result to userspace, so the ioctl
3371 * handler itself must copy the data. Output format is 32-bit
3372 * record length, followed by 0 or more 6-byte STA MAC addresses.
3373 *
3374 * Further note that due to the incorrect semantics, the "iwpriv"
3375 * userspace application is unable to correctly invoke this API,
3376 * hence it is not registered in the hostapd_private_args. This
3377 * API can only be invoked by directly invoking the ioctl() system
3378 * call.
3379 */
3380
3381 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3382 ret = wlan_hdd_validate_context(hdd_ctx);
3383 if (0 != ret)
3384 return ret;
3385
3386 /* make sure userspace allocated a reasonable buffer size */
3387 if (wrqu->data.length < sizeof(maclist_index)) {
3388 hddLog(LOG1, FL("invalid userspace buffer"));
3389 return -EINVAL;
3390 }
3391
3392 /* allocate local buffer to build the response */
3393 buf = kmalloc(wrqu->data.length, GFP_KERNEL);
3394 if (!buf) {
3395 hddLog(LOG1, FL("failed to allocate response buffer"));
3396 return -ENOMEM;
3397 }
3398
3399 /* start indexing beyond where the record count will be written */
3400 maclist_index = sizeof(maclist_index);
3401 left = wrqu->data.length - maclist_index;
3402
3403 spin_lock_bh(&pHostapdAdapter->staInfo_lock);
3404 while ((cnt < WLAN_MAX_STA_COUNT) && (left >= CDF_MAC_ADDR_SIZE)) {
3405 if ((pStaInfo[cnt].isUsed) &&
3406 (!IS_BROADCAST_MAC(pStaInfo[cnt].macAddrSTA.bytes))) {
3407 memcpy(&buf[maclist_index], &(pStaInfo[cnt].macAddrSTA),
3408 CDF_MAC_ADDR_SIZE);
3409 maclist_index += CDF_MAC_ADDR_SIZE;
3410 left -= CDF_MAC_ADDR_SIZE;
3411 }
3412 cnt++;
3413 }
3414 spin_unlock_bh(&pHostapdAdapter->staInfo_lock);
3415
3416 *((u32 *) buf) = maclist_index;
3417 wrqu->data.length = maclist_index;
3418 if (copy_to_user(wrqu->data.pointer, buf, maclist_index)) {
3419 hddLog(LOG1, FL("failed to copy response to user buffer"));
3420 ret = -EFAULT;
3421 }
3422 kfree(buf);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303423 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003424 return ret;
3425}
3426
3427int
3428static iw_softap_getassoc_stamacaddr(struct net_device *dev,
3429 struct iw_request_info *info,
3430 union iwreq_data *wrqu, char *extra)
3431{
3432 int ret;
3433
3434 cds_ssr_protect(__func__);
3435 ret = __iw_softap_getassoc_stamacaddr(dev, info, wrqu, extra);
3436 cds_ssr_unprotect(__func__);
3437
3438 return ret;
3439}
3440
3441/* Usage:
3442 mac addr will be accepted as a 6 octet mac address with each octet inputted in hex
3443 for e.g. 00:0a:f5:11:22:33 will be represented as 0x00 0x0a 0xf5 0x11 0x22 0x33
3444 while using this ioctl
3445
3446 Syntax:
3447 iwpriv softap.0 disassoc_sta <6 octet mac address>
3448
3449 e.g.
3450 disassociate sta with mac addr 00:0a:f5:11:22:33 from softap
3451 iwpriv softap.0 disassoc_sta 0x00 0x0a 0xf5 0x11 0x22 0x33
3452 */
3453
3454int
3455static __iw_softap_disassoc_sta(struct net_device *dev,
3456 struct iw_request_info *info,
3457 union iwreq_data *wrqu, char *extra)
3458{
3459 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3460 hdd_context_t *hdd_ctx;
3461 uint8_t *peerMacAddr;
3462 int ret;
3463
3464 ENTER();
3465
Mukul Sharma744420f2015-11-02 19:49:13 +05303466 if (!capable(CAP_NET_ADMIN)) {
3467 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
3468 FL("permission check failed"));
3469 return -EPERM;
3470 }
3471
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003472 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3473 ret = wlan_hdd_validate_context(hdd_ctx);
3474 if (0 != ret)
3475 return ret;
3476
3477 /* iwpriv tool or framework calls this ioctl with
3478 * data passed in extra (less than 16 octets);
3479 */
3480 peerMacAddr = (uint8_t *) (extra);
3481
3482 hddLog(LOG1, FL("data " MAC_ADDRESS_STR),
3483 MAC_ADDR_ARRAY(peerMacAddr));
3484 hdd_softap_sta_disassoc(pHostapdAdapter, peerMacAddr);
3485 EXIT();
3486 return 0;
3487}
3488
3489int
3490static iw_softap_disassoc_sta(struct net_device *dev,
3491 struct iw_request_info *info,
3492 union iwreq_data *wrqu, char *extra)
3493{
3494 int ret;
3495
3496 cds_ssr_protect(__func__);
3497 ret = __iw_softap_disassoc_sta(dev, info, wrqu, extra);
3498 cds_ssr_unprotect(__func__);
3499
3500 return ret;
3501}
3502
Govind Singha471e5e2015-10-12 17:11:14 +05303503/**
3504 * iw_get_char_setnone() - Generic "get char" private ioctl handler
3505 * @dev: device upon which the ioctl was received
3506 * @info: ioctl request information
3507 * @wrqu: ioctl request data
3508 * @extra: ioctl extra data
3509 *
3510 * Return: 0 on success, non-zero on error
3511 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003512static int __iw_get_char_setnone(struct net_device *dev,
3513 struct iw_request_info *info,
3514 union iwreq_data *wrqu, char *extra)
3515{
3516 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Govind Singha471e5e2015-10-12 17:11:14 +05303517 int ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003518 int sub_cmd = wrqu->data.flags;
3519 hdd_context_t *hdd_ctx;
3520
3521 ENTER();
3522
3523 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Govind Singha471e5e2015-10-12 17:11:14 +05303524 ret = wlan_hdd_validate_context(hdd_ctx);
3525 if (ret != 0)
3526 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003527
3528 switch (sub_cmd) {
3529 case QCSAP_GET_STATS:
3530 hdd_wlan_get_stats(adapter, &(wrqu->data.length),
3531 extra, WE_MAX_STR_LEN);
3532 break;
Govind Singha471e5e2015-10-12 17:11:14 +05303533 case QCSAP_LIST_FW_PROFILE:
3534 hdd_wlan_list_fw_profile(&(wrqu->data.length),
3535 extra, WE_MAX_STR_LEN);
3536 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003537 }
3538
3539 EXIT();
Govind Singha471e5e2015-10-12 17:11:14 +05303540 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003541}
3542
3543static int iw_get_char_setnone(struct net_device *dev,
3544 struct iw_request_info *info,
3545 union iwreq_data *wrqu, char *extra)
3546{
3547 int ret;
3548
3549 cds_ssr_protect(__func__);
3550 ret = __iw_get_char_setnone(dev, info, wrqu, extra);
3551 cds_ssr_unprotect(__func__);
3552
3553 return ret;
3554}
3555
3556static int wlan_hdd_set_force_acs_ch_range(struct net_device *dev,
3557 struct iw_request_info *info,
3558 union iwreq_data *wrqu, char *extra)
3559{
3560 hdd_adapter_t *adapter = (netdev_priv(dev));
3561 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3562 int *value = (int *)extra;
3563
Hanumantha Reddy Pothula3b8c0a52015-11-05 10:59:21 +05303564 if (!capable(CAP_NET_ADMIN)) {
3565 hddLog(LOGE, FL("permission check failed"));
3566 return -EPERM;
3567 }
3568
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003569 if (wlan_hdd_validate_operation_channel(adapter, value[0]) !=
3570 CDF_STATUS_SUCCESS ||
3571 wlan_hdd_validate_operation_channel(adapter, value[1]) !=
3572 CDF_STATUS_SUCCESS) {
3573 return -EINVAL;
3574 } else {
3575 hdd_ctx->config->force_sap_acs_st_ch = value[0];
3576 hdd_ctx->config->force_sap_acs_end_ch = value[1];
3577 }
3578
3579 return 0;
3580}
3581
3582static int iw_softap_set_force_acs_ch_range(struct net_device *dev,
3583 struct iw_request_info *info,
3584 union iwreq_data *wrqu, char *extra)
3585{
3586 int ret;
3587 cds_ssr_protect(__func__);
3588 ret = wlan_hdd_set_force_acs_ch_range(dev, info, wrqu, extra);
3589 cds_ssr_unprotect(__func__);
3590 return ret;
3591}
3592
3593static int __iw_softap_get_channel_list(struct net_device *dev,
3594 struct iw_request_info *info,
3595 union iwreq_data *wrqu, char *extra)
3596{
3597 uint32_t num_channels = 0;
3598 uint8_t i = 0;
3599 uint8_t bandStartChannel = RF_CHAN_1;
3600 uint8_t bandEndChannel = RF_CHAN_184;
3601 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3602 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
3603 tpChannelListInfo channel_list = (tpChannelListInfo) extra;
3604 eCsrBand curBand = eCSR_BAND_ALL;
3605 hdd_context_t *hdd_ctx;
3606 int ret;
3607
3608 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3609 ret = wlan_hdd_validate_context(hdd_ctx);
3610 if (0 != ret)
3611 return ret;
3612
3613 if (CDF_STATUS_SUCCESS != sme_get_freq_band(hHal, &curBand)) {
3614 hddLog(LOGE, FL("not able get the current frequency band"));
3615 return -EIO;
3616 }
3617 wrqu->data.length = sizeof(tChannelListInfo);
3618 ENTER();
3619
3620 if (eCSR_BAND_24 == curBand) {
3621 bandStartChannel = RF_CHAN_1;
3622 bandEndChannel = RF_CHAN_14;
3623 } else if (eCSR_BAND_5G == curBand) {
3624 bandStartChannel = RF_CHAN_36;
3625 bandEndChannel = RF_CHAN_184;
3626 }
3627
3628 hddLog(LOG1, FL("curBand = %d, StartChannel = %hu, EndChannel = %hu "),
3629 curBand, bandStartChannel, bandEndChannel);
3630
3631 for (i = bandStartChannel; i <= bandEndChannel; i++) {
Amar Singhal7a1726a2015-10-14 16:28:11 -07003632 if ((CHANNEL_STATE_ENABLE == CDS_CHANNEL_STATE(i)) ||
3633 (CHANNEL_STATE_DFS == CDS_CHANNEL_STATE(i))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003634 channel_list->channels[num_channels] =
Amar Singhal7a1726a2015-10-14 16:28:11 -07003635 CDS_CHANNEL_NUM(i);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003636 num_channels++;
3637 }
3638 }
3639
3640 hddLog(LOG1, FL(" number of channels %d"), num_channels);
3641
3642 if (num_channels > IW_MAX_FREQUENCIES) {
3643 num_channels = IW_MAX_FREQUENCIES;
3644 }
3645
3646 channel_list->num_channels = num_channels;
3647 EXIT();
3648
3649 return 0;
3650}
3651
3652int iw_softap_get_channel_list(struct net_device *dev,
3653 struct iw_request_info *info,
3654 union iwreq_data *wrqu, char *extra)
3655{
3656 int ret;
3657
3658 cds_ssr_protect(__func__);
3659 ret = __iw_softap_get_channel_list(dev, info, wrqu, extra);
3660 cds_ssr_unprotect(__func__);
3661
3662 return ret;
3663}
3664
3665static
3666int __iw_get_genie(struct net_device *dev,
3667 struct iw_request_info *info,
3668 union iwreq_data *wrqu, char *extra)
3669{
3670 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3671 hdd_context_t *hdd_ctx;
3672 int ret;
3673#ifndef WLAN_FEATURE_MBSSID
3674 v_CONTEXT_t cds_ctx;
3675#endif
3676 CDF_STATUS status;
3677 uint32_t length = DOT11F_IE_RSN_MAX_LEN;
3678 uint8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
3679
3680 ENTER();
3681
3682 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3683 ret = wlan_hdd_validate_context(hdd_ctx);
3684 if (0 != ret)
3685 return ret;
3686
3687#ifndef WLAN_FEATURE_MBSSID
3688 cds_ctx = hdd_ctx->pcds_context;
3689 if (NULL == cds_ctx) {
3690 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
3691 "%s: vos context is not valid ", __func__);
3692 return -EINVAL;
3693 }
3694#endif
3695
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003696 /*
3697 * Actually retrieve the RSN IE from CSR.
3698 * (We previously sent it down in the CSR Roam Profile.)
3699 */
3700 status = wlan_sap_getstation_ie_information(
3701#ifdef WLAN_FEATURE_MBSSID
3702 WLAN_HDD_GET_SAP_CTX_PTR
3703 (pHostapdAdapter),
3704#else
3705 cds_ctx,
3706#endif
3707 &length, genIeBytes);
3708 if (status == CDF_STATUS_SUCCESS) {
3709 length = CDF_MIN(length, DOT11F_IE_RSN_MAX_LEN);
3710 if (wrqu->data.length < length ||
3711 copy_to_user(wrqu->data.pointer, (void *)genIeBytes, length)) {
3712 hddLog(LOG1, FL("failed to copy data to user buffer"));
3713 return -EFAULT;
3714 }
3715 wrqu->data.length = length;
3716 hddLog(LOG1, FL(" RSN IE of %d bytes returned"),
3717 wrqu->data.length);
3718 } else {
3719 wrqu->data.length = 0;
3720 hddLog(LOG1, FL(" RSN IE failed to populate"));
3721 }
3722
3723 EXIT();
3724 return 0;
3725}
3726
3727static
3728int iw_get_genie(struct net_device *dev,
3729 struct iw_request_info *info,
3730 union iwreq_data *wrqu, char *extra)
3731{
3732 int ret;
3733
3734 cds_ssr_protect(__func__);
3735 ret = __iw_get_genie(dev, info, wrqu, extra);
3736 cds_ssr_unprotect(__func__);
3737
3738 return ret;
3739}
3740
3741static
3742int __iw_get_wpspbc_probe_req_ies(struct net_device *dev,
3743 struct iw_request_info *info,
3744 union iwreq_data *wrqu, char *extra)
3745{
3746 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3747 sQcSapreq_WPSPBCProbeReqIES_t WPSPBCProbeReqIEs;
3748 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
3749 hdd_context_t *hdd_ctx;
3750 int ret;
3751
3752 ENTER();
3753
3754 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3755 ret = wlan_hdd_validate_context(hdd_ctx);
3756 if (0 != ret)
3757 return ret;
3758
3759 hddLog(LOG1, FL("get_WPSPBCProbeReqIEs ioctl"));
3760 memset((void *)&WPSPBCProbeReqIEs, 0, sizeof(WPSPBCProbeReqIEs));
3761
3762 WPSPBCProbeReqIEs.probeReqIELen =
3763 pHddApCtx->WPSPBCProbeReq.probeReqIELen;
3764 cdf_mem_copy(&WPSPBCProbeReqIEs.probeReqIE,
3765 pHddApCtx->WPSPBCProbeReq.probeReqIE,
3766 WPSPBCProbeReqIEs.probeReqIELen);
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08003767 cdf_copy_macaddr(&WPSPBCProbeReqIEs.macaddr,
3768 &pHddApCtx->WPSPBCProbeReq.peer_macaddr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003769 if (copy_to_user(wrqu->data.pointer,
3770 (void *)&WPSPBCProbeReqIEs,
3771 sizeof(WPSPBCProbeReqIEs))) {
3772 hddLog(LOG1, FL("failed to copy data to user buffer"));
3773 return -EFAULT;
3774 }
3775 wrqu->data.length = 12 + WPSPBCProbeReqIEs.probeReqIELen;
Srinivas Girigowdaaab80e72015-11-24 14:30:37 -08003776 hdd_info("Macaddress : " MAC_ADDRESS_STR,
3777 MAC_ADDR_ARRAY(WPSPBCProbeReqIEs.macaddr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003778 up(&pHddApCtx->semWpsPBCOverlapInd);
3779 EXIT();
3780 return 0;
3781}
3782
3783static
3784int iw_get_wpspbc_probe_req_ies(struct net_device *dev,
3785 struct iw_request_info *info,
3786 union iwreq_data *wrqu, char *extra)
3787{
3788 int ret;
3789
3790 cds_ssr_protect(__func__);
3791 ret = __iw_get_wpspbc_probe_req_ies(dev, info, wrqu, extra);
3792 cds_ssr_unprotect(__func__);
3793
3794 return ret;
3795}
3796
3797/**
3798 * __iw_set_auth_hostap() -
3799 * This function sets the auth type received from the wpa_supplicant.
3800 *
3801 * @dev: pointer to the net device.
3802 * @info: pointer to the iw_request_info.
3803 * @wrqu: pointer to the iwreq_data.
3804 * @extra: pointer to the data.
3805 *
3806 * Return: 0 for success, non zero for failure
3807 */
3808static
3809int __iw_set_auth_hostap(struct net_device *dev, struct iw_request_info *info,
3810 union iwreq_data *wrqu, char *extra)
3811{
3812 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3813 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3814 hdd_context_t *hdd_ctx;
3815 int ret;
3816
3817 ENTER();
3818
3819 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
3820 ret = wlan_hdd_validate_context(hdd_ctx);
3821 if (0 != ret)
3822 return ret;
3823
3824 switch (wrqu->param.flags & IW_AUTH_INDEX) {
3825 case IW_AUTH_TKIP_COUNTERMEASURES:
3826 {
3827 if (wrqu->param.value) {
3828 hddLog(LOG2,
3829 "Counter Measure started %d", wrqu->param.value);
3830 pWextState->mTKIPCounterMeasures =
3831 TKIP_COUNTER_MEASURE_STARTED;
3832 } else {
3833 hddLog(LOG2,
3834 "Counter Measure stopped=%d", wrqu->param.value);
3835 pWextState->mTKIPCounterMeasures =
3836 TKIP_COUNTER_MEASURE_STOPED;
3837 }
3838
3839 hdd_softap_tkip_mic_fail_counter_measure(pAdapter,
3840 wrqu->param.
3841 value);
3842 }
3843 break;
3844
3845 default:
3846
3847 hddLog(LOGW, FL("called with unsupported auth type %d"),
3848 wrqu->param.flags & IW_AUTH_INDEX);
3849 break;
3850 }
3851
3852 EXIT();
3853 return 0;
3854}
3855
3856/**
3857 * iw_set_auth_hostap() - Wrapper function to protect __iw_set_auth_hostap
3858 * from the SSR.
3859 *
3860 * @dev - Pointer to the net device.
3861 * @info - Pointer to the iw_request_info.
3862 * @wrqu - Pointer to the iwreq_data.
3863 * @extra - Pointer to the data.
3864 *
3865 * Return: 0 for success, non zero for failure.
3866 */
3867static int
3868iw_set_auth_hostap(struct net_device *dev,
3869 struct iw_request_info *info,
3870 union iwreq_data *wrqu, char *extra)
3871{
3872 int ret;
3873
3874 cds_ssr_protect(__func__);
3875 ret = __iw_set_auth_hostap(dev, info, wrqu, extra);
3876 cds_ssr_unprotect(__func__);
3877
3878 return ret;
3879}
3880
3881/**
3882 * __iw_set_ap_encodeext() - set ap encode
3883 *
3884 * @dev - Pointer to the net device.
3885 * @info - Pointer to the iw_request_info.
3886 * @wrqu - Pointer to the iwreq_data.
3887 * @extra - Pointer to the data.
3888 *
3889 * Return: 0 for success, non zero for failure.
3890 */
3891static int __iw_set_ap_encodeext(struct net_device *dev,
3892 struct iw_request_info *info,
3893 union iwreq_data *wrqu, char *extra)
3894{
3895 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
3896#ifndef WLAN_FEATURE_MBSSID
3897 v_CONTEXT_t cds_ctx;
3898#endif
3899 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
3900 hdd_context_t *hdd_ctx;
3901 int ret;
3902 CDF_STATUS vstatus;
3903 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
3904 int key_index;
3905 struct iw_point *encoding = &wrqu->encoding;
3906 tCsrRoamSetKey setKey;
3907 int i;
3908
3909 ENTER();
3910
3911 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
3912 ret = wlan_hdd_validate_context(hdd_ctx);
3913 if (0 != ret)
3914 return ret;
3915
3916#ifndef WLAN_FEATURE_MBSSID
3917 cds_ctx = hdd_ctx->pcds_context;
3918 if (NULL == cds_ctx) {
3919 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
3920 "%s: pVosContext is NULL", __func__);
3921 return -EINVAL;
3922 }
3923#endif
3924
3925 key_index = encoding->flags & IW_ENCODE_INDEX;
3926
3927 if (key_index > 0) {
3928 /*Convert from 1-based to 0-based keying */
3929 key_index--;
3930 }
3931 if (!ext->key_len)
3932 return ret;
3933
3934 cdf_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
3935
3936 setKey.keyId = key_index;
3937 setKey.keyLength = ext->key_len;
3938
3939 if (ext->key_len <= CSR_MAX_KEY_LEN) {
3940 cdf_mem_copy(&setKey.Key[0], ext->key, ext->key_len);
3941 }
3942
3943 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
3944 /*Key direction for group is RX only */
3945 setKey.keyDirection = eSIR_RX_ONLY;
3946 cdf_set_macaddr_broadcast(&setKey.peerMac);
3947 } else {
3948
3949 setKey.keyDirection = eSIR_TX_RX;
3950 cdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
3951 CDF_MAC_ADDR_SIZE);
3952 }
3953 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
3954 setKey.keyDirection = eSIR_TX_DEFAULT;
3955 cdf_mem_copy(setKey.peerMac.bytes, ext->addr.sa_data,
3956 CDF_MAC_ADDR_SIZE);
3957 }
3958
3959 /*For supplicant pae role is zero */
3960 setKey.paeRole = 0;
3961
3962 switch (ext->alg) {
3963 case IW_ENCODE_ALG_NONE:
3964 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3965 break;
3966
3967 case IW_ENCODE_ALG_WEP:
3968 setKey.encType =
3969 (ext->key_len ==
3970 5) ? eCSR_ENCRYPT_TYPE_WEP40 : eCSR_ENCRYPT_TYPE_WEP104;
3971 pHddApCtx->uPrivacy = 1;
3972 hddLog(LOG1, FL("uPrivacy=%d"), pHddApCtx->uPrivacy);
3973 break;
3974
3975 case IW_ENCODE_ALG_TKIP:
3976 {
3977 uint8_t *pKey = &setKey.Key[0];
3978
3979 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3980
3981 cdf_mem_zero(pKey, CSR_MAX_KEY_LEN);
3982
3983 /*Supplicant sends the 32bytes key in this order
3984
3985 |--------------|----------|----------|
3986 | Tk1 |TX-MIC | RX Mic |
3987 |||--------------|----------|----------|
3988 <---16bytes---><--8bytes--><--8bytes-->
3989
3990 */
3991 /*Sme expects the 32 bytes key to be in the below order
3992
3993 |--------------|----------|----------|
3994 | Tk1 |RX-MIC | TX Mic |
3995 |||--------------|----------|----------|
3996 <---16bytes---><--8bytes--><--8bytes-->
3997 */
3998 /* Copy the Temporal Key 1 (TK1) */
3999 cdf_mem_copy(pKey, ext->key, 16);
4000
4001 /*Copy the rx mic first */
4002 cdf_mem_copy(&pKey[16], &ext->key[24], 8);
4003
4004 /*Copy the tx mic */
4005 cdf_mem_copy(&pKey[24], &ext->key[16], 8);
4006
4007 }
4008 break;
4009
4010 case IW_ENCODE_ALG_CCMP:
4011 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
4012 break;
4013
4014 default:
4015 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
4016 break;
4017 }
4018
4019 hddLog(LOG1, FL(":EncryptionType:%d key_len:%d, KeyId:%d"),
4020 setKey.encType, setKey.keyLength, setKey.keyId);
4021 for (i = 0; i < ext->key_len; i++)
4022 hddLog(LOG1, "%02x", setKey.Key[i]);
4023
4024#ifdef WLAN_FEATURE_MBSSID
4025 vstatus =
4026 wlansap_set_key_sta(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
4027 &setKey);
4028#else
4029 vstatus = wlansap_set_key_sta(cds_ctx, &setKey);
4030#endif
4031
4032 if (vstatus != CDF_STATUS_SUCCESS) {
4033 hddLog(LOGE, FL("wlansap_set_key_sta failed, status= %d"),
4034 vstatus);
4035 ret = -EINVAL;
4036 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304037 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004038 return ret;
4039}
4040
4041/**
4042 * iw_set_ap_encodeext() - Wrapper function to protect __iw_set_ap_encodeext
4043 * from the SSR.
4044 *
4045 * @dev - Pointer to the net device.
4046 * @info - Pointer to the iw_request_info.
4047 * @wrqu - Pointer to the iwreq_data.
4048 * @extra - Pointer to the data.
4049 *
4050 * Return: 0 for success, non zero for failure.
4051 */
4052static int iw_set_ap_encodeext(struct net_device *dev,
4053 struct iw_request_info *info,
4054 union iwreq_data *wrqu, char *extra)
4055{
4056 int ret;
4057
4058 cds_ssr_protect(__func__);
4059 ret = __iw_set_ap_encodeext(dev, info, wrqu, extra);
4060 cds_ssr_unprotect(__func__);
4061
4062 return ret;
4063}
4064
4065/**
4066 * __iw_set_ap_mlme() - set ap mlme
4067 * @dev: pointer to net_device
4068 * @info: pointer to iw_request_info
4069 * @wrqu; pointer to iwreq_data
4070 * @extra: extra
4071 *
4072 * Return; 0 on success, error number otherwise
4073 */
4074static int __iw_set_ap_mlme(struct net_device *dev,
4075 struct iw_request_info *info,
4076 union iwreq_data *wrqu, char *extra)
4077{
4078 return 0;
4079}
4080
4081/**
4082 * iw_set_ap_mlme() - SSR wrapper for __iw_set_ap_mlme
4083 * @dev: pointer to net_device
4084 * @info: pointer to iw_request_info
4085 * @wrqu; pointer to iwreq_data
4086 * @extra: extra
4087 *
4088 * Return; 0 on success, error number otherwise
4089 */
4090static int iw_set_ap_mlme(struct net_device *dev,
4091 struct iw_request_info *info,
4092 union iwreq_data *wrqu,
4093 char *extra)
4094{
4095 int ret;
4096
4097 cds_ssr_protect(__func__);
4098 ret = __iw_set_ap_mlme(dev, info, wrqu, extra);
4099 cds_ssr_unprotect(__func__);
4100
4101 return ret;
4102}
4103
4104/**
4105 * __iw_get_ap_rts_threshold() - get ap rts threshold
4106 * @dev - Pointer to the net device.
4107 * @info - Pointer to the iw_request_info.
4108 * @wrqu - Pointer to the iwreq_data.
4109 * @extra - Pointer to the data.
4110 *
4111 * Return: 0 for success, non zero for failure.
4112 */
4113static int __iw_get_ap_rts_threshold(struct net_device *dev,
4114 struct iw_request_info *info,
4115 union iwreq_data *wrqu, char *extra) {
4116
4117 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
4118 int ret;
4119 hdd_context_t *hdd_ctx;
4120
4121 ENTER();
4122
4123 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4124 ret = wlan_hdd_validate_context(hdd_ctx);
4125 if (0 != ret)
4126 return ret;
4127 ret = hdd_wlan_get_rts_threshold(pHostapdAdapter, wrqu);
4128
4129 return ret;
4130}
4131
4132/**
4133 * iw_get_ap_rts_threshold() - Wrapper function to protect
4134 * __iw_get_ap_rts_threshold from the SSR.
4135 * @dev - Pointer to the net device.
4136 * @info - Pointer to the iw_request_info.
4137 * @wrqu - Pointer to the iwreq_data.
4138 * @extra - Pointer to the data.
4139 *
4140 * Return: 0 for success, non zero for failure.
4141 */
4142static int iw_get_ap_rts_threshold(struct net_device *dev,
4143 struct iw_request_info *info,
4144 union iwreq_data *wrqu, char *extra)
4145{
4146 int ret;
4147
4148 cds_ssr_protect(__func__);
4149 ret = __iw_get_ap_rts_threshold(dev, info, wrqu, extra);
4150 cds_ssr_unprotect(__func__);
4151
4152 return ret;
4153}
4154
4155/**
4156 * __iw_get_ap_frag_threshold() - get ap fragmentation threshold
4157 * @dev - Pointer to the net device.
4158 * @info - Pointer to the iw_request_info.
4159 * @wrqu - Pointer to the iwreq_data.
4160 * @extra - Pointer to the data.
4161 *
4162 * Return: 0 for success, non zero for failure.
4163 */
4164static int __iw_get_ap_frag_threshold(struct net_device *dev,
4165 struct iw_request_info *info,
4166 union iwreq_data *wrqu, char *extra) {
4167
4168 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
4169 hdd_context_t *hdd_ctx;
4170 int ret = 0;
4171
4172 ENTER();
4173
4174 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4175 ret = wlan_hdd_validate_context(hdd_ctx);
4176 if (0 != ret)
4177 return ret;
4178
4179 ret = hdd_wlan_get_frag_threshold(pHostapdAdapter, wrqu);
4180
4181 return ret;
4182}
4183
4184/**
4185 * iw_get_ap_frag_threshold() - Wrapper function to protect
4186 * __iw_get_ap_frag_threshold from the SSR.
4187 * @dev - Pointer to the net device.
4188 * @info - Pointer to the iw_request_info.
4189 * @wrqu - Pointer to the iwreq_data.
4190 * @extra - Pointer to the data.
4191 *
4192 * Return: 0 for success, non zero for failure.
4193 */
4194static int iw_get_ap_frag_threshold(struct net_device *dev,
4195 struct iw_request_info *info,
4196 union iwreq_data *wrqu, char *extra)
4197{
4198 int ret;
4199
4200 cds_ssr_protect(__func__);
4201 ret = __iw_get_ap_frag_threshold(dev, info, wrqu, extra);
4202 cds_ssr_unprotect(__func__);
4203
4204 return ret;
4205}
4206
4207/**
4208 * __iw_get_ap_freq() - get ap frequency
4209 * @dev - Pointer to the net device.
4210 * @info - Pointer to the iw_request_info.
4211 * @wrqu - Pointer to the iwreq_data.
4212 * @extra - Pointer to the data.
4213 *
4214 * Return: 0 for success, non zero for failure.
4215 */
4216static int __iw_get_ap_freq(struct net_device *dev,
4217 struct iw_request_info *info, struct iw_freq *fwrq,
4218 char *extra) {
4219 uint32_t status = false, channel = 0, freq = 0;
4220 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4221 hdd_context_t *hdd_ctx;
4222 tHalHandle hHal;
4223 hdd_hostapd_state_t *pHostapdState;
4224 hdd_ap_ctx_t *pHddApCtx = WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter);
4225 int ret;
4226
4227 ENTER();
4228
4229 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4230 ret = wlan_hdd_validate_context(hdd_ctx);
4231 if (0 != ret)
4232 return ret;
4233
4234 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
4235 hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
4236
4237 if (pHostapdState->bssState == BSS_STOP) {
4238 if (sme_cfg_get_int(hHal, WNI_CFG_CURRENT_CHANNEL, &channel)
4239 != CDF_STATUS_SUCCESS) {
4240 return -EIO;
4241 } else {
4242 status = hdd_wlan_get_freq(channel, &freq);
4243 if (true == status) {
4244 /* Set Exponent parameter as 6 (MHZ) in struct
4245 * iw_freq * iwlist & iwconfig command
4246 * shows frequency into proper
4247 * format (2.412 GHz instead of 246.2 MHz)
4248 */
4249 fwrq->m = freq;
4250 fwrq->e = MHZ;
4251 }
4252 }
4253 } else {
4254 channel = pHddApCtx->operatingChannel;
4255 status = hdd_wlan_get_freq(channel, &freq);
4256 if (true == status) {
4257 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
4258 * iwlist & iwconfig command shows frequency into proper
4259 * format (2.412 GHz instead of 246.2 MHz)*/
4260 fwrq->m = freq;
4261 fwrq->e = MHZ;
4262 }
4263 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05304264 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004265 return 0;
4266}
4267
4268/**
4269 * iw_get_ap_freq() - Wrapper function to protect
4270 * __iw_get_ap_freq from the SSR.
4271 * @dev - Pointer to the net device.
4272 * @info - Pointer to the iw_request_info.
4273 * @wrqu - Pointer to the iwreq_data.
4274 * @extra - Pointer to the data.
4275 *
4276 * Return: 0 for success, non zero for failure.
4277 */
4278static int iw_get_ap_freq(struct net_device *dev,
4279 struct iw_request_info *info,
4280 struct iw_freq *wrqu, char *extra)
4281{
4282 int ret;
4283
4284 cds_ssr_protect(__func__);
4285 ret = __iw_get_ap_freq(dev, info, wrqu, extra);
4286 cds_ssr_unprotect(__func__);
4287
4288 return ret;
4289}
4290
4291/**
4292 * __iw_get_mode() - get mode
4293 * @dev - Pointer to the net device.
4294 * @info - Pointer to the iw_request_info.
4295 * @wrqu - Pointer to the iwreq_data.
4296 * @extra - Pointer to the data.
4297 *
4298 * Return: 0 for success, non zero for failure.
4299 */
4300static int __iw_get_mode(struct net_device *dev,
4301 struct iw_request_info *info,
4302 union iwreq_data *wrqu, char *extra) {
4303
4304 hdd_adapter_t *adapter;
4305 hdd_context_t *hdd_ctx;
4306 int ret;
4307
4308 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4309 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4310 ret = wlan_hdd_validate_context(hdd_ctx);
4311 if (0 != ret)
4312 return ret;
4313
4314 wrqu->mode = IW_MODE_MASTER;
4315
4316 return ret;
4317}
4318
4319/**
4320 * iw_get_mode() - Wrapper function to protect __iw_get_mode from the SSR.
4321 * @dev - Pointer to the net device.
4322 * @info - Pointer to the iw_request_info.
4323 * @wrqu - Pointer to the iwreq_data.
4324 * @extra - Pointer to the data.
4325 *
4326 * Return: 0 for success, non zero for failure.
4327 */
4328static int iw_get_mode(struct net_device *dev,
4329 struct iw_request_info *info,
4330 union iwreq_data *wrqu, char *extra)
4331{
4332 int ret;
4333
4334 cds_ssr_protect(__func__);
4335 ret = __iw_get_mode(dev, info, wrqu, extra);
4336 cds_ssr_unprotect(__func__);
4337
4338 return ret;
4339}
4340
4341static int
4342__iw_softap_setwpsie(struct net_device *dev,
4343 struct iw_request_info *info,
4344 union iwreq_data *wrqu, char *extra)
4345{
4346 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4347#ifndef WLAN_FEATURE_MBSSID
4348 v_CONTEXT_t cds_ctx;
4349#endif
4350 hdd_hostapd_state_t *pHostapdState;
4351 CDF_STATUS cdf_ret_status = CDF_STATUS_SUCCESS;
4352 uint8_t *wps_genie;
4353 uint8_t *fwps_genie;
4354 uint8_t *pos;
4355 tpSap_WPSIE pSap_WPSIe;
4356 uint8_t WPSIeType;
4357 uint16_t length;
4358 struct iw_point s_priv_data;
4359 hdd_context_t *hdd_ctx;
4360 int ret;
4361
4362 ENTER();
4363
Mukul Sharmaa42b0622015-11-02 19:57:31 +05304364 if (!capable(CAP_NET_ADMIN)) {
4365 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
4366 FL("permission check failed"));
4367 return -EPERM;
4368 }
4369
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004370 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4371 ret = wlan_hdd_validate_context(hdd_ctx);
4372 if (0 != ret)
4373 return ret;
4374
4375#ifndef WLAN_FEATURE_MBSSID
4376 cds_ctx = hdd_ctx->pcds_context;
4377 if (NULL == cds_ctx) {
4378 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
4379 "%s: HDD context is not valid ", __func__);
4380 return -EINVAL;
4381 }
4382#endif
4383
4384 /* helper function to get iwreq_data with compat handling. */
4385 if (hdd_priv_get_data(&s_priv_data, wrqu)) {
4386 return -EINVAL;
4387 }
4388
4389 if ((NULL == s_priv_data.pointer) ||
4390 (s_priv_data.length < QCSAP_MAX_WSC_IE)) {
4391 return -EINVAL;
4392 }
4393
4394 wps_genie = mem_alloc_copy_from_user_helper(s_priv_data.pointer,
4395 s_priv_data.length);
4396
4397 if (NULL == wps_genie) {
4398 hddLog(LOG1, FL("failed to alloc mem and copy data"));
4399 return -EFAULT;
4400 }
4401
4402 fwps_genie = wps_genie;
4403
4404 pSap_WPSIe = cdf_mem_malloc(sizeof(tSap_WPSIE));
4405 if (NULL == pSap_WPSIe) {
4406 hddLog(LOGE, "CDF unable to allocate memory");
4407 kfree(fwps_genie);
4408 return -ENOMEM;
4409 }
4410 cdf_mem_zero(pSap_WPSIe, sizeof(tSap_WPSIE));
4411
4412 hddLog(LOG1, FL("WPS IE type[0x%X] IE[0x%X], LEN[%d]"),
4413 wps_genie[0], wps_genie[1], wps_genie[2]);
4414 WPSIeType = wps_genie[0];
4415 if (wps_genie[0] == eQC_WPS_BEACON_IE) {
4416 pSap_WPSIe->sapWPSIECode = eSAP_WPS_BEACON_IE;
4417 wps_genie = wps_genie + 1;
4418 switch (wps_genie[0]) {
4419 case DOT11F_EID_WPA:
4420 if (wps_genie[1] < 2 + 4) {
4421 cdf_mem_free(pSap_WPSIe);
4422 kfree(fwps_genie);
4423 return -EINVAL;
4424 } else if (memcmp(&wps_genie[2],
4425 "\x00\x50\xf2\x04", 4) == 0) {
4426 hddLog(LOG1, FL("Set WPS BEACON IE(len %d)"),
4427 wps_genie[1] + 2);
4428 pos = &wps_genie[6];
4429 while (((size_t) pos -
4430 (size_t) &wps_genie[6]) <
4431 (wps_genie[1] - 4)) {
4432 switch ((uint16_t) (*pos << 8) |
4433 *(pos + 1)) {
4434 case HDD_WPS_ELEM_VERSION:
4435 pos += 4;
4436 pSap_WPSIe->sapwpsie.
4437 sapWPSBeaconIE.Version =
4438 *pos;
4439 hddLog(LOG1, "WPS version %d",
4440 pSap_WPSIe->sapwpsie.
4441 sapWPSBeaconIE.Version);
4442 pSap_WPSIe->sapwpsie.
4443 sapWPSBeaconIE.
4444 FieldPresent |=
4445 WPS_BEACON_VER_PRESENT;
4446 pos += 1;
4447 break;
4448
4449 case HDD_WPS_ELEM_WPS_STATE:
4450 pos += 4;
4451 pSap_WPSIe->sapwpsie.
4452 sapWPSBeaconIE.wpsState =
4453 *pos;
4454 hddLog(LOG1, "WPS State %d",
4455 pSap_WPSIe->sapwpsie.
4456 sapWPSBeaconIE.wpsState);
4457 pSap_WPSIe->sapwpsie.
4458 sapWPSBeaconIE.
4459 FieldPresent |=
4460 WPS_BEACON_STATE_PRESENT;
4461 pos += 1;
4462 break;
4463 case HDD_WPS_ELEM_APSETUPLOCK:
4464 pos += 4;
4465 pSap_WPSIe->sapwpsie.
4466 sapWPSBeaconIE.
4467 APSetupLocked = *pos;
4468 hddLog(LOG1, "AP setup lock %d",
4469 pSap_WPSIe->sapwpsie.
4470 sapWPSBeaconIE.
4471 APSetupLocked);
4472 pSap_WPSIe->sapwpsie.
4473 sapWPSBeaconIE.
4474 FieldPresent |=
4475 WPS_BEACON_APSETUPLOCK_PRESENT;
4476 pos += 1;
4477 break;
4478 case HDD_WPS_ELEM_SELECTEDREGISTRA:
4479 pos += 4;
4480 pSap_WPSIe->sapwpsie.
4481 sapWPSBeaconIE.
4482 SelectedRegistra = *pos;
4483 hddLog(LOG1,
4484 "Selected Registra %d",
4485 pSap_WPSIe->sapwpsie.
4486 sapWPSBeaconIE.
4487 SelectedRegistra);
4488 pSap_WPSIe->sapwpsie.
4489 sapWPSBeaconIE.
4490 FieldPresent |=
4491 WPS_BEACON_SELECTEDREGISTRA_PRESENT;
4492 pos += 1;
4493 break;
4494 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
4495 pos += 4;
4496 pSap_WPSIe->sapwpsie.
4497 sapWPSBeaconIE.
4498 DevicePasswordID =
4499 (*pos << 8) | *(pos + 1);
4500 hddLog(LOG1, "Password ID: %x",
4501 pSap_WPSIe->sapwpsie.
4502 sapWPSBeaconIE.
4503 DevicePasswordID);
4504 pSap_WPSIe->sapwpsie.
4505 sapWPSBeaconIE.
4506 FieldPresent |=
4507 WPS_BEACON_DEVICEPASSWORDID_PRESENT;
4508 pos += 2;
4509 break;
4510 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
4511 pos +=
4512 4;
4513 pSap_WPSIe->sapwpsie.
4514 sapWPSBeaconIE.
4515 SelectedRegistraCfgMethod =
4516 (*pos << 8) | *(pos + 1);
4517 hddLog(LOG1,
4518 "Select Registra Config Methods: %x",
4519 pSap_WPSIe->sapwpsie.
4520 sapWPSBeaconIE.
4521 SelectedRegistraCfgMethod);
4522 pSap_WPSIe->sapwpsie.
4523 sapWPSBeaconIE.
4524 FieldPresent |=
4525 WPS_BEACON_SELECTEDREGISTRACFGMETHOD_PRESENT;
4526 pos += 2;
4527 break;
4528
4529 case HDD_WPS_ELEM_UUID_E:
4530 pos += 2;
4531 length = *pos << 8 | *(pos + 1);
4532 pos += 2;
4533 cdf_mem_copy(pSap_WPSIe->
4534 sapwpsie.
4535 sapWPSBeaconIE.
4536 UUID_E, pos,
4537 length);
4538 pSap_WPSIe->sapwpsie.
4539 sapWPSBeaconIE.
4540 FieldPresent |=
4541 WPS_BEACON_UUIDE_PRESENT;
4542 pos += length;
4543 break;
4544 case HDD_WPS_ELEM_RF_BANDS:
4545 pos += 4;
4546 pSap_WPSIe->sapwpsie.
4547 sapWPSBeaconIE.RFBand =
4548 *pos;
4549 hddLog(LOG1, "RF band: %d",
4550 pSap_WPSIe->sapwpsie.
4551 sapWPSBeaconIE.RFBand);
4552 pSap_WPSIe->sapwpsie.
4553 sapWPSBeaconIE.
4554 FieldPresent |=
4555 WPS_BEACON_RF_BANDS_PRESENT;
4556 pos += 1;
4557 break;
4558
4559 default:
4560 hddLog(LOGW,
4561 "UNKNOWN TLV in WPS IE(%x)",
4562 (*pos << 8 |
4563 *(pos + 1)));
4564 cdf_mem_free(pSap_WPSIe);
4565 kfree(fwps_genie);
4566 return -EINVAL;
4567 }
4568 }
4569 } else {
4570 hddLog(LOGE, FL("WPS IE Mismatch %X"),
4571 wps_genie[0]);
4572 }
4573 break;
4574
4575 default:
4576 hddLog(LOGE, FL("Set UNKNOWN IE %X"), wps_genie[0]);
4577 cdf_mem_free(pSap_WPSIe);
4578 kfree(fwps_genie);
4579 return 0;
4580 }
4581 } else if (wps_genie[0] == eQC_WPS_PROBE_RSP_IE) {
4582 pSap_WPSIe->sapWPSIECode = eSAP_WPS_PROBE_RSP_IE;
4583 wps_genie = wps_genie + 1;
4584 switch (wps_genie[0]) {
4585 case DOT11F_EID_WPA:
4586 if (wps_genie[1] < 2 + 4) {
4587 cdf_mem_free(pSap_WPSIe);
4588 kfree(fwps_genie);
4589 return -EINVAL;
4590 } else if (memcmp(&wps_genie[2], "\x00\x50\xf2\x04", 4)
4591 == 0) {
4592 hddLog(LOG1, FL("Set WPS PROBE RSP IE(len %d)"),
4593 wps_genie[1] + 2);
4594 pos = &wps_genie[6];
4595 while (((size_t) pos -
4596 (size_t) &wps_genie[6]) <
4597 (wps_genie[1] - 4)) {
4598 switch ((uint16_t) (*pos << 8) |
4599 *(pos + 1)) {
4600 case HDD_WPS_ELEM_VERSION:
4601 pos += 4;
4602 pSap_WPSIe->sapwpsie.
4603 sapWPSProbeRspIE.Version =
4604 *pos;
4605 hddLog(LOG1, "WPS version %d",
4606 pSap_WPSIe->sapwpsie.
4607 sapWPSProbeRspIE.
4608 Version);
4609 pSap_WPSIe->sapwpsie.
4610 sapWPSProbeRspIE.
4611 FieldPresent |=
4612 WPS_PROBRSP_VER_PRESENT;
4613 pos += 1;
4614 break;
4615
4616 case HDD_WPS_ELEM_WPS_STATE:
4617 pos += 4;
4618 pSap_WPSIe->sapwpsie.
4619 sapWPSProbeRspIE.wpsState =
4620 *pos;
4621 hddLog(LOG1, "WPS State %d",
4622 pSap_WPSIe->sapwpsie.
4623 sapWPSProbeRspIE.
4624 wpsState);
4625 pSap_WPSIe->sapwpsie.
4626 sapWPSProbeRspIE.
4627 FieldPresent |=
4628 WPS_PROBRSP_STATE_PRESENT;
4629 pos += 1;
4630 break;
4631 case HDD_WPS_ELEM_APSETUPLOCK:
4632 pos += 4;
4633 pSap_WPSIe->sapwpsie.
4634 sapWPSProbeRspIE.
4635 APSetupLocked = *pos;
4636 hddLog(LOG1, "AP setup lock %d",
4637 pSap_WPSIe->sapwpsie.
4638 sapWPSProbeRspIE.
4639 APSetupLocked);
4640 pSap_WPSIe->sapwpsie.
4641 sapWPSProbeRspIE.
4642 FieldPresent |=
4643 WPS_PROBRSP_APSETUPLOCK_PRESENT;
4644 pos += 1;
4645 break;
4646 case HDD_WPS_ELEM_SELECTEDREGISTRA:
4647 pos += 4;
4648 pSap_WPSIe->sapwpsie.
4649 sapWPSProbeRspIE.
4650 SelectedRegistra = *pos;
4651 hddLog(LOG1,
4652 "Selected Registra %d",
4653 pSap_WPSIe->sapwpsie.
4654 sapWPSProbeRspIE.
4655 SelectedRegistra);
4656 pSap_WPSIe->sapwpsie.
4657 sapWPSProbeRspIE.
4658 FieldPresent |=
4659 WPS_PROBRSP_SELECTEDREGISTRA_PRESENT;
4660 pos += 1;
4661 break;
4662 case HDD_WPS_ELEM_DEVICE_PASSWORD_ID:
4663 pos += 4;
4664 pSap_WPSIe->sapwpsie.
4665 sapWPSProbeRspIE.
4666 DevicePasswordID =
4667 (*pos << 8) | *(pos + 1);
4668 hddLog(LOG1, "Password ID: %d",
4669 pSap_WPSIe->sapwpsie.
4670 sapWPSProbeRspIE.
4671 DevicePasswordID);
4672 pSap_WPSIe->sapwpsie.
4673 sapWPSProbeRspIE.
4674 FieldPresent |=
4675 WPS_PROBRSP_DEVICEPASSWORDID_PRESENT;
4676 pos += 2;
4677 break;
4678 case HDD_WPS_ELEM_REGISTRA_CONF_METHODS:
4679 pos +=
4680 4;
4681 pSap_WPSIe->sapwpsie.
4682 sapWPSProbeRspIE.
4683 SelectedRegistraCfgMethod =
4684 (*pos << 8) | *(pos + 1);
4685 hddLog(LOG1,
4686 "Select Registra Config Methods: %x",
4687 pSap_WPSIe->sapwpsie.
4688 sapWPSProbeRspIE.
4689 SelectedRegistraCfgMethod);
4690 pSap_WPSIe->sapwpsie.
4691 sapWPSProbeRspIE.
4692 FieldPresent |=
4693 WPS_PROBRSP_SELECTEDREGISTRACFGMETHOD_PRESENT;
4694 pos += 2;
4695 break;
4696 case HDD_WPS_ELEM_RSP_TYPE:
4697 pos += 4;
4698 pSap_WPSIe->sapwpsie.
4699 sapWPSProbeRspIE.
4700 ResponseType = *pos;
4701 hddLog(LOG1,
4702 "Config Methods: %d",
4703 pSap_WPSIe->sapwpsie.
4704 sapWPSProbeRspIE.
4705 ResponseType);
4706 pSap_WPSIe->sapwpsie.
4707 sapWPSProbeRspIE.
4708 FieldPresent |=
4709 WPS_PROBRSP_RESPONSETYPE_PRESENT;
4710 pos += 1;
4711 break;
4712 case HDD_WPS_ELEM_UUID_E:
4713 pos += 2;
4714 length = *pos << 8 | *(pos + 1);
4715 pos += 2;
4716 cdf_mem_copy(pSap_WPSIe->
4717 sapwpsie.
4718 sapWPSProbeRspIE.
4719 UUID_E, pos,
4720 length);
4721 pSap_WPSIe->sapwpsie.
4722 sapWPSProbeRspIE.
4723 FieldPresent |=
4724 WPS_PROBRSP_UUIDE_PRESENT;
4725 pos += length;
4726 break;
4727
4728 case HDD_WPS_ELEM_MANUFACTURER:
4729 pos += 2;
4730 length = *pos << 8 | *(pos + 1);
4731 pos += 2;
4732 pSap_WPSIe->sapwpsie.
4733 sapWPSProbeRspIE.
4734 Manufacture.num_name =
4735 length;
4736 cdf_mem_copy(pSap_WPSIe->
4737 sapwpsie.
4738 sapWPSProbeRspIE.
4739 Manufacture.name,
4740 pos, length);
4741 pSap_WPSIe->sapwpsie.
4742 sapWPSProbeRspIE.
4743 FieldPresent |=
4744 WPS_PROBRSP_MANUFACTURE_PRESENT;
4745 pos += length;
4746 break;
4747
4748 case HDD_WPS_ELEM_MODEL_NAME:
4749 pos += 2;
4750 length = *pos << 8 | *(pos + 1);
4751 pos += 2;
4752 pSap_WPSIe->sapwpsie.
4753 sapWPSProbeRspIE.ModelName.
4754 num_text = length;
4755 cdf_mem_copy(pSap_WPSIe->
4756 sapwpsie.
4757 sapWPSProbeRspIE.
4758 ModelName.text,
4759 pos, length);
4760 pSap_WPSIe->sapwpsie.
4761 sapWPSProbeRspIE.
4762 FieldPresent |=
4763 WPS_PROBRSP_MODELNAME_PRESENT;
4764 pos += length;
4765 break;
4766 case HDD_WPS_ELEM_MODEL_NUM:
4767 pos += 2;
4768 length = *pos << 8 | *(pos + 1);
4769 pos += 2;
4770 pSap_WPSIe->sapwpsie.
4771 sapWPSProbeRspIE.
4772 ModelNumber.num_text =
4773 length;
4774 cdf_mem_copy(pSap_WPSIe->
4775 sapwpsie.
4776 sapWPSProbeRspIE.
4777 ModelNumber.text,
4778 pos, length);
4779 pSap_WPSIe->sapwpsie.
4780 sapWPSProbeRspIE.
4781 FieldPresent |=
4782 WPS_PROBRSP_MODELNUMBER_PRESENT;
4783 pos += length;
4784 break;
4785 case HDD_WPS_ELEM_SERIAL_NUM:
4786 pos += 2;
4787 length = *pos << 8 | *(pos + 1);
4788 pos += 2;
4789 pSap_WPSIe->sapwpsie.
4790 sapWPSProbeRspIE.
4791 SerialNumber.num_text =
4792 length;
4793 cdf_mem_copy(pSap_WPSIe->
4794 sapwpsie.
4795 sapWPSProbeRspIE.
4796 SerialNumber.text,
4797 pos, length);
4798 pSap_WPSIe->sapwpsie.
4799 sapWPSProbeRspIE.
4800 FieldPresent |=
4801 WPS_PROBRSP_SERIALNUMBER_PRESENT;
4802 pos += length;
4803 break;
4804 case HDD_WPS_ELEM_PRIMARY_DEVICE_TYPE:
4805 pos += 4;
4806 pSap_WPSIe->sapwpsie.
4807 sapWPSProbeRspIE.
4808 PrimaryDeviceCategory =
4809 (*pos << 8 | *(pos + 1));
4810 hddLog(LOG1,
4811 "primary dev category: %d",
4812 pSap_WPSIe->sapwpsie.
4813 sapWPSProbeRspIE.
4814 PrimaryDeviceCategory);
4815 pos += 2;
4816
4817 cdf_mem_copy(pSap_WPSIe->
4818 sapwpsie.
4819 sapWPSProbeRspIE.
4820 PrimaryDeviceOUI,
4821 pos,
4822 HDD_WPS_DEVICE_OUI_LEN);
4823 hddLog(LOG1,
4824 "primary dev oui: %02x, %02x, %02x, %02x",
4825 pos[0], pos[1], pos[2],
4826 pos[3]);
4827 pos += 4;
4828 pSap_WPSIe->sapwpsie.
4829 sapWPSProbeRspIE.
4830 DeviceSubCategory =
4831 (*pos << 8 | *(pos + 1));
4832 hddLog(LOG1,
4833 "primary dev sub category: %d",
4834 pSap_WPSIe->sapwpsie.
4835 sapWPSProbeRspIE.
4836 DeviceSubCategory);
4837 pos += 2;
4838 pSap_WPSIe->sapwpsie.
4839 sapWPSProbeRspIE.
4840 FieldPresent |=
4841 WPS_PROBRSP_PRIMARYDEVICETYPE_PRESENT;
4842 break;
4843 case HDD_WPS_ELEM_DEVICE_NAME:
4844 pos += 2;
4845 length = *pos << 8 | *(pos + 1);
4846 pos += 2;
4847 pSap_WPSIe->sapwpsie.
4848 sapWPSProbeRspIE.DeviceName.
4849 num_text = length;
4850 cdf_mem_copy(pSap_WPSIe->
4851 sapwpsie.
4852 sapWPSProbeRspIE.
4853 DeviceName.text,
4854 pos, length);
4855 pos += length;
4856 pSap_WPSIe->sapwpsie.
4857 sapWPSProbeRspIE.
4858 FieldPresent |=
4859 WPS_PROBRSP_DEVICENAME_PRESENT;
4860 break;
4861 case HDD_WPS_ELEM_CONFIG_METHODS:
4862 pos += 4;
4863 pSap_WPSIe->sapwpsie.
4864 sapWPSProbeRspIE.
4865 ConfigMethod =
4866 (*pos << 8) | *(pos + 1);
4867 hddLog(LOG1,
4868 "Config Methods: %d",
4869 pSap_WPSIe->sapwpsie.
4870 sapWPSProbeRspIE.
4871 SelectedRegistraCfgMethod);
4872 pos += 2;
4873 pSap_WPSIe->sapwpsie.
4874 sapWPSProbeRspIE.
4875 FieldPresent |=
4876 WPS_PROBRSP_CONFIGMETHODS_PRESENT;
4877 break;
4878
4879 case HDD_WPS_ELEM_RF_BANDS:
4880 pos += 4;
4881 pSap_WPSIe->sapwpsie.
4882 sapWPSProbeRspIE.RFBand =
4883 *pos;
4884 hddLog(LOG1, "RF band: %d",
4885 pSap_WPSIe->sapwpsie.
4886 sapWPSProbeRspIE.RFBand);
4887 pos += 1;
4888 pSap_WPSIe->sapwpsie.
4889 sapWPSProbeRspIE.
4890 FieldPresent |=
4891 WPS_PROBRSP_RF_BANDS_PRESENT;
4892 break;
4893 } /* switch */
4894 }
4895 } else {
4896 hddLog(LOGE,
4897 FL("WPS IE Mismatch %X"), wps_genie[0]);
4898 }
4899
4900 } /* switch */
4901 }
4902#ifdef WLAN_FEATURE_MBSSID
4903 cdf_ret_status =
4904 wlansap_set_wps_ie(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter),
4905 pSap_WPSIe);
4906#else
4907 cdf_ret_status = wlansap_set_wps_ie(p_cds_context, pSap_WPSIe);
4908#endif
4909 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
4910 if (pHostapdState->bCommit && WPSIeType == eQC_WPS_PROBE_RSP_IE) {
4911#ifdef WLAN_FEATURE_MBSSID
4912 wlansap_update_wps_ie(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
4913#else
4914 wlansap_update_wps_ie(p_cds_context);
4915#endif
4916 }
4917
4918 cdf_mem_free(pSap_WPSIe);
4919 kfree(fwps_genie);
4920 EXIT();
4921 return cdf_ret_status;
4922}
4923
4924static int iw_softap_setwpsie(struct net_device *dev,
4925 struct iw_request_info *info,
4926 union iwreq_data *wrqu,
4927 char *extra)
4928{
4929 int ret;
4930
4931 cds_ssr_protect(__func__);
4932 ret = __iw_softap_setwpsie(dev, info, wrqu, extra);
4933 cds_ssr_unprotect(__func__);
4934
4935 return ret;
4936}
4937
4938static int
4939__iw_softap_stopbss(struct net_device *dev,
4940 struct iw_request_info *info,
4941 union iwreq_data *wrqu, char *extra)
4942{
4943 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
4944 CDF_STATUS status = CDF_STATUS_SUCCESS;
4945 hdd_context_t *hdd_ctx;
4946
4947 ENTER();
4948
4949 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
4950 status = wlan_hdd_validate_context(hdd_ctx);
4951 if (0 != status)
4952 return status;
4953
4954 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
4955 hdd_hostapd_state_t *pHostapdState =
4956 WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
4957
4958 cdf_event_reset(&pHostapdState->cdf_stop_bss_event);
4959#ifdef WLAN_FEATURE_MBSSID
4960 status =
4961 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
4962#else
4963 status =
4964 wlansap_stop_bss((WLAN_HDD_GET_CTX(pHostapdAdapter))->
4965 pcds_context);
4966#endif
4967 if (CDF_IS_STATUS_SUCCESS(status)) {
4968 status =
4969 cdf_wait_single_event(&pHostapdState->
4970 cdf_stop_bss_event,
4971 10000);
4972
4973 if (!CDF_IS_STATUS_SUCCESS(status)) {
4974 hddLog(LOGE,
4975 FL("wait for single_event failed!!"));
4976 CDF_ASSERT(0);
4977 }
4978 }
4979 clear_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08004980 cds_decr_session_set_pcl(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004981 pHostapdAdapter->sessionId);
4982 }
4983 EXIT();
4984 return (status == CDF_STATUS_SUCCESS) ? 0 : -EBUSY;
4985}
4986
4987static int iw_softap_stopbss(struct net_device *dev,
4988 struct iw_request_info *info,
4989 union iwreq_data *wrqu,
4990 char *extra)
4991{
4992 int ret;
4993
4994 cds_ssr_protect(__func__);
4995 ret = __iw_softap_stopbss(dev, info, wrqu, extra);
4996 cds_ssr_unprotect(__func__);
4997
4998 return ret;
4999}
5000
5001static int
5002__iw_softap_version(struct net_device *dev,
5003 struct iw_request_info *info,
5004 union iwreq_data *wrqu, char *extra)
5005{
5006 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
5007 hdd_context_t *hdd_ctx;
5008 int ret;
5009
5010 ENTER();
5011
5012 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5013 ret = wlan_hdd_validate_context(hdd_ctx);
5014 if (0 != ret)
5015 return ret;
5016
5017 hdd_wlan_get_version(pHostapdAdapter, wrqu, extra);
5018 EXIT();
5019 return 0;
5020}
5021
5022static int iw_softap_version(struct net_device *dev,
5023 struct iw_request_info *info,
5024 union iwreq_data *wrqu,
5025 char *extra)
5026{
5027 int ret;
5028
5029 cds_ssr_protect(__func__);
5030 ret = __iw_softap_version(dev, info, wrqu, extra);
5031 cds_ssr_unprotect(__func__);
5032
5033 return ret;
5034}
5035
5036static
5037CDF_STATUS hdd_softap_get_sta_info(hdd_adapter_t *pAdapter, uint8_t *pBuf,
5038 int buf_len) {
5039 uint8_t i;
5040 uint8_t maxSta = 0;
5041 int len = 0;
5042 const char sta_info_header[] = "staId staAddress";
5043 hdd_context_t *hdd_ctx;
5044
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305045 ENTER();
5046
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005047 if (NULL == pAdapter) {
5048 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
5049 "%s: Adapter is NULL", __func__);
5050 return -EINVAL;
5051 }
5052
5053 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5054 if (0 != wlan_hdd_validate_context(hdd_ctx))
5055 return CDF_STATUS_E_FAULT;
5056
5057 len = scnprintf(pBuf, buf_len, sta_info_header);
5058 pBuf += len;
5059 buf_len -= len;
5060
5061 maxSta = hdd_ctx->config->maxNumberOfPeers;
5062
5063 for (i = 0; i <= maxSta; i++) {
5064 if (pAdapter->aStaInfo[i].isUsed) {
5065 len =
5066 scnprintf(pBuf, buf_len,
5067 "%5d .%02x:%02x:%02x:%02x:%02x:%02x",
5068 pAdapter->aStaInfo[i].ucSTAId,
5069 pAdapter->aStaInfo[i].macAddrSTA.bytes[0],
5070 pAdapter->aStaInfo[i].macAddrSTA.bytes[1],
5071 pAdapter->aStaInfo[i].macAddrSTA.bytes[2],
5072 pAdapter->aStaInfo[i].macAddrSTA.bytes[3],
5073 pAdapter->aStaInfo[i].macAddrSTA.bytes[4],
5074 pAdapter->aStaInfo[i].macAddrSTA.
5075 bytes[5]);
5076 pBuf += len;
5077 buf_len -= len;
5078 }
5079 if (WE_GET_STA_INFO_SIZE > buf_len) {
5080 break;
5081 }
5082 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305083 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005084 return CDF_STATUS_SUCCESS;
5085}
5086
5087static int __iw_softap_get_sta_info(struct net_device *dev,
5088 struct iw_request_info *info,
5089 union iwreq_data *wrqu, char *extra)
5090{
5091 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
5092 CDF_STATUS status;
5093 hdd_context_t *hdd_ctx;
5094 int ret;
5095
5096 ENTER();
5097
5098 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5099 ret = wlan_hdd_validate_context(hdd_ctx);
5100 if (0 != ret)
5101 return ret;
5102
5103 status =
5104 hdd_softap_get_sta_info(pHostapdAdapter, extra,
5105 WE_SAP_MAX_STA_INFO);
5106
5107 if (!CDF_IS_STATUS_SUCCESS(status)) {
5108 hddLog(LOGE, FL("Failed to get sta info: %d"), status);
5109 return -EINVAL;
5110 }
5111 wrqu->data.length = strlen(extra);
5112 EXIT();
5113 return 0;
5114}
5115
5116static int iw_softap_get_sta_info(struct net_device *dev,
5117 struct iw_request_info *info,
5118 union iwreq_data *wrqu,
5119 char *extra)
5120{
5121 int ret;
5122
5123 cds_ssr_protect(__func__);
5124 ret = __iw_softap_get_sta_info(dev, info, wrqu, extra);
5125 cds_ssr_unprotect(__func__);
5126
5127 return ret;
5128}
5129
5130/**
5131 * __iw_set_ap_genie() - set ap wpa/rsn ie
5132 *
5133 * @dev - Pointer to the net device.
5134 * @info - Pointer to the iw_request_info.
5135 * @wrqu - Pointer to the iwreq_data.
5136 * @extra - Pointer to the data.
5137 *
5138 * Return: 0 for success, non zero for failure.
5139 */
5140static int __iw_set_ap_genie(struct net_device *dev,
5141 struct iw_request_info *info,
5142 union iwreq_data *wrqu, char *extra) {
5143
5144 hdd_adapter_t *pHostapdAdapter = netdev_priv(dev);
5145#ifndef WLAN_FEATURE_MBSSID
5146 v_CONTEXT_t cds_ctx;
5147#endif
5148 hdd_context_t *hdd_ctx;
5149 CDF_STATUS cdf_ret_status = CDF_STATUS_SUCCESS;
5150 uint8_t *genie = (uint8_t *)extra;
5151 int ret;
5152
5153 ENTER();
5154
5155 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5156 ret = wlan_hdd_validate_context(hdd_ctx);
5157 if (0 != ret)
5158 return ret;
5159
5160#ifndef WLAN_FEATURE_MBSSID
5161 cds_ctx = hdd_ctx->pcds_context;
5162 if (NULL == cds_ctx) {
5163 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
5164 "%s: CDF Context is NULL", __func__);
5165 return -EINVAL;
5166 }
5167#endif
5168
5169 if (!wrqu->data.length) {
5170 EXIT();
5171 return 0;
5172 }
5173
5174 switch (genie[0]) {
5175 case DOT11F_EID_WPA:
5176 case DOT11F_EID_RSN:
5177 if ((WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy == 0) {
5178 hdd_softap_deregister_bc_sta(pHostapdAdapter);
5179 hdd_softap_register_bc_sta(pHostapdAdapter, 1);
5180 }
5181 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = 1;
5182#ifdef WLAN_FEATURE_MBSSID
5183 cdf_ret_status =
5184 wlansap_set_wparsn_ies(WLAN_HDD_GET_SAP_CTX_PTR
5185 (pHostapdAdapter), genie,
5186 wrqu->data.length);
5187#else
5188 cdf_ret_status =
5189 wlansap_set_wparsn_ies(cds_ctx, genie,
5190 wrqu->data.length);
5191#endif
5192 break;
5193
5194 default:
5195 hddLog(LOGE, FL("Set UNKNOWN IE %X"), genie[0]);
5196 cdf_ret_status = 0;
5197 }
5198
5199 EXIT();
5200 return cdf_ret_status;
5201}
5202
5203/**
5204 * iw_set_ap_genie() - Wrapper function to protect __iw_set_ap_genie
5205 * from the SSR.
5206 *
5207 * @dev - Pointer to the net device.
5208 * @info - Pointer to the iw_request_info.
5209 * @wrqu - Pointer to the iwreq_data.
5210 * @extra - Pointer to the data.
5211 *
5212 * Return: 0 for success, non zero for failure.
5213 */
5214static int
5215iw_set_ap_genie(struct net_device *dev,
5216 struct iw_request_info *info,
5217 union iwreq_data *wrqu, char *extra)
5218{
5219 int ret;
5220
5221 cds_ssr_protect(__func__);
5222 ret = __iw_set_ap_genie(dev, info, wrqu, extra);
5223 cds_ssr_unprotect(__func__);
5224
5225 return ret;
5226}
5227
5228static
5229int __iw_get_softap_linkspeed(struct net_device *dev,
5230 struct iw_request_info *info,
5231 union iwreq_data *wrqu, char *extra)
5232{
5233 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
5234 hdd_context_t *hdd_ctx;
5235 char *pLinkSpeed = (char *)extra;
5236 uint32_t link_speed = 0;
5237 int len = sizeof(uint32_t) + 1;
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08005238 struct cdf_mac_addr macAddress;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005239 char pmacAddress[MAC_ADDRESS_STR_LEN + 1];
5240 CDF_STATUS status = CDF_STATUS_E_FAILURE;
5241 int rc, valid, i;
5242
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305243 ENTER();
5244
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005245 hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
5246 valid = wlan_hdd_validate_context(hdd_ctx);
5247 if (0 != valid)
5248 return valid;
5249
5250 hddLog(LOG1, FL("wrqu->data.length(%d)"), wrqu->data.length);
5251
5252 if (wrqu->data.length >= MAC_ADDRESS_STR_LEN - 1) {
5253 if (copy_from_user((void *)pmacAddress,
5254 wrqu->data.pointer, MAC_ADDRESS_STR_LEN)) {
5255 hddLog(LOG1, FL("failed to copy data to user buffer"));
5256 return -EFAULT;
5257 }
5258 pmacAddress[MAC_ADDRESS_STR_LEN] = '\0';
5259
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08005260 if (!mac_pton(pmacAddress, macAddress.bytes)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005261 hddLog(LOGE, FL("String to Hex conversion Failed"));
5262 return -EINVAL;
5263 }
5264 }
5265 /* If no mac address is passed and/or its length is less than 17,
5266 * link speed for first connected client will be returned.
5267 */
5268 if (wrqu->data.length < 17 || !CDF_IS_STATUS_SUCCESS(status)) {
5269 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
5270 if (pHostapdAdapter->aStaInfo[i].isUsed &&
5271 (!cdf_is_macaddr_broadcast
5272 (&pHostapdAdapter->aStaInfo[i].macAddrSTA))) {
5273 cdf_copy_macaddr(
Srinivas Girigowdadccab9a2015-11-19 14:31:14 -08005274 &macAddress,
5275 &pHostapdAdapter->aStaInfo[i].
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005276 macAddrSTA);
5277 status = CDF_STATUS_SUCCESS;
5278 break;
5279 }
5280 }
5281 }
5282 if (!CDF_IS_STATUS_SUCCESS(status)) {
5283 hddLog(LOGE, FL("Invalid peer macaddress"));
5284 return -EINVAL;
5285 }
5286 status = wlan_hdd_get_linkspeed_for_peermac(pHostapdAdapter,
5287 macAddress);
5288 if (!CDF_IS_STATUS_SUCCESS(status)) {
5289 hddLog(LOGE, FL("Unable to retrieve SME linkspeed"));
5290 return -EINVAL;
5291 }
5292
5293 link_speed = pHostapdAdapter->ls_stats.estLinkSpeed;
5294
5295 /* linkspeed in units of 500 kbps */
5296 link_speed = link_speed / 500;
5297 wrqu->data.length = len;
5298 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
5299 if ((rc < 0) || (rc >= len)) {
5300 /* encoding or length error? */
5301 hddLog(LOGE, FL("Unable to encode link speed"));
5302 return -EIO;
5303 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05305304 EXIT();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005305 return 0;
5306}
5307
5308static int
5309iw_get_softap_linkspeed(struct net_device *dev,
5310 struct iw_request_info *info,
5311 union iwreq_data *wrqu,
5312 char *extra)
5313{
5314 int ret;
5315
5316 cds_ssr_protect(__func__);
5317 ret = __iw_get_softap_linkspeed(dev, info, wrqu, extra);
5318 cds_ssr_unprotect(__func__);
5319
5320 return ret;
5321}
5322
5323static const iw_handler hostapd_handler[] = {
5324 (iw_handler) NULL, /* SIOCSIWCOMMIT */
5325 (iw_handler) NULL, /* SIOCGIWNAME */
5326 (iw_handler) NULL, /* SIOCSIWNWID */
5327 (iw_handler) NULL, /* SIOCGIWNWID */
5328 (iw_handler) NULL, /* SIOCSIWFREQ */
5329 (iw_handler) iw_get_ap_freq, /* SIOCGIWFREQ */
5330 (iw_handler) NULL, /* SIOCSIWMODE */
5331 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
5332 (iw_handler) NULL, /* SIOCSIWSENS */
5333 (iw_handler) NULL, /* SIOCGIWSENS */
5334 (iw_handler) NULL, /* SIOCSIWRANGE */
5335 (iw_handler) NULL, /* SIOCGIWRANGE */
5336 (iw_handler) NULL, /* SIOCSIWPRIV */
5337 (iw_handler) NULL, /* SIOCGIWPRIV */
5338 (iw_handler) NULL, /* SIOCSIWSTATS */
5339 (iw_handler) NULL, /* SIOCGIWSTATS */
5340 (iw_handler) NULL, /* SIOCSIWSPY */
5341 (iw_handler) NULL, /* SIOCGIWSPY */
5342 (iw_handler) NULL, /* SIOCSIWTHRSPY */
5343 (iw_handler) NULL, /* SIOCGIWTHRSPY */
5344 (iw_handler) NULL, /* SIOCSIWAP */
5345 (iw_handler) NULL, /* SIOCGIWAP */
5346 (iw_handler) iw_set_ap_mlme, /* SIOCSIWMLME */
5347 (iw_handler) NULL, /* SIOCGIWAPLIST */
5348 (iw_handler) NULL, /* SIOCSIWSCAN */
5349 (iw_handler) NULL, /* SIOCGIWSCAN */
5350 (iw_handler) NULL, /* SIOCSIWESSID */
5351 (iw_handler) NULL, /* SIOCGIWESSID */
5352 (iw_handler) NULL, /* SIOCSIWNICKN */
5353 (iw_handler) NULL, /* SIOCGIWNICKN */
5354 (iw_handler) NULL, /* -- hole -- */
5355 (iw_handler) NULL, /* -- hole -- */
5356 (iw_handler) NULL, /* SIOCSIWRATE */
5357 (iw_handler) NULL, /* SIOCGIWRATE */
5358 (iw_handler) NULL, /* SIOCSIWRTS */
5359 (iw_handler) iw_get_ap_rts_threshold, /* SIOCGIWRTS */
5360 (iw_handler) NULL, /* SIOCSIWFRAG */
5361 (iw_handler) iw_get_ap_frag_threshold, /* SIOCGIWFRAG */
5362 (iw_handler) NULL, /* SIOCSIWTXPOW */
5363 (iw_handler) NULL, /* SIOCGIWTXPOW */
5364 (iw_handler) NULL, /* SIOCSIWRETRY */
5365 (iw_handler) NULL, /* SIOCGIWRETRY */
5366 (iw_handler) NULL, /* SIOCSIWENCODE */
5367 (iw_handler) NULL, /* SIOCGIWENCODE */
5368 (iw_handler) NULL, /* SIOCSIWPOWER */
5369 (iw_handler) NULL, /* SIOCGIWPOWER */
5370 (iw_handler) NULL, /* -- hole -- */
5371 (iw_handler) NULL, /* -- hole -- */
5372 (iw_handler) iw_set_ap_genie, /* SIOCSIWGENIE */
5373 (iw_handler) NULL, /* SIOCGIWGENIE */
5374 (iw_handler) iw_set_auth_hostap, /* SIOCSIWAUTH */
5375 (iw_handler) NULL, /* SIOCGIWAUTH */
5376 (iw_handler) iw_set_ap_encodeext, /* SIOCSIWENCODEEXT */
5377 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
5378 (iw_handler) NULL, /* SIOCSIWPMKSA */
5379};
5380
5381/*
5382 * Note that the following ioctls were defined with semantics which
5383 * cannot be handled by the "iwpriv" userspace application and hence
5384 * they are not included in the hostapd_private_args array
5385 * QCSAP_IOCTL_ASSOC_STA_MACADDR
5386 */
5387
5388static const struct iw_priv_args hostapd_private_args[] = {
5389 {
5390 QCSAP_IOCTL_SETPARAM,
5391 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setparam"
5392 }, {
5393 QCSAP_IOCTL_SETPARAM,
5394 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, ""
5395 }, {
5396 QCSAP_PARAM_MAX_ASSOC,
5397 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5398 "setMaxAssoc"
5399 }, {
5400 QCSAP_PARAM_HIDE_SSID,
5401 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "hideSSID"
5402 }, {
5403 QCSAP_PARAM_SET_MC_RATE,
5404 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setMcRate"
5405 },
5406 {
5407 QCSAP_PARAM_SET_TXRX_FW_STATS,
5408 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5409 "txrx_fw_stats"
5410 }, {
5411 QCSAP_PARAM_SET_MCC_CHANNEL_LATENCY,
5412 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5413 "setMccLatency"
5414 }, {
5415 QCSAP_PARAM_SET_MCC_CHANNEL_QUOTA,
5416 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5417 "setMccQuota"
5418 }, {
5419 QCSAP_PARAM_SET_CHANNEL_CHANGE,
5420 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5421 "setChanChange"
5422 }, {
5423 QCSAP_PARAM_AUTO_CHANNEL,
5424 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
5425 "setAutoChannel"
5426 },
5427 /* Sub-cmds DBGLOG specific commands */
5428 {
5429 QCSAP_DBGLOG_LOG_LEVEL,
5430 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5431 0, "dl_loglevel"
5432 }, {
5433 QCSAP_DBGLOG_VAP_ENABLE,
5434 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_vapon"
5435 }, {
5436 QCSAP_DBGLOG_VAP_DISABLE,
5437 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5438 0, "dl_vapoff"
5439 }, {
5440 QCSAP_DBGLOG_MODULE_ENABLE,
5441 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_modon"
5442 }, {
5443 QCSAP_DBGLOG_MODULE_DISABLE,
5444 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5445 0, "dl_modoff"
5446 }, {
5447 QCSAP_DBGLOG_MOD_LOG_LEVEL,
5448 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5449 0, "dl_mod_loglevel"
5450 }, {
5451 QCSAP_DBGLOG_TYPE,
5452 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "dl_type"
5453 }, {
5454 QCSAP_DBGLOG_REPORT_ENABLE,
5455 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5456 0, "dl_report"
5457 }, {
5458 QCASAP_TXRX_FWSTATS_RESET,
5459 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5460 0, "txrx_fw_st_rst"
5461 }, {
5462 QCSAP_PARAM_RTSCTS,
5463 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5464 0, "enablertscts"
5465 }, {
5466 QCASAP_SET_11N_RATE,
5467 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5468 0, "set11NRates"
5469 }, {
5470 QCASAP_SET_VHT_RATE,
5471 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5472 0, "set11ACRates"
5473 }, {
5474 QCASAP_SHORT_GI,
5475 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5476 0, "enable_short_gi"
5477 }, {
5478 QCSAP_SET_AMPDU,
5479 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ampdu"
5480 }, {
5481 QCSAP_SET_AMSDU,
5482 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "amsdu"
5483 }, {
5484 QCSAP_GTX_HT_MCS,
5485 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxHTMcs"
5486 }, {
5487 QCSAP_GTX_VHT_MCS,
5488 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5489 0, "gtxVHTMcs"
5490 }, {
5491 QCSAP_GTX_USRCFG,
5492 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5493 0, "gtxUsrCfg"
5494 }, {
5495 QCSAP_GTX_THRE,
5496 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxThre"
5497 }, {
5498 QCSAP_GTX_MARGIN,
5499 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5500 0, "gtxMargin"
5501 }, {
5502 QCSAP_GTX_STEP,
5503 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "gtxStep"
5504 }, {
5505 QCSAP_GTX_MINTPC,
5506 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5507 0, "gtxMinTpc"
5508 }, {
5509 QCSAP_GTX_BWMASK,
5510 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5511 0, "gtxBWMask"
5512 }, {
5513 QCSAP_PARAM_CLR_ACL,
5514 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5515 0, "setClearAcl"
5516 }, {
5517 QCSAP_PARAM_ACL_MODE,
5518 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setAclMode"
5519 },
5520#ifdef QCA_PKT_PROTO_TRACE
5521 {
5522 QCASAP_SET_DEBUG_LOG,
5523 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setDbgLvl"
5524 },
5525#endif /* QCA_PKT_PROTO_TRACE */
5526 {
5527 QCASAP_SET_TM_LEVEL,
5528 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5529 0, "setTmLevel"
5530 }, {
5531 QCASAP_SET_DFS_IGNORE_CAC,
5532 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5533 0, "setDfsIgnoreCAC"
5534 }, {
5535 QCASAP_SET_DFS_NOL,
5536 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5537 0, "setdfsnol"
5538 }, {
5539 QCASAP_SET_DFS_TARGET_CHNL,
5540 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5541 0, "setNextChnl"
5542 }, {
5543 QCASAP_SET_RADAR_CMD,
5544 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setRadar"
5545 },
5546 {
5547 QCSAP_IPA_UC_STAT,
5548 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "ipaucstat"
5549 },
5550 {
5551 QCASAP_TX_CHAINMASK_CMD,
5552 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5553 0, "set_txchainmask"
5554 }, {
5555 QCASAP_RX_CHAINMASK_CMD,
5556 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5557 0, "set_rxchainmask"
5558 }, {
5559 QCASAP_NSS_CMD,
5560 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_nss"
5561 }, {
5562 QCASAP_SET_PHYMODE,
5563 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5564 0, "setphymode"
5565 }, {
5566 QCASAP_DUMP_STATS,
5567 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5568 0, "dumpStats"
5569 }, {
5570 QCASAP_CLEAR_STATS,
5571 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5572 0, "clearStats"
5573 }, {
Govind Singha471e5e2015-10-12 17:11:14 +05305574 QCSAP_START_FW_PROFILING,
5575 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5576 0, "startProfile"
5577 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005578 QCSAP_IOCTL_GETPARAM, 0,
5579 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getparam"
5580 }, {
5581 QCSAP_IOCTL_GETPARAM, 0,
5582 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, ""
5583 }, {
5584 QCSAP_PARAM_MAX_ASSOC, 0,
5585 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getMaxAssoc"
5586 }, {
5587 QCSAP_PARAM_GET_WLAN_DBG, 0,
5588 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getwlandbg"
5589 }, {
5590 QCSAP_PARAM_AUTO_CHANNEL, 0,
5591 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getAutoChannel"
5592 }, {
5593 QCSAP_GTX_BWMASK, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5594 "get_gtxBWMask"
5595 }, {
5596 QCSAP_GTX_MINTPC, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5597 "get_gtxMinTpc"
5598 }, {
5599 QCSAP_GTX_STEP, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5600 "get_gtxStep"
5601 }, {
5602 QCSAP_GTX_MARGIN, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5603 "get_gtxMargin"
5604 }, {
5605 QCSAP_GTX_THRE, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5606 "get_gtxThre"
5607 }, {
5608 QCSAP_GTX_USRCFG, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5609 "get_gtxUsrCfg"
5610 }, {
5611 QCSAP_GTX_VHT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5612 "get_gtxVHTMcs"
5613 }, {
5614 QCSAP_GTX_HT_MCS, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5615 "get_gtxHTMcs"
5616 }, {
5617 QCASAP_SHORT_GI, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5618 "get_short_gi"
5619 }, {
5620 QCSAP_PARAM_RTSCTS, 0,
5621 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rtscts"
5622 }, {
5623 QCASAP_GET_DFS_NOL, 0,
5624 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getdfsnol"
5625 }, {
5626 QCSAP_GET_ACL, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5627 "get_acl_list"
5628 }, {
5629 QCASAP_TX_CHAINMASK_CMD, 0,
5630 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5631 "get_txchainmask"
5632 }, {
5633 QCASAP_RX_CHAINMASK_CMD, 0,
5634 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5635 "get_rxchainmask"
5636 }, {
5637 QCASAP_NSS_CMD, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5638 "get_nss"
5639 }, {
5640 QCASAP_GET_TEMP_CMD, 0,
5641 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_temp"
5642 }, {
Govind Singha471e5e2015-10-12 17:11:14 +05305643 QCSAP_GET_FW_PROFILE_DATA, 0,
5644 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getProfileData"
5645 }, {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005646 QCSAP_IOCTL_GET_STAWPAIE,
5647 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, 0,
5648 "get_staWPAIE"
5649 }, {
5650 QCSAP_IOCTL_SETWPAIE,
5651 IW_PRIV_TYPE_BYTE | QCSAP_MAX_WSC_IE |
5652 IW_PRIV_SIZE_FIXED, 0, "setwpaie"
5653 }, {
5654 QCSAP_IOCTL_STOPBSS, IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED, 0,
5655 "stopbss"
5656 }, {
5657 QCSAP_IOCTL_VERSION, 0, IW_PRIV_TYPE_CHAR | QCSAP_MAX_WSC_IE,
5658 "version"
5659 }, {
5660 QCSAP_IOCTL_GET_STA_INFO, 0,
5661 IW_PRIV_TYPE_CHAR | WE_SAP_MAX_STA_INFO, "get_sta_info"
5662 }, {
5663 QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES,
5664 IW_PRIV_TYPE_BYTE |
5665 sizeof(sQcSapreq_WPSPBCProbeReqIES_t) |
5666 IW_PRIV_SIZE_FIXED, 0, "getProbeReqIEs"
5667 }
5668 , {
5669 QCSAP_IOCTL_GET_CHANNEL, 0,
5670 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
5671 }
5672 , {
5673 QCSAP_IOCTL_DISASSOC_STA,
5674 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 6, 0,
5675 "disassoc_sta"
5676 }
5677 /* handler for main ioctl */
5678 , {
5679 QCSAP_PRIV_GET_CHAR_SET_NONE, 0,
5680 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, ""
5681 }
5682 /* handler for sub-ioctl */
5683 , {
5684 QCSAP_GET_STATS, 0,
5685 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "getStats"
5686 }
5687 , {
Govind Singha471e5e2015-10-12 17:11:14 +05305688 QCSAP_LIST_FW_PROFILE, 0,
5689 IW_PRIV_TYPE_CHAR | WE_MAX_STR_LEN, "listProfile"
5690 }
5691 , {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005692 QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED,
5693 IW_PRIV_TYPE_CHAR | 18,
5694 IW_PRIV_TYPE_CHAR | 5, "getLinkSpeed"
5695 }
5696 , {
5697 QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE,
5698 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, ""
5699 }
5700 ,
5701 /* handlers for sub-ioctl */
5702 {
5703 WE_SET_WLAN_DBG,
5704 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setwlandbg"
5705 }, {
5706 WE_SET_SAP_CHANNELS,
5707 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setsapchannels"
5708 }
5709 ,
5710 /* handlers for sub-ioctl */
5711 {
5712 WE_SET_DP_TRACE,
5713 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "set_dp_trace"
5714 }
5715 ,
5716 /* handlers for main ioctl */
5717 {
5718 QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE,
5719 IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, ""
5720 }
5721 , {
5722 WE_P2P_NOA_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0, "SetP2pPs"
5723 }
5724 , {
5725 WE_UNIT_TEST_CMD, IW_PRIV_TYPE_INT | MAX_VAR_ARGS, 0,
5726 "setUnitTestCmd"
5727 }
5728 ,
5729 /* handlers for main ioctl */
5730 {
5731 QCSAP_IOCTL_MODIFY_ACL,
5732 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 8, 0, "modify_acl"
5733 }
5734 ,
5735 /* handlers for main ioctl */
5736 {
5737 QCSAP_IOCTL_GET_CHANNEL_LIST,
5738 0,
5739 IW_PRIV_TYPE_BYTE | sizeof(tChannelListInfo),
5740 "getChannelList"
5741 }
5742 ,
5743 /* handlers for main ioctl */
5744 {
5745 QCSAP_IOCTL_SET_TX_POWER,
5746 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setTxPower"
5747 }
5748 ,
5749 /* handlers for main ioctl */
5750 {
5751 QCSAP_IOCTL_SET_MAX_TX_POWER,
5752 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5753 0, "setTxMaxPower"
5754 }
5755 ,
5756 /* Set HDD CFG Ini param */
5757 {
5758 QCSAP_IOCTL_SET_INI_CFG,
5759 IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, 0, "setConfig"
5760 }
5761 ,
5762 /* Get HDD CFG Ini param */
5763 {
5764 QCSAP_IOCTL_GET_INI_CFG,
5765 0, IW_PRIV_TYPE_CHAR | QCSAP_IOCTL_MAX_STR_LEN, "getConfig"
5766 }
5767 ,
5768 /* handlers for main ioctl */
5769 {
5770 /* handlers for main ioctl */
5771 QCSAP_IOCTL_SET_TWO_INT_GET_NONE,
5772 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, ""
5773 }
5774 ,
5775 /* handlers for sub-ioctl */
5776#ifdef DEBUG
5777 {
5778 QCSAP_IOCTL_SET_FW_CRASH_INJECT,
5779 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5780 0, "crash_inject"
5781 }
5782 ,
5783#endif
5784 {
5785 QCASAP_SET_RADAR_DBG,
5786 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5787 0, "setRadarDbg"
5788 }
5789 ,
5790 /* dump dp trace - descriptor or dp trace records */
5791 {
5792 QCSAP_IOCTL_DUMP_DP_TRACE_LEVEL,
5793 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5794 0, "dump_dp_trace"
5795 }
5796 ,
Govind Singha471e5e2015-10-12 17:11:14 +05305797 {
5798 QCSAP_ENABLE_FW_PROFILE,
5799 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5800 0, "enableProfile"
5801 }
5802 ,
5803 {
5804 QCSAP_SET_FW_PROFILE_HIST_INTVL,
5805 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
5806 0, "set_hist_intvl"
5807 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005808};
5809
5810static const iw_handler hostapd_private[] = {
5811 /* set priv ioctl */
5812 [QCSAP_IOCTL_SETPARAM - SIOCIWFIRSTPRIV] = iw_softap_setparam,
5813 /* get priv ioctl */
5814 [QCSAP_IOCTL_GETPARAM - SIOCIWFIRSTPRIV] = iw_softap_getparam,
5815 /* get station genIE */
5816 [QCSAP_IOCTL_GET_STAWPAIE - SIOCIWFIRSTPRIV] = iw_get_genie,
5817 [QCSAP_IOCTL_SETWPAIE - SIOCIWFIRSTPRIV] = iw_softap_setwpsie,
5818 /* stop bss */
5819 [QCSAP_IOCTL_STOPBSS - SIOCIWFIRSTPRIV] = iw_softap_stopbss,
5820 /* get driver version */
5821 [QCSAP_IOCTL_VERSION - SIOCIWFIRSTPRIV] = iw_softap_version,
5822 [QCSAP_IOCTL_GET_WPS_PBC_PROBE_REQ_IES - SIOCIWFIRSTPRIV] =
5823 iw_get_wpspbc_probe_req_ies,
5824 [QCSAP_IOCTL_GET_CHANNEL - SIOCIWFIRSTPRIV] =
5825 iw_softap_getchannel,
5826 [QCSAP_IOCTL_ASSOC_STA_MACADDR - SIOCIWFIRSTPRIV] =
5827 iw_softap_getassoc_stamacaddr,
5828 [QCSAP_IOCTL_DISASSOC_STA - SIOCIWFIRSTPRIV] =
5829 iw_softap_disassoc_sta,
5830 [QCSAP_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] =
5831 iw_get_char_setnone,
5832 [QCSAP_IOCTL_PRIV_SET_THREE_INT_GET_NONE -
5833 SIOCIWFIRSTPRIV] =
5834 iw_set_three_ints_getnone,
5835 [QCSAP_IOCTL_PRIV_SET_VAR_INT_GET_NONE -
5836 SIOCIWFIRSTPRIV] =
5837 iw_set_var_ints_getnone,
5838 [QCSAP_IOCTL_SET_CHANNEL_RANGE - SIOCIWFIRSTPRIV] =
5839 iw_softap_set_force_acs_ch_range,
5840 [QCSAP_IOCTL_MODIFY_ACL - SIOCIWFIRSTPRIV] =
5841 iw_softap_modify_acl,
5842 [QCSAP_IOCTL_GET_CHANNEL_LIST - SIOCIWFIRSTPRIV] =
5843 iw_softap_get_channel_list,
5844 [QCSAP_IOCTL_GET_STA_INFO - SIOCIWFIRSTPRIV] =
5845 iw_softap_get_sta_info,
5846 [QCSAP_IOCTL_PRIV_GET_SOFTAP_LINK_SPEED -
5847 SIOCIWFIRSTPRIV] =
5848 iw_get_softap_linkspeed,
5849 [QCSAP_IOCTL_SET_TX_POWER - SIOCIWFIRSTPRIV] =
5850 iw_softap_set_tx_power,
5851 [QCSAP_IOCTL_SET_MAX_TX_POWER - SIOCIWFIRSTPRIV] =
5852 iw_softap_set_max_tx_power,
5853 [QCSAP_IOCTL_SET_INI_CFG - SIOCIWFIRSTPRIV] =
5854 iw_softap_set_ini_cfg,
5855 [QCSAP_IOCTL_GET_INI_CFG - SIOCIWFIRSTPRIV] =
5856 iw_softap_get_ini_cfg,
5857 [QCSAP_IOCTL_SET_TWO_INT_GET_NONE - SIOCIWFIRSTPRIV] =
5858 iw_softap_set_two_ints_getnone,
5859};
5860const struct iw_handler_def hostapd_handler_def = {
5861 .num_standard = CDF_ARRAY_SIZE(hostapd_handler),
5862 .num_private = CDF_ARRAY_SIZE(hostapd_private),
5863 .num_private_args = CDF_ARRAY_SIZE(hostapd_private_args),
5864 .standard = (iw_handler *) hostapd_handler,
5865 .private = (iw_handler *) hostapd_private,
5866 .private_args = hostapd_private_args,
5867 .get_wireless_stats = NULL,
5868};
5869
5870struct net_device_ops net_ops_struct = {
5871 .ndo_open = hdd_hostapd_open,
5872 .ndo_stop = hdd_hostapd_stop,
5873 .ndo_uninit = hdd_hostapd_uninit,
5874 .ndo_start_xmit = hdd_softap_hard_start_xmit,
5875 .ndo_tx_timeout = hdd_softap_tx_timeout,
5876 .ndo_get_stats = hdd_get_stats,
5877 .ndo_set_mac_address = hdd_hostapd_set_mac_address,
5878 .ndo_do_ioctl = hdd_ioctl,
5879 .ndo_change_mtu = hdd_hostapd_change_mtu,
5880 .ndo_select_queue = hdd_hostapd_select_queue,
5881};
5882
5883static int hdd_set_hostapd(hdd_adapter_t *pAdapter)
5884{
5885 return CDF_STATUS_SUCCESS;
5886}
5887
5888void hdd_set_ap_ops(struct net_device *pWlanHostapdDev)
5889{
5890 pWlanHostapdDev->netdev_ops = &net_ops_struct;
5891}
5892
5893CDF_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter)
5894{
5895 hdd_hostapd_state_t *phostapdBuf;
5896 struct net_device *dev = pAdapter->dev;
5897 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5898 CDF_STATUS status;
5899#ifdef WLAN_FEATURE_MBSSID
5900 v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(pAdapter))->pcds_context;
5901 v_CONTEXT_t sapContext = NULL;
5902#endif
5903 int ret;
5904
5905 ENTER();
5906
5907#ifdef WLAN_FEATURE_MBSSID
5908 sapContext = wlansap_open(p_cds_context);
5909 if (sapContext == NULL) {
5910 hddLog(LOGE, ("ERROR: wlansap_open failed!!"));
5911 return CDF_STATUS_E_FAULT;
5912 }
5913
5914 pAdapter->sessionCtx.ap.sapContext = sapContext;
5915
5916 status = wlansap_start(sapContext);
5917 if (!CDF_IS_STATUS_SUCCESS(status)) {
5918 hddLog(LOGE, ("ERROR: wlansap_start failed!!"));
5919 wlansap_close(sapContext);
5920 return status;
5921 }
5922#endif
5923
5924 /* Allocate the Wireless Extensions state structure */
5925 phostapdBuf = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
5926
5927 sme_set_curr_device_mode(pHddCtx->hHal, pAdapter->device_mode);
5928
5929 /* Zero the memory. This zeros the profile structure. */
5930 memset(phostapdBuf, 0, sizeof(hdd_hostapd_state_t));
5931
5932 /* Set up the pointer to the Wireless Extensions state structure */
5933 /* NOP */
5934 status = hdd_set_hostapd(pAdapter);
5935 if (!CDF_IS_STATUS_SUCCESS(status)) {
5936 hddLog(LOGE, ("ERROR: hdd_set_hostapd failed!!"));
5937#ifdef WLAN_FEATURE_MBSSID
5938 wlansap_close(sapContext);
5939#endif
5940 return status;
5941 }
5942
5943 status = cdf_event_init(&phostapdBuf->cdf_event);
5944 if (!CDF_IS_STATUS_SUCCESS(status)) {
5945 hddLog(LOGE, ("ERROR: Hostapd HDD cdf event init failed!!"));
5946#ifdef WLAN_FEATURE_MBSSID
5947 wlansap_close(sapContext);
5948#endif
5949 return status;
5950 }
5951
5952 status = cdf_event_init(&phostapdBuf->cdf_stop_bss_event);
5953 if (!CDF_IS_STATUS_SUCCESS(status)) {
5954 CDF_TRACE(CDF_MODULE_ID_HDD, CDF_TRACE_LEVEL_ERROR,
5955 ("ERROR: Hostapd HDD stop bss event init failed!!"));
5956#ifdef WLAN_FEATURE_MBSSID
5957 wlansap_close(sapContext);
5958#endif
5959 return status;
5960 }
5961
5962 init_completion(&pAdapter->session_close_comp_var);
5963 init_completion(&pAdapter->session_open_comp_var);
5964
5965 sema_init(&(WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->semWpsPBCOverlapInd, 1);
5966
5967 /* Register as a wireless device */
5968 dev->wireless_handlers = (struct iw_handler_def *)&hostapd_handler_def;
5969
5970 /* Initialize the data path module */
5971 status = hdd_softap_init_tx_rx(pAdapter);
5972 if (!CDF_IS_STATUS_SUCCESS(status)) {
5973 hddLog(LOGP, FL("hdd_softap_init_tx_rx failed"));
5974 }
5975
5976 status = hdd_wmm_adapter_init(pAdapter);
5977 if (!CDF_IS_STATUS_SUCCESS(status)) {
5978 hddLog(LOGE,
5979 "hdd_wmm_adapter_init() failed code %08d [x%08x]",
5980 status, status);
5981 goto error_wmm_init;
5982 }
5983
5984 set_bit(WMM_INIT_DONE, &pAdapter->event_flags);
5985
5986 ret = wma_cli_set_command(pAdapter->sessionId,
5987 WMI_PDEV_PARAM_BURST_ENABLE,
5988 pHddCtx->config->enableSifsBurst,
5989 PDEV_CMD);
5990
5991 if (0 != ret) {
5992 hddLog(LOGE,
5993 FL("WMI_PDEV_PARAM_BURST_ENABLE set failed %d"), ret);
5994 }
5995 pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
5996 cdf_mem_free(pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
5997 cdf_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
5998 sizeof(struct sap_acs_cfg));
5999 return status;
6000
6001error_wmm_init:
6002 hdd_softap_deinit_tx_rx(pAdapter);
6003#ifdef WLAN_FEATURE_MBSSID
6004 wlansap_close(sapContext);
6005#endif
6006 EXIT();
6007 return status;
6008}
6009
6010/**
6011 * hdd_wlan_create_ap_dev() - create an AP-mode device
6012 * @pHddCtx: Global HDD context
6013 * @macAddr: MAC address to assign to the interface
6014 * @iface_name: User-visible name of the interface
6015 *
6016 * This function will allocate a Linux net_device and configuration it
6017 * for an AP mode of operation. Note that the device is NOT actually
6018 * registered with the kernel at this time.
6019 *
6020 * Return: A pointer to the private data portion of the net_device if
6021 * the allocation and initialization was successful, NULL otherwise.
6022 */
6023hdd_adapter_t *hdd_wlan_create_ap_dev(hdd_context_t *pHddCtx,
6024 tSirMacAddr macAddr,
6025 uint8_t *iface_name) {
6026 struct net_device *pWlanHostapdDev = NULL;
6027 hdd_adapter_t *pHostapdAdapter = NULL;
6028
6029 hddLog(LOG4, FL("iface_name = %s"), iface_name);
6030
6031 pWlanHostapdDev =
6032 alloc_netdev_mq(sizeof(hdd_adapter_t), iface_name,
6033#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
6034 NET_NAME_UNKNOWN,
6035#endif
6036 ether_setup,
6037 NUM_TX_QUEUES);
6038
6039 if (pWlanHostapdDev != NULL) {
6040 pHostapdAdapter = netdev_priv(pWlanHostapdDev);
6041
6042 /* Init the net_device structure */
6043 ether_setup(pWlanHostapdDev);
6044
6045 /* Initialize the adapter context to zeros. */
6046 cdf_mem_zero(pHostapdAdapter, sizeof(hdd_adapter_t));
6047 pHostapdAdapter->dev = pWlanHostapdDev;
6048 pHostapdAdapter->pHddCtx = pHddCtx;
6049 pHostapdAdapter->magic = WLAN_HDD_ADAPTER_MAGIC;
6050
6051 hddLog(LOG4,
6052 FL("pWlanHostapdDev = %p, pHostapdAdapter = %p, concurrency_mode=0x%x"),
6053 pWlanHostapdDev,
6054 pHostapdAdapter,
6055 (int)cds_get_concurrency_mode());
6056
6057 /* Init the net_device structure */
6058 strlcpy(pWlanHostapdDev->name, (const char *)iface_name,
6059 IFNAMSIZ);
6060
6061 hdd_set_ap_ops(pHostapdAdapter->dev);
6062
6063 pWlanHostapdDev->watchdog_timeo = HDD_TX_TIMEOUT;
6064 pWlanHostapdDev->mtu = HDD_DEFAULT_MTU;
Mohit Khannaee9e80f2015-11-10 11:32:49 -08006065 pWlanHostapdDev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006066
6067 cdf_mem_copy(pWlanHostapdDev->dev_addr, (void *)macAddr,
6068 sizeof(tSirMacAddr));
6069 cdf_mem_copy(pHostapdAdapter->macAddressCurrent.bytes,
6070 (void *)macAddr, sizeof(tSirMacAddr));
6071
6072 pHostapdAdapter->offloads_configured = false;
6073 pWlanHostapdDev->destructor = free_netdev;
6074 pWlanHostapdDev->ieee80211_ptr = &pHostapdAdapter->wdev;
6075 pHostapdAdapter->wdev.wiphy = pHddCtx->wiphy;
6076 pHostapdAdapter->wdev.netdev = pWlanHostapdDev;
6077 init_completion(&pHostapdAdapter->tx_action_cnf_event);
6078 init_completion(&pHostapdAdapter->cancel_rem_on_chan_var);
6079 init_completion(&pHostapdAdapter->rem_on_chan_ready_event);
6080 init_completion(&pHostapdAdapter->sta_authorized_event);
6081 init_completion(&pHostapdAdapter->offchannel_tx_event);
6082 init_completion(&pHostapdAdapter->scan_info.
6083 abortscan_event_var);
6084
6085 SET_NETDEV_DEV(pWlanHostapdDev, pHddCtx->parent_dev);
6086 spin_lock_init(&pHostapdAdapter->pause_map_lock);
6087 }
6088 return pHostapdAdapter;
6089}
6090
6091/**
6092 * hdd_register_hostapd() - register hostapd
6093 * @pAdapter: Pointer to hostapd adapter
6094 * @rtnl_lock_held: RTNL lock held
6095 *
6096 * Return: CDF status
6097 */
6098CDF_STATUS hdd_register_hostapd(hdd_adapter_t *pAdapter,
6099 uint8_t rtnl_lock_held) {
6100 struct net_device *dev = pAdapter->dev;
6101 CDF_STATUS status = CDF_STATUS_SUCCESS;
6102
6103 ENTER();
6104
6105 if (rtnl_lock_held) {
6106 if (strnchr(dev->name, strlen(dev->name), '%')) {
6107 if (dev_alloc_name(dev, dev->name) < 0) {
6108 hddLog(LOGE, FL("Failed:dev_alloc_name"));
6109 return CDF_STATUS_E_FAILURE;
6110 }
6111 }
6112 if (register_netdevice(dev)) {
6113 hddLog(LOGE, FL("Failed:register_netdevice"));
6114 return CDF_STATUS_E_FAILURE;
6115 }
6116 } else {
6117 if (register_netdev(dev)) {
6118 hddLog(LOGE, FL("Failed:register_netdev"));
6119 return CDF_STATUS_E_FAILURE;
6120 }
6121 }
6122 set_bit(NET_DEVICE_REGISTERED, &pAdapter->event_flags);
6123
6124 EXIT();
6125 return status;
6126}
6127
6128/**
6129 * hdd_unregister_hostapd() - unregister hostapd
6130 * @pAdapter: Pointer to hostapd adapter
6131 * @rtnl_held: true if rtnl lock held; false otherwise
6132 *
6133 * Return: CDF_STATUS enumaration
6134 */
6135CDF_STATUS hdd_unregister_hostapd(hdd_adapter_t *pAdapter, bool rtnl_held)
6136{
6137#ifdef WLAN_FEATURE_MBSSID
6138 CDF_STATUS status;
6139 void *sapContext = WLAN_HDD_GET_SAP_CTX_PTR(pAdapter);
6140#endif
6141
6142 ENTER();
6143
6144 hdd_softap_deinit_tx_rx(pAdapter);
6145
6146 /* if we are being called during driver unload,
6147 * then the dev has already been invalidated.
6148 * if we are being called at other times, then we can
6149 * detach the wireless device handlers
6150 */
6151 if (pAdapter->dev) {
6152 if (rtnl_held)
6153 pAdapter->dev->wireless_handlers = NULL;
6154 else {
6155 rtnl_lock();
6156 pAdapter->dev->wireless_handlers = NULL;
6157 rtnl_unlock();
6158 }
6159 }
6160
6161#ifdef WLAN_FEATURE_MBSSID
6162 status = wlansap_stop(sapContext);
6163 if (!CDF_IS_STATUS_SUCCESS(status))
6164 hddLog(LOGE, FL("Failed:wlansap_stop"));
6165
6166 status = wlansap_close(sapContext);
6167 if (!CDF_IS_STATUS_SUCCESS(status))
6168 hddLog(LOGE, FL("Failed:WLANSAP_close"));
6169 pAdapter->sessionCtx.ap.sapContext = NULL;
6170#endif
6171
6172 EXIT();
6173 return 0;
6174}
6175
6176/**
6177 * wlan_hdd_rate_is_11g() - check if rate is 11g rate or not
6178 * @rate: Rate to be checked
6179 *
6180 * Return: true if rate if 11g else false
6181 */
6182static bool wlan_hdd_rate_is_11g(u8 rate)
6183{
6184 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72,
6185 96, 108}; /* actual rate * 2 */
6186 u8 i;
6187 for (i = 0; i < 8; i++) {
6188 if (rate == gRateArray[i])
6189 return true;
6190 }
6191 return false;
6192}
6193
6194#ifdef QCA_HT_2040_COEX
6195/**
6196 * wlan_hdd_get_sap_obss() - Get SAP OBSS enable config based on HT_CAPAB IE
6197 * @pHostapdAdapter: Pointer to hostapd adapter
6198 *
6199 * Return: HT support channel width config value
6200 */
6201static bool wlan_hdd_get_sap_obss(hdd_adapter_t *pHostapdAdapter)
6202{
6203 uint8_t ht_cap_ie[DOT11F_IE_HTCAPS_MAX_LEN];
6204 tDot11fIEHTCaps dot11_ht_cap_ie = {0};
6205 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(pHostapdAdapter);
6206 beacon_data_t *beacon = pHostapdAdapter->sessionCtx.ap.beacon;
6207 uint8_t *ie = NULL;
6208
6209 ie = wlan_hdd_cfg80211_get_ie_ptr(beacon->tail, beacon->tail_len,
6210 WLAN_EID_HT_CAPABILITY);
6211 if (ie && ie[1]) {
6212 cdf_mem_copy(ht_cap_ie, &ie[2], DOT11F_IE_HTCAPS_MAX_LEN);
6213 dot11f_unpack_ie_ht_caps((tpAniSirGlobal)hdd_ctx->hHal,
6214 ht_cap_ie, ie[1], &dot11_ht_cap_ie);
6215 return dot11_ht_cap_ie.supportedChannelWidthSet;
6216 }
6217
6218 return false;
6219}
6220#else
6221static bool wlan_hdd_get_sap_obss(hdd_adapter_t *pHostapdAdapter)
6222{
6223 return false;
6224}
6225#endif
6226/**
6227 * wlan_hdd_set_channel() - set channel in sap mode
6228 * @wiphy: Pointer to wiphy structure
6229 * @dev: Pointer to net_device structure
6230 * @chandef: Pointer to channel definition structure
6231 * @channel_type: Channel type
6232 *
6233 * Return: 0 for success non-zero for failure
6234 */
6235static int wlan_hdd_set_channel(struct wiphy *wiphy,
6236 struct net_device *dev,
6237 struct cfg80211_chan_def *chandef,
6238 enum nl80211_channel_type channel_type)
6239{
6240 hdd_adapter_t *pAdapter = NULL;
6241 uint32_t num_ch = 0;
6242 int channel = 0;
6243 int channel_seg2 = 0;
6244 hdd_context_t *pHddCtx;
6245 int status;
6246
6247 tSmeConfigParams smeConfig;
6248 tsap_Config_t *sap_config;
6249
6250 ENTER();
6251
6252
6253 if (NULL == dev) {
6254 hddLog(LOGE, FL("Called with dev = NULL."));
6255 return -ENODEV;
6256 }
6257 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6258
6259 MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
6260 TRACE_CODE_HDD_CFG80211_SET_CHANNEL,
6261 pAdapter->sessionId, channel_type));
6262
6263 hddLog(LOG1, FL("Device_mode %s(%d) freq = %d"),
6264 hdd_device_mode_to_string(pAdapter->device_mode),
6265 pAdapter->device_mode, chandef->chan->center_freq);
6266
6267 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6268 status = wlan_hdd_validate_context(pHddCtx);
6269
6270 if (0 != status) {
6271 hddLog(LOGE, FL("HDD context is not valid"));
6272 return status;
6273 }
6274
6275 /*
6276 * Do freq to chan conversion
6277 * TODO: for 11a
6278 */
6279
6280 channel = ieee80211_frequency_to_channel(chandef->chan->center_freq);
6281 if (NL80211_CHAN_WIDTH_80P80 == chandef->width)
6282 channel_seg2 = ieee80211_frequency_to_channel(chandef->center_freq2);
6283 else
6284 channel_seg2 = 0;
6285
6286 /* Check freq range */
6287 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6288 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel)) {
6289 hddLog(LOGE,
6290 FL("Channel [%d] is outside valid range from %d to %d"),
6291 channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6292 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6293 return -EINVAL;
6294 }
6295
6296 /* Check freq range */
6297
6298 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel_seg2) ||
6299 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel_seg2)) {
6300 hddLog(LOGE,
6301 FL("Channel [%d] is outside valid range from %d to %d"),
6302 channel_seg2, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6303 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6304 return -EINVAL;
6305 }
6306
6307 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6308
6309 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6310 (WLAN_HDD_P2P_GO != pAdapter->device_mode)) {
6311 if (CDF_STATUS_SUCCESS !=
6312 wlan_hdd_validate_operation_channel(pAdapter, channel)) {
6313 hddLog(LOGE, FL("Invalid Channel [%d]"), channel);
6314 return -EINVAL;
6315 }
6316 hddLog(LOG2,
6317 FL("set channel to [%d] for device mode %s(%d)"),
6318 channel,
6319 hdd_device_mode_to_string(pAdapter->device_mode),
6320 pAdapter->device_mode);
6321 }
6322
6323 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
6324 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
6325 ) {
6326 hdd_wext_state_t *pWextState =
6327 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6328 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
6329 hdd_station_ctx_t *pHddStaCtx =
6330 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6331
6332 if (eConnectionState_IbssConnected ==
6333 pHddStaCtx->conn_info.connState) {
6334 /* Link is up then return cant set channel */
6335 hddLog(LOGE,
6336 FL("IBSS Associated, can't set the channel"));
6337 return -EINVAL;
6338 }
6339
6340 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6341 pHddStaCtx->conn_info.operationChannel = channel;
6342 pRoamProfile->ChannelInfo.ChannelList =
6343 &pHddStaCtx->conn_info.operationChannel;
6344 } else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
6345 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
6346 ) {
6347 sap_config = &((WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig);
6348 if (WLAN_HDD_P2P_GO == pAdapter->device_mode) {
6349 if (CDF_STATUS_SUCCESS !=
6350 wlan_hdd_validate_operation_channel(pAdapter,
6351 channel)) {
6352 hddLog(LOGE,
6353 FL("Invalid Channel [%d]"), channel);
6354 return -EINVAL;
6355 }
6356 sap_config->channel = channel;
6357 sap_config->ch_params.center_freq_seg1 = channel_seg2;
6358 } else {
6359 /* set channel to what hostapd configured */
6360 if (CDF_STATUS_SUCCESS !=
6361 wlan_hdd_validate_operation_channel(pAdapter,
6362 channel)) {
6363 hddLog(LOGE,
6364 FL("Invalid Channel [%d]"), channel);
6365 return -EINVAL;
6366 }
6367
6368 sap_config->channel = channel;
6369 sap_config->ch_params.center_freq_seg1 = channel_seg2;
6370
6371 cdf_mem_zero(&smeConfig, sizeof(smeConfig));
6372 sme_get_config_param(pHddCtx->hHal, &smeConfig);
6373 switch (channel_type) {
6374 case NL80211_CHAN_HT20:
6375 case NL80211_CHAN_NO_HT:
6376 smeConfig.csrConfig.obssEnabled = false;
6377 if (channel <= 14)
6378 smeConfig.csrConfig.
6379 channelBondingMode24GHz =
6380 eCSR_INI_SINGLE_CHANNEL_CENTERED;
6381 else
6382 smeConfig.csrConfig.
6383 channelBondingMode5GHz =
6384 eCSR_INI_SINGLE_CHANNEL_CENTERED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006385 sap_config->sec_ch = 0;
6386 break;
6387
6388 case NL80211_CHAN_HT40MINUS:
6389 if (channel <= 14)
6390 smeConfig.csrConfig.
6391 channelBondingMode24GHz =
6392 eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
6393 else
6394 smeConfig.csrConfig.
6395 channelBondingMode5GHz =
6396 eCSR_INI_DOUBLE_CHANNEL_HIGH_PRIMARY;
6397 sap_config->sec_ch = sap_config->channel - 4;
6398 break;
6399 case NL80211_CHAN_HT40PLUS:
6400 if (channel <= 14)
6401 smeConfig.csrConfig.
6402 channelBondingMode24GHz =
6403 eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
6404 else
6405 smeConfig.csrConfig.
6406 channelBondingMode5GHz =
6407 eCSR_INI_DOUBLE_CHANNEL_LOW_PRIMARY;
6408 sap_config->sec_ch = sap_config->channel + 4;
6409 break;
6410 default:
6411 hddLog(LOGE,
6412 FL("Error!!! Invalid HT20/40 mode !"));
6413 return -EINVAL;
6414 }
6415 smeConfig.csrConfig.obssEnabled = wlan_hdd_get_sap_obss(
6416 pAdapter);
6417 sme_update_config(pHddCtx->hHal, &smeConfig);
6418 }
6419 } else {
6420 hddLog(LOGE,
6421 FL("Invalid device mode failed to set valid channel"));
6422 return -EINVAL;
6423 }
6424 EXIT();
6425 return status;
6426}
6427
6428/**
6429 * wlan_hdd_check_11gmode() - check for 11g mode
6430 * @pIe: Pointer to IE
6431 * @require_ht: Pointer to require ht
6432 * @require_vht: Pointer to require vht
6433 * @pCheckRatesfor11g: Pointer to check rates for 11g mode
6434 * @pSapHw_mode: SAP HW mode
6435 *
6436 * Check for 11g rate and set proper 11g only mode
6437 *
6438 * Return: none
6439 */
6440static void wlan_hdd_check_11gmode(u8 *pIe, u8 *require_ht, u8 *require_vht,
6441 u8 *pCheckRatesfor11g,
6442 eCsrPhyMode *pSapHw_mode)
6443{
6444 u8 i, num_rates = pIe[0];
6445
6446 pIe += 1;
6447 for (i = 0; i < num_rates; i++) {
6448 if (*pCheckRatesfor11g
6449 && (true == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK))) {
6450 /* If rate set have 11g rate than change the mode
6451 * to 11G
6452 */
6453 *pSapHw_mode = eCSR_DOT11_MODE_11g;
6454 if (pIe[i] & BASIC_RATE_MASK) {
6455 /* If we have 11g rate as basic rate, it
6456 * means mode is 11g only mode.
6457 */
6458 *pSapHw_mode = eCSR_DOT11_MODE_11g_ONLY;
6459 *pCheckRatesfor11g = false;
6460 }
6461 } else {
6462 if ((BASIC_RATE_MASK |
6463 WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6464 *require_ht = true;
6465 else if ((BASIC_RATE_MASK |
6466 WLAN_BSS_MEMBERSHIP_SELECTOR_VHT_PHY) == pIe[i])
6467 *require_vht = true;
6468 }
6469 }
6470 return;
6471}
6472
6473/**
6474 * wlan_hdd_add_ie() - add ie
6475 * @pHostapdAdapter: Pointer to hostapd adapter
6476 * @genie: Pointer to ie to be added
6477 * @total_ielen: Pointer to store total ie length
6478 * @oui: Pointer to oui
6479 * @oui_size: Size of oui
6480 *
6481 * Return: 0 for success non-zero for failure
6482 */
6483static int wlan_hdd_add_ie(hdd_adapter_t *pHostapdAdapter, uint8_t *genie,
6484 uint8_t *total_ielen, uint8_t *oui,
6485 uint8_t oui_size)
6486{
6487 uint16_t ielen = 0;
6488 uint8_t *pIe = NULL;
6489 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6490
6491 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6492 pBeacon->tail, pBeacon->tail_len);
6493
6494 if (pIe) {
6495 ielen = pIe[1] + 2;
6496 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
6497 cdf_mem_copy(&genie[*total_ielen], pIe, ielen);
6498 } else {
6499 hddLog(LOGE,
6500 "**Ie Length is too big***");
6501 return -EINVAL;
6502 }
6503 *total_ielen += ielen;
6504 }
6505 return 0;
6506}
6507
6508/**
6509 * wlan_hdd_add_hostapd_conf_vsie() - configure vsie in sap mode
6510 * @pHostapdAdapter: Pointer to hostapd adapter
6511 * @genie: Pointer to vsie
6512 * @total_ielen: Pointer to store total ie length
6513 *
6514 * Return: none
6515 */
6516static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t *pHostapdAdapter,
6517 uint8_t *genie,
6518 uint8_t *total_ielen)
6519{
6520 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6521 int left = pBeacon->tail_len;
6522 uint8_t *ptr = pBeacon->tail;
6523 uint8_t elem_id, elem_len;
6524 uint16_t ielen = 0;
6525
6526 if (NULL == ptr || 0 == left)
6527 return;
6528
6529 while (left >= 2) {
6530 elem_id = ptr[0];
6531 elem_len = ptr[1];
6532 left -= 2;
6533 if (elem_len > left) {
6534 hddLog(LOGE,
6535 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
6536 elem_id, elem_len, left);
6537 return;
6538 }
6539 if (IE_EID_VENDOR == elem_id) {
6540 /* skipping the VSIE's which we don't want to include or
6541 * it will be included by existing code
6542 */
6543 if ((memcmp(&ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) !=
6544 0) &&
6545#ifdef WLAN_FEATURE_WFD
6546 (memcmp(&ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) !=
6547 0) &&
6548#endif
6549 (memcmp
6550 (&ptr[2], WHITELIST_OUI_TYPE,
6551 WPA_OUI_TYPE_SIZE) != 0)
6552 &&
6553 (memcmp
6554 (&ptr[2], BLACKLIST_OUI_TYPE,
6555 WPA_OUI_TYPE_SIZE) != 0)
6556 &&
6557 (memcmp
6558 (&ptr[2], "\x00\x50\xf2\x02",
6559 WPA_OUI_TYPE_SIZE) != 0)
6560 && (memcmp(&ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE)
6561 != 0)
6562 && (memcmp(&ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE)
6563 != 0)) {
6564 ielen = ptr[1] + 2;
6565 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
6566 cdf_mem_copy(&genie[*total_ielen], ptr,
6567 ielen);
6568 *total_ielen += ielen;
6569 } else {
6570 hddLog(LOGE,
6571 FL("IE Length is too big IEs eid=%d elem_len=%d total_ie_lent=%d"),
6572 elem_id, elem_len, *total_ielen);
6573 }
6574 }
6575 }
6576
6577 left -= elem_len;
6578 ptr += (elem_len + 2);
6579 }
6580 return;
6581}
6582
6583/**
6584 * wlan_hdd_add_extra_ie() - add extra ies in beacon
6585 * @pHostapdAdapter: Pointer to hostapd adapter
6586 * @genie: Pointer to extra ie
6587 * @total_ielen: Pointer to store total ie length
6588 * @temp_ie_id: ID of extra ie
6589 *
6590 * Return: none
6591 */
6592static void wlan_hdd_add_extra_ie(hdd_adapter_t *pHostapdAdapter,
6593 uint8_t *genie, uint8_t *total_ielen,
6594 uint8_t temp_ie_id)
6595{
6596 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6597 int left = pBeacon->tail_len;
6598 uint8_t *ptr = pBeacon->tail;
6599 uint8_t elem_id, elem_len;
6600 uint16_t ielen = 0;
6601
6602 if (NULL == ptr || 0 == left)
6603 return;
6604
6605 while (left >= 2) {
6606 elem_id = ptr[0];
6607 elem_len = ptr[1];
6608 left -= 2;
6609 if (elem_len > left) {
6610 hddLog(LOGE,
6611 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
6612 elem_id, elem_len, left);
6613 return;
6614 }
6615
6616 if (temp_ie_id == elem_id) {
6617 ielen = ptr[1] + 2;
6618 if ((*total_ielen + ielen) <= MAX_GENIE_LEN) {
6619 cdf_mem_copy(&genie[*total_ielen], ptr, ielen);
6620 *total_ielen += ielen;
6621 } else {
6622 hddLog(LOGE,
6623 FL("IE Length is too big IEs eid=%d elem_len=%d total_ie_lent=%d"),
6624 elem_id, elem_len, *total_ielen);
6625 }
6626 }
6627
6628 left -= elem_len;
6629 ptr += (elem_len + 2);
6630 }
6631 return;
6632}
6633
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006634/**
6635 * wlan_hdd_cfg80211_alloc_new_beacon() - alloc beacon in ap mode
6636 * @pAdapter: Pointer to hostapd adapter
6637 * @ppBeacon: Pointer to pointer to beacon data
6638 * @params: Pointer to beacon parameters
6639 * @dtim_period: DTIM period
6640 *
6641 * Return: 0 for success non-zero for failure
6642 */
6643int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
6644 beacon_data_t **ppBeacon,
6645 struct cfg80211_beacon_data *params,
6646 int dtim_period)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006647{
6648 int size;
6649 beacon_data_t *beacon = NULL;
6650 beacon_data_t *old = NULL;
6651 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
6652 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
6653
6654 ENTER();
6655 if (params->head && !params->head_len) {
6656 hddLog(LOGE, FL("head_len is NULL"));
6657 return -EINVAL;
6658 }
6659
6660 old = pAdapter->sessionCtx.ap.beacon;
6661
6662 if (!params->head && !old) {
6663 hddLog(LOGE, FL("session(%d) old and new heads points to NULL"),
6664 pAdapter->sessionId);
6665 return -EINVAL;
6666 }
6667
6668 if (params->head) {
6669 head_len = params->head_len;
6670 head = params->head;
6671 } else {
6672 head_len = old->head_len;
6673 head = old->head;
6674 }
6675
6676 if (params->tail || !old) {
6677 tail_len = params->tail_len;
6678 tail = params->tail;
6679 } else {
6680 tail_len = old->tail_len;
6681 tail = old->tail;
6682 }
6683
6684 if (params->proberesp_ies || !old) {
6685 proberesp_ies_len = params->proberesp_ies_len;
6686 proberesp_ies = params->proberesp_ies;
6687 } else {
6688 proberesp_ies_len = old->proberesp_ies_len;
6689 proberesp_ies = old->proberesp_ies;
6690 }
6691
6692 if (params->assocresp_ies || !old) {
6693 assocresp_ies_len = params->assocresp_ies_len;
6694 assocresp_ies = params->assocresp_ies;
6695 } else {
6696 assocresp_ies_len = old->assocresp_ies_len;
6697 assocresp_ies = old->assocresp_ies;
6698 }
6699
6700 size = sizeof(beacon_data_t) + head_len + tail_len +
6701 proberesp_ies_len + assocresp_ies_len;
6702
6703 beacon = kzalloc(size, GFP_KERNEL);
6704
6705 if (beacon == NULL) {
6706 hddLog(LOGE,
6707 FL("Mem allocation for beacon failed"));
6708 return -ENOMEM;
6709 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006710 if (dtim_period)
6711 beacon->dtim_period = dtim_period;
6712 else if (old)
6713 beacon->dtim_period = old->dtim_period;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006714 /* -----------------------------------------------
6715 * | head | tail | proberesp_ies | assocresp_ies |
6716 * -----------------------------------------------
6717 */
6718 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6719 beacon->tail = beacon->head + head_len;
6720 beacon->proberesp_ies = beacon->tail + tail_len;
6721 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
6722
6723 beacon->head_len = head_len;
6724 beacon->tail_len = tail_len;
6725 beacon->proberesp_ies_len = proberesp_ies_len;
6726 beacon->assocresp_ies_len = assocresp_ies_len;
6727
6728 if (head && head_len)
6729 memcpy(beacon->head, head, head_len);
6730 if (tail && tail_len)
6731 memcpy(beacon->tail, tail, tail_len);
6732 if (proberesp_ies && proberesp_ies_len)
6733 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
6734 if (assocresp_ies && assocresp_ies_len)
6735 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
6736
6737 *ppBeacon = beacon;
6738
6739 kfree(old);
6740
6741 return 0;
6742
6743}
6744
6745/**
6746 * wlan_hdd_cfg80211_update_apies() - update ap mode ies
6747 * @adapter: Pointer to hostapd adapter
6748 *
6749 * Return: 0 for success non-zero for failure
6750 */
6751int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *adapter)
6752{
6753 uint8_t *genie;
6754 uint8_t total_ielen = 0;
6755 int ret = 0;
6756 tsap_Config_t *pConfig;
6757 tSirUpdateIE updateIE;
6758 beacon_data_t *beacon = NULL;
6759
6760 pConfig = &adapter->sessionCtx.ap.sapConfig;
6761 beacon = adapter->sessionCtx.ap.beacon;
6762
6763 genie = cdf_mem_malloc(MAX_GENIE_LEN);
6764
6765 if (genie == NULL)
6766 return -ENOMEM;
6767
6768 if (0 != wlan_hdd_add_ie(adapter, genie,
6769 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE)) {
6770 hddLog(LOGE, FL("Adding WPS IE failed"));
6771 ret = -EINVAL;
6772 goto done;
6773 }
6774#ifdef WLAN_FEATURE_WFD
6775 if (0 != wlan_hdd_add_ie(adapter, genie,
6776 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE)) {
6777 hddLog(LOGE, FL("Adding WFD IE failed"));
6778 ret = -EINVAL;
6779 goto done;
6780 }
6781#endif
6782
6783#ifdef FEATURE_WLAN_WAPI
6784 if (WLAN_HDD_SOFTAP == adapter->device_mode) {
6785 wlan_hdd_add_extra_ie(adapter, genie, &total_ielen,
6786 WLAN_EID_WAPI);
6787 }
6788#endif
6789
6790 if (adapter->device_mode == WLAN_HDD_SOFTAP ||
6791 adapter->device_mode == WLAN_HDD_P2P_GO)
6792 wlan_hdd_add_hostapd_conf_vsie(adapter, genie,
6793 &total_ielen);
6794
6795 if (wlan_hdd_add_ie(adapter, genie,
6796 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0) {
6797 hddLog(LOGE, FL("Adding P2P IE failed"));
6798 ret = -EINVAL;
6799 goto done;
6800 }
6801
6802#ifdef QCA_HT_2040_COEX
6803 if (WLAN_HDD_SOFTAP == adapter->device_mode) {
6804 tSmeConfigParams smeConfig;
6805 cdf_mem_zero(&smeConfig, sizeof(smeConfig));
6806 sme_get_config_param(WLAN_HDD_GET_HAL_CTX(adapter),
6807 &smeConfig);
6808 if (smeConfig.csrConfig.obssEnabled)
6809 wlan_hdd_add_extra_ie(adapter, genie,
6810 &total_ielen,
6811 WLAN_EID_OVERLAP_BSS_SCAN_PARAM);
6812 }
6813#endif
Srinivas Girigowda8b983962015-11-18 22:14:34 -08006814 cdf_copy_macaddr(&updateIE.bssid, &adapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006815 updateIE.smeSessionId = adapter->sessionId;
6816
6817 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6818 updateIE.ieBufferlength = total_ielen;
6819 updateIE.pAdditionIEBuffer = genie;
6820 updateIE.append = false;
6821 updateIE.notify = true;
6822 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6823 &updateIE,
6824 eUPDATE_IE_PROBE_BCN) ==
6825 CDF_STATUS_E_FAILURE) {
6826 hddLog(LOGE,
6827 FL("Could not pass on Add Ie probe beacon data"));
6828 ret = -EINVAL;
6829 goto done;
6830 }
6831 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_BCN);
6832 } else {
6833 wlansap_update_sap_config_add_ie(pConfig,
6834 genie,
6835 total_ielen,
6836 eUPDATE_IE_PROBE_BCN);
6837 }
6838
6839 /* Added for Probe Response IE */
6840 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6841 updateIE.ieBufferlength = beacon->proberesp_ies_len;
6842 updateIE.pAdditionIEBuffer = (uint8_t *) beacon->proberesp_ies;
6843 updateIE.append = false;
6844 updateIE.notify = false;
6845 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6846 &updateIE,
6847 eUPDATE_IE_PROBE_RESP) ==
6848 CDF_STATUS_E_FAILURE) {
6849 hddLog(LOGE,
6850 FL("Could not pass on PROBE_RESP add Ie data"));
6851 ret = -EINVAL;
6852 goto done;
6853 }
6854 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_PROBE_RESP);
6855 } else {
6856 wlansap_update_sap_config_add_ie(pConfig,
6857 beacon->proberesp_ies,
6858 beacon->proberesp_ies_len,
6859 eUPDATE_IE_PROBE_RESP);
6860 }
6861
6862 /* Assoc resp Add ie Data */
6863 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6864 updateIE.ieBufferlength = beacon->assocresp_ies_len;
6865 updateIE.pAdditionIEBuffer = (uint8_t *) beacon->assocresp_ies;
6866 updateIE.append = false;
6867 updateIE.notify = false;
6868 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(adapter),
6869 &updateIE,
6870 eUPDATE_IE_ASSOC_RESP) ==
6871 CDF_STATUS_E_FAILURE) {
6872 hddLog(LOGE,
6873 FL("Could not pass on Add Ie Assoc Response data"));
6874 ret = -EINVAL;
6875 goto done;
6876 }
6877 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ASSOC_RESP);
6878 } else {
6879 wlansap_update_sap_config_add_ie(pConfig,
6880 beacon->assocresp_ies,
6881 beacon->assocresp_ies_len,
6882 eUPDATE_IE_ASSOC_RESP);
6883 }
6884
6885done:
6886 cdf_mem_free(genie);
6887 return ret;
6888}
6889
6890/**
6891 * wlan_hdd_set_sap_hwmode() - set sap hw mode
6892 * @pHostapdAdapter: Pointer to hostapd adapter
6893 *
6894 * Return: none
6895 */
6896static void wlan_hdd_set_sap_hwmode(hdd_adapter_t *pHostapdAdapter)
6897{
6898 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6899 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6900 struct ieee80211_mgmt *pMgmt_frame =
6901 (struct ieee80211_mgmt *)pBeacon->head;
6902 u8 checkRatesfor11g = true;
6903 u8 require_ht = false, require_vht = false;
6904 u8 *pIe = NULL;
6905
6906 pConfig->SapHw_mode = eCSR_DOT11_MODE_11b;
6907
6908 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6909 pBeacon->head_len,
6910 WLAN_EID_SUPP_RATES);
6911 if (pIe != NULL) {
6912 pIe += 1;
6913 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
6914 &checkRatesfor11g, &pConfig->SapHw_mode);
6915 }
6916
6917 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6918 WLAN_EID_EXT_SUPP_RATES);
6919 if (pIe != NULL) {
6920 pIe += 1;
6921 wlan_hdd_check_11gmode(pIe, &require_ht, &require_vht,
6922 &checkRatesfor11g, &pConfig->SapHw_mode);
6923 }
6924
6925 if (pConfig->channel > 14)
6926 pConfig->SapHw_mode = eCSR_DOT11_MODE_11a;
6927
6928 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6929 WLAN_EID_HT_CAPABILITY);
6930
6931 if (pIe) {
6932 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n;
6933 if (require_ht)
6934 pConfig->SapHw_mode = eCSR_DOT11_MODE_11n_ONLY;
6935 }
6936
6937 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6938 WLAN_EID_VHT_CAPABILITY);
6939
6940 if (pIe) {
6941 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac;
6942 if (require_vht)
6943 pConfig->SapHw_mode = eCSR_DOT11_MODE_11ac_ONLY;
6944 }
6945}
6946
6947/**
6948 * wlan_hdd_config_acs() - config ACS needed parameters
6949 * @hdd_ctx: HDD context
6950 * @adapter: Adapter pointer
6951 *
6952 * This function get ACS related INI paramters and populated
6953 * sap config and smeConfig for ACS needed configurations.
6954 *
6955 * Return: The CDF_STATUS code associated with performing the operation.
6956 */
6957CDF_STATUS wlan_hdd_config_acs(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter)
6958{
6959 tsap_Config_t *sap_config;
6960 struct hdd_config *ini_config;
6961 tHalHandle hal;
6962
6963 hal = WLAN_HDD_GET_HAL_CTX(adapter);
6964 sap_config = &adapter->sessionCtx.ap.sapConfig;
6965 ini_config = hdd_ctx->config;
6966
6967 sap_config->enOverLapCh = !!hdd_ctx->config->gEnableOverLapCh;
6968
6969#if defined(WLAN_FEATURE_MBSSID) && defined(FEATURE_WLAN_AP_AP_ACS_OPTIMIZE)
6970 hddLog(LOG1, FL("HDD_ACS_SKIP_STATUS = %d"),
6971 hdd_ctx->skip_acs_scan_status);
6972 if (hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN) {
6973 hdd_adapter_t *con_sap_adapter;
6974 tsap_Config_t *con_sap_config = NULL;
6975
6976 con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);
6977
6978 if (con_sap_adapter)
6979 con_sap_config =
6980 &con_sap_adapter->sessionCtx.ap.sapConfig;
6981
6982 sap_config->acs_cfg.skip_scan_status = eSAP_DO_NEW_ACS_SCAN;
6983
6984 if (con_sap_config &&
6985 con_sap_config->acs_cfg.acs_mode == true &&
6986 hdd_ctx->skip_acs_scan_status == eSAP_SKIP_ACS_SCAN &&
6987 con_sap_config->acs_cfg.hw_mode ==
6988 sap_config->acs_cfg.hw_mode) {
6989 uint8_t con_sap_st_ch, con_sap_end_ch;
6990 uint8_t cur_sap_st_ch, cur_sap_end_ch;
6991 uint8_t bandStartChannel, bandEndChannel;
6992
6993 con_sap_st_ch =
6994 con_sap_config->acs_cfg.start_ch;
6995 con_sap_end_ch =
6996 con_sap_config->acs_cfg.end_ch;
6997 cur_sap_st_ch = sap_config->acs_cfg.start_ch;
6998 cur_sap_end_ch = sap_config->acs_cfg.end_ch;
6999
7000 wlansap_extend_to_acs_range(
7001 &cur_sap_st_ch, &cur_sap_end_ch,
7002 &bandStartChannel, &bandEndChannel);
7003
7004 wlansap_extend_to_acs_range(
7005 &con_sap_st_ch, &con_sap_end_ch,
7006 &bandStartChannel, &bandEndChannel);
7007
7008 if (con_sap_st_ch <= cur_sap_st_ch &&
7009 con_sap_end_ch >= cur_sap_end_ch) {
7010 sap_config->acs_cfg.skip_scan_status =
7011 eSAP_SKIP_ACS_SCAN;
7012
7013 } else if (con_sap_st_ch >= cur_sap_st_ch &&
7014 con_sap_end_ch >= cur_sap_end_ch) {
7015 sap_config->acs_cfg.skip_scan_status =
7016 eSAP_DO_PAR_ACS_SCAN;
7017
7018 sap_config->acs_cfg.skip_scan_range1_stch =
7019 cur_sap_st_ch;
7020 sap_config->acs_cfg.skip_scan_range1_endch =
7021 con_sap_st_ch - 1;
7022 sap_config->acs_cfg.skip_scan_range2_stch =
7023 0;
7024 sap_config->acs_cfg.skip_scan_range2_endch =
7025 0;
7026
7027 } else if (con_sap_st_ch <= cur_sap_st_ch &&
7028 con_sap_end_ch <= cur_sap_end_ch) {
7029 sap_config->acs_cfg.skip_scan_status =
7030 eSAP_DO_PAR_ACS_SCAN;
7031
7032 sap_config->acs_cfg.skip_scan_range1_stch =
7033 con_sap_end_ch + 1;
7034 sap_config->acs_cfg.skip_scan_range1_endch =
7035 cur_sap_end_ch;
7036 sap_config->acs_cfg.skip_scan_range2_stch =
7037 0;
7038 sap_config->acs_cfg.skip_scan_range2_endch =
7039 0;
7040
7041 } else if (con_sap_st_ch >= cur_sap_st_ch &&
7042 con_sap_end_ch <= cur_sap_end_ch) {
7043 sap_config->acs_cfg.skip_scan_status =
7044 eSAP_DO_PAR_ACS_SCAN;
7045
7046 sap_config->acs_cfg.skip_scan_range1_stch =
7047 cur_sap_st_ch;
7048 sap_config->acs_cfg.skip_scan_range1_endch =
7049 con_sap_st_ch - 1;
7050 sap_config->acs_cfg.skip_scan_range2_stch =
7051 con_sap_end_ch;
7052 sap_config->acs_cfg.skip_scan_range2_endch =
7053 cur_sap_end_ch + 1;
7054
7055 } else
7056 sap_config->acs_cfg.skip_scan_status =
7057 eSAP_DO_NEW_ACS_SCAN;
7058
7059
7060 hddLog(LOG1, FL(
7061 "SecAP ACS Skip=%d, ACS CH RANGE=%d-%d, %d-%d"),
7062 sap_config->acs_cfg.skip_scan_status,
7063 sap_config->acs_cfg.skip_scan_range1_stch,
7064 sap_config->acs_cfg.skip_scan_range1_endch,
7065 sap_config->acs_cfg.skip_scan_range2_stch,
7066 sap_config->acs_cfg.skip_scan_range2_endch);
7067 }
7068 }
7069#endif
7070
7071 return CDF_STATUS_SUCCESS;
7072}
7073
7074/**
7075 * wlan_hdd_setup_driver_overrides : Overrides SAP / P2P GO Params
7076 * @adapter: pointer to adapter struct
7077 *
7078 * This function overrides SAP / P2P Go configuration based on driver INI
7079 * parameters for 11AC override and ACS. This overrides are done to support
7080 * android legacy configuration method.
7081 *
7082 * NOTE: Non android platform supports concurrency and these overrides shall
7083 * not be used. Also future driver based overrides shall be consolidated in this
7084 * function only. Avoid random overrides in other location based on ini.
7085 *
7086 * Return: 0 for Success or Negative error codes.
7087 */
7088int wlan_hdd_setup_driver_overrides(hdd_adapter_t *ap_adapter)
7089{
7090 tsap_Config_t *sap_cfg = &ap_adapter->sessionCtx.ap.sapConfig;
7091 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
7092 tHalHandle h_hal = WLAN_HDD_GET_HAL_CTX(ap_adapter);
7093
7094 if (ap_adapter->device_mode == WLAN_HDD_SOFTAP &&
7095 hdd_ctx->config->force_sap_acs)
7096 goto setup_acs_overrides;
7097
7098 /* Fixed channel 11AC override:
7099 * 11AC override in qcacld is introduced for following reasons:
7100 * 1. P2P GO also follows start_bss and since p2p GO could not be
7101 * configured to setup VHT channel width in wpa_supplicant
7102 * 2. Android UI does not provide advanced configuration options for SAP
7103 *
7104 * Default override enabled (for android). MDM shall disable this in ini
7105 */
7106 if (hdd_ctx->config->sap_p2p_11ac_override &&
7107 (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
7108 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
7109 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY)) {
7110 hddLog(LOG1, FL("** Driver force 11AC override for SAP/Go **"));
7111
7112 /* 11n only shall not be overridden since it may be on purpose*/
7113 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n)
7114 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
7115
7116 if (sap_cfg->channel >= 36)
7117 sap_cfg->ch_width_orig =
7118 hdd_ctx->config->vhtChannelWidth;
7119 else
7120 sap_cfg->ch_width_orig =
7121 hdd_ctx->config->nChannelBondingMode24GHz ?
7122 eHT_CHANNEL_WIDTH_40MHZ :
7123 eHT_CHANNEL_WIDTH_20MHZ;
7124 }
7125 sap_cfg->ch_params.ch_width = sap_cfg->ch_width_orig;
7126 sme_set_ch_params(h_hal, sap_cfg->SapHw_mode, sap_cfg->channel,
7127 sap_cfg->sec_ch, &sap_cfg->ch_params);
7128
7129 return 0;
7130
7131setup_acs_overrides:
7132 hddLog(LOGE, FL("** Driver force ACS override **"));
7133
7134 sap_cfg->channel = AUTO_CHANNEL_SELECT;
7135 sap_cfg->acs_cfg.acs_mode = true;
7136 sap_cfg->acs_cfg.start_ch = hdd_ctx->config->force_sap_acs_st_ch;
7137 sap_cfg->acs_cfg.end_ch = hdd_ctx->config->force_sap_acs_end_ch;
7138
7139 if (sap_cfg->acs_cfg.start_ch > sap_cfg->acs_cfg.end_ch) {
7140 hddLog(LOGE, FL("Driver force ACS start ch (%d) > end ch (%d)"),
7141 sap_cfg->acs_cfg.start_ch, sap_cfg->acs_cfg.end_ch);
7142 return -EINVAL;
7143 }
7144
7145 /* Derive ACS HW mode */
7146 sap_cfg->SapHw_mode = hdd_cfg_xlate_to_csr_phy_mode(
7147 hdd_ctx->config->dot11Mode);
7148 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_AUTO)
7149 sap_cfg->SapHw_mode = eCSR_DOT11_MODE_11ac;
7150
7151 if ((sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11b ||
7152 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11g ||
7153 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11g_ONLY) &&
7154 sap_cfg->acs_cfg.start_ch > 14) {
7155 hddLog(LOGE, FL("Invalid ACS HW Mode %d + CH range <%d - %d>"),
7156 sap_cfg->SapHw_mode, sap_cfg->acs_cfg.start_ch,
7157 sap_cfg->acs_cfg.end_ch);
7158 return -EINVAL;
7159 }
7160 sap_cfg->acs_cfg.hw_mode = sap_cfg->SapHw_mode;
7161
7162 /* Derive ACS BW */
7163 sap_cfg->ch_width_orig = eHT_CHANNEL_WIDTH_20MHZ;
7164 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac ||
7165 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11ac_ONLY) {
7166
7167 sap_cfg->ch_width_orig = hdd_ctx->config->vhtChannelWidth;
7168 /* VHT in 2.4G depends on gChannelBondingMode24GHz INI param */
7169 if (sap_cfg->acs_cfg.end_ch <= 14)
7170 sap_cfg->ch_width_orig =
7171 hdd_ctx->config->nChannelBondingMode24GHz ?
7172 eHT_CHANNEL_WIDTH_40MHZ :
7173 eHT_CHANNEL_WIDTH_20MHZ;
7174 }
7175
7176 if (sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n ||
7177 sap_cfg->SapHw_mode == eCSR_DOT11_MODE_11n_ONLY) {
7178 if (sap_cfg->acs_cfg.end_ch <= 14)
7179 sap_cfg->ch_width_orig =
7180 hdd_ctx->config->nChannelBondingMode24GHz ?
7181 eHT_CHANNEL_WIDTH_40MHZ :
7182 eHT_CHANNEL_WIDTH_20MHZ;
7183 else
7184 sap_cfg->ch_width_orig =
7185 hdd_ctx->config->nChannelBondingMode5GHz ?
7186 eHT_CHANNEL_WIDTH_40MHZ :
7187 eHT_CHANNEL_WIDTH_20MHZ;
7188 }
7189 sap_cfg->acs_cfg.ch_width = sap_cfg->ch_width_orig;
7190
7191 hddLog(LOG1, FL("Force ACS Config: HW_MODE: %d ACS_BW: %d"),
7192 sap_cfg->acs_cfg.hw_mode, sap_cfg->acs_cfg.ch_width);
7193 hddLog(LOG1, FL("Force ACS Config: ST_CH: %d END_CH: %d"),
7194 sap_cfg->acs_cfg.start_ch, sap_cfg->acs_cfg.end_ch);
7195
7196 return 0;
7197}
7198
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007199/**
7200 * wlan_hdd_cfg80211_start_bss() - start bss
7201 * @pHostapdAdapter: Pointer to hostapd adapter
7202 * @params: Pointer to start bss beacon parameters
7203 * @ssid: Pointer ssid
7204 * @ssid_len: Length of ssid
7205 * @hidden_ssid: Hidden SSID parameter
7206 *
7207 * Return: 0 for success non-zero for failure
7208 */
7209static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7210 struct cfg80211_beacon_data *params,
7211 const u8 *ssid, size_t ssid_len,
7212 enum nl80211_hidden_ssid hidden_ssid)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007213{
7214 tsap_Config_t *pConfig;
7215 beacon_data_t *pBeacon = NULL;
7216 struct ieee80211_mgmt *pMgmt_frame;
7217 uint8_t *pIe = NULL;
7218 uint16_t capab_info;
7219 eCsrAuthType RSNAuthType;
7220 eCsrEncryptionType RSNEncryptType;
7221 eCsrEncryptionType mcRSNEncryptType;
7222 int status = CDF_STATUS_SUCCESS, ret;
7223 tpWLAN_SAPEventCB pSapEventCallback;
7224 hdd_hostapd_state_t *pHostapdState;
7225#ifndef WLAN_FEATURE_MBSSID
7226 v_CONTEXT_t p_cds_context =
7227 (WLAN_HDD_GET_CTX(pHostapdAdapter))->pcds_context;
7228#endif
7229 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
7230 struct qc_mac_acl_entry *acl_entry = NULL;
7231 int32_t i;
7232 struct hdd_config *iniConfig;
7233 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
7234 tSmeConfigParams sme_config;
7235 bool MFPCapable = false;
7236 bool MFPRequired = false;
7237 uint16_t prev_rsn_length = 0;
7238 ENTER();
7239
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007240 if (cds_is_connection_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007241 hdd_err("Can't start BSS: connection is in progress");
7242 return -EINVAL;
7243 }
7244
7245 iniConfig = pHddCtx->config;
7246 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7247
7248 clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
7249 clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);
7250
7251 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7252
7253 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7254
7255 pMgmt_frame = (struct ieee80211_mgmt *)pBeacon->head;
7256
7257 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7258
7259 pConfig->disableDFSChSwitch = iniConfig->disableDFSChSwitch;
7260
7261 /* channel is already set in the set_channel Call back */
7262 /* pConfig->channel = pCommitConfig->channel; */
7263
7264 /* Protection parameter to enable or disable */
7265 pConfig->protEnabled = iniConfig->apProtEnabled;
7266
7267 pConfig->dtim_period = pBeacon->dtim_period;
7268
7269 hddLog(LOG2, FL("****pConfig->dtim_period=%d***"),
7270 pConfig->dtim_period);
7271
7272 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
7273 pIe =
7274 wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail,
7275 pBeacon->tail_len,
7276 WLAN_EID_COUNTRY);
7277 if (pIe) {
7278 pConfig->ieee80211d = 1;
7279 cdf_mem_copy(pConfig->countryCode, &pIe[2], 3);
7280 sme_set_reg_info(hHal, pConfig->countryCode);
7281 sme_apply_channel_power_info_to_fw(hHal);
7282 } else {
7283 pConfig->countryCode[0] = pHddCtx->reg.alpha2[0];
7284 pConfig->countryCode[1] = pHddCtx->reg.alpha2[1];
7285 pConfig->ieee80211d = 0;
7286 }
7287
7288 ret = wlan_hdd_sap_cfg_dfs_override(pHostapdAdapter);
7289 if (ret < 0) {
7290 return ret;
7291 } else {
7292 if (ret == 0) {
7293 if (CDS_IS_DFS_CH(pConfig->channel))
7294 pHddCtx->dev_dfs_cac_status =
7295 DFS_CAC_NEVER_DONE;
7296 }
7297 }
7298
7299 if (CDF_STATUS_SUCCESS !=
7300 wlan_hdd_validate_operation_channel(pHostapdAdapter,
7301 pConfig->channel)) {
7302 hddLog(LOGE, FL("Invalid Channel [%d]"),
7303 pConfig->channel);
7304 return -EINVAL;
7305 }
7306
7307 /* reject SAP if DFS channel scan is not allowed */
7308 if (!(pHddCtx->config->enableDFSChnlScan) &&
7309 (CHANNEL_STATE_DFS == cds_get_channel_state(
7310 pConfig->channel))) {
7311 hddLog(LOGE,
7312 FL("not allowed to start SAP on DFS channel"));
7313 return -EOPNOTSUPP;
7314 }
7315 wlansap_set_dfs_ignore_cac(hHal, iniConfig->ignoreCAC);
7316 wlansap_set_dfs_restrict_japan_w53(hHal,
7317 iniConfig->gDisableDfsJapanW53);
7318 wlansap_set_dfs_preferred_channel_location(hHal,
7319 iniConfig->gSapPreferredChanLocation);
7320#ifdef FEATURE_AP_MCC_CH_AVOIDANCE
7321 wlan_sap_set_channel_avoidance(hHal,
7322 iniConfig->sap_channel_avoidance);
7323#endif
7324 } else if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
7325 pConfig->countryCode[0] = pHddCtx->reg.alpha2[0];
7326 pConfig->countryCode[1] = pHddCtx->reg.alpha2[1];
7327 pConfig->ieee80211d = 0;
7328 } else {
7329 pConfig->ieee80211d = 0;
7330 }
7331
7332 capab_info = pMgmt_frame->u.beacon.capab_info;
7333
7334 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
7335 WLAN_CAPABILITY_PRIVACY) ? true : false;
7336
7337 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7338
7339 /*Set wps station to configured */
7340 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7341
7342 if (pIe) {
7343 if (pIe[1] < (2 + WPS_OUI_TYPE_SIZE)) {
7344 hddLog(LOGE,
7345 FL("**Wps Ie Length is too small***"));
7346 return -EINVAL;
7347 } else if (memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) ==
7348 0) {
7349 hddLog(LOG1, FL("** WPS IE(len %d) ***"), (pIe[1] + 2));
7350 /* Check 15 bit of WPS IE as it contain information for
7351 * wps state
7352 */
7353 if (SAP_WPS_ENABLED_UNCONFIGURED == pIe[15]) {
7354 pConfig->wps_state =
7355 SAP_WPS_ENABLED_UNCONFIGURED;
7356 } else if (SAP_WPS_ENABLED_CONFIGURED == pIe[15]) {
7357 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7358 }
7359 }
7360 } else {
7361 hdd_info("WPS disabled");
7362 pConfig->wps_state = SAP_WPS_DISABLED;
7363 }
7364 /* Forward WPS PBC probe request frame up */
7365 pConfig->fwdWPSPBCProbeReq = 1;
7366
7367 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7368 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7369 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7370 eCSR_ENCRYPT_TYPE_NONE;
7371
7372 pConfig->RSNWPAReqIELength = 0;
7373 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
7374 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7375 WLAN_EID_RSN);
7376 if (pIe && pIe[1]) {
7377 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7378 if (pConfig->RSNWPAReqIELength < sizeof(pConfig->RSNWPAReqIE))
7379 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
7380 pConfig->RSNWPAReqIELength);
7381 else
7382 hddLog(LOGE,
7383 FL("RSNWPA IE MAX Length exceeded; length =%d"),
7384 pConfig->RSNWPAReqIELength);
7385 /* The actual processing may eventually be more extensive than
7386 * this. Right now, just consume any PMKIDs that are sent in
7387 * by the app.
7388 * */
7389 status =
7390 hdd_softap_unpack_ie(cds_get_context
7391 (CDF_MODULE_ID_SME),
7392 &RSNEncryptType, &mcRSNEncryptType,
7393 &RSNAuthType, &MFPCapable,
7394 &MFPRequired,
7395 pConfig->RSNWPAReqIE[1] + 2,
7396 pConfig->RSNWPAReqIE);
7397
7398 if (CDF_STATUS_SUCCESS == status) {
7399 /* Now copy over all the security attributes you have
7400 * parsed out. Use the cipher type in the RSN IE
7401 */
7402 pConfig->RSNEncryptType = RSNEncryptType;
7403 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7404 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
7405 ucEncryptType = RSNEncryptType;
7406 hddLog(LOG1,
7407 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
7408 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7409 }
7410 }
7411
7412 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7413 pBeacon->tail, pBeacon->tail_len);
7414
7415 if (pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA)) {
7416 if (pConfig->RSNWPAReqIE[0]) {
7417 /*Mixed mode WPA/WPA2 */
7418 prev_rsn_length = pConfig->RSNWPAReqIELength;
7419 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7420 if (pConfig->RSNWPAReqIELength <
7421 sizeof(pConfig->RSNWPAReqIE))
7422 memcpy(&pConfig->RSNWPAReqIE[0] +
7423 prev_rsn_length, pIe, pIe[1] + 2);
7424 else
7425 hddLog(LOGE,
7426 "RSNWPA IE MAX Length exceeded; length =%d",
7427 pConfig->RSNWPAReqIELength);
7428 } else {
7429 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7430 if (pConfig->RSNWPAReqIELength <
7431 sizeof(pConfig->RSNWPAReqIE))
7432 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
7433 pConfig->RSNWPAReqIELength);
7434 else
7435 hddLog(LOGE,
7436 "RSNWPA IE MAX Length exceeded; length =%d",
7437 pConfig->RSNWPAReqIELength);
7438 status = hdd_softap_unpack_ie
7439 (cds_get_context(CDF_MODULE_ID_SME),
7440 &RSNEncryptType,
7441 &mcRSNEncryptType, &RSNAuthType,
7442 &MFPCapable, &MFPRequired,
7443 pConfig->RSNWPAReqIE[1] + 2,
7444 pConfig->RSNWPAReqIE);
7445
7446 if (CDF_STATUS_SUCCESS == status) {
7447 /* Now copy over all the security attributes
7448 * you have parsed out. Use the cipher type
7449 * in the RSN IE
7450 */
7451 pConfig->RSNEncryptType = RSNEncryptType;
7452 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7453 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->
7454 ucEncryptType = RSNEncryptType;
7455 hddLog(LOG1,
7456 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
7457 RSNAuthType, RSNEncryptType,
7458 mcRSNEncryptType);
7459 }
7460 }
7461 }
7462
7463 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
7464 hddLog(LOGE,
7465 FL("**RSNWPAReqIELength is too large***"));
7466 return -EINVAL;
7467 }
7468
7469 pConfig->SSIDinfo.ssidHidden = false;
7470
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007471 if (ssid != NULL) {
7472 cdf_mem_copy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7473 pConfig->SSIDinfo.ssid.length = ssid_len;
7474
7475 switch (hidden_ssid) {
7476 case NL80211_HIDDEN_SSID_NOT_IN_USE:
7477 hddLog(LOG1, "HIDDEN_SSID_NOT_IN_USE");
7478 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_NOT_IN_USE;
7479 break;
7480 case NL80211_HIDDEN_SSID_ZERO_LEN:
7481 hddLog(LOG1, "HIDDEN_SSID_ZERO_LEN");
7482 pConfig->SSIDinfo.ssidHidden = eHIDDEN_SSID_ZERO_LEN;
7483 break;
7484 case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
7485 hddLog(LOG1, "HIDDEN_SSID_ZERO_CONTENTS");
7486 pConfig->SSIDinfo.ssidHidden =
7487 eHIDDEN_SSID_ZERO_CONTENTS;
7488 break;
7489 default:
7490 hddLog(LOGE, "Wrong hidden_ssid param %d", hidden_ssid);
7491 break;
7492 }
7493 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007494
7495 cdf_mem_copy(pConfig->self_macaddr.bytes,
7496 pHostapdAdapter->macAddressCurrent.bytes,
7497 CDF_MAC_ADDR_SIZE);
7498
7499 /* default value */
7500 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7501 pConfig->num_accept_mac = 0;
7502 pConfig->num_deny_mac = 0;
7503#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
7504 /*
7505 * We don't want P2PGO to follow STA's channel
7506 * so lets limit the logic for SAP only.
7507 * Later if we decide to make p2pgo follow STA's
7508 * channel then remove this check.
7509 */
7510 if ((0 == pHddCtx->config->conc_custom_rule1) ||
7511 (pHddCtx->config->conc_custom_rule1 &&
7512 WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode))
7513 pConfig->cc_switch_mode = iniConfig->WlanMccToSccSwitchMode;
7514#endif
7515
7516 pIe =
7517 wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE,
7518 WPA_OUI_TYPE_SIZE, pBeacon->tail,
7519 pBeacon->tail_len);
7520
7521 /* pIe for black list is following form:
7522 * type : 1 byte
7523 * length : 1 byte
7524 * OUI : 4 bytes
7525 * acl type : 1 byte
7526 * no of mac addr in black list: 1 byte
7527 * list of mac_acl_entries: variable, 6 bytes per mac
7528 * address + sizeof(int) for vlan id
7529 */
7530 if ((pIe != NULL) && (pIe[1] != 0)) {
7531 pConfig->SapMacaddr_acl = pIe[6];
7532 pConfig->num_deny_mac = pIe[7];
7533 hddLog(LOG1,
7534 FL("acl type = %d no deny mac = %d"), pIe[6], pIe[7]);
7535 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7536 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
7537 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7538 for (i = 0; i < pConfig->num_deny_mac; i++) {
7539 cdf_mem_copy(&pConfig->deny_mac[i], acl_entry->addr,
7540 sizeof(qcmacaddr));
7541 acl_entry++;
7542 }
7543 }
7544 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE,
7545 WPA_OUI_TYPE_SIZE, pBeacon->tail,
7546 pBeacon->tail_len);
7547
7548 /* pIe for white list is following form:
7549 * type : 1 byte
7550 * length : 1 byte
7551 * OUI : 4 bytes
7552 * acl type : 1 byte
7553 * no of mac addr in white list: 1 byte
7554 * list of mac_acl_entries: variable, 6 bytes per mac
7555 * address + sizeof(int) for vlan id
7556 */
7557 if ((pIe != NULL) && (pIe[1] != 0)) {
7558 pConfig->SapMacaddr_acl = pIe[6];
7559 pConfig->num_accept_mac = pIe[7];
7560 hddLog(LOG1, FL("acl type = %d no accept mac = %d"),
7561 pIe[6], pIe[7]);
7562 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7563 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
7564 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7565 for (i = 0; i < pConfig->num_accept_mac; i++) {
7566 cdf_mem_copy(&pConfig->accept_mac[i], acl_entry->addr,
7567 sizeof(qcmacaddr));
7568 acl_entry++;
7569 }
7570 }
7571
7572 wlan_hdd_set_sap_hwmode(pHostapdAdapter);
7573 cdf_mem_zero(&sme_config, sizeof(tSmeConfigParams));
7574 sme_get_config_param(pHddCtx->hHal, &sme_config);
7575 /* Override hostapd.conf wmm_enabled only for 11n and 11AC configs (IOT)
7576 * As per spec 11N/AC STA are QOS STA and may not connect or throughput
7577 * may not be good with non QOS 11N AP
7578 * Default: enable QOS for SAP unless WMM IE not present for 11bga
7579 */
7580 sme_config.csrConfig.WMMSupportMode = eCsrRoamWmmAuto;
7581 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WMM_OUI_TYPE, WMM_OUI_TYPE_SIZE,
7582 pBeacon->tail, pBeacon->tail_len);
7583 if (!pIe && (pConfig->SapHw_mode == eCSR_DOT11_MODE_11a ||
7584 pConfig->SapHw_mode == eCSR_DOT11_MODE_11g ||
7585 pConfig->SapHw_mode == eCSR_DOT11_MODE_11b))
7586 sme_config.csrConfig.WMMSupportMode = eCsrRoamWmmNoQos;
7587 sme_update_config(pHddCtx->hHal, &sme_config);
7588
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007589 if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_80P80) {
7590 if (pHddCtx->isVHT80Allowed == false)
7591 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7592 else
7593 pConfig->ch_width_orig = CH_WIDTH_80P80MHZ;
7594 } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_160) {
7595 if (pHddCtx->isVHT80Allowed == false)
7596 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7597 else
7598 pConfig->ch_width_orig = CH_WIDTH_160MHZ;
7599 } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_80) {
7600 if (pHddCtx->isVHT80Allowed == false)
7601 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7602 else
7603 pConfig->ch_width_orig = CH_WIDTH_80MHZ;
7604 } else if (pConfig->ch_width_orig == NL80211_CHAN_WIDTH_40) {
7605 pConfig->ch_width_orig = CH_WIDTH_40MHZ;
7606 } else {
7607 pConfig->ch_width_orig = CH_WIDTH_20MHZ;
7608 }
7609
7610 if (wlan_hdd_setup_driver_overrides(pHostapdAdapter))
7611 return -EINVAL;
7612
7613 /* ht_capab is not what the name conveys,this is used for protection
7614 * bitmap */
7615 pConfig->ht_capab = iniConfig->apProtection;
7616
7617 if (0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter)) {
7618 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7619 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7620 return -EINVAL;
7621 }
7622 /* Uapsd Enabled Bit */
7623 pConfig->UapsdEnable = iniConfig->apUapsdEnabled;
7624 /* Enable OBSS protection */
7625 pConfig->obssProtEnabled = iniConfig->apOBSSProtEnabled;
7626
7627 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7628 pConfig->sap_dot11mc =
7629 (WLAN_HDD_GET_CTX(pHostapdAdapter))->config->sap_dot11mc;
7630 else /* for P2P-Go case */
7631 pConfig->sap_dot11mc = 1;
7632
7633 hddLog(LOG1, FL("11MC Support Enabled : %d\n"),
7634 pConfig->sap_dot11mc);
7635
7636#ifdef WLAN_FEATURE_11W
7637 pConfig->mfpCapable = MFPCapable;
7638 pConfig->mfpRequired = MFPRequired;
7639 hddLog(LOG1, FL("Soft AP MFP capable %d, MFP required %d"),
7640 pConfig->mfpCapable, pConfig->mfpRequired);
7641#endif
7642
7643 hddLog(LOGW, FL("SOftAP macaddress : " MAC_ADDRESS_STR),
7644 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
7645 hddLog(LOGW, FL("ssid =%s, beaconint=%d, channel=%d"),
7646 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7647 (int)pConfig->channel);
7648 hddLog(LOGW, FL("hw_mode=%x, privacy=%d, authType=%d"),
7649 pConfig->SapHw_mode, pConfig->privacy, pConfig->authType);
7650 hddLog(LOGW, FL("RSN/WPALen=%d, Uapsd = %d"),
7651 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7652 hddLog(LOGW, FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7653 pConfig->protEnabled, pConfig->obssProtEnabled);
7654
7655 if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) {
7656 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7657 /* Bss already started. just return. */
7658 /* TODO Probably it should update some beacon params. */
7659 hddLog(LOGE, "Bss Already started...Ignore the request");
7660 EXIT();
7661 return 0;
7662 }
7663
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007664 if (!cds_allow_concurrency(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007665 cds_convert_device_mode_to_hdd_type(
7666 pHostapdAdapter->device_mode),
7667 pConfig->channel, HW_MODE_20_MHZ)) {
7668 hddLog(LOGW,
7669 FL("This concurrency combination is not allowed"));
7670 return -EINVAL;
7671 }
7672
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007673 if (!cds_set_connection_in_progress(true)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007674 hdd_err("Can't start BSS: set connnection in progress failed");
7675 return -EINVAL;
7676 }
7677
7678 pConfig->persona = pHostapdAdapter->device_mode;
7679
7680 pSapEventCallback = hdd_hostapd_sap_event_cb;
7681
7682 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->dfs_cac_block_tx = true;
7683
7684 cdf_event_reset(&pHostapdState->cdf_event);
7685 status = wlansap_start_bss(
7686#ifdef WLAN_FEATURE_MBSSID
7687 WLAN_HDD_GET_SAP_CTX_PTR
7688 (pHostapdAdapter),
7689#else
7690 p_cds_context,
7691#endif
7692 pSapEventCallback, pConfig,
7693 pHostapdAdapter->dev);
7694 if (!CDF_IS_STATUS_SUCCESS(status)) {
7695 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007696 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007697 hddLog(LOGE, FL("SAP Start Bss fail"));
7698 return -EINVAL;
7699 }
7700
7701 hddLog(LOG1,
7702 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7703
7704 status = cdf_wait_single_event(&pHostapdState->cdf_event, 10000);
7705
7706 wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL);
7707
7708 if (!CDF_IS_STATUS_SUCCESS(status)) {
7709 hddLog(LOGE,
7710 FL("ERROR: HDD cdf wait for single_event failed!!"));
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007711 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007712 sme_get_command_q_status(hHal);
7713#ifdef WLAN_FEATURE_MBSSID
7714 wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter));
7715#else
7716 wlansap_stop_bss(p_cds_context);
7717#endif
7718 CDF_ASSERT(0);
7719 return -EINVAL;
7720 }
7721 /* Succesfully started Bss update the state bit. */
7722 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
7723 /* Initialize WMM configuation */
7724 hdd_wmm_init(pHostapdAdapter);
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007725 cds_incr_active_session(pHostapdAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007726 pHostapdAdapter->sessionId);
7727#ifdef DHCP_SERVER_OFFLOAD
7728 if (iniConfig->enableDHCPServerOffload)
7729 wlan_hdd_set_dhcp_server_offload(pHostapdAdapter);
7730#endif /* DHCP_SERVER_OFFLOAD */
7731
7732#ifdef WLAN_FEATURE_P2P_DEBUG
7733 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO) {
7734 if (global_p2p_connection_status == P2P_GO_NEG_COMPLETED) {
7735 global_p2p_connection_status = P2P_GO_COMPLETED_STATE;
7736 hddLog(LOGE,
7737 FL("[P2P State] From Go nego completed to Non-autonomous Group started"));
7738 } else if (global_p2p_connection_status == P2P_NOT_ACTIVE) {
7739 global_p2p_connection_status = P2P_GO_COMPLETED_STATE;
7740 hddLog(LOGE,
7741 FL("[P2P State] From Inactive to Autonomous Group started"));
7742 }
7743 }
7744#endif
7745
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08007746 cds_set_connection_in_progress(false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007747 pHostapdState->bCommit = true;
7748 EXIT();
7749
7750 return 0;
7751}
7752
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007753/**
7754 * __wlan_hdd_cfg80211_stop_ap() - stop soft ap
7755 * @wiphy: Pointer to wiphy structure
7756 * @dev: Pointer to net_device structure
7757 *
7758 * Return: 0 for success non-zero for failure
7759 */
7760static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7761 struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007762{
7763 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7764 hdd_context_t *pHddCtx = NULL;
7765 hdd_scaninfo_t *pScanInfo = NULL;
7766 hdd_adapter_t *staAdapter = NULL;
7767 CDF_STATUS status = CDF_STATUS_E_FAILURE;
7768 tSirUpdateIE updateIE;
7769 beacon_data_t *old;
7770 int ret;
7771 unsigned long rc;
7772 hdd_adapter_list_node_t *pAdapterNode = NULL;
7773 hdd_adapter_list_node_t *pNext = NULL;
7774
7775 ENTER();
7776
Peng Xuf5d60c82015-10-02 17:17:03 -07007777 if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007778 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7779 return -EINVAL;
7780 }
7781
7782 MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
7783 TRACE_CODE_HDD_CFG80211_STOP_AP,
7784 pAdapter->sessionId, pAdapter->device_mode));
7785
7786 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7787 ret = wlan_hdd_validate_context(pHddCtx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05307788 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007789 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007790
7791 if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP ||
7792 pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
7793 return -EOPNOTSUPP;
7794 }
7795
7796 hddLog(LOG1, FL("Device_mode %s(%d)"),
7797 hdd_device_mode_to_string(pAdapter->device_mode),
7798 pAdapter->device_mode);
7799
7800 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
7801 while (NULL != pAdapterNode && CDF_STATUS_SUCCESS == status) {
7802 staAdapter = pAdapterNode->pAdapter;
7803
7804 if (WLAN_HDD_INFRA_STATION == staAdapter->device_mode ||
7805 (WLAN_HDD_P2P_CLIENT == staAdapter->device_mode) ||
7806 (WLAN_HDD_P2P_GO == staAdapter->device_mode)) {
7807 pScanInfo = &staAdapter->scan_info;
7808
7809 if (pScanInfo && pScanInfo->mScanPending) {
7810 hddLog(LOG1, FL("Aborting pending scan for device mode:%d"),
7811 staAdapter->device_mode);
7812 INIT_COMPLETION(pScanInfo->abortscan_event_var);
7813 hdd_abort_mac_scan(staAdapter->pHddCtx,
7814 staAdapter->sessionId,
7815 eCSR_SCAN_ABORT_DEFAULT);
7816 rc = wait_for_completion_timeout(
7817 &pScanInfo->abortscan_event_var,
7818 msecs_to_jiffies(
7819 WLAN_WAIT_TIME_ABORTSCAN));
7820 if (!rc) {
7821 hddLog(LOGE,
7822 FL("Timeout occurred while waiting for abortscan"));
7823 CDF_ASSERT(pScanInfo->mScanPending);
7824 }
7825 }
7826 }
7827
7828 status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
7829 pAdapterNode = pNext;
7830 }
7831 /*
7832 * When ever stop ap adapter gets called, we need to check
7833 * whether any restart AP work is pending. If any restart is pending
7834 * then lets finish it and go ahead from there.
7835 */
7836 if (pHddCtx->config->conc_custom_rule1 &&
7837 (WLAN_HDD_SOFTAP == pAdapter->device_mode)) {
7838 cds_flush_work(&pHddCtx->sap_start_work);
7839 hddLog(LOGW, FL("Canceled the pending restart work"));
7840 spin_lock(&pHddCtx->sap_update_info_lock);
7841 pHddCtx->is_sap_restart_required = false;
7842 spin_unlock(&pHddCtx->sap_update_info_lock);
7843 }
7844 pAdapter->sessionCtx.ap.sapConfig.acs_cfg.acs_mode = false;
7845 if (pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list)
7846 cdf_mem_free(pAdapter->sessionCtx.ap.sapConfig.acs_cfg.ch_list);
7847 cdf_mem_zero(&pAdapter->sessionCtx.ap.sapConfig.acs_cfg,
7848 sizeof(struct sap_acs_cfg));
7849 hdd_hostapd_stop(dev);
7850
7851 old = pAdapter->sessionCtx.ap.beacon;
7852 if (!old) {
7853 hddLog(LOGE,
7854 FL("Session(%d) beacon data points to NULL"),
7855 pAdapter->sessionId);
7856 return -EINVAL;
7857 }
7858
7859 hdd_cleanup_actionframe(pHddCtx, pAdapter);
7860
7861 mutex_lock(&pHddCtx->sap_lock);
7862 if (test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags)) {
7863 hdd_hostapd_state_t *pHostapdState =
7864 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7865
7866 cdf_event_reset(&pHostapdState->cdf_stop_bss_event);
7867#ifdef WLAN_FEATURE_MBSSID
7868 status = wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter));
7869#else
7870 status = wlansap_stop_bss(pHddCtx->pcds_context);
7871#endif
7872 if (CDF_IS_STATUS_SUCCESS(status)) {
7873 status =
7874 cdf_wait_single_event(&pHostapdState->
7875 cdf_stop_bss_event,
7876 10000);
7877
7878 if (!CDF_IS_STATUS_SUCCESS(status)) {
7879 hddLog(LOGE,
7880 FL("HDD cdf wait for single_event failed!!"));
7881 CDF_ASSERT(0);
7882 }
7883 }
7884 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
7885 /*BSS stopped, clear the active sessions for this device mode*/
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08007886 cds_decr_session_set_pcl(pAdapter->device_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007887 pAdapter->sessionId);
7888 pAdapter->sessionCtx.ap.beacon = NULL;
7889 kfree(old);
7890 }
7891 mutex_unlock(&pHddCtx->sap_lock);
7892
7893 if (status != CDF_STATUS_SUCCESS) {
7894 hddLog(LOGE, FL("Stopping the BSS"));
7895 return -EINVAL;
7896 }
7897
Srinivas Girigowda8b983962015-11-18 22:14:34 -08007898 cdf_copy_macaddr(&updateIE.bssid, &pAdapter->macAddressCurrent);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007899 updateIE.smeSessionId = pAdapter->sessionId;
7900 updateIE.ieBufferlength = 0;
7901 updateIE.pAdditionIEBuffer = NULL;
7902 updateIE.append = true;
7903 updateIE.notify = true;
7904 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
7905 &updateIE,
7906 eUPDATE_IE_PROBE_BCN) == CDF_STATUS_E_FAILURE) {
7907 hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE"));
7908 }
7909
7910 if (sme_update_add_ie(WLAN_HDD_GET_HAL_CTX(pAdapter),
7911 &updateIE,
7912 eUPDATE_IE_ASSOC_RESP) == CDF_STATUS_E_FAILURE) {
7913 hddLog(LOGE, FL("Could not pass on ASSOC_RSP data to PE"));
7914 }
7915 /* Reset WNI_CFG_PROBE_RSP Flags */
7916 wlan_hdd_reset_prob_rspies(pAdapter);
7917
7918#ifdef WLAN_FEATURE_P2P_DEBUG
7919 if ((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7920 (global_p2p_connection_status == P2P_GO_COMPLETED_STATE)) {
7921 hddLog(LOGE,
7922 "[P2P State] From GO completed to Inactive state GO got removed");
7923 global_p2p_connection_status = P2P_NOT_ACTIVE;
7924 }
7925#endif
7926 EXIT();
7927 return ret;
7928}
7929
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007930/**
7931 * wlan_hdd_get_channel_bw() - get channel bandwidth
7932 * @width: input channel width in nl80211_chan_width value
7933 *
7934 * Return: channel width value defined by driver
7935 */
7936static enum hw_mode_bandwidth wlan_hdd_get_channel_bw(
7937 enum nl80211_chan_width width)
7938{
7939 enum hw_mode_bandwidth ch_bw = HW_MODE_20_MHZ;
7940
7941 switch (width) {
7942 case NL80211_CHAN_WIDTH_20_NOHT:
7943 case NL80211_CHAN_WIDTH_20:
7944 ch_bw = HW_MODE_20_MHZ;
7945 break;
7946 case NL80211_CHAN_WIDTH_40:
7947 ch_bw = HW_MODE_40_MHZ;
7948 break;
7949 case NL80211_CHAN_WIDTH_80:
7950 ch_bw = HW_MODE_80_MHZ;
7951 break;
7952 case NL80211_CHAN_WIDTH_80P80:
7953 ch_bw = HW_MODE_80_PLUS_80_MHZ;
7954 break;
7955 case NL80211_CHAN_WIDTH_160:
7956 ch_bw = HW_MODE_160_MHZ;
7957 break;
7958 default:
7959 hdd_err("Invalid width: %d, using default 20MHz", width);
7960 break;
7961 }
7962
7963 return ch_bw;
7964}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007965
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007966/**
7967 * wlan_hdd_cfg80211_stop_ap() - stop sap
7968 * @wiphy: Pointer to wiphy
7969 * @dev: Pointer to netdev
7970 *
7971 * Return: zero for success non-zero for failure
7972 */
7973int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7974 struct net_device *dev)
7975{
7976 int ret;
7977
7978 cds_ssr_protect(__func__);
7979 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7980 cds_ssr_unprotect(__func__);
7981
7982 return ret;
7983}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007984
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007985/**
7986 * __wlan_hdd_cfg80211_start_ap() - start soft ap mode
7987 * @wiphy: Pointer to wiphy structure
7988 * @dev: Pointer to net_device structure
7989 * @params: Pointer to AP settings parameters
7990 *
7991 * Return: 0 for success non-zero for failure
7992 */
7993static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7994 struct net_device *dev,
7995 struct cfg80211_ap_settings *params)
7996{
7997 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7998 hdd_context_t *pHddCtx;
Chandrasekaran, Manishekar96c90962015-11-20 16:47:45 +05307999 enum hw_mode_bandwidth channel_width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008000 int status;
8001 uint8_t channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008002
8003 ENTER();
8004
Peng Xuf5d60c82015-10-02 17:17:03 -07008005 if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008006 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8007 return -EINVAL;
8008 }
8009
8010 MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
8011 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8012 params->beacon_interval));
8013 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
8014 hddLog(LOGE, FL("HDD adapter magic is invalid"));
8015 return -ENODEV;
8016 }
8017
8018 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8019 status = wlan_hdd_validate_context(pHddCtx);
8020
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308021 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008022 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008023
8024 hddLog(LOG2, FL("pAdapter = %p, Device mode %s(%d)"), pAdapter,
8025 hdd_device_mode_to_string(pAdapter->device_mode),
8026 pAdapter->device_mode);
8027
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008028 channel_width = wlan_hdd_get_channel_bw(params->chandef.width);
8029 channel = ieee80211_frequency_to_channel(
8030 params->chandef.chan->center_freq);
Amar Singhal01098f72015-10-08 11:55:32 -07008031
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008032 /* check if concurrency is allowed */
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08008033 if (!cds_allow_concurrency(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008034 cds_convert_device_mode_to_hdd_type(
8035 pAdapter->device_mode),
8036 channel,
8037 channel_width)) {
8038 hdd_err("Connection failed due to concurrency check failure");
8039 return -EINVAL;
8040 }
8041 if (pHddCtx->config->policy_manager_enabled) {
Chandrasekaran, Manishekareceb8112015-11-16 15:38:53 +05308042 status = cdf_reset_connection_update();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008043 if (!CDF_IS_STATUS_SUCCESS(status))
8044 hdd_err("ERR: clear event failed");
8045
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05308046 status = cds_current_connections_update(pAdapter->sessionId,
8047 channel,
8048 CDS_UPDATE_REASON_START_AP);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008049 if (CDF_STATUS_E_FAILURE == status) {
8050 hdd_err("ERROR: connections update failed!!");
8051 return -EINVAL;
8052 }
8053
8054 if (CDF_STATUS_SUCCESS == status) {
Chandrasekaran, Manishekareceb8112015-11-16 15:38:53 +05308055 status = cdf_wait_for_connection_update();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008056 if (!CDF_IS_STATUS_SUCCESS(status)) {
8057 hdd_err("ERROR: cdf wait for event failed!!");
8058 return -EINVAL;
8059 }
8060 }
8061 }
8062
8063 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8064 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
8065 ) {
8066 beacon_data_t *old, *new;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008067 enum nl80211_channel_type channel_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008068
8069 old = pAdapter->sessionCtx.ap.beacon;
8070
8071 if (old)
8072 return -EALREADY;
8073
8074 status =
8075 wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new,
8076 &params->beacon,
8077 params->dtim_period);
8078
8079 if (status != 0) {
8080 hddLog(LOGE, FL("Error!!! Allocating the new beacon"));
8081 return -EINVAL;
8082 }
8083 pAdapter->sessionCtx.ap.beacon = new;
8084
8085 if (params->chandef.width < NL80211_CHAN_WIDTH_80)
8086 channel_type = cfg80211_get_chandef_type(
8087 &(params->chandef));
8088 else
8089 channel_type = NL80211_CHAN_HT40PLUS;
8090
8091
8092 wlan_hdd_set_channel(wiphy, dev,
8093 &params->chandef,
8094 channel_type);
8095
8096 /* set authentication type */
8097 switch (params->auth_type) {
8098 case NL80211_AUTHTYPE_OPEN_SYSTEM:
8099 pAdapter->sessionCtx.ap.sapConfig.authType =
8100 eSAP_OPEN_SYSTEM;
8101 break;
8102 case NL80211_AUTHTYPE_SHARED_KEY:
8103 pAdapter->sessionCtx.ap.sapConfig.authType =
8104 eSAP_SHARED_KEY;
8105 break;
8106 default:
8107 pAdapter->sessionCtx.ap.sapConfig.authType =
8108 eSAP_AUTO_SWITCH;
8109 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008110 pAdapter->sessionCtx.ap.sapConfig.ch_width_orig =
8111 params->chandef.width;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008112 status =
8113 wlan_hdd_cfg80211_start_bss(pAdapter,
8114 &params->beacon,
8115 params->ssid, params->ssid_len,
8116 params->hidden_ssid);
8117 }
8118
8119 EXIT();
8120 return status;
8121}
8122
8123/**
8124 * wlan_hdd_cfg80211_start_ap() - start sap
8125 * @wiphy: Pointer to wiphy
8126 * @dev: Pointer to netdev
8127 * @params: Pointer to start ap configuration parameters
8128 *
8129 * Return: zero for success non-zero for failure
8130 */
8131int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8132 struct net_device *dev,
8133 struct cfg80211_ap_settings *params)
8134{
8135 int ret;
8136
8137 cds_ssr_protect(__func__);
8138 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8139 cds_ssr_unprotect(__func__);
8140
8141 return ret;
8142}
8143
8144/**
8145 * __wlan_hdd_cfg80211_change_beacon() - change beacon for sofatap/p2p go
8146 * @wiphy: Pointer to wiphy structure
8147 * @dev: Pointer to net_device structure
8148 * @params: Pointer to change beacon parameters
8149 *
8150 * Return: 0 for success non-zero for failure
8151 */
8152static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8153 struct net_device *dev,
8154 struct cfg80211_beacon_data *params)
8155{
8156 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8157 hdd_context_t *pHddCtx;
8158 beacon_data_t *old, *new;
8159 int status;
8160
8161 ENTER();
8162
Peng Xuf5d60c82015-10-02 17:17:03 -07008163 if (CDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008164 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8165 return -EINVAL;
8166 }
8167
8168 MTRACE(cdf_trace(CDF_MODULE_ID_HDD,
8169 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8170 pAdapter->sessionId, pAdapter->device_mode));
8171 hddLog(LOG1, FL("Device_mode %s(%d)"),
8172 hdd_device_mode_to_string(pAdapter->device_mode),
8173 pAdapter->device_mode);
8174
8175 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8176 status = wlan_hdd_validate_context(pHddCtx);
8177
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05308178 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008179 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008180
8181 if (!(pAdapter->device_mode == WLAN_HDD_SOFTAP ||
8182 pAdapter->device_mode == WLAN_HDD_P2P_GO)) {
8183 return -EOPNOTSUPP;
8184 }
8185
8186 old = pAdapter->sessionCtx.ap.beacon;
8187
8188 if (!old) {
8189 hddLog(LOGE, FL("session(%d) beacon data points to NULL"),
8190 pAdapter->sessionId);
8191 return -EINVAL;
8192 }
8193
8194 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8195
8196 if (status != CDF_STATUS_SUCCESS) {
8197 hddLog(LOGE, FL("new beacon alloc failed"));
8198 return -EINVAL;
8199 }
8200
8201 pAdapter->sessionCtx.ap.beacon = new;
8202 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
8203
8204 EXIT();
8205 return status;
8206}
8207
8208/**
8209 * wlan_hdd_cfg80211_change_beacon() - change beacon content in sap mode
8210 * @wiphy: Pointer to wiphy
8211 * @dev: Pointer to netdev
8212 * @params: Pointer to change beacon parameters
8213 *
8214 * Return: zero for success non-zero for failure
8215 */
8216int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8217 struct net_device *dev,
8218 struct cfg80211_beacon_data *params)
8219{
8220 int ret;
8221
8222 cds_ssr_protect(__func__);
8223 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8224 cds_ssr_unprotect(__func__);
8225
8226 return ret;
8227}