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