blob: e06d9148e46f3fbebc08d694ab99e683beb2e346 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
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 ------------------------------------------------------------------------ *
24
25
26 \file wlan_hdd_wext.c
27
28 \brief Airgo Linux Wireless Extensions Common Control Plane Types and
29 interfaces.
30
31 $Id: wlan_hdd_wext.c,v 1.34 2007/04/14 01:49:23 jimz Exp jimz $
32
33 Copyright (C) 2007 Airgo Networks, Incorporated
34
35 This file defines all of the types that are utilized by the CCP module
36 of the "Portable" HDD. This file also includes the underlying Linux
37 Wireless Extensions Data types referred to by CCP.
38
39 ======================================================================== */
40
41#include <linux/version.h>
42#include <linux/module.h>
43#include <linux/kernel.h>
44#include <linux/init.h>
45#include <linux/wireless.h>
46#include <wlan_hdd_includes.h>
47#include <wlan_btc_svc.h>
48#include <wlan_nlink_common.h>
49#ifdef WLAN_BTAMP_FEATURE
50#include <bap_hdd_main.h>
51#endif
52#include <vos_api.h>
53#include <net/arp.h>
54#include "ccmApi.h"
55#include "sirParams.h"
56#include "csrApi.h"
57#include "csrInsideApi.h"
58#if defined WLAN_FEATURE_VOWIFI
59#include "smeRrmInternal.h"
60#endif
61#include <aniGlobal.h>
62#include "dot11f.h"
63#include <wlan_hdd_wowl.h>
64#include <wlan_hdd_cfg.h>
65#include <wlan_hdd_wmm.h>
66#include "utilsApi.h"
67#ifdef WLAN_FEATURE_P2P
68#include "wlan_hdd_p2p.h"
69#endif
70
71#ifdef CONFIG_HAS_EARLYSUSPEND
72#include <linux/earlysuspend.h>
73#endif
74#include "wlan_hdd_power.h"
75#include "qwlan_version.h"
76#include <vos_power.h>
77#include "wlan_hdd_host_offload.h"
78#include "wlan_hdd_keep_alive.h"
79#ifdef WLAN_FEATURE_PACKET_FILTERING
80#include "wlan_hdd_packet_filtering.h"
81#endif
82
83#ifdef CONFIG_CFG80211
84#include <linux/wireless.h>
85#include <net/cfg80211.h>
86#endif
87#ifdef FEATURE_WLAN_INTEGRATED_SOC
88#include "wlan_qct_pal_trace.h"
89#endif // FEATURE_WLAN_INTEGRATED_SOC
90
91#include "wlan_hdd_misc.h"
92#include "bap_hdd_misc.h"
93
94#include "wlan_hdd_dev_pwr.h"
95#include "qc_sap_ioctl.h"
96#define WE_MAX_STR_LEN 1024
97
98#ifdef CONFIG_HAS_EARLYSUSPEND
99extern void hdd_suspend_wlan(struct early_suspend *wlan_suspend);
100extern void hdd_resume_wlan(struct early_suspend *wlan_suspend);
101#endif
102
Jeff Johnsone7245742012-09-05 17:12:55 -0700103#ifdef FEATURE_OEM_DATA_SUPPORT
104#define MAX_OEM_DATA_RSP_LEN 1024
105#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700106
107#define HDD_FINISH_ULA_TIME_OUT 800
108
109extern int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand);
110int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr);
111
112static int ioctl_debug = 0;
113module_param(ioctl_debug, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
114
115struct statsContext
116{
117 struct completion completion;
118 hdd_adapter_t *pAdapter;
119 unsigned int magic;
120};
121
122#define STATS_CONTEXT_MAGIC 0x53544154 //STAT
123#define RSSI_CONTEXT_MAGIC 0x52535349 //RSSI
124#define POWER_CONTEXT_MAGIC 0x504F5752 // POWR
125
126/* To Validate Channel against the Frequency and Vice-Versa */
127static const hdd_freq_chan_map_t freq_chan_map[] = { {2412, 1}, {2417, 2},
128 {2422, 3}, {2427, 4}, {2432, 5}, {2437, 6}, {2442, 7}, {2447, 8},
129 {2452, 9}, {2457, 10}, {2462, 11}, {2467 ,12}, {2472, 13},
130 {2484, 14}, {4920, 240}, {4940, 244}, {4960, 248}, {4980, 252},
131 {5040, 208}, {5060, 212}, {5080, 216}, {5180, 36}, {5200, 40}, {5220, 44},
132 {5240, 48}, {5260, 52}, {5280, 56}, {5300, 60}, {5320, 64}, {5500, 100},
133 {5520, 104}, {5540, 108}, {5560, 112}, {5580, 116}, {5600, 120},
134 {5620, 124}, {5640, 128}, {5660, 132}, {5680, 136}, {5700, 140},
135 {5745, 149}, {5765, 153}, {5785, 157}, {5805, 161}, {5825, 165} };
136
137#define FREQ_CHAN_MAP_TABLE_SIZE sizeof(freq_chan_map)/sizeof(freq_chan_map[0])
138
139/* Private ioctls and their sub-ioctls */
140#define WLAN_PRIV_SET_INT_GET_NONE (SIOCIWFIRSTPRIV + 0)
141#define WE_SET_11D_STATE 1
142#define WE_WOWL 2
143#define WE_SET_POWER 3
144#define WE_SET_MAX_ASSOC 4
145#define WE_SET_SAP_AUTO_CHANNEL_SELECTION 5
146#define WE_SET_DATA_INACTIVITY_TO 6
147#define WE_SET_MAX_TX_POWER 7
148#define WE_SET_HIGHER_DTIM_TRANSITION 8
149#define WE_SET_TM_LEVEL 9
150
151/* Private ioctls and their sub-ioctls */
152#define WLAN_PRIV_SET_NONE_GET_INT (SIOCIWFIRSTPRIV + 1)
153#define WE_GET_11D_STATE 1
154#define WE_IBSS_STATUS 2
155#define WE_PMC_STATE 3
156#define WE_GET_WLAN_DBG 4
157#define WE_MODULE_DOWN_IND 5
158#define WE_GET_MAX_ASSOC 6
159#define WE_GET_WDI_DBG 7
160#define WE_GET_SAP_AUTO_CHANNEL_SELECTION 8
161#define WE_GET_CONCURRENCY_MODE 9
162/* Private ioctls and their sub-ioctls */
163#define WLAN_PRIV_SET_INT_GET_INT (SIOCIWFIRSTPRIV + 2)
164
165/* Private ioctls and their sub-ioctls */
166#define WLAN_PRIV_SET_CHAR_GET_NONE (SIOCIWFIRSTPRIV + 3)
167#define WE_WOWL_ADD_PTRN 1
168#define WE_WOWL_DEL_PTRN 2
169#if defined WLAN_FEATURE_VOWIFI
170#define WE_NEIGHBOR_REPORT_REQUEST 3
171#endif
172#define WE_SET_AP_WPS_IE 4 //This is called in station mode to set probe rsp ie.
173#define WE_SET_CONFIG 5
174
175/* Private ioctls and their sub-ioctls */
176#define WLAN_PRIV_SET_THREE_INT_GET_NONE (SIOCIWFIRSTPRIV + 4)
177#define WE_SET_WLAN_DBG 1
178#define WE_SET_WDI_DBG 2
179#define WE_SET_SAP_CHANNELS 3
180
181/* Private ioctls and their sub-ioctls */
182#define WLAN_PRIV_GET_CHAR_SET_NONE (SIOCIWFIRSTPRIV + 5)
183#define WE_WLAN_VERSION 1
184#define WE_GET_STATS 2
185#define WE_GET_CFG 3
186#define WE_GET_WMM_STATUS 4
187#define WE_GET_CHANNEL_LIST 5
Jeff Johnsone7245742012-09-05 17:12:55 -0700188#ifdef WLAN_FEATURE_11AC
189#define WE_GET_RSSI 6
190#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700191
192/* Private ioctls and their sub-ioctls */
193#define WLAN_PRIV_SET_NONE_GET_NONE (SIOCIWFIRSTPRIV + 6)
194#define WE_CLEAR_STATS 1
195#define WE_INIT_AP 2
196#define WE_STOP_AP 3
197#define WE_ENABLE_AMP 4
198#define WE_DISABLE_AMP 5
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -0700199#define WE_ENABLE_DXE_STALL_DETECT 6
200#define WE_DISPLAY_DXE_SNAP_SHOT 7
Jeff Johnson295189b2012-06-20 16:38:30 -0700201
202/* Private ioctls and their sub-ioctls */
203#define WLAN_PRIV_SET_VAR_INT_GET_NONE (SIOCIWFIRSTPRIV + 7)
204#define WE_LOG_DUMP_CMD 1
205
206#ifdef WLAN_FEATURE_P2P
207#define WE_P2P_NOA_CMD 2
208#endif
209
210#define MAX_VAR_ARGS 7
211
212/* Private ioctls (with no sub-ioctls) */
213/* note that they must be odd so that they have "get" semantics */
214#define WLAN_PRIV_ADD_TSPEC (SIOCIWFIRSTPRIV + 9)
215#define WLAN_PRIV_DEL_TSPEC (SIOCIWFIRSTPRIV + 11)
216#define WLAN_PRIV_GET_TSPEC (SIOCIWFIRSTPRIV + 13)
217
218#ifdef FEATURE_WLAN_WAPI
219/* Private ioctls EVEN NO: SET, ODD NO:GET */
220#define WLAN_PRIV_SET_WAPI_MODE (SIOCIWFIRSTPRIV + 8)
221#define WLAN_PRIV_GET_WAPI_MODE (SIOCIWFIRSTPRIV + 16)
222#define WLAN_PRIV_SET_WAPI_ASSOC_INFO (SIOCIWFIRSTPRIV + 10)
223#define WLAN_PRIV_SET_WAPI_KEY (SIOCIWFIRSTPRIV + 12)
224#define WLAN_PRIV_SET_WAPI_BKID (SIOCIWFIRSTPRIV + 14)
225#define WLAN_PRIV_GET_WAPI_BKID (SIOCIWFIRSTPRIV + 15)
226#define WAPI_PSK_AKM_SUITE 0x02721400
227#define WAPI_CERT_AKM_SUITE 0x01721400
228#endif
229
Jeff Johnsone7245742012-09-05 17:12:55 -0700230#ifdef FEATURE_OEM_DATA_SUPPORT
231/* Private ioctls for setting the measurement configuration */
232#define WLAN_PRIV_SET_OEM_DATA_REQ (SIOCIWFIRSTPRIV + 17)
233#define WLAN_PRIV_GET_OEM_DATA_RSP (SIOCIWFIRSTPRIV + 19)
234#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700235
236#ifdef WLAN_FEATURE_VOWIFI_11R
237#define WLAN_PRIV_SET_FTIES (SIOCIWFIRSTPRIV + 20)
238#endif
239
240/* Private ioctl for setting the host offload feature */
241#define WLAN_PRIV_SET_HOST_OFFLOAD (SIOCIWFIRSTPRIV + 18)
242
243/* Private ioctl to get the statistics */
244#define WLAN_GET_WLAN_STATISTICS (SIOCIWFIRSTPRIV + 21)
245
246/* Private ioctl to set the Keep Alive Params */
247#define WLAN_SET_KEEPALIVE_PARAMS (SIOCIWFIRSTPRIV + 22)
248#ifdef WLAN_FEATURE_PACKET_FILTERING
249/* Private ioctl to set the Packet Filtering Params */
250#define WLAN_SET_PACKET_FILTER_PARAMS (SIOCIWFIRSTPRIV + 23)
251#endif
252
253#ifdef FEATURE_WLAN_SCAN_PNO
254/* Private ioctl to get the statistics */
255#define WLAN_SET_PNO (SIOCIWFIRSTPRIV + 24)
256#endif
257
258#define WLAN_SET_BAND_CONFIG (SIOCIWFIRSTPRIV + 25) /*Don't change this number*/
259
260#define WLAN_PRIV_SET_MCBC_FILTER (SIOCIWFIRSTPRIV + 26)
261#define WLAN_PRIV_CLEAR_MCBC_FILTER (SIOCIWFIRSTPRIV + 27)
262#define WLAN_SET_POWER_PARAMS (SIOCIWFIRSTPRIV + 29)
263#define WLAN_GET_LINK_SPEED (SIOCIWFIRSTPRIV + 31)
264
265#define WLAN_STATS_INVALID 0
266#define WLAN_STATS_RETRY_CNT 1
267#define WLAN_STATS_MUL_RETRY_CNT 2
268#define WLAN_STATS_TX_FRM_CNT 3
269#define WLAN_STATS_RX_FRM_CNT 4
270#define WLAN_STATS_FRM_DUP_CNT 5
271#define WLAN_STATS_FAIL_CNT 6
272#define WLAN_STATS_RTS_FAIL_CNT 7
273#define WLAN_STATS_ACK_FAIL_CNT 8
274#define WLAN_STATS_RTS_SUC_CNT 9
275#define WLAN_STATS_RX_DISCARD_CNT 10
276#define WLAN_STATS_RX_ERROR_CNT 11
277#define WLAN_STATS_TX_BYTE_CNT 12
278
279#define WLAN_STATS_RX_BYTE_CNT 13
280#define WLAN_STATS_RX_RATE 14
281#define WLAN_STATS_TX_RATE 15
282
Jeff Johnsone7245742012-09-05 17:12:55 -0700283#define WLAN_STATS_RX_UC_BYTE_CNT 16
284#define WLAN_STATS_RX_MC_BYTE_CNT 17
285#define WLAN_STATS_RX_BC_BYTE_CNT 18
286#define WLAN_STATS_TX_UC_BYTE_CNT 19
287#define WLAN_STATS_TX_MC_BYTE_CNT 20
288#define WLAN_STATS_TX_BC_BYTE_CNT 21
289
Jeff Johnson295189b2012-06-20 16:38:30 -0700290#define FILL_TLV(__p, __type, __size, __val, __tlen) \
291{\
292 if ((__tlen + __size + 2) < WE_MAX_STR_LEN) \
293 {\
294 *__p++ = __type;\
295 *__p++ = __size;\
296 memcpy(__p, __val, __size);\
297 __p += __size;\
298 __tlen += __size + 2;\
299 }\
300 else \
301 { \
302 hddLog(VOS_TRACE_LEVEL_ERROR, "FILL_TLV Failed!!!\n");\
303 } \
304}while(0);
305
306#define VERSION_VALUE_MAX_LEN 32
307
308#define TX_PER_TRACKING_DEFAULT_RATIO 5
309#define TX_PER_TRACKING_MAX_RATIO 10
310#define TX_PER_TRACKING_DEFAULT_WATERMARK 5
311
312#define WLAN_HDD_UI_BAND_AUTO 0
313#define WLAN_HDD_UI_BAND_5_GHZ 1
314#define WLAN_HDD_UI_BAND_2_4_GHZ 2
315#define WLAN_HDD_UI_SET_BAND_VALUE_OFFSET 8
316
317#ifdef WLAN_FEATURE_PACKET_FILTERING
Jeff Johnsone7245742012-09-05 17:12:55 -0700318int wlan_hdd_set_filter(hdd_context_t *pHddCtx, tpPacketFilterCfg pRequest,
319 v_U8_t sessionId);
320void wlan_hdd_set_mc_addr_list(hdd_context_t *pHddCtx, v_U8_t set, v_U8_t sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700321#endif
322
323#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
324/**---------------------------------------------------------------------------
325
326 \brief hdd_wlan_get_version() -
327
328 This function use to get Wlan Driver And Firmware Version.
329
330 \param - pAdapter Pointer to the adapter.
331 wrqu - Pointer to IOCTL REQUEST Data.
332 extra - Pointer to char
333
334 \return - 0 for success, non zero for failure
335
336 --------------------------------------------------------------------------*/
337int hdd_wlan_get_version(hdd_adapter_t *pAdapter, union iwreq_data *wrqu,
338 char *extra)
339{
340 VOS_STATUS status;
341 FwVersionInfo fwversion;
342 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
343 v_U32_t reg_val;
344 char *buf = extra;
345
346 buf += snprintf(buf, VERSION_VALUE_MAX_LEN, "%s_", WLAN_CHIP_VERSION);
347 /*Read the RevID*/
348 status = sme_DbgReadRegister(hHal, QWLAN_RFAPB_REV_ID_REG, &reg_val);
349
350 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
351 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!\n", __func__);
352 return -EINVAL;
353 }
354
355 buf += snprintf(buf, VERSION_VALUE_MAX_LEN, "%x.%x-", (v_U8_t)(reg_val >> 8),
356 (v_U8_t)(reg_val & 0x000000FF));
357
358 status = sme_GetFwVersion(hHal, &fwversion);
359
360 if ( !VOS_IS_STATUS_SUCCESS( status ) ) {
361 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Failed!!!\n", __func__);
362 return -EINVAL;
363 }
364 buf += snprintf(buf, VERSION_VALUE_MAX_LEN, "%s-", QWLAN_VERSIONSTR);
365 buf += snprintf(buf, VERSION_VALUE_MAX_LEN, "%ld.%ld.%ld.%ld",
366 fwversion.uMj, fwversion.uMn,
367 fwversion.uPatch, fwversion.uBuild);
368 wrqu->data.length = strlen(extra);
369
370 return 0;
371}
372
373#endif
374int hdd_wlan_get_rts_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu)
375{
376 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
377 v_U32_t threshold = 0,status = 0;
378
379 ENTER();
380
381 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
383 "%s:LOGP in Progress. Ignore!!!",__func__);
384 return status;
385 }
386
387 if ( eHAL_STATUS_SUCCESS !=
388 ccmCfgGetInt(hHal, WNI_CFG_RTS_THRESHOLD, &threshold) )
389 {
390 return -EIO;
391 }
392 wrqu->rts.value = threshold;
393
394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
395 ("Rts-Threshold=%ld!!\n"), wrqu->rts.value);
396
397 EXIT();
398
399 return 0;
400}
401
402int hdd_wlan_get_frag_threshold(hdd_adapter_t *pAdapter, union iwreq_data *wrqu)
403{
404 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
405 v_U32_t threshold = 0,status = 0;
406
407 ENTER();
408
409 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
411 "%s:LOGP in Progress. Ignore!!!",__func__);
412 return status;
413 }
414
415 if ( ccmCfgGetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, &threshold)
416 != eHAL_STATUS_SUCCESS )
417 {
418 return -EIO;
419 }
420 wrqu->frag.value = threshold;
421
422 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
423 ("Frag-Threshold=%ld!!\n"), wrqu->frag.value);
424
425 EXIT();
426
427 return 0;
428}
429
430int hdd_wlan_get_freq(v_U32_t channel, v_U32_t *pfreq)
431{
Jeff Johnsone7245742012-09-05 17:12:55 -0700432 int i;
433 if (channel > 0)
434 {
435 for (i=0; i < FREQ_CHAN_MAP_TABLE_SIZE; i++)
436 {
437 if (channel == freq_chan_map[i].chan)
438 {
439 *pfreq = freq_chan_map[i].freq;
440 return 1;
441 }
442 }
443 }
444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
445 ("Invalid channel no=%d!!\n"), channel);
446 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -0700447}
448
449static v_BOOL_t
450hdd_IsAuthTypeRSN( tHalHandle halHandle, eCsrAuthType authType)
451{
452 v_BOOL_t rsnType = VOS_FALSE;
453 // is the authType supported?
454 switch (authType)
455 {
456 case eCSR_AUTH_TYPE_NONE: //never used
457 rsnType = eANI_BOOLEAN_FALSE;
458 break;
459 // MAC layer authentication types
460 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
461 rsnType = eANI_BOOLEAN_FALSE;
462 break;
463 case eCSR_AUTH_TYPE_SHARED_KEY:
464 rsnType = eANI_BOOLEAN_FALSE;
465 break;
466 case eCSR_AUTH_TYPE_AUTOSWITCH:
467 rsnType = eANI_BOOLEAN_FALSE;
468 break;
469
470 // Upper layer authentication types
471 case eCSR_AUTH_TYPE_WPA:
472 rsnType = eANI_BOOLEAN_TRUE;
473 break;
474 case eCSR_AUTH_TYPE_WPA_PSK:
475 rsnType = eANI_BOOLEAN_TRUE;
476 break;
477 case eCSR_AUTH_TYPE_WPA_NONE:
478 rsnType = eANI_BOOLEAN_TRUE;
479 break;
480#ifdef WLAN_FEATURE_VOWIFI_11R
481 case eCSR_AUTH_TYPE_FT_RSN:
482#endif
483 case eCSR_AUTH_TYPE_RSN:
484 rsnType = eANI_BOOLEAN_TRUE;
485 break;
486#ifdef WLAN_FEATURE_VOWIFI_11R
487 case eCSR_AUTH_TYPE_FT_RSN_PSK:
488#endif
489 case eCSR_AUTH_TYPE_RSN_PSK:
490 rsnType = eANI_BOOLEAN_TRUE;
491 break;
492 //case eCSR_AUTH_TYPE_FAILED:
493 case eCSR_AUTH_TYPE_UNKNOWN:
494 rsnType = eANI_BOOLEAN_FALSE;
495 break;
496 default:
497 hddLog(LOGE, FL("%s called with unknown authType - default to Open, None\n"),
498 __FUNCTION__);
499 rsnType = eANI_BOOLEAN_FALSE;
500 break;
501 }
502 hddLog(LOGE, FL("%s called with authType: %d, returned: %d\n"),
503 __FUNCTION__, authType, rsnType);
504 return rsnType;
505}
506
507static void hdd_GetRssiCB( v_S7_t rssi, tANI_U32 staId, void *pContext )
508{
509 struct statsContext *pStatsContext;
510 hdd_adapter_t *pAdapter;
511
512 if (ioctl_debug)
513 {
514 pr_info("%s: rssi [%d] STA [%d] pContext [%p]\n",
515 __FUNCTION__, (int)rssi, (int)staId, pContext);
516 }
517
518 if (NULL == pContext)
519 {
520 hddLog(VOS_TRACE_LEVEL_ERROR,
521 "%s: Bad param, pContext [%p]",
522 __FUNCTION__, pContext);
523 return;
524 }
525
526 /* there is a race condition that exists between this callback function
527 and the caller since the caller could time out either before or
528 while this code is executing. we'll assume the timeout hasn't
529 occurred, but we'll verify that right before we save our work */
530
531 pStatsContext = pContext;
532 pAdapter = pStatsContext->pAdapter;
533 if ((NULL == pAdapter) || (RSSI_CONTEXT_MAGIC != pStatsContext->magic))
534 {
535 /* the caller presumably timed out so there is nothing we can do */
536 hddLog(VOS_TRACE_LEVEL_WARN,
537 "%s: Invalid context, pAdapter [%p] magic [%08x]",
538 __FUNCTION__, pAdapter, pStatsContext->magic);
539 if (ioctl_debug)
540 {
541 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
542 __FUNCTION__, pAdapter, pStatsContext->magic);
543 }
544 return;
545 }
546
547 /* the race is on. caller could have timed out immediately after
548 we verified the magic, but if so, caller will wait a short time
549 for us to copy over the rssi */
550 pAdapter->rssi = rssi;
551
552 /* and notify the caller */
553 complete(&pStatsContext->completion);
554}
555
556VOS_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, v_S7_t *rssi_value)
557{
558 struct statsContext context;
559 hdd_context_t *pHddCtx;
560 hdd_station_ctx_t *pHddStaCtx;
561 eHalStatus hstatus;
562 long lrc;
563
564 if (NULL == pAdapter)
565 {
566 hddLog(VOS_TRACE_LEVEL_WARN,
567 "%s: Invalid context, pAdapter", __func__);
568 return VOS_STATUS_E_FAULT;
569 }
570 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
571 {
572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__);
573 /* return a cached value */
574 *rssi_value = pAdapter->rssi;
575 return VOS_STATUS_SUCCESS;
576 }
577
578 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
579 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
580
581 init_completion(&context.completion);
582 context.pAdapter = pAdapter;
583 context.magic = RSSI_CONTEXT_MAGIC;
584
585 hstatus = sme_GetRssi(pHddCtx->hHal, hdd_GetRssiCB,
586 pHddStaCtx->conn_info.staId[ 0 ],
587 pHddStaCtx->conn_info.bssId,
588 &context, pHddCtx->pvosContext);
589 if (eHAL_STATUS_SUCCESS != hstatus)
590 {
591 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Unable to retrieve RSSI",
592 __FUNCTION__);
593 /* we'll returned a cached value below */
594 }
595 else
596 {
597 /* request was sent -- wait for the response */
598 lrc = wait_for_completion_interruptible_timeout(&context.completion,
599 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
600 /* either we have a response or we timed out
601 either way, first invalidate our magic */
602 context.magic = 0;
603 if (lrc <= 0)
604 {
605 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while retrieving RSSI ",
606 __FUNCTION__, (0 == lrc) ? "timeout" : "interrupt");
607 /* there is a race condition such that the callback
608 function could be executing at the same time we are. of
609 primary concern is if the callback function had already
610 verified the "magic" but hasn't yet set the completion
611 variable. Since the completion variable is on our
612 stack, we'll delay just a bit to make sure the data is
613 still valid if that is the case */
614 msleep(50);
615 /* we'll now returned a cached value below */
616 }
617 }
618 *rssi_value = pAdapter->rssi;
619
620 return VOS_STATUS_SUCCESS;
621}
622
623void hdd_StatisticsCB( void *pStats, void *pContext )
624{
625 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pContext;
626 hdd_stats_t *pStatsCache = NULL;
627 hdd_wext_state_t *pWextState;
628 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
629
630 tCsrSummaryStatsInfo *pSummaryStats = NULL;
631 tCsrGlobalClassAStatsInfo *pClassAStats = NULL;
632 tCsrGlobalClassBStatsInfo *pClassBStats = NULL;
633 tCsrGlobalClassCStatsInfo *pClassCStats = NULL;
634 tCsrGlobalClassDStatsInfo *pClassDStats = NULL;
635 tCsrPerStaStatsInfo *pPerStaStats = NULL;
636
637 if (pAdapter!= NULL)
638 pStatsCache = &pAdapter->hdd_stats;
639
640
641 pSummaryStats = (tCsrSummaryStatsInfo *)pStats;
642 pClassAStats = (tCsrGlobalClassAStatsInfo *)( pSummaryStats + 1 );
643 pClassBStats = (tCsrGlobalClassBStatsInfo *)( pClassAStats + 1 );
644 pClassCStats = (tCsrGlobalClassCStatsInfo *)( pClassBStats + 1 );
645 pClassDStats = (tCsrGlobalClassDStatsInfo *)( pClassCStats + 1 );
646 pPerStaStats = (tCsrPerStaStatsInfo *)( pClassDStats + 1 );
647
648 if (pStatsCache!=NULL)
649 {
650 // and copy the stats into the cache we keep in the adapter instance structure
651 vos_mem_copy( &pStatsCache->summary_stat, pSummaryStats, sizeof( pStatsCache->summary_stat ) );
652 vos_mem_copy( &pStatsCache->ClassA_stat, pClassAStats, sizeof( pStatsCache->ClassA_stat ) );
653 vos_mem_copy( &pStatsCache->ClassB_stat, pClassBStats, sizeof( pStatsCache->ClassB_stat ) );
654 vos_mem_copy( &pStatsCache->ClassC_stat, pClassCStats, sizeof( pStatsCache->ClassC_stat ) );
655 vos_mem_copy( &pStatsCache->ClassD_stat, pClassDStats, sizeof( pStatsCache->ClassD_stat ) );
656 vos_mem_copy( &pStatsCache->perStaStats, pPerStaStats, sizeof( pStatsCache->perStaStats ) );
657 }
658
659 if(pAdapter)
660 {
661 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
662 if(pWextState)
663 {
664 vos_status = vos_event_set(&pWextState->vosevent);
665 if (!VOS_IS_STATUS_SUCCESS(vos_status))
666 {
667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
668 "%s: vos_event_set failed", __FUNCTION__);
669 return;
670 }
671 }
672 }
673}
674
675void ccmCfgSetCallback(tHalHandle halHandle, tANI_S32 result)
676{
677 v_CONTEXT_t pVosContext;
678 hdd_context_t *pHddCtx;
679 VOS_STATUS hdd_reconnect_all_adapters( hdd_context_t *pHddCtx );
680#if 0
681 hdd_wext_state_t *pWextState;
682 v_U32_t roamId;
683#endif
684
685 ENTER();
686
687 pVosContext = vos_get_global_context(VOS_MODULE_ID_SYS,NULL);
688
689 pHddCtx = (hdd_context_t*) vos_get_context(VOS_MODULE_ID_HDD,pVosContext);
690 if (NULL == pHddCtx)
691 {
692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid pHddCtx", __FUNCTION__);
693 return;
694 }
695#if 0
696 pWextState = pAdapter->pWextState;
697#endif
698
699 if (WNI_CFG_NEED_RESTART == result || WNI_CFG_NEED_RELOAD == result)
700 {
701 //TODO Verify is this is really used. If yes need to fix it.
702 hdd_reconnect_all_adapters( pHddCtx );
703#if 0
704 pAdapter->conn_info.connState = eConnectionState_NotConnected;
705 INIT_COMPLETION(pAdapter->disconnect_comp_var);
706 vosStatus = sme_RoamDisconnect(halHandle, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
707
708 if(VOS_STATUS_SUCCESS == vosStatus)
709 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
710 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
711
712 sme_RoamConnect(halHandle,
713 pAdapter->sessionId, &(pWextState->roamProfile),
714 &roamId);
715#endif
716 }
717
718 EXIT();
719
720}
721
722void hdd_clearRoamProfileIe( hdd_adapter_t *pAdapter)
723{
724 int i = 0;
725 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
726
727 /* clear WPA/RSN/WSC IE information in the profile */
728 pWextState->roamProfile.nWPAReqIELength = 0;
729 pWextState->roamProfile.pWPAReqIE = (tANI_U8 *)NULL;
730 pWextState->roamProfile.nRSNReqIELength = 0;
731 pWextState->roamProfile.pRSNReqIE = (tANI_U8 *)NULL;
732
733 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
734 pWextState->roamProfile.pAddIEScan = (tANI_U8 *)NULL;
735 pWextState->roamProfile.nAddIEScanLength = 0;
736 pWextState->roamProfile.pAddIEAssoc = (tANI_U8 *)NULL;
737 pWextState->roamProfile.nAddIEAssocLength = 0;
738
739 pWextState->roamProfile.EncryptionType.numEntries = 1;
740 pWextState->roamProfile.EncryptionType.encryptionType[0]
741 = eCSR_ENCRYPT_TYPE_NONE;
742
743 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
744 pWextState->roamProfile.mcEncryptionType.encryptionType[0]
745 = eCSR_ENCRYPT_TYPE_NONE;
746
747 pWextState->roamProfile.AuthType.numEntries = 1;
748 pWextState->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
749
750 pWextState->authKeyMgmt = 0;
751
752 for (i=0; i < CSR_MAX_NUM_KEY; i++)
753 {
754 if (pWextState->roamProfile.Keys.KeyMaterial[i])
755 {
756 pWextState->roamProfile.Keys.KeyLength[i] = 0;
757 }
758 }
759#ifdef FEATURE_WLAN_WAPI
760 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_OPEN;
761 pAdapter->wapi_info.nWapiMode = 0;
762#endif
763
764 vos_mem_zero((void *)(pWextState->req_bssId), WNI_CFG_BSSID_LEN);
765
766}
767
768void wlan_hdd_ula_done_cb(v_VOID_t *callbackContext)
769{
770 hdd_adapter_t *pAdapter = (hdd_adapter_t*)callbackContext;
771 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
772
773 complete(&pWextState->completion_var);
774}
775
776VOS_STATUS wlan_hdd_check_ula_done(hdd_adapter_t *pAdapter)
777{
778 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
779 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
780 VOS_STATUS vos_status;
781
782 if (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated)
783 {
784 INIT_COMPLETION(pWextState->completion_var);
785
786 /*To avoid race condition between the set key and the last EAPOL
787 packet, notify TL to finish upper layer authentication incase if the
788 last EAPOL packet pending in the TL queue.*/
789 vos_status = WLANTL_Finish_ULA(wlan_hdd_ula_done_cb,pAdapter);
790
791 if ( vos_status != VOS_STATUS_SUCCESS )
792 {
793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
794 "[%4d] WLANTL_Finish_ULA returned ERROR status= %d",
795 __LINE__, vos_status );
796 return vos_status;
797
798 }
799
800 wait_for_completion_timeout(&pWextState->completion_var,
801 msecs_to_jiffies(HDD_FINISH_ULA_TIME_OUT));
802 }
803 return VOS_STATUS_SUCCESS;
804}
805
806v_U8_t* wlan_hdd_get_vendor_oui_ie_ptr(v_U8_t *oui, v_U8_t oui_size, v_U8_t *ie, int ie_len)
807{
808
809 int left = ie_len;
810 v_U8_t *ptr = ie;
811 v_U8_t elem_id,elem_len;
812 v_U8_t eid = 0xDD;
813
814 if ( NULL == ie || 0 == ie_len )
815 return NULL;
816
817 while(left >= 2)
818 {
819 elem_id = ptr[0];
820 elem_len = ptr[1];
821 left -= 2;
822 if(elem_len > left)
823 {
824 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -0700825 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -0700826 eid,elem_len,left);
827 return NULL;
828 }
829 if (elem_id == eid)
830 {
831 if(memcmp( &ptr[2], oui, oui_size)==0)
832 return ptr;
833 }
834
835 left -= elem_len;
836 ptr += (elem_len + 2);
837 }
838 return NULL;
839}
840
841static int iw_set_commit(struct net_device *dev, struct iw_request_info *info,
842 union iwreq_data *wrqu, char *extra)
843{
844 hddLog( LOG1, "In %s\n", __FUNCTION__);
845 /* Do nothing for now */
846 return 0;
847}
848
849static int iw_get_name(struct net_device *dev,
850 struct iw_request_info *info,
851 char *wrqu, char *extra)
852{
853
854 ENTER();
855 strlcpy(wrqu, "Qcom:802.11n", IFNAMSIZ);
856 EXIT();
857 return 0;
858}
859
860static int iw_set_mode(struct net_device *dev,
861 struct iw_request_info *info,
862 union iwreq_data *wrqu, char *extra)
863{
864 hdd_wext_state_t *pWextState;
865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
866 tCsrRoamProfile *pRoamProfile;
867 eCsrRoamBssType LastBSSType;
868 eMib_dot11DesiredBssType connectedBssType;
869 hdd_config_t *pConfig;
870#ifdef CONFIG_CFG80211
871 struct wireless_dev *wdev;
872#endif
873
874 ENTER();
875
876 if (NULL == pAdapter)
877 {
878 hddLog(VOS_TRACE_LEVEL_WARN,
879 "%s: Invalid context, pAdapter", __func__);
880 return 0;
881 }
882
883 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
884 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
885 return 0;
886 }
887
888 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
889 if (pWextState == NULL)
890 {
891 hddLog (LOGE, "%s ERROR: Data Storage Corruption", __FUNCTION__);
892 return -EINVAL;
893 }
894
895#ifdef CONFIG_CFG80211
896 wdev = dev->ieee80211_ptr;
897#endif
898 pRoamProfile = &pWextState->roamProfile;
899 LastBSSType = pRoamProfile->BSSType;
900
901 hddLog( LOG1,"%s Old Bss type = %d", __FUNCTION__, LastBSSType);
902
903 switch (wrqu->mode)
904 {
905 case IW_MODE_ADHOC:
906 hddLog( LOG1,"%s Setting AP Mode as IW_MODE_ADHOC", __FUNCTION__);
907 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
908 // Set the phymode correctly for IBSS.
909 pConfig = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
910 pWextState->roamProfile.phyMode = hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
911#ifdef CONFIG_CFG80211
912 wdev->iftype = NL80211_IFTYPE_ADHOC;
913#endif
914 break;
915 case IW_MODE_INFRA:
916 hddLog( LOG1, "%s Setting AP Mode as IW_MODE_INFRA", __FUNCTION__);
917 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
918#ifdef CONFIG_CFG80211
919 wdev->iftype = NL80211_IFTYPE_STATION;
920#endif
921 break;
922 case IW_MODE_AUTO:
923 hddLog(LOG1,"%s Setting AP Mode as IW_MODE_AUTO", __FUNCTION__);
924 pRoamProfile->BSSType = eCSR_BSS_TYPE_ANY;
925 break;
926 default:
927 hddLog(LOG1,"%s Unknown AP Mode value", __FUNCTION__);
928 return -EOPNOTSUPP;
929 }
930
931 if ( LastBSSType != pRoamProfile->BSSType )
932 {
933 //the BSS mode changed
934 // We need to issue disconnect if connected or in IBSS disconnect state
935 if ( hdd_connGetConnectedBssType( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
936 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
937 {
938 VOS_STATUS vosStatus;
939 // need to issue a disconnect to CSR.
940 INIT_COMPLETION(pAdapter->disconnect_comp_var);
941 vosStatus = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
942 pAdapter->sessionId,
943 eCSR_DISCONNECT_REASON_IBSS_LEAVE );
944 if(VOS_STATUS_SUCCESS == vosStatus)
945 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
946 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
947 }
948 }
949
950
951
952 EXIT();
953 return 0;
954}
955
956
957static int iw_get_mode(struct net_device *dev,
958 struct iw_request_info *info,
959 v_U32_t *uwrq, char *extra)
960{
961
962 hdd_wext_state_t *pWextState;
963 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
964
965 hddLog (LOG1, "In %s",__FUNCTION__);
966
967 if (NULL == pAdapter)
968 {
969 hddLog(VOS_TRACE_LEVEL_WARN,
970 "%s: Invalid context, pAdapter", __func__);
971 return 0;
972 }
973
974 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
975 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
976 return 0;
977 }
978
979 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
980 if (pWextState == NULL)
981 {
982 hddLog (LOGE, "%s ERROR: Data Storage Corruption", __FUNCTION__);
983 return -EINVAL;
984 }
985
986 switch (pWextState->roamProfile.BSSType)
987 {
988 case eCSR_BSS_TYPE_INFRASTRUCTURE:
989 hddLog(LOG1, "%s returns IW_MODE_INFRA\n", __FUNCTION__);
990 *uwrq = IW_MODE_INFRA ;
991 break;
992 case eCSR_BSS_TYPE_IBSS:
993 case eCSR_BSS_TYPE_START_IBSS:
994 hddLog( LOG1,"%s returns IW_MODE_ADHOC\n", __FUNCTION__);
995 *uwrq= IW_MODE_ADHOC;
996 break;
997 case eCSR_BSS_TYPE_ANY:
998 hddLog( LOG1,"%s returns IW_MODE_AUTO\n", __FUNCTION__);
999 *uwrq= IW_MODE_AUTO;
1000 break;
1001 default:
1002 hddLog( LOG1,"%s returns APMODE_UNKNOWN\n", __FUNCTION__);
1003 break;
1004 }
1005 return 0;
1006}
1007
1008static int iw_set_freq(struct net_device *dev, struct iw_request_info *info,
1009 union iwreq_data *wrqu, char *extra)
1010{
1011 v_U32_t numChans = 0;
1012 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1013 v_U32_t indx = 0;
1014 v_U32_t status = 0;
1015
1016 hdd_wext_state_t *pWextState;
1017 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1018 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1019 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1020 tCsrRoamProfile * pRoamProfile;
1021 ENTER();
1022
1023 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
1024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1025 return status;
1026 }
1027
1028 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1029
1030 pRoamProfile = &pWextState->roamProfile;
1031
1032 hddLog(LOG1,"setCHANNEL ioctl\n");
1033
1034 /* Link is up then return cant set channel*/
1035 if(eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState ||
1036 eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1037 {
1038 hddLog( LOGE, "IBSS Associated\n");
1039 return -EOPNOTSUPP;
1040 }
1041
1042 /* Settings by Frequency as input */
1043 if((wrqu->freq.e == 1) && (wrqu->freq.m >= (tANI_U32)2.412e8) &&
1044 (wrqu->freq.m <= (tANI_U32)5.825e8))
1045 {
1046 tANI_U32 freq = wrqu->freq.m / 100000;
1047
1048 while ((indx < FREQ_CHAN_MAP_TABLE_SIZE) && (freq != freq_chan_map[indx].freq))
1049 indx++;
1050 if (indx >= FREQ_CHAN_MAP_TABLE_SIZE)
1051 {
1052 return -EINVAL;
1053 }
1054 wrqu->freq.e = 0;
1055 wrqu->freq.m = freq_chan_map[indx].chan;
1056
1057 }
1058
1059 if (wrqu->freq.e == 0)
1060 {
1061 if((wrqu->freq.m < WNI_CFG_CURRENT_CHANNEL_STAMIN) ||
1062 (wrqu->freq.m > WNI_CFG_CURRENT_CHANNEL_STAMAX))
1063 {
1064 hddLog(LOG1,"%s: Channel [%d] is outside valid range from %d to %d\n",
1065 __FUNCTION__, wrqu->freq.m, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1066 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1067 return -EINVAL;
1068 }
1069
1070 numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1071
1072 if (ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1073 validChan, &numChans) != eHAL_STATUS_SUCCESS){
1074 return -EIO;
1075 }
1076
1077 for (indx = 0; indx < numChans; indx++) {
1078 if (wrqu->freq.m == validChan[indx]){
1079 break;
1080 }
1081 }
1082 }
1083 else{
1084
1085 return -EINVAL;
1086 }
1087
1088 if(indx >= numChans)
1089 {
1090 return -EINVAL;
1091 }
1092
1093 /* Set the Operational Channel */
1094 numChans = pRoamProfile->ChannelInfo.numOfChannels = 1;
1095 pHddStaCtx->conn_info.operationChannel = wrqu->freq.m;
1096 pRoamProfile->ChannelInfo.ChannelList = &pHddStaCtx->conn_info.operationChannel;
1097
1098 hddLog(LOG1,"pRoamProfile->operationChannel = %d\n", wrqu->freq.m);
1099
1100 EXIT();
1101
1102 return status;
1103}
1104
1105static int iw_get_freq(struct net_device *dev, struct iw_request_info *info,
1106 struct iw_freq *fwrq, char *extra)
1107{
Jeff Johnsone7245742012-09-05 17:12:55 -07001108 v_U32_t status = FALSE, channel = 0, freq = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001109 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1110 tHalHandle hHal;
1111 hdd_wext_state_t *pWextState;
1112 tCsrRoamProfile * pRoamProfile;
1113 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1114
1115 ENTER();
1116
1117 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
1118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1119 return status;
1120 }
1121
1122 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1123 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1124
1125 pRoamProfile = &pWextState->roamProfile;
1126
1127 if( pHddStaCtx->conn_info.connState== eConnectionState_Associated )
1128 {
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001129 if (sme_GetOperationChannel(hHal, &channel, pAdapter->sessionId) != eHAL_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07001130 {
1131 return -EIO;
1132 }
1133 else
1134 {
Jeff Johnsone7245742012-09-05 17:12:55 -07001135 status = hdd_wlan_get_freq(channel, &freq);
1136 if( TRUE == status )
1137 {
1138 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
1139 * iwlist & iwconfig command shows frequency into proper
1140 * format (2.412 GHz instead of 246.2 MHz)*/
1141 fwrq->m = freq;
1142 fwrq->e = MHZ;
1143 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001144 }
1145 }
1146 else
1147 {
Madan Mohan Koyyalamudi99f9c662012-10-11 17:00:31 -07001148 /* Set Exponent parameter as 6 (MHZ) in struct iw_freq
1149 * iwlist & iwconfig command shows frequency into proper
1150 * format (2.412 GHz instead of 246.2 MHz)*/
1151 fwrq->m = 0;
1152 fwrq->e = MHZ;
Jeff Johnson295189b2012-06-20 16:38:30 -07001153 }
Jeff Johnsone7245742012-09-05 17:12:55 -07001154 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001155}
1156
1157static int iw_get_tx_power(struct net_device *dev,
1158 struct iw_request_info *info,
1159 union iwreq_data *wrqu, char *extra)
1160{
1161
1162 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1163 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1164 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1165
1166 if (pHddCtx->isLogpInProgress)
1167 {
1168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
1169 "%s:LOGP in Progress. Ignore!!!",__func__);
1170 return -EBUSY;
1171 }
1172
1173 if(eConnectionState_Associated != pHddStaCtx->conn_info.connState)
1174 {
1175 wrqu->txpower.value = 0;
1176 return 0;
1177 }
1178 wlan_hdd_get_classAstats(pAdapter);
1179 wrqu->txpower.value = pAdapter->hdd_stats.ClassA_stat.max_pwr;
1180
1181 return 0;
1182}
1183
1184static int iw_set_tx_power(struct net_device *dev,
1185 struct iw_request_info *info,
1186 union iwreq_data *wrqu, char *extra)
1187{
1188 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1189 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1190
1191 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1192 {
1193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1194 return 0;
1195 }
1196
1197 ENTER();
1198
1199 if ( ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL, wrqu->txpower.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
1200 {
1201 return -EIO;
1202 }
1203
1204 EXIT();
1205
1206 return 0;
1207}
1208
1209static int iw_get_bitrate(struct net_device *dev,
1210 struct iw_request_info *info,
1211 union iwreq_data *wrqu, char *extra)
1212{
1213 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
1214 eHalStatus status = eHAL_STATUS_SUCCESS;
1215 hdd_wext_state_t *pWextState;
1216 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1217 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1218
1219 ENTER();
1220
1221 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
1222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1223 return status;
1224 }
1225
1226 if(eConnectionState_Associated != pHddStaCtx->conn_info.connState) {
1227 wrqu->bitrate.value = 0;
1228 }
1229 else {
1230 status = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_HDD,
1231 SME_SUMMARY_STATS |
1232 SME_GLOBAL_CLASSA_STATS |
1233 SME_GLOBAL_CLASSB_STATS |
1234 SME_GLOBAL_CLASSC_STATS |
1235 SME_GLOBAL_CLASSD_STATS |
1236 SME_PER_STA_STATS,
1237 hdd_StatisticsCB, 0, FALSE,
1238 pHddStaCtx->conn_info.staId[0], pAdapter );
1239
1240 if(eHAL_STATUS_SUCCESS != status)
1241 {
1242 hddLog(VOS_TRACE_LEVEL_ERROR,
1243 "%s: Unable to retrieve statistics",
1244 __FUNCTION__);
1245 return status;
1246 }
1247
1248 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1249
1250 vos_status = vos_wait_single_event(&pWextState->vosevent, WLAN_WAIT_TIME_STATS);
1251
1252 if (!VOS_IS_STATUS_SUCCESS(vos_status))
1253 {
1254 hddLog(VOS_TRACE_LEVEL_ERROR,
1255 "%s: SME timeout while retrieving statistics",
1256 __FUNCTION__);
1257 return VOS_STATUS_E_FAILURE;
1258 }
1259
1260 wrqu->bitrate.value = pAdapter->hdd_stats.ClassA_stat.tx_rate*500*1000;
1261 }
1262
1263 EXIT();
1264
1265 return vos_status;
1266}
1267/* ccm call back function */
1268
1269static int iw_set_bitrate(struct net_device *dev,
1270 struct iw_request_info *info,
1271 union iwreq_data *wrqu,
1272 char *extra)
1273{
1274 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1275 hdd_wext_state_t *pWextState;
1276 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1277 v_U8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
1278 v_U32_t a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
1279 v_U32_t b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
1280 v_U32_t i, rate;
1281 v_U32_t valid_rate = FALSE, active_phy_mode = 0;
1282
1283 ENTER();
1284
1285 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
1286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1287 return 0;
1288 }
1289
1290 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1291
1292 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
1293 {
1294 return -ENXIO ;
1295 }
1296
1297 rate = wrqu->bitrate.value;
1298
1299 if (rate == -1)
1300 {
1301 rate = WNI_CFG_FIXED_RATE_AUTO;
1302 valid_rate = TRUE;
1303 }
1304 else if (ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
1305 WNI_CFG_DOT11_MODE, &active_phy_mode) == eHAL_STATUS_SUCCESS)
1306 {
1307 if (active_phy_mode == WNI_CFG_DOT11_MODE_11A || active_phy_mode == WNI_CFG_DOT11_MODE_11G
1308 || active_phy_mode == WNI_CFG_DOT11_MODE_11B)
1309 {
1310 if ((ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
1311 WNI_CFG_SUPPORTED_RATES_11A,
1312 supp_rates, &a_len) == eHAL_STATUS_SUCCESS) &&
1313 (ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
1314 WNI_CFG_SUPPORTED_RATES_11B,
1315 supp_rates, &b_len) == eHAL_STATUS_SUCCESS))
1316 {
1317 for (i = 0; i < (b_len + a_len); ++i)
1318 {
1319 /* supported rates returned is double the actual rate so we divide it by 2 */
1320 if ((supp_rates[i]&0x7F)/2 == rate)
1321 {
1322 valid_rate = TRUE;
1323 rate = i + WNI_CFG_FIXED_RATE_1MBPS;
1324 break;
1325 }
1326 }
1327 }
1328 }
1329 }
1330 if (valid_rate != TRUE)
1331 {
1332 return -EINVAL;
1333 }
1334 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
1335 WNI_CFG_FIXED_RATE, rate,
1336 ccmCfgSetCallback,eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
1337 {
1338 return -EIO;
1339 }
1340 return 0;
1341}
1342
1343
1344static int iw_set_genie(struct net_device *dev,
1345 struct iw_request_info *info,
1346 union iwreq_data *wrqu,
1347 char *extra)
1348{
1349 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1350 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1351 u_int8_t *genie;
1352 v_U16_t remLen;
1353
1354 ENTER();
1355 if(!wrqu->data.length) {
1356 hdd_clearRoamProfileIe(pAdapter);
1357 EXIT();
1358 return 0;
1359 }
1360
1361 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
1362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1363 return 0;
1364 }
1365
1366 genie = wrqu->data.pointer;
1367 remLen = wrqu->data.length;
1368
1369 hddLog(LOG1,"iw_set_genie ioctl IE[0x%X], LEN[%d]\n", genie[0], genie[1]);
1370
1371 /* clear any previous genIE before this call */
1372 memset( &pWextState->genIE, 0, sizeof(pWextState->genIE) );
1373
1374 while (remLen >= 2)
1375 {
1376 v_U16_t eLen = 0;
1377 v_U8_t elementId;
1378 elementId = *genie++;
1379 eLen = *genie++;
1380 remLen -= 2;
1381
1382 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]\n",
1383 __func__, elementId, eLen);
1384
1385 switch ( elementId )
1386 {
1387 case IE_EID_VENDOR:
1388 if ((IE_LEN_SIZE+IE_EID_SIZE+IE_VENDOR_OUI_SIZE) > eLen) /* should have at least OUI */
1389 return -EINVAL;
1390
1391 if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
1392 {
1393 v_U16_t curGenIELen = pWextState->genIE.length;
1394 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS OUI(%02x %02x %02x %02x) IE(len %d)",
1395 __func__, genie[0], genie[1], genie[2], genie[3], eLen + 2);
1396
1397 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->genIE.length + eLen) )
1398 {
1399 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. "
1400 "Need bigger buffer space\n");
1401 VOS_ASSERT(0);
1402 return -ENOMEM;
1403 }
1404 // save to Additional IE ; it should be accumulated to handle WPS IE + other IE
1405 memcpy( pWextState->genIE.addIEdata + curGenIELen, genie - 2, eLen + 2);
1406 pWextState->genIE.length += eLen + 2;
1407 }
1408 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
1409 {
1410 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
1411 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
1412 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2));
1413 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
1414 pWextState->roamProfile.nWPAReqIELength = eLen + 2;
1415 }
1416 else /* any vendorId except WPA IE should be accumulated to genIE */
1417 {
1418 v_U16_t curGenIELen = pWextState->genIE.length;
1419 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OUI(%02x %02x %02x %02x) IE(len %d)",
1420 __func__, genie[0], genie[1], genie[2], genie[3], eLen + 2);
1421
1422 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->genIE.length + eLen) )
1423 {
1424 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate genIE. "
1425 "Need bigger buffer space\n");
1426 VOS_ASSERT(0);
1427 return -ENOMEM;
1428 }
1429 // save to Additional IE ; it should be accumulated to handle WPS IE + other IE
1430 memcpy( pWextState->genIE.addIEdata + curGenIELen, genie - 2, eLen + 2);
1431 pWextState->genIE.length += eLen + 2;
1432 }
1433 break;
1434 case DOT11F_EID_RSN:
1435 hddLog (LOG1, "%s Set RSN IE (len %d)",__FUNCTION__, eLen+2);
1436 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
1437 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2));
1438 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
1439 pWextState->roamProfile.nRSNReqIELength = eLen + 2;
1440 break;
1441
1442 default:
1443 hddLog (LOGE, "%s Set UNKNOWN IE %X",__FUNCTION__, elementId);
1444 return 0;
1445 }
1446 genie += eLen;
1447 remLen -= eLen;
1448 }
1449 EXIT();
1450 return 0;
1451}
1452
1453static int iw_get_genie(struct net_device *dev,
1454 struct iw_request_info *info,
1455 union iwreq_data *wrqu,
1456 char *extra)
1457{
1458 hdd_wext_state_t *pWextState;
1459 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1460 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1461 eHalStatus status;
1462 v_U32_t length = DOT11F_IE_RSN_MAX_LEN;
1463 v_U8_t genIeBytes[DOT11F_IE_RSN_MAX_LEN];
1464
1465 ENTER();
1466
1467 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
1468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1469 return 0;
1470 }
1471
1472
1473 hddLog(LOG1,"getGEN_IE ioctl\n");
1474
1475 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1476
1477 if( pHddStaCtx->conn_info.connState == eConnectionState_NotConnected)
1478 {
1479 return -ENXIO;
1480 }
1481
1482 // Return something ONLY if we are associated with an RSN or WPA network
1483 if ( VOS_TRUE != hdd_IsAuthTypeRSN(WLAN_HDD_GET_HAL_CTX(pAdapter),
1484 pWextState->roamProfile.negotiatedAuthType))
1485 {
1486 return -ENXIO;
1487 }
1488
1489 // Actually retrieve the RSN IE from CSR. (We previously sent it down in the CSR Roam Profile.)
1490 status = csrRoamGetWpaRsnReqIE(WLAN_HDD_GET_HAL_CTX(pAdapter),
1491 pAdapter->sessionId,
1492 &length,
1493 genIeBytes);
1494 wrqu->data.length = VOS_MIN((u_int16_t) length, DOT11F_IE_RSN_MAX_LEN);
1495
1496 vos_mem_copy( wrqu->data.pointer, (v_VOID_t*)genIeBytes, wrqu->data.length);
1497
1498 hddLog(LOG1,"%s: RSN IE of %d bytes returned\n", __FUNCTION__, wrqu->data.length );
1499
1500 EXIT();
1501
1502 return 0;
1503}
1504
1505static int iw_get_encode(struct net_device *dev,
1506 struct iw_request_info *info,
1507 struct iw_point *dwrq, char *extra)
1508{
1509 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1510 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1511 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
1512 int keyId;
1513 eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
1514 int i;
1515
1516 ENTER();
1517
1518 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress) {
1519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
1520 return 0;
1521 }
1522
1523 keyId = pRoamProfile->Keys.defaultIndex;
1524
1525 if(keyId < 0 || keyId >= MAX_WEP_KEYS)
1526 {
1527 hddLog(LOG1,"%s: Invalid keyId : %d\n",__FUNCTION__,keyId);
1528 return -EINVAL;
1529 }
1530
1531 if(pRoamProfile->Keys.KeyLength[keyId] > 0)
1532 {
1533 dwrq->flags |= IW_ENCODE_ENABLED;
1534 dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
1535 vos_mem_copy(extra,&(pRoamProfile->Keys.KeyMaterial[keyId][0]),pRoamProfile->Keys.KeyLength[keyId]);
1536
1537 dwrq->flags |= (keyId + 1);
1538
1539 }
1540 else
1541 {
1542 dwrq->flags |= IW_ENCODE_DISABLED;
1543 }
1544
1545 for(i=0; i < MAX_WEP_KEYS; i++)
1546 {
1547 if(pRoamProfile->Keys.KeyMaterial[i] == NULL)
1548 {
1549 continue;
1550 }
1551 else
1552 {
1553 break;
1554 }
1555 }
1556
1557 if(MAX_WEP_KEYS == i)
1558 {
1559 dwrq->flags |= IW_ENCODE_NOKEY;
1560 }
1561
1562 authType = ((hdd_station_ctx_t*)WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
1563
1564 if(eCSR_AUTH_TYPE_OPEN_SYSTEM == authType)
1565 {
1566 dwrq->flags |= IW_ENCODE_OPEN;
1567 }
1568 else
1569 {
1570 dwrq->flags |= IW_ENCODE_RESTRICTED;
1571 }
1572 EXIT();
1573 return 0;
1574}
1575
1576#define PAE_ROLE_AUTHENTICATOR 1 // =1 for authenticator,
1577#define PAE_ROLE_SUPPLICANT 0 // =0 for supplicant
1578
1579
1580/*
1581 * This function sends a single 'key' to LIM at all time.
1582 */
1583
1584static int iw_get_rts_threshold(struct net_device *dev,
1585 struct iw_request_info *info,
1586 union iwreq_data *wrqu, char *extra)
1587{
1588 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1589 v_U32_t status = 0;
1590
1591 status = hdd_wlan_get_rts_threshold(pAdapter,wrqu);
1592
1593 return status;
1594}
1595
1596static int iw_set_rts_threshold(struct net_device *dev,
1597 struct iw_request_info *info,
1598 union iwreq_data *wrqu, char *extra)
1599{
1600 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1601 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1602
1603 ENTER();
1604
1605 if ( wrqu->rts.value < WNI_CFG_RTS_THRESHOLD_STAMIN || wrqu->rts.value > WNI_CFG_RTS_THRESHOLD_STAMAX )
1606 {
1607 return -EINVAL;
1608 }
1609
1610 if ( ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD, wrqu->rts.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
1611 {
1612 return -EIO;
1613 }
1614
1615 EXIT();
1616
1617 return 0;
1618}
1619
1620static int iw_get_frag_threshold(struct net_device *dev,
1621 struct iw_request_info *info,
1622 union iwreq_data *wrqu, char *extra)
1623{
1624 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1625 v_U32_t status = 0;
1626
1627 status = hdd_wlan_get_frag_threshold(pAdapter,wrqu);
1628
1629 return status;
1630}
1631
1632static int iw_set_frag_threshold(struct net_device *dev,
1633 struct iw_request_info *info,
1634 union iwreq_data *wrqu, char *extra)
1635{
1636 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1637 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1638
1639 ENTER();
1640
1641 if ( wrqu->frag.value < WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN || wrqu->frag.value > WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX )
1642 {
1643 return -EINVAL;
1644 }
1645
1646 if ( ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD, wrqu->frag.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
1647 {
1648 return -EIO;
1649 }
1650
1651 EXIT();
1652
1653 return 0;
1654}
1655
1656static int iw_get_power_mode(struct net_device *dev,
1657 struct iw_request_info *info,
1658 union iwreq_data *wrqu, char *extra)
1659{
1660 ENTER();
1661 return -EOPNOTSUPP;
1662}
1663
1664static int iw_set_power_mode(struct net_device *dev,
1665 struct iw_request_info *info,
1666 union iwreq_data *wrqu, char *extra)
1667{
1668 ENTER();
1669 return -EOPNOTSUPP;
1670}
1671
1672static int iw_get_range(struct net_device *dev, struct iw_request_info *info,
1673 union iwreq_data *wrqu, char *extra)
1674{
1675 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1676 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1677 struct iw_range *range = (struct iw_range *) extra;
1678
1679 v_U8_t channels[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1680
1681 v_U32_t num_channels = sizeof(channels);
1682 v_U8_t supp_rates[WNI_CFG_SUPPORTED_RATES_11A_LEN];
1683 v_U32_t a_len;
1684 v_U32_t b_len;
1685 v_U32_t active_phy_mode = 0;
1686 v_U8_t index = 0, i;
1687
1688 ENTER();
1689
1690 wrqu->data.length = sizeof(struct iw_range);
1691 memset(range, 0, sizeof(struct iw_range));
1692
1693
1694 /*Get the phy mode*/
1695 if (ccmCfgGetInt(hHal,
1696 WNI_CFG_DOT11_MODE, &active_phy_mode) == eHAL_STATUS_SUCCESS)
1697 {
1698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1699 "active_phy_mode = %ld", active_phy_mode);
1700
1701 if (active_phy_mode == WNI_CFG_DOT11_MODE_11A || active_phy_mode == WNI_CFG_DOT11_MODE_11G)
1702 {
1703 /*Get the supported rates for 11G band*/
1704 if (ccmCfgGetStr(hHal,
1705 WNI_CFG_SUPPORTED_RATES_11A,
1706 supp_rates, &a_len) == eHAL_STATUS_SUCCESS)
1707 {
1708 if (a_len > WNI_CFG_SUPPORTED_RATES_11A_LEN)
1709 {
1710 a_len = WNI_CFG_SUPPORTED_RATES_11A_LEN;
1711 }
1712 for (i = 0; i < a_len; i++)
1713 {
1714 range->bitrate[i] = ((supp_rates[i] & 0x7F) / 2) * 1000000;
1715 }
1716 range->num_bitrates = a_len;
1717 }
1718 else
1719 {
1720 return -EIO;
1721 }
1722 }
1723 else if (active_phy_mode == WNI_CFG_DOT11_MODE_11B)
1724 {
1725 /*Get the supported rates for 11B band*/
1726 if (ccmCfgGetStr(hHal,
1727 WNI_CFG_SUPPORTED_RATES_11B,
1728 supp_rates, &b_len) == eHAL_STATUS_SUCCESS)
1729 {
1730 if (b_len > WNI_CFG_SUPPORTED_RATES_11B_LEN)
1731 {
1732 b_len = WNI_CFG_SUPPORTED_RATES_11B_LEN;
1733 }
1734 for (i = 0; i < b_len; i++)
1735 {
1736 range->bitrate[i] = ((supp_rates[i] & 0x7F) / 2) * 1000000;
1737 }
1738 range->num_bitrates = b_len;
1739 }
1740 else
1741 {
1742 return -EIO;
1743 }
1744 }
1745 }
1746
1747 range->max_rts = WNI_CFG_RTS_THRESHOLD_STAMAX;
1748 range->min_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN;
1749 range->max_frag = WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX;
1750
1751 range->encoding_size[0] = 5;
1752 range->encoding_size[1] = 13;
1753 range->num_encoding_sizes = 2;
1754 range->max_encoding_tokens = MAX_WEP_KEYS;
1755
1756 // we support through Wireless Extensions 22
1757 range->we_version_compiled = WIRELESS_EXT;
1758 range->we_version_source = 22;
1759
1760 /*Supported Channels and Frequencies*/
1761 if (ccmCfgGetStr((hHal), WNI_CFG_VALID_CHANNEL_LIST, channels, &num_channels) != eHAL_STATUS_SUCCESS)
1762 {
1763 return -EIO;
1764 }
1765 if (num_channels > IW_MAX_FREQUENCIES)
1766 {
1767 num_channels = IW_MAX_FREQUENCIES;
1768 }
1769
1770 range->num_channels = num_channels;
1771 range->num_frequency = num_channels;
1772
1773 for (index=0; index < num_channels; index++)
1774 {
1775 v_U32_t frq_indx = 0;
1776
1777 range->freq[index].i = channels[index];
1778 while (frq_indx < FREQ_CHAN_MAP_TABLE_SIZE)
1779 {
1780 if(channels[index] == freq_chan_map[frq_indx].chan)
1781 {
1782 range->freq[index].m = freq_chan_map[frq_indx].freq * 100000;
1783 range->freq[index].e = 1;
1784 break;
1785 }
1786 frq_indx++;
1787 }
1788 }
1789
1790 /* Event capability (kernel + driver) */
1791 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
1792 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
1793 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
1794 range->event_capa[1] = IW_EVENT_CAPA_K_1;
1795
1796 /*Encryption capability*/
1797 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
1798 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
1799
1800 /* Txpower capability */
1801 range->txpower_capa = IW_TXPOW_MWATT;
1802
1803 /*Scanning capability*/
1804 #if WIRELESS_EXT >= 22
1805 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_CHANNEL;
1806 #endif
1807
1808 EXIT();
1809 return 0;
1810}
1811
1812/* Callback function registered with PMC to know status of PMC request */
1813static void iw_power_callback_fn (void *pContext, eHalStatus status)
1814{
1815 struct statsContext *pStatsContext;
1816 hdd_adapter_t *pAdapter;
1817
1818 if (NULL == pContext)
1819 {
1820 hddLog(VOS_TRACE_LEVEL_ERROR,
1821 "%s: Bad param, pContext [%p]",
1822 __FUNCTION__, pContext);
1823 return;
1824 }
1825
1826 /* there is a race condition that exists between this callback function
1827 and the caller since the caller could time out either before or
1828 while this code is executing. we'll assume the timeout hasn't
1829 occurred, but we'll verify that right before we save our work */
1830
1831 pStatsContext = (struct statsContext *)pContext;
1832 pAdapter = pStatsContext->pAdapter;
1833
1834 if ((NULL == pAdapter) || (POWER_CONTEXT_MAGIC != pStatsContext->magic))
1835 {
1836 /* the caller presumably timed out so there is nothing we can do */
1837 hddLog(VOS_TRACE_LEVEL_WARN,
1838 "%s: Invalid context, pAdapter [%p] magic [%08x]",
1839 __FUNCTION__, pAdapter, pStatsContext->magic);
1840
1841 if (ioctl_debug)
1842 {
1843 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
1844 __FUNCTION__, pAdapter, pStatsContext->magic);
1845 }
1846 return;
1847 }
1848
1849 /* and notify the caller */
1850 complete(&pStatsContext->completion);
1851}
1852
1853/* Callback function for tx per hit */
1854void hdd_tx_per_hit_cb (void *pCallbackContext)
1855{
1856 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pCallbackContext;
1857 unsigned char tx_fail[16];
1858 union iwreq_data wrqu;
1859
1860 if (NULL == pAdapter)
1861 {
1862 hddLog(LOGE, "hdd_tx_per_hit_cb: pAdapter is NULL\n");
1863 return;
1864 }
1865 memset(&wrqu, 0, sizeof(wrqu));
1866 wrqu.data.length = strlcpy(tx_fail, "TX_FAIL", sizeof(tx_fail));
1867 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, tx_fail);
1868}
1869
1870void hdd_GetClassA_statisticsCB(void *pStats, void *pContext)
1871{
1872 struct statsContext *pStatsContext;
1873 tCsrGlobalClassAStatsInfo *pClassAStats;
1874 hdd_adapter_t *pAdapter;
1875
1876 if (ioctl_debug)
1877 {
1878 pr_info("%s: pStats [%p] pContext [%p]\n",
1879 __FUNCTION__, pStats, pContext);
1880 }
1881
1882 if ((NULL == pStats) || (NULL == pContext))
1883 {
1884 hddLog(VOS_TRACE_LEVEL_ERROR,
1885 "%s: Bad param, pStats [%p] pContext [%p]",
1886 __FUNCTION__, pStats, pContext);
1887 return;
1888 }
1889
1890 /* there is a race condition that exists between this callback function
1891 and the caller since the caller could time out either before or
1892 while this code is executing. we'll assume the timeout hasn't
1893 occurred, but we'll verify that right before we save our work */
1894
1895 pClassAStats = pStats;
1896 pStatsContext = pContext;
1897 pAdapter = pStatsContext->pAdapter;
1898 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
1899 {
1900 /* the caller presumably timed out so there is nothing we can do */
1901 hddLog(VOS_TRACE_LEVEL_WARN,
1902 "%s: Invalid context, pAdapter [%p] magic [%08x]",
1903 __FUNCTION__, pAdapter, pStatsContext->magic);
1904 if (ioctl_debug)
1905 {
1906 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
1907 __FUNCTION__, pAdapter, pStatsContext->magic);
1908 }
1909 return;
1910 }
1911
1912 /* the race is on. caller could have timed out immediately after
1913 we verified the magic, but if so, caller will wait a short time
1914 for us to copy over the stats. do so as a struct copy */
1915 pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
1916
1917 /* and notify the caller */
1918 complete(&pStatsContext->completion);
1919}
1920
1921VOS_STATUS wlan_hdd_get_classAstats(hdd_adapter_t *pAdapter)
1922{
1923 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1924 eHalStatus hstatus;
1925 long lrc;
1926 struct statsContext context;
1927
1928 if (NULL == pAdapter)
1929 {
1930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Padapter is NULL", __func__);
1931 return VOS_STATUS_E_FAULT;
1932 }
1933 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
1934 {
1935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "%s:LOGP in Progress. Ignore!!!",__func__);
1936 return VOS_STATUS_SUCCESS;
1937 }
1938
1939 /* we are connected
1940 prepare our callback context */
1941 init_completion(&context.completion);
1942 context.pAdapter = pAdapter;
1943 context.magic = STATS_CONTEXT_MAGIC;
1944 /* query only for Class A statistics (which include link speed) */
1945 hstatus = sme_GetStatistics( WLAN_HDD_GET_HAL_CTX(pAdapter),
1946 eCSR_HDD,
1947 SME_GLOBAL_CLASSA_STATS,
1948 hdd_GetClassA_statisticsCB,
1949 0, // not periodic
1950 FALSE, //non-cached results
1951 pHddStaCtx->conn_info.staId[0],
1952 &context);
1953 if (eHAL_STATUS_SUCCESS != hstatus)
1954 {
1955 hddLog(VOS_TRACE_LEVEL_ERROR,
1956 "%s: Unable to retrieve Class A statistics ",
1957 __FUNCTION__);
1958 /* we'll returned a cached value below */
1959 }
1960 else
1961 {
1962 /* request was sent -- wait for the response */
1963 lrc = wait_for_completion_interruptible_timeout(&context.completion,
1964 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
1965 /* either we have a response or we timed out
1966 either way, first invalidate our magic */
1967 context.magic = 0;
1968 if (lrc <= 0)
1969 {
1970 hddLog(VOS_TRACE_LEVEL_ERROR,
1971 "%s: SME %s while retrieving Class A statistics",
1972 __FUNCTION__, (0 == lrc) ? "timeout" : "interrupt");
1973 /* there is a race condition such that the callback
1974 function could be executing at the same time we are. of
1975 primary concern is if the callback function had already
1976 verified the "magic" but hasn't yet set the completion
1977 variable. Since the completion variable is on our
1978 stack, we'll delay just a bit to make sure the data is
1979 still valid if that is the case */
1980 msleep(50);
1981 }
1982 }
1983 return VOS_STATUS_SUCCESS;
1984}
1985
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07001986static void hdd_get_station_statisticsCB(void *pStats, void *pContext)
1987{
1988 struct statsContext *pStatsContext;
1989 tCsrSummaryStatsInfo *pSummaryStats;
1990 tCsrGlobalClassAStatsInfo *pClassAStats;
1991 hdd_adapter_t *pAdapter;
1992
1993 if (ioctl_debug)
1994 {
1995 pr_info("%s: pStats [%p] pContext [%p]\n",
1996 __FUNCTION__, pStats, pContext);
1997 }
1998
1999 if ((NULL == pStats) || (NULL == pContext))
2000 {
2001 hddLog(VOS_TRACE_LEVEL_ERROR,
2002 "%s: Bad param, pStats [%p] pContext [%p]",
2003 __FUNCTION__, pStats, pContext);
2004 return;
2005 }
2006
2007 /* there is a race condition that exists between this callback function
2008 and the caller since the caller could time out either before or
2009 while this code is executing. we'll assume the timeout hasn't
2010 occurred, but we'll verify that right before we save our work */
2011
2012 pSummaryStats = (tCsrSummaryStatsInfo *)pStats;
2013 pClassAStats = (tCsrGlobalClassAStatsInfo *)( pSummaryStats + 1 );
2014 pStatsContext = pContext;
2015 pAdapter = pStatsContext->pAdapter;
2016 if ((NULL == pAdapter) || (STATS_CONTEXT_MAGIC != pStatsContext->magic))
2017 {
2018 /* the caller presumably timed out so there is nothing we can do */
2019 hddLog(VOS_TRACE_LEVEL_WARN,
2020 "%s: Invalid context, pAdapter [%p] magic [%08x]",
2021 __FUNCTION__, pAdapter, pStatsContext->magic);
2022 if (ioctl_debug)
2023 {
2024 pr_info("%s: Invalid context, pAdapter [%p] magic [%08x]\n",
2025 __FUNCTION__, pAdapter, pStatsContext->magic);
2026 }
2027 return;
2028 }
2029
2030 /* the race is on. caller could have timed out immediately after
2031 we verified the magic, but if so, caller will wait a short time
2032 for us to copy over the stats. do so as a struct copy */
2033 pAdapter->hdd_stats.summary_stat = *pSummaryStats;
2034 pAdapter->hdd_stats.ClassA_stat = *pClassAStats;
2035
2036 /* and notify the caller */
2037 complete(&pStatsContext->completion);
2038}
2039
2040VOS_STATUS wlan_hdd_get_station_stats(hdd_adapter_t *pAdapter)
2041{
2042 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2043 eHalStatus hstatus;
2044 long lrc;
2045 struct statsContext context;
2046
2047 if (NULL == pAdapter)
2048 {
2049 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Padapter is NULL", __func__);
2050 return VOS_STATUS_SUCCESS;
2051 }
2052
2053 /* we are connected
2054 prepare our callback context */
2055 init_completion(&context.completion);
2056 context.pAdapter = pAdapter;
2057 context.magic = STATS_CONTEXT_MAGIC;
2058
2059 /* query only for Summary & Class A statistics */
2060 hstatus = sme_GetStatistics(WLAN_HDD_GET_HAL_CTX(pAdapter),
2061 eCSR_HDD,
2062 SME_SUMMARY_STATS |
2063 SME_GLOBAL_CLASSA_STATS,
2064 hdd_get_station_statisticsCB,
2065 0, // not periodic
2066 FALSE, //non-cached results
2067 pHddStaCtx->conn_info.staId[0],
2068 &context);
2069 if (eHAL_STATUS_SUCCESS != hstatus)
2070 {
2071 hddLog(VOS_TRACE_LEVEL_ERROR,
2072 "%s: Unable to retrieve statistics",
2073 __FUNCTION__);
2074 /* we'll return with cached values */
2075 }
2076 else
2077 {
2078 /* request was sent -- wait for the response */
2079 lrc = wait_for_completion_interruptible_timeout(&context.completion,
2080 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
2081 /* either we have a response or we timed out
2082 either way, first invalidate our magic */
2083 context.magic = 0;
2084 if (lrc <= 0)
2085 {
2086 hddLog(VOS_TRACE_LEVEL_ERROR,
2087 "%s: SME %s while retrieving statistics",
2088 __FUNCTION__, (0 == lrc) ? "timeout" : "interrupt");
2089 /* there is a race condition such that the callback
2090 function could be executing at the same time we are. of
2091 primary concern is if the callback function had already
2092 verified the "magic" but hasn't yet set the completion
2093 variable. Since the completion variable is on our
2094 stack, we'll delay just a bit to make sure the data is
2095 still valid if that is the case */
2096 msleep(50);
2097 }
2098 }
2099 return VOS_STATUS_SUCCESS;
2100}
2101
2102
Jeff Johnson295189b2012-06-20 16:38:30 -07002103/*
2104 * Support for the LINKSPEED private command
2105 * Per the WiFi framework the response must be of the form
2106 * "LinkSpeed xx"
2107 */
2108static int iw_get_linkspeed(struct net_device *dev,
2109 struct iw_request_info *info,
2110 union iwreq_data *wrqu, char *extra)
2111{
2112 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2113 char *pLinkSpeed = (char*)extra;
2114 int len = sizeof(v_U16_t) + 1;
2115 v_U16_t link_speed;
2116 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2117 int rc;
2118
2119 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
2120 {
2121 /* we are not connected so we don't have a classAstats */
2122 link_speed = 0;
2123 }
2124 else
2125 {
2126 wlan_hdd_get_classAstats(pAdapter);
2127 //The linkspeed returned by HAL is in units of 500kbps.
2128 //converting it to mbps
2129 link_speed = pAdapter->hdd_stats.ClassA_stat.tx_rate/2;
2130 }
2131
2132 wrqu->data.length = len;
2133 // return the linkspeed in the format required by the WiFi Framework
2134 rc = snprintf(pLinkSpeed, len, "%u", link_speed);
2135 if ((rc < 0) || (rc >= len))
2136 {
2137 // encoding or length error?
2138 hddLog(VOS_TRACE_LEVEL_ERROR,
2139 "%s: Unable to encode link speed, got [%s]",
2140 __FUNCTION__,pLinkSpeed);
2141 return -EIO;
2142 }
2143
2144 /* a value is being successfully returned */
2145 return 0;
2146}
2147
2148
2149/*
2150 * Support for the RSSI & RSSI-APPROX private commands
2151 * Per the WiFi framework the response must be of the form
2152 * "<ssid> rssi <xx>"
2153 * unless we are not associated, in which case the response is
2154 * "OK"
2155 */
2156static int iw_get_rssi(struct net_device *dev,
2157 struct iw_request_info *info,
2158 union iwreq_data *wrqu, char *extra)
2159{
2160 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2161 char *cmd = (char*)wrqu->data.pointer;
2162 int len = wrqu->data.length;
2163 v_S7_t s7Rssi = 0;
2164 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2165 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
2166 VOS_STATUS vosStatus;
2167 int rc;
2168
2169 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
2170 (0 == ssidlen) || (ssidlen >= len))
2171 {
2172 /* we are not connected or our SSID is too long
2173 so we cannot report an rssi */
2174 rc = snprintf(cmd, len, "OK");
2175 }
2176 else
2177 {
2178 /* we are connected with a valid SSID
2179 so we can write the SSID into the return buffer
2180 (note that it is not NUL-terminated) */
2181 memcpy(cmd, pHddStaCtx->conn_info.SSID.SSID.ssId, ssidlen );
2182
2183 vosStatus = wlan_hdd_get_rssi(pAdapter, &s7Rssi);
2184
2185 if (VOS_STATUS_SUCCESS == vosStatus)
2186 {
2187 /* append the rssi to the ssid in the format required by
2188 the WiFI Framework */
2189 rc = snprintf(&cmd[ssidlen], len - ssidlen, " rssi %d", s7Rssi);
2190 }
2191 else
2192 {
2193 rc = -1;
2194 }
2195 }
2196
2197 /* verify that we wrote a valid response */
2198 if ((rc < 0) || (rc >= len))
2199 {
2200 // encoding or length error?
2201 hddLog(VOS_TRACE_LEVEL_ERROR,
2202 "%s: Unable to encode RSSI, got [%s]",
2203 __FUNCTION__, cmd);
2204 return -EIO;
2205 }
2206
2207 /* a value is being successfully returned */
2208 return 0;
2209}
2210
2211/*
2212 * Support for SoftAP channel range private command
2213 */
2214static int iw_softap_set_channel_range( struct net_device *dev,
2215 int startChannel,
2216 int endChannel,
2217 int band)
2218{
Jeff Johnson43971f52012-07-17 12:26:56 -07002219 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002220 int ret = 0;
2221 hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev));
2222 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
2223
2224 status = WLANSAP_SetChannelRange(hHal, startChannel, endChannel, band);
2225 if (VOS_STATUS_SUCCESS != status)
2226 {
2227 ret = -EINVAL;
2228 }
2229 return ret;
2230}
2231
2232VOS_STATUS wlan_hdd_enter_bmps(hdd_adapter_t *pAdapter, int mode)
2233{
2234 struct statsContext context;
2235 eHalStatus status;
2236 hdd_context_t *pHddCtx;
2237
2238 if (NULL == pAdapter)
2239 {
2240 hddLog(VOS_TRACE_LEVEL_FATAL, "Adapter NULL");
2241 return VOS_STATUS_E_FAULT;
2242 }
2243
2244 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "power mode=%d", mode);
2245 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2246 init_completion(&context.completion);
2247
2248 context.pAdapter = pAdapter;
2249 context.magic = POWER_CONTEXT_MAGIC;
2250
2251 if (DRIVER_POWER_MODE_ACTIVE == mode)
2252 {
2253 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering "
2254 "Full Power", __func__);
2255 status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
2256 iw_power_callback_fn, &context,
2257 eSME_FULL_PWR_NEEDED_BY_HDD);
2258 // Enter Full power command received from GUI this means we are disconnected
2259 // Set PMC remainInPowerActiveTillDHCP flag to disable auto BMPS entry by PMC
2260 sme_SetDHCPTillPowerActiveFlag(pHddCtx->hHal, TRUE);
2261 if (eHAL_STATUS_PMC_PENDING == status)
2262 {
2263 int lrc = wait_for_completion_interruptible_timeout(
2264 &context.completion,
2265 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
2266 context.magic = 0;
2267 if (lrc <= 0)
2268 {
2269 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while requesting fullpower ",
2270 __FUNCTION__, (0 == lrc) ? "timeout" : "interrupt");
2271 /* there is a race condition such that the callback
2272 function could be executing at the same time we are. of
2273 primary concern is if the callback function had already
2274 verified the "magic" but hasn't yet set the completion
2275 variable. Since the completion variable is on our
2276 stack, we'll delay just a bit to make sure the data is
2277 still valid if that is the case */
2278 msleep(50);
2279 /* we'll now returned a cached value below */
2280 }
2281 }
2282 }
2283 else if (DRIVER_POWER_MODE_AUTO == mode)
2284 {
2285 if (pHddCtx->cfg_ini->fIsBmpsEnabled)
2286 {
2287 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s:Wlan driver Entering Bmps ",
2288 __func__);
2289 // Enter BMPS command received from GUI this means DHCP is completed
2290 // Clear PMC remainInPowerActiveTillDHCP flag to enable auto BMPS entry
2291 sme_SetDHCPTillPowerActiveFlag(WLAN_HDD_GET_HAL_CTX(pAdapter),
2292 FALSE);
2293 status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter),
2294 iw_power_callback_fn, &context);
2295 if (eHAL_STATUS_PMC_PENDING == status)
2296 {
2297 int lrc = wait_for_completion_interruptible_timeout(
2298 &context.completion,
2299 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
2300 context.magic = 0;
2301 if (lrc <= 0)
2302 {
2303 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while requesting BMPS ",
2304 __FUNCTION__, (0 == lrc) ? "timeout" : "interrupt");
2305 /* there is a race condition such that the callback
2306 function could be executing at the same time we are. of
2307 primary concern is if the callback function had already
2308 verified the "magic" but hasn't yet set the completion
2309 variable. Since the completion variable is on our
2310 stack, we'll delay just a bit to make sure the data is
2311 still valid if that is the case */
2312 msleep(50);
2313 /* we'll now returned a cached value below */
2314 }
2315 }
2316 }
2317 else
2318 {
2319 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "BMPS is not "
2320 "enabled in the cfg");
2321 }
2322 }
2323 return VOS_STATUS_SUCCESS;
2324}
2325
2326VOS_STATUS wlan_hdd_exit_lowpower(hdd_context_t *pHddCtx,
2327 hdd_adapter_t *pAdapter)
2328{
2329 VOS_STATUS vos_Status;
2330
2331 if ((NULL == pAdapter) || (NULL == pHddCtx))
2332 {
2333 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid pointer");
2334 return VOS_STATUS_E_FAULT;
2335 }
2336
2337 /**Exit from Deep sleep or standby if we get the driver
2338 START cmd from android GUI
2339 */
2340 if (WLAN_MAP_DRIVER_STOP_TO_STANDBY == pHddCtx->cfg_ini->nEnableDriverStop)
2341 {
2342 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: WLAN being exit "
2343 "from Stand by",__func__);
2344 vos_Status = hdd_exit_standby(pHddCtx);
2345 }
2346 else if (eHDD_SUSPEND_DEEP_SLEEP == pHddCtx->hdd_ps_state)
2347 {
2348 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: WLAN being exit "
2349 "from deep sleep",__func__);
2350 vos_Status = hdd_exit_deep_sleep(pHddCtx, pAdapter);
2351 }
2352 else
2353 {
2354 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Not in standby or deep sleep. "
2355 "Ignore start cmd %d", __func__, pHddCtx->hdd_ps_state);
2356 vos_Status = VOS_STATUS_SUCCESS;
2357 }
2358
2359 return vos_Status;
2360}
2361
2362VOS_STATUS wlan_hdd_enter_lowpower(hdd_context_t *pHddCtx)
2363{
2364 VOS_STATUS vos_Status = VOS_STATUS_E_FAILURE;
2365
2366 if (NULL == pHddCtx)
2367 {
2368 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "HDD context NULL");
2369 return VOS_STATUS_E_FAULT;
2370 }
2371
2372 if (WLAN_MAP_DRIVER_STOP_TO_STANDBY == pHddCtx->cfg_ini->nEnableDriverStop)
2373 {
2374 //Execute standby procedure.
2375 //Executing standby procedure will cause the STA to
2376 //disassociate first and then the chip will be put into standby.
2377 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Wlan driver entering Stand by mode");
2378 vos_Status = hdd_enter_standby(pHddCtx);
2379 }
2380 else if (WLAN_MAP_DRIVER_STOP_TO_DEEP_SLEEP ==
2381 pHddCtx->cfg_ini->nEnableDriverStop)
2382 {
2383 //Execute deep sleep procedure
2384 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Wlan driver entering "
2385 "deep sleep mode\n");
2386 //Deep sleep not supported
2387 vos_Status = hdd_enter_standby(pHddCtx);
2388 }
2389 else
2390 {
2391 hddLog(VOS_TRACE_LEVEL_INFO_LOW, "%s: Driver stop is not enabled %d",
2392 __func__, pHddCtx->cfg_ini->nEnableDriverStop);
2393 vos_Status = VOS_STATUS_SUCCESS;
2394 }
2395
2396 return vos_Status;
2397}
2398
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002399
2400void* wlan_hdd_change_country_code_callback(void *pAdapter)
2401{
2402
2403 hdd_adapter_t *call_back_pAdapter = pAdapter;
2404
2405 complete(&call_back_pAdapter->change_country_code);
2406
2407 return NULL;
2408}
2409
Jeff Johnson295189b2012-06-20 16:38:30 -07002410static int iw_set_priv(struct net_device *dev,
2411 struct iw_request_info *info,
2412 union iwreq_data *wrqu, char *extra)
2413{
2414 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2415 char *cmd = (char*)wrqu->data.pointer;
2416 int cmd_len = wrqu->data.length;
2417 int ret = 0;
2418 int status = 0;
2419 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2420
2421 ENTER();
2422
2423 if (ioctl_debug)
2424 {
2425 pr_info("%s: req [%s] len [%d]\n", __FUNCTION__, cmd, cmd_len);
2426 }
2427
2428 hddLog(VOS_TRACE_LEVEL_INFO_MED, "***Received %s cmd from Wi-Fi GUI***", cmd);
2429
2430 if (pHddCtx->isLogpInProgress) {
2431 if (ioctl_debug)
2432 {
2433 pr_info("%s: RESTART in progress\n", __FUNCTION__);
2434 }
2435
2436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2437 "%s:LOGP in Progress. Ignore!!!",__func__);
2438 return status;
2439 }
2440
2441 if(strncmp(cmd, "CSCAN",5) == 0 )
2442 {
2443 status = iw_set_cscan(dev, info, wrqu, extra);
2444 }
2445 else if( strcasecmp(cmd, "start") == 0 ) {
2446
2447 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Start command\n");
2448 /*Exit from Deep sleep or standby if we get the driver START cmd from android GUI*/
2449 status = wlan_hdd_exit_lowpower(pHddCtx, pAdapter);
2450
2451 if(status == VOS_STATUS_SUCCESS)
2452 {
2453 union iwreq_data wrqu;
2454 char buf[10];
2455
2456 memset(&wrqu, 0, sizeof(wrqu));
2457 wrqu.data.length = strlcpy(buf, "START", sizeof(buf));
2458 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
2459 }
2460 else
2461 {
2462 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: START CMD Status %d", __func__, status);
2463 }
2464 goto done;
2465 }
2466 else if( strcasecmp(cmd, "stop") == 0 )
2467 {
2468 union iwreq_data wrqu;
2469 char buf[10];
2470
2471 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "Stop command\n");
2472
2473 wlan_hdd_enter_lowpower(pHddCtx);
2474 memset(&wrqu, 0, sizeof(wrqu));
2475 wrqu.data.length = strlcpy(buf, "STOP", sizeof(buf));
2476 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
2477 status = VOS_STATUS_SUCCESS;
2478 goto done;
2479 }
2480 else if (strcasecmp(cmd, "macaddr") == 0)
2481 {
2482 ret = snprintf(cmd, cmd_len, "Macaddr = " MAC_ADDRESS_STR,
2483 MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes));
2484 }
2485 else if (strcasecmp(cmd, "scan-active") == 0)
2486 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002487 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07002488 ret = snprintf(cmd, cmd_len, "OK");
2489 }
2490 else if (strcasecmp(cmd, "scan-passive") == 0)
2491 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002492 pHddCtx->scan_info.scan_mode = eSIR_PASSIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07002493 ret = snprintf(cmd, cmd_len, "OK");
2494 }
2495 else if( strcasecmp(cmd, "scan-mode") == 0 )
2496 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002497 ret = snprintf(cmd, cmd_len, "ScanMode = %u", pHddCtx->scan_info.scan_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002498 }
2499 else if( strcasecmp(cmd, "linkspeed") == 0 )
2500 {
2501 status = iw_get_linkspeed(dev, info, wrqu, extra);
2502 }
2503 else if( strncasecmp(cmd, "COUNTRY", 7) == 0 ) {
2504 char *country_code;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002505 long lrc;
Jeff Johnson295189b2012-06-20 16:38:30 -07002506
2507 country_code = cmd + 8;
2508
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002509 init_completion(&pAdapter->change_country_code);
2510
Jeff Johnson295189b2012-06-20 16:38:30 -07002511 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002512 (void *)(tSmeChangeCountryCallback)wlan_hdd_change_country_code_callback,
Jeff Johnson295189b2012-06-20 16:38:30 -07002513 country_code,
2514 pAdapter,
2515 pHddCtx->pvosContext);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002516
2517 /* Wait for completion */
2518 lrc = wait_for_completion_interruptible_timeout(&pAdapter->change_country_code,
2519 msecs_to_jiffies(WLAN_WAIT_TIME_STATS));
2520
2521 if (lrc <= 0)
2522 {
2523 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while setting country code ",
2524 __FUNCTION__, "Timed out");
2525 }
2526
Jeff Johnson295189b2012-06-20 16:38:30 -07002527 if( 0 != status )
2528 {
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002529 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2530 "%s: SME Change Country code fail \n",__func__);
2531 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07002532 }
2533 }
2534 else if( strncasecmp(cmd, "rssi", 4) == 0 )
2535 {
2536 status = iw_get_rssi(dev, info, wrqu, extra);
2537 }
2538 else if( strncasecmp(cmd, "powermode", 9) == 0 ) {
2539 int mode;
2540 char *ptr = (char*)(cmd + 9);
2541
2542 sscanf(ptr,"%d",&mode);
2543 wlan_hdd_enter_bmps(pAdapter, mode);
2544 /*TODO:Set the power mode*/
2545 }
2546 else if (strncasecmp(cmd, "getpower", 8) == 0 ) {
2547 v_U32_t pmc_state;
2548 v_U16_t value;
2549
2550 pmc_state = pmcGetPmcState(WLAN_HDD_GET_HAL_CTX(pAdapter));
2551 if(pmc_state == BMPS) {
2552 value = DRIVER_POWER_MODE_AUTO;
2553 }
2554 else {
2555 value = DRIVER_POWER_MODE_ACTIVE;
2556 }
2557 ret = snprintf(cmd, cmd_len, "powermode = %u", value);
2558 }
2559 else if( strncasecmp(cmd, "btcoexmode", 10) == 0 ) {
2560 hddLog( VOS_TRACE_LEVEL_INFO, "btcoexmode\n");
2561 /*TODO: set the btcoexmode*/
2562 }
2563 else if( strcasecmp(cmd, "btcoexstat") == 0 ) {
2564
2565 hddLog(VOS_TRACE_LEVEL_INFO, "BtCoex Status\n");
2566 /*TODO: Return the btcoex status*/
2567 }
2568 else if( strcasecmp(cmd, "rxfilter-start") == 0 ) {
2569
2570 hddLog(VOS_TRACE_LEVEL_INFO, "Rx Data Filter Start command\n");
2571
2572 /*TODO: Enable Rx data Filter*/
2573 }
2574 else if( strcasecmp(cmd, "rxfilter-stop") == 0 ) {
2575
2576 hddLog(VOS_TRACE_LEVEL_INFO, "Rx Data Filter Stop command\n");
2577
2578 /*TODO: Disable Rx data Filter*/
2579 }
2580 else if( strcasecmp(cmd, "rxfilter-statistics") == 0 ) {
2581
2582 hddLog( VOS_TRACE_LEVEL_INFO, "Rx Data Filter Statistics command\n");
2583 /*TODO: rxfilter-statistics*/
2584 }
2585 else if( strncasecmp(cmd, "rxfilter-add", 12) == 0 ) {
2586
2587 hddLog( VOS_TRACE_LEVEL_INFO, "rxfilter-add\n");
2588 /*TODO: rxfilter-add*/
2589 }
2590 else if( strncasecmp(cmd, "rxfilter-remove",15) == 0 ) {
2591
2592 hddLog( VOS_TRACE_LEVEL_INFO, "rxfilter-remove\n");
2593 /*TODO: rxfilter-remove*/
2594 }
2595#ifdef FEATURE_WLAN_SCAN_PNO
2596 else if( strncasecmp(cmd, "pno",3) == 0 ) {
2597
2598 hddLog( VOS_TRACE_LEVEL_INFO, "pno\n");
2599 status = iw_set_pno(dev, info, wrqu, extra, 3);
2600 return status;
2601 }
2602 else if( strncasecmp(cmd, "rssifilter",10) == 0 ) {
2603
2604 hddLog( VOS_TRACE_LEVEL_INFO, "rssifilter\n");
2605 status = iw_set_rssi_filter(dev, info, wrqu, extra, 10);
2606 return status;
2607 }
2608#endif /*FEATURE_WLAN_SCAN_PNO*/
2609 else if( strncasecmp(cmd, "powerparams",11) == 0 ) {
2610 hddLog( VOS_TRACE_LEVEL_INFO, "powerparams\n");
2611 status = iw_set_power_params(dev, info, wrqu, extra, 11);
2612 return status;
2613 }
2614 else if( 0 == strncasecmp(cmd, "CONFIG-TX-TRACKING", 18) ) {
2615 tSirTxPerTrackingParam tTxPerTrackingParam;
2616 char *ptr = (char*)(cmd + 18);
2617 sscanf(ptr,"%hhu %hhu %hhu %lu",&(tTxPerTrackingParam.ucTxPerTrackingEnable), &(tTxPerTrackingParam.ucTxPerTrackingPeriod),
2618 &(tTxPerTrackingParam.ucTxPerTrackingRatio), &(tTxPerTrackingParam.uTxPerTrackingWatermark));
2619
2620 // parameters checking
2621 // period has to be larger than 0
2622 if (0 == tTxPerTrackingParam.ucTxPerTrackingPeriod)
2623 {
2624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Period input is not correct");
2625 return VOS_STATUS_E_FAILURE;
2626 }
2627
2628 // use default value 5 is the input is not reasonable. in unit of 10%
2629 if ((tTxPerTrackingParam.ucTxPerTrackingRatio > TX_PER_TRACKING_MAX_RATIO) || (0 == tTxPerTrackingParam.ucTxPerTrackingRatio))
2630 {
2631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Ratio input is not good. use default 5");
2632 tTxPerTrackingParam.ucTxPerTrackingRatio = TX_PER_TRACKING_DEFAULT_RATIO;
2633 }
2634
2635 // default is 5
2636 if (0 == tTxPerTrackingParam.uTxPerTrackingWatermark)
2637 {
2638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Tx Packet number input is not good. use default 5");
2639 tTxPerTrackingParam.uTxPerTrackingWatermark = TX_PER_TRACKING_DEFAULT_WATERMARK;
2640 }
2641
2642 status = sme_SetTxPerTracking(pHddCtx->hHal, hdd_tx_per_hit_cb, (void*)pAdapter, &tTxPerTrackingParam);
2643 if(status != eHAL_STATUS_SUCCESS){
2644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Set Tx PER Tracking Failed!");
2645 }
2646 }
2647 else {
2648 hddLog( VOS_TRACE_LEVEL_WARN, "Unsupported GUI command %s", cmd);
2649 }
2650done:
2651 /* many of the commands write information back into the command
2652 string using snprintf(). check the return value here in one
2653 place */
2654 if ((ret < 0) || (ret >= cmd_len))
2655 {
2656 /* there was an encoding error or overflow */
2657 status = -EIO;
2658 }
2659
2660 if (ioctl_debug)
2661 {
2662 pr_info("%s: rsp [%s] len [%d] status %d\n",
2663 __FUNCTION__, cmd, wrqu->data.length, status);
2664 }
2665 return status;
2666
2667}
2668
2669static int iw_set_nick(struct net_device *dev,
2670 struct iw_request_info *info,
2671 union iwreq_data *wrqu, char *extra)
2672{
2673 ENTER();
2674 return 0;
2675}
2676
2677static int iw_get_nick(struct net_device *dev,
2678 struct iw_request_info *info,
2679 union iwreq_data *wrqu, char *extra)
2680{
2681 ENTER();
2682 return 0;
2683}
2684
2685static struct iw_statistics *get_wireless_stats(struct net_device *dev)
2686{
2687 ENTER();
2688 return NULL;
2689}
2690
2691static int iw_set_encode(struct net_device *dev,struct iw_request_info *info,
2692 union iwreq_data *wrqu,char *extra)
2693
2694{
2695 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2696 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2697 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2698 struct iw_point *encoderq = &(wrqu->encoding);
2699 v_U32_t keyId;
2700 v_U8_t key_length;
2701 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
2702 v_BOOL_t fKeyPresent = 0;
2703 int i;
2704 eHalStatus status = eHAL_STATUS_SUCCESS;
2705
2706
2707 ENTER();
2708
2709 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2710 {
2711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2712 "%s:LOGP in Progress. Ignore!!!",__func__);
2713 return 0;
2714 }
2715
2716
2717 keyId = encoderq->flags & IW_ENCODE_INDEX;
2718
2719 if(keyId)
2720 {
2721 if(keyId > MAX_WEP_KEYS)
2722 {
2723 return -EINVAL;
2724 }
2725
2726 fKeyPresent = 1;
2727 keyId--;
2728 }
2729 else
2730 {
2731 fKeyPresent = 0;
2732 }
2733
2734
2735 if(wrqu->data.flags & IW_ENCODE_DISABLED)
2736 {
2737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "****iwconfig wlan0 key off*****\n");
2738 if(!fKeyPresent) {
2739
2740 for(i=0;i < CSR_MAX_NUM_KEY; i++) {
2741
2742 if(pWextState->roamProfile.Keys.KeyMaterial[i])
2743 pWextState->roamProfile.Keys.KeyLength[i] = 0;
2744 }
2745 }
2746 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
2747 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
2748 pWextState->roamProfile.EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2749 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2750
2751 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
2752 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
2753
2754 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2755 {
2756 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2757 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED );
Jeff Johnson43971f52012-07-17 12:26:56 -07002758 if(eHAL_STATUS_SUCCESS == status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002759 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
2760 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2761 }
2762
2763 return status;
2764
2765 }
2766
2767 if (wrqu->data.flags & (IW_ENCODE_OPEN | IW_ENCODE_RESTRICTED))
2768 {
2769 hddLog(VOS_TRACE_LEVEL_INFO, "iwconfig wlan0 key on");
2770
2771 pHddStaCtx->conn_info.authType = (encoderq->flags & IW_ENCODE_RESTRICTED) ? eCSR_AUTH_TYPE_SHARED_KEY : eCSR_AUTH_TYPE_OPEN_SYSTEM;
2772
2773 }
2774
2775
2776 if(wrqu->data.length > 0)
2777 {
2778 hddLog(VOS_TRACE_LEVEL_INFO, "%s : wrqu->data.length : %d",__FUNCTION__,wrqu->data.length);
2779
2780 key_length = wrqu->data.length;
2781
2782 /* IW_ENCODING_TOKEN_MAX is the value that is set for wrqu->data.length by iwconfig.c when 'iwconfig wlan0 key on' is issued.*/
2783
2784 if(5 == key_length)
2785 {
2786 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Call with WEP40,key_len=%d",__FUNCTION__,key_length);
2787
2788 if((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
2789 {
2790 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
2791 }
2792 else
2793 {
2794 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2795 }
2796 }
2797 else if(13 == key_length)
2798 {
2799 hddLog(VOS_TRACE_LEVEL_INFO, "%s:Call with WEP104,key_len:%d",__FUNCTION__,key_length);
2800
2801 if((IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
2802 {
2803 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
2804 }
2805 else
2806 {
2807 encryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2808 }
2809 }
2810 else
2811 {
2812 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Invalid WEP key length :%d",
2813 __FUNCTION__, key_length);
2814 return -EINVAL;
2815 }
2816
2817 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
2818 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
2819 pWextState->roamProfile.EncryptionType.numEntries = 1;
2820 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
2821 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
2822 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
2823
2824 if((eConnectionState_NotConnected == pHddStaCtx->conn_info.connState) &&
2825 ((eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType) ||
2826 (eCSR_AUTH_TYPE_SHARED_KEY == pHddStaCtx->conn_info.authType)))
2827 {
2828
2829 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[keyId][0],extra,key_length);
2830
2831 pWextState->roamProfile.Keys.KeyLength[keyId] = (v_U8_t)key_length;
2832 pWextState->roamProfile.Keys.defaultIndex = (v_U8_t)keyId;
2833
2834 return status;
2835 }
2836 }
2837
2838 return 0;
2839}
2840
2841static int iw_get_encodeext(struct net_device *dev,
2842 struct iw_request_info *info,
2843 struct iw_point *dwrq,
2844 char *extra)
2845{
2846 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2847 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2848 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
2849 int keyId;
2850 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
2851 eCsrAuthType authType = eCSR_AUTH_TYPE_NONE;
2852 int i;
2853
2854 ENTER();
2855
2856 keyId = pRoamProfile->Keys.defaultIndex;
2857
2858 if(keyId < 0 || keyId >= MAX_WEP_KEYS)
2859 {
2860 hddLog(LOG1,"%s: Invalid keyId : %d\n",__FUNCTION__,keyId);
2861 return -EINVAL;
2862 }
2863
2864 if(pRoamProfile->Keys.KeyLength[keyId] > 0)
2865 {
2866 dwrq->flags |= IW_ENCODE_ENABLED;
2867 dwrq->length = pRoamProfile->Keys.KeyLength[keyId];
2868 palCopyMemory(dev,extra,&(pRoamProfile->Keys.KeyMaterial[keyId][0]),pRoamProfile->Keys.KeyLength[keyId]);
2869 }
2870 else
2871 {
2872 dwrq->flags |= IW_ENCODE_DISABLED;
2873 }
2874
2875 for(i=0; i < MAX_WEP_KEYS; i++)
2876 {
2877 if(pRoamProfile->Keys.KeyMaterial[i] == NULL)
2878 {
2879 continue;
2880 }
2881 else
2882 {
2883 break;
2884 }
2885 }
2886
2887 if(MAX_WEP_KEYS == i)
2888 {
2889 dwrq->flags |= IW_ENCODE_NOKEY;
2890 }
2891 else
2892 {
2893 dwrq->flags |= IW_ENCODE_ENABLED;
2894 }
2895
2896 encryptionType = pRoamProfile->EncryptionType.encryptionType[0];
2897
2898 if(eCSR_ENCRYPT_TYPE_NONE == encryptionType)
2899 {
2900 dwrq->flags |= IW_ENCODE_DISABLED;
2901 }
2902
2903 authType = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
2904
2905 if(IW_AUTH_ALG_OPEN_SYSTEM == authType)
2906 {
2907 dwrq->flags |= IW_ENCODE_OPEN;
2908 }
2909 else
2910 {
2911 dwrq->flags |= IW_ENCODE_RESTRICTED;
2912 }
2913 EXIT();
2914 return 0;
2915
2916}
2917
2918static int iw_set_encodeext(struct net_device *dev,
2919 struct iw_request_info *info,
2920 union iwreq_data *wrqu, char *extra)
2921{
2922 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2923 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2924 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2925 eHalStatus halStatus= eHAL_STATUS_SUCCESS;
2926
2927 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
2928 v_U32_t status = 0;
2929
2930 struct iw_encode_ext *ext = (struct iw_encode_ext*)extra;
2931
2932 v_U8_t groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
2933
2934 int key_index;
2935 struct iw_point *encoding = &wrqu->encoding;
2936 tCsrRoamSetKey setKey;
2937 v_U32_t roamId= 0xFF;
2938 VOS_STATUS vos_status;
2939
2940 ENTER();
2941
2942 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2943 {
2944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2945 "%s:LOGP in Progress. Ignore!!!",__func__);
2946 return 0;
2947 }
2948
2949 key_index = encoding->flags & IW_ENCODE_INDEX;
2950
2951 if(key_index > 0) {
2952
2953 /*Convert from 1-based to 0-based keying*/
2954 key_index--;
2955 }
2956 if(!ext->key_len) {
2957
2958 /*Set the encrytion type to NONE*/
2959 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
2960 return status;
2961 }
2962
2963 if(eConnectionState_NotConnected == pHddStaCtx->conn_info.connState &&
2964 (IW_ENCODE_ALG_WEP == ext->alg))
2965 {
2966 if(IW_AUTH_KEY_MGMT_802_1X == pWextState->authKeyMgmt) {
2967
2968 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,("Invalid Configuration:%s \n"),__FUNCTION__);
2969 return -EINVAL;
2970 }
2971 else {
2972 /*Static wep, update the roam profile with the keys */
2973 if(ext->key && (ext->key_len <= eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES) &&
2974 key_index < CSR_MAX_NUM_KEY) {
2975 vos_mem_copy(&pRoamProfile->Keys.KeyMaterial[key_index][0],ext->key,ext->key_len);
2976 pRoamProfile->Keys.KeyLength[key_index] = (v_U8_t)ext->key_len;
2977
2978 if(ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
2979 pRoamProfile->Keys.defaultIndex = (v_U8_t)key_index;
2980
2981 }
2982 }
2983 return status;
2984 }
2985
2986 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
2987
2988 setKey.keyId = key_index;
2989 setKey.keyLength = ext->key_len;
2990
2991 if(ext->key_len <= CSR_MAX_KEY_LEN) {
2992 vos_mem_copy(&setKey.Key[0],ext->key,ext->key_len);
2993 }
2994
2995 if(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2996 /*Key direction for group is RX only*/
2997 setKey.keyDirection = eSIR_RX_ONLY;
2998 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
2999 }
3000 else {
3001
3002 setKey.keyDirection = eSIR_TX_RX;
3003 vos_mem_copy(setKey.peerMac,ext->addr.sa_data,WNI_CFG_BSSID_LEN);
3004 }
3005
3006 /*For supplicant pae role is zero*/
3007 setKey.paeRole = 0;
3008
3009 switch(ext->alg)
3010 {
3011 case IW_ENCODE_ALG_NONE:
3012 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3013 break;
3014
3015 case IW_ENCODE_ALG_WEP:
3016 setKey.encType = (ext->key_len== 5) ? eCSR_ENCRYPT_TYPE_WEP40:eCSR_ENCRYPT_TYPE_WEP104;
3017 break;
3018
3019 case IW_ENCODE_ALG_TKIP:
3020 {
3021 v_U8_t *pKey = &setKey.Key[0];
3022
3023 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3024
3025 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3026
3027 /*Supplicant sends the 32bytes key in this order
3028
3029 |--------------|----------|----------|
3030 | Tk1 |TX-MIC | RX Mic |
3031 |--------------|----------|----------|
3032 <---16bytes---><--8bytes--><--8bytes-->
3033
3034 */
3035 /*Sme expects the 32 bytes key to be in the below order
3036
3037 |--------------|----------|----------|
3038 | Tk1 |RX-MIC | TX Mic |
3039 |--------------|----------|----------|
3040 <---16bytes---><--8bytes--><--8bytes-->
3041 */
3042 /* Copy the Temporal Key 1 (TK1) */
3043 vos_mem_copy(pKey,ext->key,16);
3044
3045 /*Copy the rx mic first*/
3046 vos_mem_copy(&pKey[16],&ext->key[24],8);
3047
3048 /*Copy the tx mic */
3049 vos_mem_copy(&pKey[24],&ext->key[16],8);
3050
3051 }
3052 break;
3053
3054 case IW_ENCODE_ALG_CCMP:
3055 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3056 break;
3057
3058#ifdef FEATURE_WLAN_CCX
3059#define IW_ENCODE_ALG_KRK 6
3060 case IW_ENCODE_ALG_KRK:
3061 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3062 break;
3063#endif /* FEATURE_WLAN_CCX */
3064
3065 default:
3066 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3067 break;
3068 }
3069
3070 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3071 ("%s:cipher_alg:%d key_len[%d] *pEncryptionType :%d \n"),__FUNCTION__,(int)ext->alg,(int)ext->key_len,setKey.encType);
3072
3073#ifdef WLAN_FEATURE_VOWIFI_11R
3074/* The supplicant may attempt to set the PTK once pre-authentication is done.
3075 Save the key in the UMAC and include it in the ADD BSS request */
3076 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
3077 if( halStatus == eHAL_STATUS_SUCCESS )
3078 {
3079 return halStatus;
3080 }
3081#endif /* WLAN_FEATURE_VOWIFI_11R */
3082
3083 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3084
3085 vos_status = wlan_hdd_check_ula_done(pAdapter);
3086 if ( vos_status != VOS_STATUS_SUCCESS )
3087 {
3088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3089 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3090 __LINE__, vos_status );
3091
3092 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3093 }
3094
3095 halStatus = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),pAdapter->sessionId, &setKey, &roamId );
3096
3097 if ( halStatus != eHAL_STATUS_SUCCESS )
3098 {
3099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3100 "[%4d] sme_RoamSetKey returned ERROR status= %d",
3101 __LINE__, halStatus );
3102
3103 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3104 }
3105
3106 return halStatus;
3107}
3108
3109static int iw_set_retry(struct net_device *dev, struct iw_request_info *info,
3110 union iwreq_data *wrqu, char *extra)
3111{
3112 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3113 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3114
3115 ENTER();
3116
3117 if(wrqu->retry.value < WNI_CFG_LONG_RETRY_LIMIT_STAMIN ||
3118 wrqu->retry.value > WNI_CFG_LONG_RETRY_LIMIT_STAMAX) {
3119
3120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("Invalid Retry-Limit=%ld!!\n"),wrqu->retry.value);
3121
3122 return -EINVAL;
3123 }
3124
3125 if(wrqu->retry.flags & IW_RETRY_LIMIT) {
3126
3127 if((wrqu->retry.flags & IW_RETRY_LONG))
3128 {
3129 if ( ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT, wrqu->retry.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
3130 {
3131 return -EIO;
3132 }
3133 }
3134 else if((wrqu->retry.flags & IW_RETRY_SHORT))
3135 {
3136 if ( ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT, wrqu->retry.value, ccmCfgSetCallback, eANI_BOOLEAN_TRUE) != eHAL_STATUS_SUCCESS )
3137 {
3138 return -EIO;
3139 }
3140 }
3141 }
3142 else
3143 {
3144 return -EOPNOTSUPP;
3145 }
3146
3147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("Set Retry-Limit=%ld!!\n"),wrqu->retry.value);
3148
3149 EXIT();
3150
3151 return 0;
3152
3153}
3154
3155static int iw_get_retry(struct net_device *dev, struct iw_request_info *info,
3156 union iwreq_data *wrqu, char *extra)
3157{
3158 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3159 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3160 v_U32_t retry = 0;
3161
3162 ENTER();
3163
3164 if((wrqu->retry.flags & IW_RETRY_LONG))
3165 {
3166 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
3167
3168 if ( ccmCfgGetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT, &retry) != eHAL_STATUS_SUCCESS )
3169 {
3170 return -EIO;
3171 }
3172
3173 wrqu->retry.value = retry;
3174 }
3175 else if ((wrqu->retry.flags & IW_RETRY_SHORT))
3176 {
3177 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;
3178
3179 if ( ccmCfgGetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT, &retry) != eHAL_STATUS_SUCCESS )
3180 {
3181 return -EIO;
3182 }
3183
3184 wrqu->retry.value = retry;
3185 }
3186 else {
3187 return -EOPNOTSUPP;
3188 }
3189
3190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("Retry-Limit=%ld!!\n"),retry);
3191
3192 EXIT();
3193
3194 return 0;
3195}
3196
3197static int iw_set_mlme(struct net_device *dev,
3198 struct iw_request_info *info,
3199 union iwreq_data *wrqu,
3200 char *extra)
3201{
3202 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3203 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3204 struct iw_mlme *mlme = (struct iw_mlme *)extra;
3205 eHalStatus status = eHAL_STATUS_SUCCESS;
3206
3207 ENTER();
3208
3209 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
3210 {
3211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3212 "%s:LOGP in Progress. Ignore!!!",__func__);
3213 return 0;
3214 }
3215
3216 //reason_code is unused. By default it is set to eCSR_DISCONNECT_REASON_UNSPECIFIED
3217 switch (mlme->cmd) {
3218 case IW_MLME_DISASSOC:
3219 case IW_MLME_DEAUTH:
3220
3221 if( pHddStaCtx->conn_info.connState == eConnectionState_Associated )
3222 {
3223 eCsrRoamDisconnectReason reason = eCSR_DISCONNECT_REASON_UNSPECIFIED;
3224
3225 if( mlme->reason_code == HDD_REASON_MICHAEL_MIC_FAILURE )
3226 reason = eCSR_DISCONNECT_REASON_MIC_ERROR;
3227
3228 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3229 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,reason);
3230
Jeff Johnson43971f52012-07-17 12:26:56 -07003231 if(eHAL_STATUS_SUCCESS == status)
Jeff Johnson295189b2012-06-20 16:38:30 -07003232 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
3233 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3234 else
3235 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate : csrRoamDisconnect failure returned %d \n",
3236 __FUNCTION__, (int)mlme->cmd, (int)status );
3237
3238 /* Resetting authKeyMgmt */
3239 (WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->authKeyMgmt = 0;
3240
3241 netif_tx_disable(dev);
3242 netif_carrier_off(dev);
3243
3244 }
3245 else
3246 {
3247 hddLog(LOGE,"%s %d Command Disassociate/Deauthenticate called but station is not in associated state \n", __FUNCTION__, (int)mlme->cmd );
3248 }
3249 break;
3250 default:
3251 hddLog(LOGE,"%s %d Command should be Disassociate/Deauthenticate \n", __FUNCTION__, (int)mlme->cmd );
3252 return -EINVAL;
3253 }//end of switch
3254
3255 EXIT();
3256
3257 return status;
3258
3259}
3260
3261/* set param sub-ioctls */
3262static int iw_setint_getnone(struct net_device *dev, struct iw_request_info *info,
3263 union iwreq_data *wrqu, char *extra)
3264{
3265 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3266 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3267 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3268 int *value = (int *)extra;
3269 int sub_cmd = value[0];
3270 int set_value = value[1];
3271 int ret = 0; /* success */
3272 int enable_pbm, enable_mp;
3273#ifdef CONFIG_HAS_EARLYSUSPEND
3274 v_U8_t nEnableSuspendOld;
3275#endif
3276 INIT_COMPLETION(pWextState->completion_var);
3277
3278 switch(sub_cmd)
3279 {
3280 case WE_SET_11D_STATE:
3281 {
3282 tSmeConfigParams smeConfig;;
3283 if((ENABLE_11D == set_value) || (DISABLE_11D == set_value)) {
3284
3285 sme_GetConfigParam(hHal,&smeConfig);
3286 smeConfig.csrConfig.Is11dSupportEnabled = (v_BOOL_t)set_value;
3287
3288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("11D state=%ld!!\n"),smeConfig.csrConfig.Is11dSupportEnabled);
3289
3290 sme_UpdateConfig(hHal,&smeConfig);
3291 }
3292 else {
3293 return -EINVAL;
3294 }
3295 break;
3296 }
3297
3298 case WE_WOWL:
3299 {
3300 switch (set_value)
3301 {
3302 case 0x00:
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07003303 hdd_exit_wowl(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003304 break;
3305 case 0x01:
3306 case 0x02:
3307 case 0x03:
3308 enable_mp = (set_value & 0x01) ? 1 : 0;
3309 enable_pbm = (set_value & 0x02) ? 1 : 0;
3310 hddLog(LOGE, "magic packet ? = %s pattern byte matching ? = %s\n",
3311 (enable_mp ? "YES":"NO"), (enable_pbm ? "YES":"NO"));
3312 hdd_enter_wowl(pAdapter, enable_mp, enable_pbm);
3313 break;
3314 default:
3315 hddLog(LOGE, "Invalid arg %d in WE_WOWL IOCTL\n", set_value);
3316 ret = -EINVAL;
3317 break;
3318 }
3319
3320 break;
3321 }
3322 case WE_SET_POWER:
3323 {
3324 switch (set_value)
3325 {
3326 case 0: //Full Power
3327 {
3328 struct statsContext context;
3329 eHalStatus status;
3330
3331 init_completion(&context.completion);
3332
3333 context.pAdapter = pAdapter;
3334 context.magic = POWER_CONTEXT_MAGIC;
3335
3336 status = sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
3337 iw_power_callback_fn, &context,
3338 eSME_FULL_PWR_NEEDED_BY_HDD);
3339 if(eHAL_STATUS_PMC_PENDING == status)
3340 {
3341 int lrc = wait_for_completion_interruptible_timeout(
3342 &context.completion,
3343 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
3344 context.magic = 0;
3345 if (lrc <= 0)
3346 {
3347 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while "
3348 "requesting fullpower ",
3349 __FUNCTION__, (0 == lrc) ?
3350 "timeout" : "interrupt");
3351 /* there is a race condition such that the callback
3352 function could be executing at the same time we are. of
3353 primary concern is if the callback function had already
3354 verified the "magic" but hasn't yet set the completion
3355 variable. Since the completion variable is on our
3356 stack, we'll delay just a bit to make sure the data is
3357 still valid if that is the case */
3358 msleep(50);
3359 /* we'll now returned a cached value below */
3360 }
3361 }
3362 hddLog(LOGE, "iwpriv Full Power completed\n");
3363 break;
3364 }
3365 case 1: //Enable BMPS
3366 sme_EnablePowerSave(hHal, ePMC_BEACON_MODE_POWER_SAVE);
3367 break;
3368 case 2: //Disable BMPS
3369 sme_DisablePowerSave(hHal, ePMC_BEACON_MODE_POWER_SAVE);
3370 break;
3371 case 3: //Request Bmps
3372 {
3373 struct statsContext context;
3374 eHalStatus status;
3375
3376 init_completion(&context.completion);
3377
3378 context.pAdapter = pAdapter;
3379 context.magic = POWER_CONTEXT_MAGIC;
3380
3381 status = sme_RequestBmps(WLAN_HDD_GET_HAL_CTX(pAdapter),
3382 iw_power_callback_fn, &context);
3383 if(eHAL_STATUS_PMC_PENDING == status)
3384 {
3385 int lrc = wait_for_completion_interruptible_timeout(
3386 &context.completion,
3387 msecs_to_jiffies(WLAN_WAIT_TIME_POWER));
3388 context.magic = 0;
3389 if (lrc <= 0)
3390 {
3391 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: SME %s while "
3392 "requesting BMPS",
3393 __FUNCTION__, (0 == lrc) ? "timeout" :
3394 "interrupt");
3395 /* there is a race condition such that the callback
3396 function could be executing at the same time we are. of
3397 primary concern is if the callback function had already
3398 verified the "magic" but hasn't yet set the completion
3399 variable. Since the completion variable is on our
3400 stack, we'll delay just a bit to make sure the data is
3401 still valid if that is the case */
3402 msleep(50);
3403 /* we'll now returned a cached value below */
3404 }
3405 }
3406 hddLog(LOGE, "iwpriv Request BMPS completed\n");
3407 break;
3408 }
3409 case 4: //Enable IMPS
3410 sme_EnablePowerSave(hHal, ePMC_IDLE_MODE_POWER_SAVE);
3411 break;
3412 case 5: //Disable IMPS
3413 sme_DisablePowerSave(hHal, ePMC_IDLE_MODE_POWER_SAVE);
3414 break;
3415 case 6: //Enable Standby
3416 sme_EnablePowerSave(hHal, ePMC_STANDBY_MODE_POWER_SAVE);
3417 break;
3418 case 7: //Disable Standby
3419 sme_DisablePowerSave(hHal, ePMC_STANDBY_MODE_POWER_SAVE);
3420 break;
3421 case 8: //Request Standby
3422#ifdef CONFIG_HAS_EARLYSUSPEND
3423#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
3424 (void)hdd_enter_standby(pAdapter->pHddCtx);
3425#endif
3426#endif
3427 break;
3428 case 9: //Start Auto Bmps Timer
3429 sme_StartAutoBmpsTimer(hHal);
3430 break;
3431 case 10://Stop Auto BMPS Timer
3432 sme_StopAutoBmpsTimer(hHal);
3433 break;
3434#ifdef CONFIG_HAS_EARLYSUSPEND
3435 case 11://suspend to standby
3436#ifdef CONFIG_HAS_EARLYSUSPEND
3437 nEnableSuspendOld = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend;
3438 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = 1;
3439#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
3440 hdd_suspend_wlan(NULL);
3441#endif
3442 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = nEnableSuspendOld;
3443#endif
3444 break;
3445 case 12://suspend to deep sleep
3446#ifdef CONFIG_HAS_EARLYSUSPEND
3447 nEnableSuspendOld = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend;
3448 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = 2;
3449#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
3450 hdd_suspend_wlan(NULL);
3451#endif
3452 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->nEnableSuspend = nEnableSuspendOld;
3453#endif
3454 break;
3455 case 13://resume from suspend
3456#ifdef CONFIG_HAS_EARLYSUSPEND
3457#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
3458 hdd_resume_wlan(NULL);
3459#endif
3460#endif
3461 break;
3462#endif
3463 case 14://reset wlan (power down/power up)
3464 vos_chipReset(NULL, VOS_FALSE, NULL, NULL, VOS_CHIP_RESET_UNKNOWN_EXCEPTION);
3465 break;
3466 default:
3467 hddLog(LOGE, "Invalid arg %d in WE_SET_POWER IOCTL\n", set_value);
3468 ret = -EINVAL;
3469 break;
3470 }
3471 break;
3472 }
3473
3474 case WE_SET_MAX_ASSOC:
3475 {
3476 if ((WNI_CFG_ASSOC_STA_LIMIT_STAMIN > set_value) ||
3477 (WNI_CFG_ASSOC_STA_LIMIT_STAMAX < set_value))
3478 {
3479 ret = -EINVAL;
3480 }
3481 else if ( ccmCfgSetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT,
3482 set_value, NULL, eANI_BOOLEAN_FALSE)
3483 != eHAL_STATUS_SUCCESS )
3484 {
3485 ret = -EIO;
3486 }
3487 break;
3488 }
3489
3490 case WE_SET_SAP_AUTO_CHANNEL_SELECTION:
3491 {
3492 if( 0 == set_value )
3493 {
3494 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->apAutoChannelSelection = 0;
3495 }
3496 else if ( 1 == set_value )
3497 {
3498 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->apAutoChannelSelection = 1;
3499 }
3500 else
3501 {
3502 hddLog(LOGE, "Invalid arg %d in WE_SET_SAP_AUTO_CHANNEL_SELECTION IOCTL\n", set_value);
3503 ret = -EINVAL;
3504 }
3505 break;
3506 }
3507
3508 case WE_SET_DATA_INACTIVITY_TO:
3509 {
3510 if ((set_value < CFG_DATA_INACTIVITY_TIMEOUT_MIN) ||
3511 (set_value > CFG_DATA_INACTIVITY_TIMEOUT_MAX) ||
3512 (ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
3513 WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT,
3514 set_value,
3515 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE))
3516 {
3517 hddLog(LOGE,"Failure: Could not pass on "
3518 "WNI_CFG_PS_DATA_INACTIVITY_TIMEOUT configuration info "
3519 "to CCM\n");
3520 ret = -EINVAL;
3521 }
3522 break;
3523 }
3524 case WE_SET_MAX_TX_POWER:
3525 {
3526 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3527 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3528
3529 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Setting maximum tx power %d dBm",
3530 __func__, set_value);
3531 if( sme_SetMaxTxPower(hHal, bssid, selfMac, set_value) !=
3532 eHAL_STATUS_SUCCESS )
3533 {
3534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
3535 __func__);
3536 return -EIO;
3537 }
3538
3539 break;
3540 }
3541 case WE_SET_HIGHER_DTIM_TRANSITION:
3542 {
3543 if(!((set_value == eANI_BOOLEAN_FALSE) ||
3544 (set_value == eANI_BOOLEAN_TRUE)))
3545 {
3546 hddLog(LOGE, "Dynamic DTIM Incorrect data:%d", set_value);
3547 ret = -EINVAL;
3548 }
3549 else
3550 {
3551 if(pAdapter->higherDtimTransition != set_value)
3552 {
3553 pAdapter->higherDtimTransition = set_value;
3554 hddLog(LOG1, "%s: higherDtimTransition set to :%d", __FUNCTION__, pAdapter->higherDtimTransition);
3555 }
3556 }
3557
3558 break;
3559 }
3560
3561 case WE_SET_TM_LEVEL:
3562 {
3563 hdd_context_t *hddCtxt = WLAN_HDD_GET_CTX(pAdapter);
3564 hddLog(VOS_TRACE_LEVEL_INFO, "Set Thermal Mitigation Level %d", (int)set_value);
3565 hddDevTmLevelChangedHandler(hddCtxt->parent_dev, set_value);
3566
3567 break;
3568 }
3569
3570 default:
3571 {
3572 hddLog(LOGE, "Invalid IOCTL setvalue command %d value %d \n",
3573 sub_cmd, set_value);
3574 break;
3575 }
3576 }
3577
3578 return ret;
3579}
3580
3581/* set param sub-ioctls */
3582static int iw_setchar_getnone(struct net_device *dev, struct iw_request_info *info,
3583 union iwreq_data *wrqu, char *extra)
3584{
3585 VOS_STATUS vstatus;
3586 int sub_cmd = wrqu->data.flags;
3587 int ret = 0; /* success */
3588 hdd_adapter_t *pAdapter = (netdev_priv(dev));
3589 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3590#ifdef WLAN_FEATURE_VOWIFI
3591 hdd_config_t *pConfig = pHddCtx->cfg_ini;
3592#endif /* WLAN_FEATURE_VOWIFI */
3593
3594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Received length %d", __FUNCTION__, wrqu->data.length);
3595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: Received data %s", __FUNCTION__, (char*)wrqu->data.pointer);
3596
3597 switch(sub_cmd)
3598 {
3599 case WE_WOWL_ADD_PTRN:
3600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "ADD_PTRN\n");
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07003601 hdd_add_wowl_ptrn(pAdapter, (char*)wrqu->data.pointer);
Jeff Johnson295189b2012-06-20 16:38:30 -07003602 break;
3603 case WE_WOWL_DEL_PTRN:
3604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "DEL_PTRN\n");
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07003605 hdd_del_wowl_ptrn(pAdapter, (char*)wrqu->data.pointer);
Jeff Johnson295189b2012-06-20 16:38:30 -07003606 break;
3607#if defined WLAN_FEATURE_VOWIFI
3608 case WE_NEIGHBOR_REPORT_REQUEST:
3609 {
3610 tRrmNeighborReq neighborReq;
3611 tRrmNeighborRspCallbackInfo callbackInfo;
3612
3613 if (pConfig->fRrmEnable)
3614 {
3615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Neighbor Request\n");
3616 neighborReq.no_ssid = (wrqu->data.length - 1) ? false : true ;
3617 if( !neighborReq.no_ssid )
3618 {
3619 neighborReq.ssid.length = (wrqu->data.length - 1) > 32 ? 32 : (wrqu->data.length - 1) ;
3620 vos_mem_copy( neighborReq.ssid.ssId, wrqu->data.pointer, neighborReq.ssid.length );
3621 }
3622
3623 callbackInfo.neighborRspCallback = NULL;
3624 callbackInfo.neighborRspCallbackContext = NULL;
3625 callbackInfo.timeout = 5000; //5 seconds
3626 sme_NeighborReportRequest( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, &neighborReq, &callbackInfo );
3627 }
3628 else
3629 {
3630 hddLog(LOGE, "%s: Ignoring neighbor request as RRM is not enabled\n", __func__);
3631 ret = -EINVAL;
3632 }
3633 }
3634 break;
3635#endif
3636#ifdef WLAN_FEATURE_P2P
3637 case WE_SET_AP_WPS_IE:
3638 hddLog( LOGE, "Received WE_SET_AP_WPS_IE" );
3639#ifdef WLAN_FEATURE_P2P
3640 sme_updateP2pIe( WLAN_HDD_GET_HAL_CTX(pAdapter), wrqu->data.pointer, wrqu->data.length );
3641#endif // WLAN_FEATURE_P2P
3642 break;
3643#endif
3644 case WE_SET_CONFIG:
3645 vstatus = hdd_execute_config_command(pHddCtx, wrqu->data.pointer);
3646 if (VOS_STATUS_SUCCESS != vstatus)
3647 {
3648 ret = -EINVAL;
3649 }
3650 break;
3651 default:
3652 {
3653 hddLog(LOGE, "%s: Invalid sub command %d\n",__FUNCTION__, sub_cmd);
3654 ret = -EINVAL;
3655 break;
3656 }
3657 }
3658 return ret;
3659}
3660
3661/* get param sub-ioctls */
3662static int iw_setnone_getint(struct net_device *dev, struct iw_request_info *info,
3663 union iwreq_data *wrqu, char *extra)
3664{
3665 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3666 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
3667 int *value = (int *)extra;
3668 int ret = 0; /* success */
3669
3670
3671 switch (value[0])
3672 {
3673 case WE_GET_11D_STATE:
3674 {
3675 tSmeConfigParams smeConfig;;
3676
3677 sme_GetConfigParam(hHal,&smeConfig);
3678
3679 *value = smeConfig.csrConfig.Is11dSupportEnabled;
3680
3681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("11D state=%ld!!\n"),*value);
3682
3683 break;
3684 }
3685
3686 case WE_IBSS_STATUS:
3687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "****Return IBSS Status*****\n");
3688 break;
3689
3690 case WE_PMC_STATE:
3691 {
3692 *value = pmcGetPmcState(hHal);
3693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("PMC state=%ld!!\n"),*value);
3694 break;
3695 }
3696 case WE_GET_WLAN_DBG:
3697 {
3698 vos_trace_display();
3699 *value = 0;
3700 break;
3701 }
3702 case WE_MODULE_DOWN_IND:
3703 {
3704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: sending WLAN_MODULE_DOWN_IND", __FUNCTION__);
3705 send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0);
3706#ifdef WLAN_BTAMP_FEATURE
3707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: Take down AMP PAL", __FUNCTION__);
3708 BSL_Deinit(vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
3709#endif
3710 //WLANBAP_Close(vos_get_global_context(VOS_MODULE_ID_HDD, NULL));
3711
3712 *value = 0;
3713 break;
3714 }
3715 case WE_GET_MAX_ASSOC:
3716 {
3717 if (ccmCfgGetInt(hHal, WNI_CFG_ASSOC_STA_LIMIT, (tANI_U32 *)value) != eHAL_STATUS_SUCCESS)
3718 {
3719 ret = -EIO;
3720 }
3721 break;
3722 }
3723
3724#ifdef FEATURE_WLAN_INTEGRATED_SOC
3725 case WE_GET_WDI_DBG:
3726 {
3727 wpalTraceDisplay();
3728 *value = 0;
3729 break;
3730 }
3731#endif // FEATURE_WLAN_INTEGRATED_SOC
3732
3733 case WE_GET_SAP_AUTO_CHANNEL_SELECTION:
3734 {
3735 *value = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->apAutoChannelSelection;
3736 break;
3737 }
3738 case WE_GET_CONCURRENCY_MODE:
3739 {
3740 *value = hdd_get_concurrency_mode ( );
3741
3742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, ("concurrency mode=%d \n"),*value);
3743 break;
3744 }
3745
3746 default:
3747 {
3748 hddLog(LOGE, "Invalid IOCTL get_value command %d ",value[0]);
3749 break;
3750 }
3751 }
3752
3753 return ret;
3754}
3755
3756/* set param sub-ioctls */
3757int iw_set_three_ints_getnone(struct net_device *dev, struct iw_request_info *info,
3758 union iwreq_data *wrqu, char *extra)
3759{
3760 int *value = (int *)extra;
3761 int sub_cmd = value[0];
3762 int ret = 0;
3763
3764 switch(sub_cmd)
3765 {
3766 case WE_SET_WLAN_DBG:
3767 {
3768 vos_trace_setValue( value[1], value[2], value[3]);
3769 break;
3770 }
3771#ifdef FEATURE_WLAN_INTEGRATED_SOC
3772 case WE_SET_WDI_DBG:
3773 {
3774 wpalTraceSetLevel( value[1], value[2], value[3]);
3775 break;
3776 }
3777#endif // FEATURE_WLAN_INTEGRATED_SOC
3778 case WE_SET_SAP_CHANNELS:
3779 {
3780 ret = iw_softap_set_channel_range( dev, value[1], value[2], value[3]);
3781 break;
3782 }
3783
3784 default:
3785 {
3786 hddLog(LOGE, "Invalid IOCTL command %d \n", sub_cmd );
3787 break;
3788 }
3789 }
3790 return ret;
3791}
3792
3793static int iw_get_char_setnone(struct net_device *dev, struct iw_request_info *info,
3794 union iwreq_data *wrqu, char *extra)
3795{
3796 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3797 int sub_cmd = wrqu->data.flags;
3798#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
3799 VOS_STATUS status;
3800#endif // FEATURE_WLAN_NON_INTEGRATED_SOC
3801 switch(sub_cmd)
3802 {
3803 case WE_WLAN_VERSION:
3804 {
3805#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
3806 status = hdd_wlan_get_version(pAdapter, wrqu, extra);
3807#else // FEATURE_WLAN_NON_INTEGRATED_SOC
3808 char *buf = extra;
3809 wrqu->data.length = snprintf(buf, WE_MAX_STR_LEN, "%s_",
3810 WLAN_CHIP_VERSION);
3811#endif
3812 break;
3813 }
3814
3815 case WE_GET_STATS:
3816 {
3817 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3818 hdd_tx_rx_stats_t *pStats = &pAdapter->hdd_stats.hddTxRxStats;
3819 hdd_chip_reset_stats_t *pResetStats = &pHddCtx->hddChipResetStats;
3820
3821 snprintf(extra, WE_MAX_STR_LEN,
3822 "\nTransmit"
3823 "\ncalled %u, dropped %u, backpressured %u, queued %u"
3824 "\n dropped BK %u, BE %u, VI %u, VO %u"
3825 "\n classified BK %u, BE %u, VI %u, VO %u"
3826 "\nbackpressured BK %u, BE %u, VI %u, VO %u"
3827 "\n queued BK %u, BE %u, VI %u, VO %u"
3828 "\nfetched %u, empty %u, lowres %u, deqerr %u"
3829 "\ndequeued %u, depressured %u, completed %u, flushed %u"
3830 "\n fetched BK %u, BE %u, VI %u, VO %u"
3831 "\n dequeued BK %u, BE %u, VI %u, VO %u"
3832 "\n depressured BK %u, BE %u, VI %u, VO %u"
3833 "\n flushed BK %u, BE %u, VI %u, VO %u"
3834 "\n\nReceive"
3835 "\nchains %u, packets %u, dropped %u, delivered %u, refused %u"
3836 "\n\nResetsStats"
3837 "\n TotalLogp %u Cmd53 %u MutexRead %u MIF-Error %u FW-Heartbeat %u Others %u"
3838 "\n",
3839 pStats->txXmitCalled,
3840 pStats->txXmitDropped,
3841 pStats->txXmitBackPressured,
3842 pStats->txXmitQueued,
3843
3844 pStats->txXmitDroppedAC[WLANTL_AC_BK],
3845 pStats->txXmitDroppedAC[WLANTL_AC_BE],
3846 pStats->txXmitDroppedAC[WLANTL_AC_VI],
3847 pStats->txXmitDroppedAC[WLANTL_AC_VO],
3848
3849 pStats->txXmitClassifiedAC[WLANTL_AC_BK],
3850 pStats->txXmitClassifiedAC[WLANTL_AC_BE],
3851 pStats->txXmitClassifiedAC[WLANTL_AC_VI],
3852 pStats->txXmitClassifiedAC[WLANTL_AC_VO],
3853
3854 pStats->txXmitBackPressuredAC[WLANTL_AC_BK],
3855 pStats->txXmitBackPressuredAC[WLANTL_AC_BE],
3856 pStats->txXmitBackPressuredAC[WLANTL_AC_VI],
3857 pStats->txXmitBackPressuredAC[WLANTL_AC_VO],
3858
3859 pStats->txXmitQueuedAC[WLANTL_AC_BK],
3860 pStats->txXmitQueuedAC[WLANTL_AC_BE],
3861 pStats->txXmitQueuedAC[WLANTL_AC_VI],
3862 pStats->txXmitQueuedAC[WLANTL_AC_VO],
3863
3864 pStats->txFetched,
3865 pStats->txFetchEmpty,
3866 pStats->txFetchLowResources,
3867 pStats->txFetchDequeueError,
3868
3869 pStats->txFetchDequeued,
3870 pStats->txFetchDePressured,
3871 pStats->txCompleted,
3872 pStats->txFlushed,
3873
3874 pStats->txFetchedAC[WLANTL_AC_BK],
3875 pStats->txFetchedAC[WLANTL_AC_BE],
3876 pStats->txFetchedAC[WLANTL_AC_VI],
3877 pStats->txFetchedAC[WLANTL_AC_VO],
3878
3879 pStats->txFetchDequeuedAC[WLANTL_AC_BK],
3880 pStats->txFetchDequeuedAC[WLANTL_AC_BE],
3881 pStats->txFetchDequeuedAC[WLANTL_AC_VI],
3882 pStats->txFetchDequeuedAC[WLANTL_AC_VO],
3883
3884 pStats->txFetchDePressuredAC[WLANTL_AC_BK],
3885 pStats->txFetchDePressuredAC[WLANTL_AC_BE],
3886 pStats->txFetchDePressuredAC[WLANTL_AC_VI],
3887 pStats->txFetchDePressuredAC[WLANTL_AC_VO],
3888
3889 pStats->txFlushedAC[WLANTL_AC_BK],
3890 pStats->txFlushedAC[WLANTL_AC_BE],
3891 pStats->txFlushedAC[WLANTL_AC_VI],
3892 pStats->txFlushedAC[WLANTL_AC_VO],
3893
3894 pStats->rxChains,
3895 pStats->rxPackets,
3896 pStats->rxDropped,
3897 pStats->rxDelivered,
3898 pStats->rxRefused,
3899
3900 pResetStats->totalLogpResets,
3901 pResetStats->totalCMD53Failures,
3902 pResetStats->totalMutexReadFailures,
3903 pResetStats->totalMIFErrorFailures,
3904 pResetStats->totalFWHearbeatFailures,
3905 pResetStats->totalUnknownExceptions
3906 );
3907 wrqu->data.length = strlen(extra)+1;
3908 break;
3909 }
3910
3911 case WE_GET_CFG:
3912 {
3913 hdd_cfg_get_config(WLAN_HDD_GET_CTX(pAdapter), extra, WE_MAX_STR_LEN);
3914 wrqu->data.length = strlen(extra)+1;
3915 break;
3916 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003917#ifdef WLAN_FEATURE_11AC
3918 case WE_GET_RSSI:
3919 {
3920 v_S7_t s7Rssi = 0;
3921 wlan_hdd_get_rssi(pAdapter, &s7Rssi);
3922 snprintf(extra, WE_MAX_STR_LEN, "rssi=%d",s7Rssi);
3923 wrqu->data.length = strlen(extra)+1;
3924 break;
3925 }
3926#endif
3927
Jeff Johnson295189b2012-06-20 16:38:30 -07003928 case WE_GET_WMM_STATUS:
3929 {
3930 snprintf(extra, WE_MAX_STR_LEN,
3931 "\nDir: 0=up, 1=down, 3=both\n"
3932 "|------------------------|\n"
3933 "|AC | ACM |Admitted| Dir |\n"
3934 "|------------------------|\n"
3935 "|VO | %d | %3s | %d |\n"
3936 "|VI | %d | %3s | %d |\n"
3937 "|BE | %d | %3s | %d |\n"
3938 "|BK | %d | %3s | %d |\n"
3939 "|------------------------|\n",
3940 pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcAccessRequired,
3941 pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcAccessAllowed?"YES":"NO",
3942 pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VO].wmmAcTspecInfo.ts_info.direction,
3943 pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcAccessRequired,
3944 pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcAccessAllowed?"YES":"NO",
3945 pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_VI].wmmAcTspecInfo.ts_info.direction,
3946 pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcAccessRequired,
3947 pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcAccessAllowed?"YES":"NO",
3948 pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BE].wmmAcTspecInfo.ts_info.direction,
3949 pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcAccessRequired,
3950 pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcAccessAllowed?"YES":"NO",
3951 pAdapter->hddWmmStatus.wmmAcStatus[WLANTL_AC_BK].wmmAcTspecInfo.ts_info.direction);
3952
Jeff Johnsone7245742012-09-05 17:12:55 -07003953
Jeff Johnson295189b2012-06-20 16:38:30 -07003954 wrqu->data.length = strlen(extra)+1;
3955 break;
3956 }
3957 case WE_GET_CHANNEL_LIST:
3958 {
3959 VOS_STATUS status;
3960 v_U8_t i, len;
3961 char* buf ;
3962 tChannelListInfo channel_list;
3963
3964 status = iw_softap_get_channel_list(dev, info, wrqu, (char *)&channel_list);
3965 if ( !VOS_IS_STATUS_SUCCESS( status ) )
3966 {
3967 hddLog(VOS_TRACE_LEVEL_ERROR, "%s GetChannelList Failed!!!\n",__func__);
3968 return -EINVAL;
3969 }
3970 buf = extra;
3971
3972 /**
3973 * Maximum channels = WNI_CFG_VALID_CHANNEL_LIST_LEN. Maximum buffer
3974 * needed = 5 * number of channels. Check if sufficient buffer is available and
3975 * then proceed to fill the buffer.
3976 */
3977 if(WE_MAX_STR_LEN < (5 * WNI_CFG_VALID_CHANNEL_LIST_LEN))
3978 {
3979 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Insufficient Buffer to populate channel list\n",__func__);
3980 return -EINVAL;
3981 }
3982 len = snprintf(buf, 5, "%u ", channel_list.num_channels);
3983 buf += len;
3984 for(i = 0 ; i < channel_list.num_channels; i++)
3985 {
3986 len = snprintf(buf, 5,
3987 "%u ", channel_list.channels[i]);
3988 buf += len;
3989 }
3990 wrqu->data.length = strlen(extra)+1;
3991
3992 break;
3993 }
3994 default:
3995 {
3996 hddLog(LOGE, "Invalid IOCTL command %d \n", sub_cmd );
3997 break;
3998 }
3999 }
4000
4001 return 0;
4002}
4003
4004/* action sub-ioctls */
4005static int iw_setnone_getnone(struct net_device *dev, struct iw_request_info *info,
4006 union iwreq_data *wrqu, char *extra)
4007{
4008 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4009 int sub_cmd = wrqu->data.flags;
4010 int ret = 0; /* sucess */
4011
4012 switch (sub_cmd)
4013 {
4014 case WE_CLEAR_STATS:
4015 {
4016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: clearing", __FUNCTION__);
4017 memset(&pAdapter->stats, 0, sizeof(pAdapter->stats));
4018 memset(&pAdapter->hdd_stats, 0, sizeof(pAdapter->hdd_stats));
4019 break;
4020 }
4021#ifdef WLAN_SOFTAP_FEATURE
4022 case WE_INIT_AP:
4023 {
4024 pr_info("Init AP trigger\n");
4025 hdd_open_adapter( WLAN_HDD_GET_CTX(pAdapter), WLAN_HDD_SOFTAP, "softap.%d",
4026 wlan_hdd_get_intf_addr( WLAN_HDD_GET_CTX(pAdapter) ),TRUE);
4027 break;
4028 }
4029 case WE_STOP_AP:
4030 {
4031 /*FIX ME: Need to be revisited if multiple SAPs to be supported */
4032 /* As Soft AP mode has been changed to STA already with killing of Hostapd,
4033 * this is a dead code and need to find the adpater by name rather than mode */
4034 hdd_adapter_t* pAdapter_to_stop =
4035 hdd_get_adapter_by_name(WLAN_HDD_GET_CTX(pAdapter), "softap.0");
4036 if( pAdapter_to_stop )
4037 {
4038 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4039
4040 pr_info("Stopping AP mode\n");
4041
4042 /*Make sure that pAdapter cleaned properly*/
4043 hdd_stop_adapter( pHddCtx, pAdapter_to_stop );
4044 hdd_deinit_adapter( pHddCtx, pAdapter_to_stop );
4045 memset(&pAdapter_to_stop->sessionCtx, 0, sizeof(pAdapter_to_stop->sessionCtx));
4046
4047 wlan_hdd_release_intf_addr(WLAN_HDD_GET_CTX(pAdapter),
4048 pAdapter_to_stop->macAddressCurrent.bytes);
4049 hdd_close_adapter(WLAN_HDD_GET_CTX(pAdapter), pAdapter_to_stop,
4050 TRUE);
4051 }
4052 else
4053 {
4054 printk(KERN_ERR"SAP adaptor not found to stop it!\n");
4055 }
4056
4057 break;
4058 }
4059#endif
4060#ifdef WLAN_BTAMP_FEATURE
4061 case WE_ENABLE_AMP:
4062 {
4063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: enabling AMP", __FUNCTION__);
4064 WLANBAP_RegisterWithHCI(pAdapter);
4065 break;
4066 }
4067 case WE_DISABLE_AMP:
4068 {
4069 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4070 VOS_STATUS status;
4071
4072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"%s: disabling AMP", __FUNCTION__);
4073
4074 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4075 status = WLANBAP_StopAmp();
4076 if(VOS_STATUS_SUCCESS != status )
4077 {
4078 pHddCtx->isAmpAllowed = VOS_TRUE;
4079 hddLog(VOS_TRACE_LEVEL_FATAL,
4080 "%s: Failed to stop AMP", __func__);
4081 }
4082 else
4083 {
4084 //a state m/c implementation in PAL is TBD to avoid this delay
4085 msleep(500);
4086 pHddCtx->isAmpAllowed = VOS_FALSE;
4087 WLANBAP_DeregisterFromHCI();
4088 }
4089
4090 break;
4091 }
4092#endif
4093
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07004094 case WE_ENABLE_DXE_STALL_DETECT:
4095 {
4096 sme_transportDebug(VOS_FALSE, VOS_TRUE);
4097 break;
4098 }
4099 case WE_DISPLAY_DXE_SNAP_SHOT:
4100 {
4101 sme_transportDebug(VOS_TRUE, VOS_FALSE);
4102 break;
4103 }
4104
Jeff Johnson295189b2012-06-20 16:38:30 -07004105 default:
4106 {
4107 hddLog(LOGE, "%s: unknown ioctl %d", __FUNCTION__, sub_cmd);
4108 break;
4109 }
4110 }
4111
4112 return ret;
4113}
4114
4115int iw_set_var_ints_getnone(struct net_device *dev, struct iw_request_info *info,
4116 union iwreq_data *wrqu, char *extra)
4117{
4118 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4119 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4120 int sub_cmd = wrqu->data.flags;
4121 int *value = (int*)wrqu->data.pointer;
4122 int apps_args[MAX_VAR_ARGS] = {0};
4123 int num_args = wrqu->data.length;
4124
4125 hddLog(LOG1, "%s: Received length %d", __FUNCTION__, wrqu->data.length);
4126 if (num_args > MAX_VAR_ARGS)
4127 {
4128 num_args = MAX_VAR_ARGS;
4129 }
4130 vos_mem_copy(apps_args, value, (sizeof(int)) * num_args);
4131
4132 switch (sub_cmd)
4133 {
4134 case WE_LOG_DUMP_CMD:
4135 {
4136 hddLog(LOG1, "%s: LOG_DUMP %d arg1 %d arg2 %d arg3 %d arg4 %d",
4137 __FUNCTION__, apps_args[0], apps_args[1], apps_args[2],
4138 apps_args[3], apps_args[4]);
4139
4140 logPrintf(hHal, apps_args[0], apps_args[1], apps_args[2],
4141 apps_args[3], apps_args[4]);
4142
4143 }
4144 break;
4145
4146#ifdef WLAN_FEATURE_P2P
4147 case WE_P2P_NOA_CMD:
4148 {
4149 p2p_app_setP2pPs_t p2pNoA;
4150
4151 p2pNoA.opp_ps = apps_args[0];
4152 p2pNoA.ctWindow = apps_args[1];
4153 p2pNoA.duration = apps_args[2];
4154 p2pNoA.interval = apps_args[3];
4155 p2pNoA.count = apps_args[4];
4156 p2pNoA.single_noa_duration = apps_args[5];
4157 p2pNoA.psSelection = apps_args[6];
4158
4159 hddLog(LOG1, "%s: P2P_NOA_ATTR:oppPS %d ctWindow %d duration %d "
4160 "interval %d count %d single noa duration %d PsSelection %x",
4161 __FUNCTION__, apps_args[0], apps_args[1], apps_args[2],
4162 apps_args[3], apps_args[4], apps_args[5], apps_args[6]);
4163
4164 hdd_setP2pPs(dev, &p2pNoA);
4165
4166 }
4167 break;
4168#endif
4169
4170 default:
4171 {
4172 hddLog(LOGE, "Invalid IOCTL command %d", sub_cmd );
4173 }
4174 break;
4175 }
4176
4177 return 0;
4178}
4179
4180
4181static int iw_add_tspec(struct net_device *dev, struct iw_request_info *info,
4182 union iwreq_data *wrqu, char *extra)
4183{
4184 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4185 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4186 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra;
4187 int params[HDD_WLAN_WMM_PARAM_COUNT];
4188 sme_QosWmmTspecInfo tSpec;
4189 v_U32_t handle;
4190
4191 // make sure the application is sufficiently priviledged
4192 // note that the kernel will do this for "set" ioctls, but since
4193 // this ioctl wants to return status to user space it must be
4194 // defined as a "get" ioctl
4195 if (!capable(CAP_NET_ADMIN))
4196 {
4197 return -EPERM;
4198 }
4199
4200 // we must be associated in order to add a tspec
4201 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4202 {
4203 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
4204 return 0;
4205 }
4206
4207 // since we are defined to be a "get" ioctl, and since the number
4208 // of params exceeds the number of params that wireless extensions
4209 // will pass down in the iwreq_data, we must copy the "set" params
4210 // from user space ourselves
4211 if (copy_from_user(&params, wrqu->data.pointer, sizeof(params)))
4212 {
4213 // hmmm, can't get them
4214 return -EIO;
4215 }
4216
4217 // clear the tspec
4218 memset(&tSpec, 0, sizeof(tSpec));
4219
4220 // validate the handle
4221 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
4222 if (HDD_WMM_HANDLE_IMPLICIT == handle)
4223 {
4224 // that one is reserved
4225 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
4226 return 0;
4227 }
4228
4229 // validate the TID
4230 if (params[HDD_WLAN_WMM_PARAM_TID] > 7)
4231 {
4232 // out of range
4233 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
4234 return 0;
4235 }
4236 tSpec.ts_info.tid = params[HDD_WLAN_WMM_PARAM_TID];
4237
4238 // validate the direction
4239 switch (params[HDD_WLAN_WMM_PARAM_DIRECTION])
4240 {
4241 case HDD_WLAN_WMM_DIRECTION_UPSTREAM:
4242 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_UPLINK;
4243 break;
4244
4245 case HDD_WLAN_WMM_DIRECTION_DOWNSTREAM:
4246 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_DOWNLINK;
4247 break;
4248
4249 case HDD_WLAN_WMM_DIRECTION_BIDIRECTIONAL:
4250 tSpec.ts_info.direction = SME_QOS_WMM_TS_DIR_BOTH;
4251 break;
4252
4253 default:
4254 // unknown
4255 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
4256 return 0;
4257 }
4258
4259 // validate the user priority
4260 if (params[HDD_WLAN_WMM_PARAM_USER_PRIORITY] >= SME_QOS_WMM_UP_MAX)
4261 {
4262 // out of range
4263 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
4264 return 0;
4265 }
4266 tSpec.ts_info.up = params[HDD_WLAN_WMM_PARAM_USER_PRIORITY];
4267
4268 tSpec.nominal_msdu_size = params[HDD_WLAN_WMM_PARAM_NOMINAL_MSDU_SIZE];
4269 tSpec.maximum_msdu_size = params[HDD_WLAN_WMM_PARAM_MAXIMUM_MSDU_SIZE];
4270 tSpec.min_data_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_DATA_RATE];
4271 tSpec.mean_data_rate = params[HDD_WLAN_WMM_PARAM_MEAN_DATA_RATE];
4272 tSpec.peak_data_rate = params[HDD_WLAN_WMM_PARAM_PEAK_DATA_RATE];
4273 tSpec.max_burst_size = params[HDD_WLAN_WMM_PARAM_MAX_BURST_SIZE];
4274 tSpec.min_phy_rate = params[HDD_WLAN_WMM_PARAM_MINIMUM_PHY_RATE];
4275 tSpec.surplus_bw_allowance = params[HDD_WLAN_WMM_PARAM_SURPLUS_BANDWIDTH_ALLOWANCE];
4276 tSpec.min_service_interval = params[HDD_WLAN_WMM_PARAM_SERVICE_INTERVAL];
4277 tSpec.max_service_interval = params[HDD_WLAN_WMM_PARAM_MAX_SERVICE_INTERVAL];
4278 tSpec.suspension_interval = params[HDD_WLAN_WMM_PARAM_SUSPENSION_INTERVAL];
4279 tSpec.inactivity_interval = params[HDD_WLAN_WMM_PARAM_INACTIVITY_INTERVAL];
4280
4281 tSpec.ts_info.burst_size_defn = params[HDD_WLAN_WMM_PARAM_BURST_SIZE_DEFN];
4282
4283 // validate the ts info ack policy
4284 switch (params[HDD_WLAN_WMM_PARAM_ACK_POLICY])
4285 {
4286 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_NORMAL_ACK:
4287 tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_NORMAL_ACK;
4288 break;
4289
4290 case HDD_WLAN_WMM_TS_INFO_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK:
4291 tSpec.ts_info.ack_policy = SME_QOS_WMM_TS_ACK_POLICY_HT_IMMEDIATE_BLOCK_ACK;
4292 break;
4293
4294 default:
4295 // unknown
4296 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
4297 return 0;
4298 }
4299
4300 *pStatus = hdd_wmm_addts(pAdapter, handle, &tSpec);
4301 return 0;
4302}
4303
4304
4305static int iw_del_tspec(struct net_device *dev, struct iw_request_info *info,
4306 union iwreq_data *wrqu, char *extra)
4307{
4308 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4309 int *params = (int *)extra;
4310 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra;
4311 v_U32_t handle;
4312
4313 // make sure the application is sufficiently priviledged
4314 // note that the kernel will do this for "set" ioctls, but since
4315 // this ioctl wants to return status to user space it must be
4316 // defined as a "get" ioctl
4317 if (!capable(CAP_NET_ADMIN))
4318 {
4319 return -EPERM;
4320 }
4321
4322 // although we are defined to be a "get" ioctl, the params we require
4323 // will fit in the iwreq_data, therefore unlike iw_add_tspec() there
4324 // is no need to copy the params from user space
4325
4326 // validate the handle
4327 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
4328 if (HDD_WMM_HANDLE_IMPLICIT == handle)
4329 {
4330 // that one is reserved
4331 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
4332 return 0;
4333 }
4334
4335 *pStatus = hdd_wmm_delts(pAdapter, handle);
4336 return 0;
4337}
4338
4339
4340static int iw_get_tspec(struct net_device *dev, struct iw_request_info *info,
4341 union iwreq_data *wrqu, char *extra)
4342{
4343 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4344 int *params = (int *)extra;
4345 hdd_wlan_wmm_status_e *pStatus = (hdd_wlan_wmm_status_e *)extra;
4346 v_U32_t handle;
4347
4348 // although we are defined to be a "get" ioctl, the params we require
4349 // will fit in the iwreq_data, therefore unlike iw_add_tspec() there
4350 // is no need to copy the params from user space
4351
4352 // validate the handle
4353 handle = params[HDD_WLAN_WMM_PARAM_HANDLE];
4354 if (HDD_WMM_HANDLE_IMPLICIT == handle)
4355 {
4356 // that one is reserved
4357 *pStatus = HDD_WLAN_WMM_STATUS_SETUP_FAILED_BAD_PARAM;
4358 return 0;
4359 }
4360
4361 *pStatus = hdd_wmm_checkts(pAdapter, handle);
4362 return 0;
4363}
4364
4365
4366#ifdef FEATURE_WLAN_WAPI
4367static int iw_qcom_set_wapi_mode(struct net_device *dev, struct iw_request_info *info,
4368 union iwreq_data *wrqu, char *extra)
4369{
4370 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4371 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4372 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4373 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
4374
4375 WAPI_FUNCTION_MODE *pWapiMode = (WAPI_FUNCTION_MODE *)wrqu->data.pointer;
4376
4377 hddLog(LOG1, "The function iw_qcom_set_wapi_mode called");
4378 hddLog(LOG1, "%s: Received data %s", __FUNCTION__, (char*)wrqu->data.pointer);
4379 hddLog(LOG1, "%s: Received length %d", __FUNCTION__, wrqu->data.length);
4380 hddLog(LOG1, "%s: Input Data (wreq) WAPI Mode:%02d", __FUNCTION__, pWapiMode->wapiMode);
4381
4382
4383 if(WZC_ORIGINAL == pWapiMode->wapiMode) {
4384 hddLog(LOG1, "%s: WAPI Mode Set to OFF", __FUNCTION__);
4385 /* Set Encryption mode to defualt , this allows next successfull non-WAPI Association */
4386 pRoamProfile->EncryptionType.numEntries = 1;
4387 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
4388 pRoamProfile->mcEncryptionType.numEntries = 1;
4389 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
4390
4391 pRoamProfile->AuthType.numEntries = 1;
4392 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4393 pRoamProfile->AuthType.authType[0] = pHddStaCtx->conn_info.authType;
4394 }
4395 else if(WAPI_EXTENTION == pWapiMode->wapiMode) {
4396 hddLog(LOG1, "%s: WAPI Mode Set to ON", __FUNCTION__);
4397 }
4398 else
4399 return -EINVAL;
4400
4401 pAdapter->wapi_info.nWapiMode = pWapiMode->wapiMode;
4402
4403 return 0;
4404}
4405
4406static int iw_qcom_get_wapi_mode(struct net_device *dev, struct iw_request_info *info,
4407 union iwreq_data *wrqu, char *extra)
4408{
4409 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4410 WAPI_FUNCTION_MODE *pWapiMode = (WAPI_FUNCTION_MODE *)(extra);
4411
4412 hddLog(LOG1, "The function iw_qcom_get_wapi_mode called");
4413
4414 pWapiMode->wapiMode = pAdapter->wapi_info.nWapiMode;
4415 hddLog(LOG1, "%s: GET WAPI Mode Value:%02d", __FUNCTION__, pWapiMode->wapiMode);
4416 printk("\nGET WAPI MODE:%d",pWapiMode->wapiMode);
4417 return 0;
4418}
4419
4420static int iw_qcom_set_wapi_assoc_info(struct net_device *dev, struct iw_request_info *info,
4421 union iwreq_data *wrqu, char *extra)
4422{
4423 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4424// WAPI_AssocInfo *pWapiAssocInfo = (WAPI_AssocInfo *)(wrqu->data.pointer);
4425 WAPI_AssocInfo *pWapiAssocInfo = (WAPI_AssocInfo *)(extra);
4426 int i = 0, j = 0;
4427 hddLog(LOG1, "The function iw_qcom_set_wapi_assoc_info called");
4428 hddLog(LOG1, "%s: Received length %d", __FUNCTION__, wrqu->data.length);
4429 hddLog(LOG1, "%s: Received data %s", __FUNCTION__, (char*)wrqu->data.pointer);
4430 hddLog(LOG1, "%s: Received data %s", __FUNCTION__, (char*)extra);
4431
4432 VOS_ASSERT(pWapiAssocInfo);
4433
4434 hddLog(LOG1, "%s: INPUT DATA:\nElement ID:0x%02x Length:0x%02x Version:0x%04x\n",__FUNCTION__,pWapiAssocInfo->elementID,pWapiAssocInfo->length,pWapiAssocInfo->version);
4435 hddLog(LOG1,"%s: akm Suite Cnt:0x%04x",__FUNCTION__,pWapiAssocInfo->akmSuiteCount);
4436 for(i =0 ; i < 16 ; i++)
4437 hddLog(LOG1,"akm suite[%02d]:0x%08lx",i,pWapiAssocInfo->akmSuite[i]);
4438
4439 hddLog(LOG1,"%s: Unicast Suite Cnt:0x%04x",__FUNCTION__,pWapiAssocInfo->unicastSuiteCount);
4440 for(i =0 ; i < 16 ; i++)
4441 hddLog(LOG1, "Unicast suite[%02d]:0x%08lx",i,pWapiAssocInfo->unicastSuite[i]);
4442
4443 hddLog(LOG1,"%s: Multicast suite:0x%08lx Wapi capa:0x%04x",__FUNCTION__,pWapiAssocInfo->multicastSuite,pWapiAssocInfo->wapiCability);
4444 hddLog(LOG1, "%s: BKID Cnt:0x%04x\n",__FUNCTION__,pWapiAssocInfo->bkidCount);
4445 for(i = 0 ; i < 16 ; i++) {
4446 hddLog(LOG1, "BKID List[%02d].bkid:0x",i);
4447 for(j = 0 ; j < 16 ; j++)
4448 hddLog(LOG1,"%02x",pWapiAssocInfo->bkidList[i].bkid[j]);
4449 }
4450
4451 /* We are not using the entire IE as provided by the supplicant.
4452 * This is being calculated by SME. This is the same as in the
4453 * case of WPA. Only the auth mode information needs to be
4454 * extracted here*/
4455 if ( pWapiAssocInfo->akmSuite[0] == WAPI_PSK_AKM_SUITE ) {
4456 hddLog(LOG1, "%s: WAPI AUTH MODE SET TO PSK",__FUNCTION__);
4457 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
4458 }
4459
4460 if ( pWapiAssocInfo->akmSuite[0] == WAPI_CERT_AKM_SUITE) {
4461 hddLog(LOG1, "%s: WAPI AUTH MODE SET TO CERTIFICATE",__FUNCTION__);
4462 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
4463 }
4464 return 0;
4465}
4466
4467static int iw_qcom_set_wapi_key(struct net_device *dev, struct iw_request_info *info,
4468 union iwreq_data *wrqu, char *extra)
4469{
4470 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4471 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4472 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
4473 tANI_U32 roamId = 0xFF;
4474 tANI_U8 *pKeyPtr = NULL;
4475 v_BOOL_t isConnected = TRUE;
4476 tCsrRoamSetKey setKey;
4477 int i = 0;
4478
4479// WLAN_WAPI_KEY *pWapiKey = (WLAN_WAPI_KEY *)(wrqu->data.pointer);
4480 WLAN_WAPI_KEY *pWapiKey = (WLAN_WAPI_KEY *)(extra);
4481
4482 hddLog(LOG1, "The function iw_qcom_set_wapi_key called ");
4483 hddLog(LOG1, "%s: Received length %d", __FUNCTION__, wrqu->data.length);
4484 hddLog(LOG1, "%s: Received data %s", __FUNCTION__, (char*)wrqu->data.pointer);
4485 hddLog(LOG1, "%s: Received data %s", __FUNCTION__, (char*)extra);
4486
4487 hddLog(LOG1,":s: INPUT DATA:\nKey Type:0x%02x Key Direction:0x%02x KEY ID:0x%02x\n", __FUNCTION__,pWapiKey->keyType,pWapiKey->keyDirection,pWapiKey->keyId);
4488 hddLog(LOG1,"Add Index:0x");
4489 for(i =0 ; i < 12 ; i++)
4490 hddLog(LOG1,"%02x",pWapiKey->addrIndex[i]);
4491
4492 hddLog(LOG1,"\n%s: WAPI ENCRYPTION KEY LENGTH:0x%04x", __FUNCTION__,pWapiKey->wpiekLen);
4493 hddLog(LOG1, "WAPI ENCRYPTION KEY:0x");
4494 for(i =0 ; i < 16 ; i++)
4495 hddLog(LOG1,"%02x",pWapiKey->wpiek[i]);
4496
4497 hddLog(LOG1,"\n%s: WAPI INTEGRITY CHECK KEY LENGTH:0x%04x", __FUNCTION__,pWapiKey->wpickLen);
4498 hddLog(LOG1,"WAPI INTEGRITY CHECK KEY:0x");
4499 for(i =0 ; i < 16 ; i++)
4500 hddLog(LOG1,"%02x",pWapiKey->wpick[i]);
4501
4502 hddLog(LOG1,"\nWAPI PN NUMBER:0x");
4503 for(i = 0 ; i < 16 ; i++)
4504 hddLog(LOG1,"%02x",pWapiKey->pn[i]);
4505
4506 // Clear the setkey memory
4507 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4508 // Store Key ID
4509 setKey.keyId = (unsigned char)( pWapiKey->keyId );
4510 // SET WAPI Encryption
4511 setKey.encType = eCSR_ENCRYPT_TYPE_WPI;
4512 // Key Directionn both TX and RX
4513 setKey.keyDirection = eSIR_TX_RX; // Do WE NEED to update this based on Key Type as GRP/UNICAST??
4514 // the PAE role
4515 setKey.paeRole = 0 ;
4516
4517 switch ( pWapiKey->keyType )
4518 {
4519 case HDD_PAIRWISE_WAPI_KEY:
4520 {
4521 isConnected = hdd_connIsConnected(pHddStaCtx);
4522 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
4523 break;
4524 }
4525 case HDD_GROUP_WAPI_KEY:
4526 {
4527 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
4528 break;
4529 }
4530 default:
4531 {
4532 //Any other option is invalid.
4533 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4534 "[%4d] %s() failed to Set Key. Invalid key type %d", __LINE__,__FUNCTION__ , -1 );
4535
4536 hddLog(LOGE," %s: Error WAPI Key Add Type",__FUNCTION__);
4537 halStatus = !eHAL_STATUS_SUCCESS; // NEED TO UPDATE THIS WITH CORRECT VALUE
4538 break; // NEED RETURN FROM HERE ????
4539 }
4540 }
4541
4542 // Concatenating the Encryption Key (EK) and the MIC key (CK): EK followed by CK
4543 setKey.keyLength = (v_U16_t)((pWapiKey->wpiekLen)+(pWapiKey->wpickLen));
4544 pKeyPtr = setKey.Key;
4545 memcpy( pKeyPtr, pWapiKey->wpiek, pWapiKey->wpiekLen );
4546 pKeyPtr += pWapiKey->wpiekLen;
4547 memcpy( pKeyPtr, pWapiKey->wpick, pWapiKey->wpickLen );
4548
4549 // Set the new key with SME.
4550 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
4551
4552 if ( isConnected ) {
4553 halStatus = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, &setKey, &roamId );
4554 if ( halStatus != eHAL_STATUS_SUCCESS )
4555 {
4556 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4557 "[%4d] sme_RoamSetKey returned ERROR status= %d", __LINE__, halStatus );
4558
4559 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4560 }
4561 }
4562#if 0 /// NEED TO CHECK ON THIS
4563 else
4564 {
4565 // Store the keys in the adapter to be moved to the profile & passed to
4566 // SME in the ConnectRequest if we are not yet in connected state.
4567 memcpy( &pAdapter->setKey[ setKey.keyId ], &setKey, sizeof( setKey ) );
4568 pAdapter->fKeySet[ setKey.keyId ] = TRUE;
4569
4570 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
4571 " Saving key [idx= %d] to apply when moving to connected state ",
4572 setKey.keyId );
4573
4574 }
4575#endif
4576 return halStatus;
4577}
4578
4579static int iw_qcom_set_wapi_bkid(struct net_device *dev, struct iw_request_info *info,
4580 union iwreq_data *wrqu, char *extra)
4581{
4582#ifdef WLAN_DEBUG
4583 int i = 0;
4584 WLAN_BKID_LIST *pBkid = ( WLAN_BKID_LIST *) (wrqu->data.pointer);
4585#endif
4586
4587 hddLog(LOG1, "The function iw_qcom_set_wapi_bkid called");
4588 hddLog(LOG1, "%s: Received length %d", __FUNCTION__, wrqu->data.length);
4589 hddLog(LOG1, "%s: Received data %s", __FUNCTION__, (char*)wrqu->data.pointer);
4590 hddLog(LOG1, "%s: Received data %s", __FUNCTION__, (char*)extra);
4591
4592 hddLog(LOG1,"%s: INPUT DATA:\n BKID Length:0x%08lx\n", __FUNCTION__,pBkid->length);
4593 hddLog(LOG1,"%s: BKID Cnt:0x%04lx",pBkid->BKIDCount);
4594
4595 hddLog(LOG1,"BKID KEY LIST[0]:0x");
4596#ifdef WLAN_DEBUG
4597 for(i =0 ; i < 16 ; i++)
4598 hddLog(LOG1,"%02x",pBkid->BKID[0].bkid[i]);
4599#endif
4600
4601 return 0;
4602}
4603
4604static int iw_qcom_get_wapi_bkid(struct net_device *dev, struct iw_request_info *info,
4605 union iwreq_data *wrqu, char *extra)
4606{
4607 /* Yet to implement this function, 19th April 2010 */
4608 hddLog(LOG1, "The function iw_qcom_get_wapi_bkid called ");
4609
4610 return 0;
4611}
4612#endif /* FEATURE_WLAN_WAPI */
4613
4614#ifdef WLAN_FEATURE_VOWIFI_11R
4615//
4616//
4617// Each time the supplicant has the auth_request or reassoc request
4618// IEs ready. This is pushed to the driver. The driver will inturn use
4619// it to send out the auth req and reassoc req for 11r FT Assoc.
4620//
4621static int iw_set_fties(struct net_device *dev, struct iw_request_info *info,
4622 union iwreq_data *wrqu, char *extra)
4623{
4624 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4625 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4626 //v_CONTEXT_t pVosContext;
4627
4628 if (!wrqu->data.length)
4629 {
4630 hddLog(LOGE, FL("%s called with 0 length IEs\n"));
4631 return -EINVAL;
4632 }
4633 if (wrqu->data.pointer == NULL)
4634 {
4635 hddLog(LOGE, FL("%s called with NULL IE\n"));
4636 return -EINVAL;
4637 }
4638
4639 // Added for debug on reception of Re-assoc Req.
4640 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
4641 {
4642 hddLog(LOGE, FL("Called with Ie of length = %d when not associated\n"),
4643 wrqu->data.length);
4644 hddLog(LOGE, FL("Should be Re-assoc Req IEs\n"));
4645 }
4646
4647#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
4648 hddLog(LOGE, FL("%s called with Ie of length = %d\n"), __func__, wrqu->data.length);
4649#endif
4650
4651 // Pass the received FT IEs to SME
4652 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, wrqu->data.pointer,
4653 wrqu->data.length);
4654
4655 return 0;
4656}
4657#endif
4658
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07004659static int iw_set_dynamic_mcbc_filter(struct net_device *dev,
4660 struct iw_request_info *info,
Jeff Johnson295189b2012-06-20 16:38:30 -07004661 union iwreq_data *wrqu, char *extra)
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07004662{
Jeff Johnson295189b2012-06-20 16:38:30 -07004663 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4664 tpMcBcFilterCfg pRequest = (tpMcBcFilterCfg)wrqu->data.pointer;
4665 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07004666 tpSirWlanSetRxpFilters wlanRxpFilterParam;
Madan Mohan Koyyalamudi51d87f72012-09-24 12:05:23 -07004667 VOS_STATUS vstatus = VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004668
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07004669 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
4670 "%s: Set MC BC Filter Config request: %d suspend %d",
4671 __FUNCTION__, pRequest->mcastBcastFilterSetting,
4672 pHddCtx->hdd_wlan_suspended);
Jeff Johnson295189b2012-06-20 16:38:30 -07004673
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07004674 wlanRxpFilterParam = vos_mem_malloc(sizeof(tSirWlanSetRxpFilters));
4675 if(NULL == wlanRxpFilterParam)
4676 {
4677 hddLog(VOS_TRACE_LEVEL_FATAL,
4678 "%s: vos_mem_alloc failed ", __func__);
4679 return -EINVAL;
4680 }
4681
4682 pHddCtx->dynamic_mcbc_filter.mcastBcastFilterSetting =
4683 pRequest->mcastBcastFilterSetting;
4684 pHddCtx->dynamic_mcbc_filter.enableCfg = TRUE;
4685
4686 if(pHddCtx->hdd_wlan_suspended)
4687 {
4688 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
Jeff Johnson295189b2012-06-20 16:38:30 -07004689 pRequest->mcastBcastFilterSetting;
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07004690 wlanRxpFilterParam->setMcstBcstFilter = TRUE;
4691
4692 if((pHddCtx->cfg_ini->fhostArpOffload) &&
4693 (eConnectionState_Associated ==
4694 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
4695 {
Madan Mohan Koyyalamudi51d87f72012-09-24 12:05:23 -07004696 vstatus = hdd_conf_hostarpoffload(pHddCtx, TRUE);
4697 if (!VOS_IS_STATUS_SUCCESS(vstatus))
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07004698 {
4699 hddLog(VOS_TRACE_LEVEL_INFO,
4700 "%s:Failed to enable ARPOFFLOAD Feature %d\n",
Madan Mohan Koyyalamudi51d87f72012-09-24 12:05:23 -07004701 __func__, vstatus);
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07004702 }
4703 else
4704 {
4705 if (HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST_BROADCAST ==
4706 pHddCtx->dynamic_mcbc_filter.mcastBcastFilterSetting)
4707 {
4708 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
4709 HDD_MCASTBCASTFILTER_FILTER_ALL_MULTICAST;
4710 }
4711 else if(HDD_MCASTBCASTFILTER_FILTER_ALL_BROADCAST ==
4712 pHddCtx->dynamic_mcbc_filter.mcastBcastFilterSetting)
4713 {
4714 wlanRxpFilterParam->configuredMcstBcstFilterSetting =
4715 HDD_MCASTBCASTFILTER_FILTER_NONE;
4716 }
4717 }
4718 }
4719
4720 hddLog(VOS_TRACE_LEVEL_INFO, "%s:MC/BC changed Req %d Set %d En %d",
4721 __func__,
4722 pHddCtx->dynamic_mcbc_filter.mcastBcastFilterSetting,
4723 wlanRxpFilterParam->configuredMcstBcstFilterSetting,
4724 wlanRxpFilterParam->setMcstBcstFilter);
4725
4726 if (eHAL_STATUS_SUCCESS != sme_ConfigureRxpFilter(WLAN_HDD_GET_HAL_CTX(pAdapter),
4727 wlanRxpFilterParam))
4728 {
4729 hddLog(VOS_TRACE_LEVEL_ERROR,
4730 "%s: Failure to execute set HW MC/BC Filter request\n",
4731 __func__);
4732 return -EINVAL;
4733 }
4734
4735 pHddCtx->dynamic_mcbc_filter.mcBcFilterSuspend =
4736 wlanRxpFilterParam->configuredMcstBcstFilterSetting;
4737 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004738
4739 return 0;
4740}
4741
Madan Mohan Koyyalamudif55e62a2012-09-24 11:14:27 -07004742static int iw_clear_dynamic_mcbc_filter(struct net_device *dev,
4743 struct iw_request_info *info,
Jeff Johnson295189b2012-06-20 16:38:30 -07004744 union iwreq_data *wrqu, char *extra)
4745{
4746 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4747 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4748
4749 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: ", __FUNCTION__);
4750
4751 pHddCtx->dynamic_mcbc_filter.enableCfg = FALSE;
4752
4753 return 0;
4754}
4755
4756static int iw_set_host_offload(struct net_device *dev, struct iw_request_info *info,
4757 union iwreq_data *wrqu, char *extra)
4758{
4759 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4760 tpHostOffloadRequest pRequest = (tpHostOffloadRequest)wrqu->data.pointer;
4761 tSirHostOffloadReq offloadRequest;
4762
4763 /* Debug display of request components. */
4764 switch (pRequest->offloadType)
4765 {
4766 case WLAN_IPV4_ARP_REPLY_OFFLOAD:
4767 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Host offload request: ARP reply", __FUNCTION__);
4768 switch (pRequest->enableOrDisable)
4769 {
4770 case WLAN_OFFLOAD_DISABLE:
4771 hddLog(VOS_TRACE_LEVEL_WARN, " disable");
4772 break;
4773 case WLAN_OFFLOAD_ARP_AND_BC_FILTER_ENABLE:
4774 hddLog(VOS_TRACE_LEVEL_WARN, " BC Filtering enable");
4775 case WLAN_OFFLOAD_ENABLE:
4776 hddLog(VOS_TRACE_LEVEL_WARN, " ARP offload enable");
4777 hddLog(VOS_TRACE_LEVEL_WARN, " IP address: %d.%d.%d.%d",
4778 pRequest->params.hostIpv4Addr[0], pRequest->params.hostIpv4Addr[1],
4779 pRequest->params.hostIpv4Addr[2], pRequest->params.hostIpv4Addr[3]);
4780 }
4781 break;
4782
4783 case WLAN_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD:
4784 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Host offload request: neighbor discovery\n",
4785 __FUNCTION__);
4786 switch (pRequest->enableOrDisable)
4787 {
4788 case WLAN_OFFLOAD_DISABLE:
4789 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, " disable");
4790 break;
4791 case WLAN_OFFLOAD_ENABLE:
4792 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, " enable");
4793 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, " IP address: %x:%x:%x:%x:%x:%x:%x:%x",
4794 *(v_U16_t *)(pRequest->params.hostIpv6Addr),
4795 *(v_U16_t *)(pRequest->params.hostIpv6Addr + 2),
4796 *(v_U16_t *)(pRequest->params.hostIpv6Addr + 4),
4797 *(v_U16_t *)(pRequest->params.hostIpv6Addr + 6),
4798 *(v_U16_t *)(pRequest->params.hostIpv6Addr + 8),
4799 *(v_U16_t *)(pRequest->params.hostIpv6Addr + 10),
4800 *(v_U16_t *)(pRequest->params.hostIpv6Addr + 12),
4801 *(v_U16_t *)(pRequest->params.hostIpv6Addr + 14));
4802 }
4803 }
4804
4805 /* Execute offload request. The reason that we can copy the request information
4806 from the ioctl structure to the SME structure is that they are laid out
4807 exactly the same. Otherwise, each piece of information would have to be
4808 copied individually. */
4809 memcpy(&offloadRequest, pRequest, wrqu->data.length);
Jeff Johnsone7245742012-09-05 17:12:55 -07004810 if (eHAL_STATUS_SUCCESS != sme_SetHostOffload(WLAN_HDD_GET_HAL_CTX(pAdapter),
4811 pAdapter->sessionId, &offloadRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07004812 {
4813 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute host offload request\n",
4814 __func__);
4815 return -EINVAL;
4816 }
4817
4818 return 0;
4819}
4820
4821static int iw_set_keepalive_params(struct net_device *dev, struct iw_request_info *info,
4822 union iwreq_data *wrqu, char *extra)
4823{
4824 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4825 tpKeepAliveRequest pRequest = (tpKeepAliveRequest)wrqu->data.pointer;
4826 tSirKeepAliveReq keepaliveRequest;
4827
4828 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
4829 {
4830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4831 "%s:LOGP in Progress. Ignore!!!",__func__);
4832 return 0;
4833 }
4834
4835 /* Debug display of request components. */
4836 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set Keep Alive Request : TimePeriod %d size %d",
4837 __FUNCTION__,pRequest->timePeriod, sizeof(tKeepAliveRequest));
4838
4839 switch (pRequest->packetType)
4840 {
4841 case WLAN_KEEP_ALIVE_NULL_PKT:
4842 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Keep Alive Request: Tx NULL", __FUNCTION__);
4843 break;
4844
4845 case WLAN_KEEP_ALIVE_UNSOLICIT_ARP_RSP:
4846
4847 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Keep Alive Request: Tx UnSolicited ARP RSP\n",
4848 __FUNCTION__);
4849
4850 hddLog(VOS_TRACE_LEVEL_WARN, " Host IP address: %d.%d.%d.%d",
4851 pRequest->hostIpv4Addr[0], pRequest->hostIpv4Addr[1],
4852 pRequest->hostIpv4Addr[2], pRequest->hostIpv4Addr[3]);
4853
4854 hddLog(VOS_TRACE_LEVEL_WARN, " Dest IP address: %d.%d.%d.%d",
4855 pRequest->destIpv4Addr[0], pRequest->destIpv4Addr[1],
4856 pRequest->destIpv4Addr[2], pRequest->destIpv4Addr[3]);
4857
4858 hddLog(VOS_TRACE_LEVEL_WARN, " Dest MAC address: %d:%d:%d:%d:%d:%d",
4859 pRequest->destMacAddr[0], pRequest->destMacAddr[1],
4860 pRequest->destMacAddr[2], pRequest->destMacAddr[3],
4861 pRequest->destMacAddr[4], pRequest->destMacAddr[5]);
4862 break;
4863
4864 }
4865
4866 /* Execute keep alive request. The reason that we can copy the request information
4867 from the ioctl structure to the SME structure is that they are laid out
4868 exactly the same. Otherwise, each piece of information would have to be
4869 copied individually. */
4870 memcpy(&keepaliveRequest, pRequest, wrqu->data.length);
4871
4872 hddLog(VOS_TRACE_LEVEL_ERROR, "set Keep: TP before SME %d\n", keepaliveRequest.timePeriod);
4873
Jeff Johnsone7245742012-09-05 17:12:55 -07004874 if (eHAL_STATUS_SUCCESS != sme_SetKeepAlive(WLAN_HDD_GET_HAL_CTX(pAdapter),
4875 pAdapter->sessionId, &keepaliveRequest))
Jeff Johnson295189b2012-06-20 16:38:30 -07004876 {
4877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Keep Alive\n",
4878 __func__);
4879 return -EINVAL;
4880 }
4881
4882 return 0;
4883}
4884
4885#ifdef WLAN_FEATURE_PACKET_FILTERING
Jeff Johnsone7245742012-09-05 17:12:55 -07004886int wlan_hdd_set_filter(hdd_context_t *pHddCtx, tpPacketFilterCfg pRequest,
4887 tANI_U8 sessionId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004888{
Madan Mohan Koyyalamudi96dd30d2012-10-05 17:24:51 -07004889 tSirRcvPktFilterCfgType packetFilterSetReq = {0};
4890 tSirRcvFltPktClearParam packetFilterClrReq = {0};
Jeff Johnson295189b2012-06-20 16:38:30 -07004891 int i=0;
4892
4893 if (pHddCtx->cfg_ini->disablePacketFilter)
4894 {
4895 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Packet Filtering Disabled. Returning ",
4896 __FUNCTION__ );
4897 return 0;
4898 }
4899
4900 /* Debug display of request components. */
4901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Packet Filter Request : FA %d params %d",
4902 __FUNCTION__, pRequest->filterAction, pRequest->numParams);
4903
4904 switch (pRequest->filterAction)
4905 {
4906 case HDD_RCV_FILTER_SET:
4907 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Set Packet Filter Request for Id: %d",
4908 __FUNCTION__, pRequest->filterId);
4909
4910 packetFilterSetReq.filterId = pRequest->filterId;
4911 if ( pRequest->numParams >= HDD_MAX_CMP_PER_PACKET_FILTER)
4912 {
4913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Number of Params exceed Max limit %d\n",
4914 __func__, pRequest->numParams);
4915 return -EINVAL;
4916 }
4917 packetFilterSetReq.numFieldParams = pRequest->numParams;
4918 packetFilterSetReq.coalesceTime = 0;
4919 packetFilterSetReq.filterType = 1;
4920 for (i=0; i < pRequest->numParams; i++)
4921 {
4922 packetFilterSetReq.paramsData[i].protocolLayer = pRequest->paramsData[i].protocolLayer;
4923 packetFilterSetReq.paramsData[i].cmpFlag = pRequest->paramsData[i].cmpFlag;
4924 packetFilterSetReq.paramsData[i].dataOffset = pRequest->paramsData[i].dataOffset;
4925 packetFilterSetReq.paramsData[i].dataLength = pRequest->paramsData[i].dataLength;
4926 packetFilterSetReq.paramsData[i].reserved = 0;
4927
4928 hddLog(VOS_TRACE_LEVEL_INFO, "Proto %d Comp Flag %d Filter Type\n",
4929 pRequest->paramsData[i].protocolLayer, pRequest->paramsData[i].cmpFlag,
4930 packetFilterSetReq.filterType);
4931
4932 hddLog(VOS_TRACE_LEVEL_INFO, "Data Offset %d Data Len %d\n",
4933 pRequest->paramsData[i].dataOffset, pRequest->paramsData[i].dataLength);
4934
4935 memcpy(&packetFilterSetReq.paramsData[i].compareData,
4936 pRequest->paramsData[i].compareData, pRequest->paramsData[i].dataLength);
4937 memcpy(&packetFilterSetReq.paramsData[i].dataMask,
4938 pRequest->paramsData[i].dataMask, pRequest->paramsData[i].dataLength);
4939
4940 hddLog(VOS_TRACE_LEVEL_INFO, "CData %d CData %d CData %d CData %d CData %d CData %d\n",
4941 pRequest->paramsData[i].compareData[0], pRequest->paramsData[i].compareData[1],
4942 pRequest->paramsData[i].compareData[2], pRequest->paramsData[i].compareData[3],
4943 pRequest->paramsData[i].compareData[4], pRequest->paramsData[i].compareData[5]);
4944
4945 hddLog(VOS_TRACE_LEVEL_INFO, "MData %d MData %d MData %d MData %d MData %d MData %d\n",
4946 pRequest->paramsData[i].dataMask[0], pRequest->paramsData[i].dataMask[1],
4947 pRequest->paramsData[i].dataMask[2], pRequest->paramsData[i].dataMask[3],
4948 pRequest->paramsData[i].dataMask[4], pRequest->paramsData[i].dataMask[5]);
4949 }
4950
Madan Mohan Koyyalamudi59a40c92012-09-24 14:13:16 -07004951 if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterSetFilter(pHddCtx->hHal, &packetFilterSetReq, sessionId))
Jeff Johnson295189b2012-06-20 16:38:30 -07004952 {
4953 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Set Filter\n",
4954 __func__);
4955 return -EINVAL;
4956 }
4957
4958 break;
4959
4960 case HDD_RCV_FILTER_CLEAR:
4961
4962 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Clear Packet Filter Request for Id: %d\n",
4963 __FUNCTION__, pRequest->filterId);
4964 packetFilterClrReq.filterId = pRequest->filterId;
Madan Mohan Koyyalamudi59a40c92012-09-24 14:13:16 -07004965 if (eHAL_STATUS_SUCCESS != sme_ReceiveFilterClearFilter(pHddCtx->hHal, &packetFilterClrReq, sessionId))
Jeff Johnson295189b2012-06-20 16:38:30 -07004966 {
4967 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failure to execute Clear Filter\n",
4968 __func__);
4969 return -EINVAL;
4970 }
4971 break;
4972
4973 default :
4974 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: Packet Filter Request: Invalid %d\n",
4975 __FUNCTION__, pRequest->filterAction);
4976 return -EINVAL;
4977 }
4978 return 0;
4979}
4980
Jeff Johnsone7245742012-09-05 17:12:55 -07004981void wlan_hdd_set_mc_addr_list(hdd_context_t *pHddCtx, v_U8_t set, v_U8_t sessionId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004982{
4983 v_U8_t filterAction = 0;
4984 tPacketFilterCfg request = {0};
4985 v_U8_t i = 0;
4986
4987 filterAction = set ? HDD_RCV_FILTER_SET : HDD_RCV_FILTER_CLEAR;
4988
4989 /*set mulitcast addr list*/
4990 for (i = 0; i < pHddCtx->mc_addr_list.mc_cnt; i++)
4991 {
4992 memset(&request, 0, sizeof (tPacketFilterCfg));
4993 request.filterAction = filterAction;
4994 request.filterId = i;
4995 if (set)
4996 {
4997 request.numParams = 1;
4998 request.paramsData[0].protocolLayer = HDD_FILTER_PROTO_TYPE_MAC;
4999 request.paramsData[0].cmpFlag = HDD_FILTER_CMP_TYPE_EQUAL;
5000 request.paramsData[0].dataOffset = WLAN_HDD_80211_FRM_DA_OFFSET;
5001 request.paramsData[0].dataLength = ETH_ALEN;
5002 memcpy(&(request.paramsData[0].compareData[0]),
5003 &(pHddCtx->mc_addr_list.addr[i][0]), ETH_ALEN);
5004 /*set mulitcast filters*/
5005 hddLog(VOS_TRACE_LEVEL_INFO,
5006 "%s: %s multicast filter: addr ="
5007 "%02x:%02x:%02x:%02x:%02x:%02x",
5008 __func__, set ? "setting" : "clearing",
5009 request.paramsData[0].compareData[0],
5010 request.paramsData[0].compareData[1],
5011 request.paramsData[0].compareData[2],
5012 request.paramsData[0].compareData[3],
5013 request.paramsData[0].compareData[4],
5014 request.paramsData[0].compareData[5]);
5015 }
Jeff Johnsone7245742012-09-05 17:12:55 -07005016 wlan_hdd_set_filter(pHddCtx, &request, sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005017 }
5018 pHddCtx->mc_addr_list.isFilterApplied = set ? TRUE : FALSE;
5019}
5020
5021static int iw_set_packet_filter_params(struct net_device *dev, struct iw_request_info *info,
5022 union iwreq_data *wrqu, char *extra)
5023{
5024 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5025 tpPacketFilterCfg pRequest = (tpPacketFilterCfg)wrqu->data.pointer;
Jeff Johnsone7245742012-09-05 17:12:55 -07005026 return wlan_hdd_set_filter(WLAN_HDD_GET_CTX(pAdapter), pRequest, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07005027}
5028#endif
5029static int iw_get_statistics(struct net_device *dev,
5030 struct iw_request_info *info,
5031 union iwreq_data *wrqu, char *extra)
5032{
5033
5034 VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
5035 eHalStatus status = eHAL_STATUS_SUCCESS;
5036 hdd_wext_state_t *pWextState;
5037 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5038 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5039 char *p = extra;
5040 int tlen = 0;
5041 tCsrSummaryStatsInfo *pStats = &(pAdapter->hdd_stats.summary_stat);
5042
5043 tCsrGlobalClassAStatsInfo *aStats = &(pAdapter->hdd_stats.ClassA_stat);
5044 tCsrGlobalClassDStatsInfo *dStats = &(pAdapter->hdd_stats.ClassD_stat);
5045
5046 ENTER();
5047
5048 if (pHddCtx->isLogpInProgress) {
5049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, "%s:LOGP in Progress. Ignore!!!",__func__);
5050 return -EINVAL;
5051 }
5052
5053 if (eConnectionState_Associated != (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState) {
5054
5055 wrqu->txpower.value = 0;
5056 }
5057 else {
5058 status = sme_GetStatistics( pHddCtx->hHal, eCSR_HDD,
5059 SME_SUMMARY_STATS |
5060 SME_GLOBAL_CLASSA_STATS |
5061 SME_GLOBAL_CLASSB_STATS |
5062 SME_GLOBAL_CLASSC_STATS |
5063 SME_GLOBAL_CLASSD_STATS |
5064 SME_PER_STA_STATS,
5065 hdd_StatisticsCB, 0, FALSE,
5066 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], pAdapter );
5067
5068 if (eHAL_STATUS_SUCCESS != status)
5069 {
5070 hddLog(VOS_TRACE_LEVEL_ERROR,
5071 "%s: Unable to retrieve SME statistics",
5072 __FUNCTION__);
5073 return -EINVAL;
5074 }
5075
5076 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5077
5078 vos_status = vos_wait_single_event(&pWextState->vosevent, WLAN_WAIT_TIME_STATS);
5079 if (!VOS_IS_STATUS_SUCCESS(vos_status))
5080 {
5081 hddLog(VOS_TRACE_LEVEL_ERROR,
5082 "%s: SME timeout while retrieving statistics",
5083 __FUNCTION__);
5084 /*Remove the SME statistics list by passing NULL in callback argument*/
5085 status = sme_GetStatistics( pHddCtx->hHal, eCSR_HDD,
5086 SME_SUMMARY_STATS |
5087 SME_GLOBAL_CLASSA_STATS |
5088 SME_GLOBAL_CLASSB_STATS |
5089 SME_GLOBAL_CLASSC_STATS |
5090 SME_GLOBAL_CLASSD_STATS |
5091 SME_PER_STA_STATS,
5092 NULL, 0, FALSE,
5093 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.staId[0], pAdapter );
5094
5095 return -EINVAL;
5096 }
5097 FILL_TLV(p, (tANI_U8)WLAN_STATS_RETRY_CNT,
5098 (tANI_U8) sizeof (pStats->retry_cnt),
5099 (char*) &(pStats->retry_cnt[0]),
5100 tlen);
5101
5102 FILL_TLV(p, (tANI_U8)WLAN_STATS_MUL_RETRY_CNT,
5103 (tANI_U8) sizeof (pStats->multiple_retry_cnt),
5104 (char*) &(pStats->multiple_retry_cnt[0]),
5105 tlen);
5106
5107 FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_FRM_CNT,
5108 (tANI_U8) sizeof (pStats->tx_frm_cnt),
5109 (char*) &(pStats->tx_frm_cnt[0]),
5110 tlen);
5111
5112 FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_FRM_CNT,
5113 (tANI_U8) sizeof (pStats->rx_frm_cnt),
5114 (char*) &(pStats->rx_frm_cnt),
5115 tlen);
5116
5117 FILL_TLV(p, (tANI_U8)WLAN_STATS_FRM_DUP_CNT,
5118 (tANI_U8) sizeof (pStats->frm_dup_cnt),
5119 (char*) &(pStats->frm_dup_cnt),
5120 tlen);
5121
5122 FILL_TLV(p, (tANI_U8)WLAN_STATS_FAIL_CNT,
5123 (tANI_U8) sizeof (pStats->fail_cnt),
5124 (char*) &(pStats->fail_cnt[0]),
5125 tlen);
5126
5127 FILL_TLV(p, (tANI_U8)WLAN_STATS_RTS_FAIL_CNT,
5128 (tANI_U8) sizeof (pStats->rts_fail_cnt),
5129 (char*) &(pStats->rts_fail_cnt),
5130 tlen);
5131
5132 FILL_TLV(p, (tANI_U8)WLAN_STATS_ACK_FAIL_CNT,
5133 (tANI_U8) sizeof (pStats->ack_fail_cnt),
5134 (char*) &(pStats->ack_fail_cnt),
5135 tlen);
5136
5137 FILL_TLV(p, (tANI_U8)WLAN_STATS_RTS_SUC_CNT,
5138 (tANI_U8) sizeof (pStats->rts_succ_cnt),
5139 (char*) &(pStats->rts_succ_cnt),
5140 tlen);
5141
5142 FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_DISCARD_CNT,
5143 (tANI_U8) sizeof (pStats->rx_discard_cnt),
5144 (char*) &(pStats->rx_discard_cnt),
5145 tlen);
5146
5147 FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_ERROR_CNT,
5148 (tANI_U8) sizeof (pStats->rx_error_cnt),
5149 (char*) &(pStats->rx_error_cnt),
5150 tlen);
5151
Jeff Johnsone7245742012-09-05 17:12:55 -07005152 FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_BYTE_CNT,
5153 (tANI_U8) sizeof (dStats->tx_uc_byte_cnt[0]),
5154 (char*) &(dStats->tx_uc_byte_cnt[0]),
Jeff Johnson295189b2012-06-20 16:38:30 -07005155 tlen);
5156
5157 FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_BYTE_CNT,
5158 (tANI_U8) sizeof (dStats->rx_byte_cnt),
5159 (char*) &(dStats->rx_byte_cnt),
5160 tlen);
5161
5162 FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_RATE,
5163 (tANI_U8) sizeof (dStats->rx_rate),
5164 (char*) &(dStats->rx_rate),
5165 tlen);
5166
5167 /* Transmit rate, in units of 500 kbit/sec */
5168 FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_RATE,
5169 (tANI_U8) sizeof (aStats->tx_rate),
5170 (char*) &(aStats->tx_rate),
5171 tlen);
5172
Jeff Johnsone7245742012-09-05 17:12:55 -07005173 FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_UC_BYTE_CNT,
5174 (tANI_U8) sizeof (dStats->rx_uc_byte_cnt[0]),
5175 (char*) &(dStats->rx_uc_byte_cnt[0]),
5176 tlen);
5177 FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_MC_BYTE_CNT,
5178 (tANI_U8) sizeof (dStats->rx_mc_byte_cnt),
5179 (char*) &(dStats->rx_mc_byte_cnt),
5180 tlen);
5181 FILL_TLV(p, (tANI_U8)WLAN_STATS_RX_BC_BYTE_CNT,
5182 (tANI_U8) sizeof (dStats->rx_bc_byte_cnt),
5183 (char*) &(dStats->rx_bc_byte_cnt),
5184 tlen);
5185 FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_UC_BYTE_CNT,
5186 (tANI_U8) sizeof (dStats->tx_uc_byte_cnt[0]),
5187 (char*) &(dStats->tx_uc_byte_cnt[0]),
5188 tlen);
5189 FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_MC_BYTE_CNT,
5190 (tANI_U8) sizeof (dStats->tx_mc_byte_cnt),
5191 (char*) &(dStats->tx_mc_byte_cnt),
5192 tlen);
5193 FILL_TLV(p, (tANI_U8)WLAN_STATS_TX_BC_BYTE_CNT,
5194 (tANI_U8) sizeof (dStats->tx_bc_byte_cnt),
5195 (char*) &(dStats->tx_bc_byte_cnt),
5196 tlen);
5197
Jeff Johnson295189b2012-06-20 16:38:30 -07005198 wrqu->data.length = tlen;
5199
5200 }
5201
5202 EXIT();
5203
5204 return 0;
5205}
5206
5207
5208#ifdef FEATURE_WLAN_SCAN_PNO
5209
5210/*Max Len for PNO notification*/
5211#define MAX_PNO_NOTIFY_LEN 100
5212void found_pref_network_cb (void *callbackContext,
5213 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
5214{
5215 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
5216 union iwreq_data wrqu;
5217 char buf[MAX_PNO_NOTIFY_LEN+1];
5218
5219 hddLog(VOS_TRACE_LEVEL_WARN, "A preferred network was found: %s with rssi: -%d",
5220 pPrefNetworkFoundInd->ssId.ssId, pPrefNetworkFoundInd->rssi);
5221
5222 // create the event
5223 memset(&wrqu, 0, sizeof(wrqu));
5224 memset(buf, 0, sizeof(buf));
5225
5226 snprintf(buf, MAX_PNO_NOTIFY_LEN, "QCOM: Found preferred network: %s with RSSI of -%u",
5227 pPrefNetworkFoundInd->ssId.ssId,
5228 (unsigned int)pPrefNetworkFoundInd->rssi);
5229
5230 wrqu.data.pointer = buf;
5231 wrqu.data.length = strlen(buf);
5232
5233 // send the event
5234
5235 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
5236
5237}
5238
5239
5240/*string based input*/
5241VOS_STATUS iw_set_pno(struct net_device *dev, struct iw_request_info *info,
5242 union iwreq_data *wrqu, char *extra, int nOffset)
5243{
5244 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5245 tSirPNOScanReq pnoRequest;
5246 char *ptr;
5247 v_U8_t i,j, ucParams, ucMode;
5248 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
5249
5250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5251 "PNO data len %d data %s",
5252 wrqu->data.length,
5253 wrqu->data.pointer);
5254
5255 if (wrqu->data.length <= nOffset )
5256 {
5257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "PNO input is not correct");
5258 return VOS_STATUS_E_FAILURE;
5259 }
5260
5261 pnoRequest.enable = 0;
5262 pnoRequest.ucNetworksCount = 0;
5263 /*-----------------------------------------------------------------------
5264 Input is string based and expected to be like this:
5265
5266 <enabled> <netw_count>
5267 for each network:
5268 <ssid_len> <ssid> <authentication> <encryption>
5269 <ch_num> <channel_list optional> <bcast_type> <rssi_threshold>
5270 <scan_timers> <scan_time> <scan_repeat> <scan_time> <scan_repeat>
5271
5272 e.g:
5273 1 2 4 test 0 0 3 1 6 11 2 40 5 test2 4 4 6 1 2 3 4 5 6 1 0 2 5 2 300 0
5274
5275 this translates into:
5276 -----------------------------
5277 enable PNO
5278 look for 2 networks:
5279 test - with authentication type 0 and encryption type 0,
5280 that can be found on 3 channels: 1 6 and 11 ,
5281 SSID bcast type is unknown (directed probe will be sent if AP not found)
5282 and must meet -40dBm RSSI
5283
5284 test2 - with auth and enrytption type 4/4
5285 that can be found on 6 channels 1, 2, 3, 4, 5 and 6
5286 bcast type is non-bcast (directed probe will be sent)
5287 and must not meet any RSSI threshold
5288
5289 scan every 5 seconds 2 times, scan every 300 seconds until stopped
5290 -----------------------------------------------------------------------*/
5291 ptr = (char*)(wrqu->data.pointer + nOffset);
5292
5293 sscanf(ptr,"%hhu%n", &(pnoRequest.enable), &nOffset);
5294
5295 if ( 0 == pnoRequest.enable )
5296 {
5297 /*Disable PNO*/
5298 memset(&pnoRequest, 0, sizeof(pnoRequest));
5299 sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), &pnoRequest,
5300 pAdapter->sessionId,
5301 found_pref_network_cb, pAdapter);
5302 return VOS_STATUS_SUCCESS;
5303 }
5304
5305 ptr += nOffset;
5306 sscanf(ptr,"%hhu %n", &(pnoRequest.ucNetworksCount), &nOffset);
5307
5308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5309 "PNO enable %d networks count %d offset %d",
5310 pnoRequest.enable,
5311 pnoRequest.ucNetworksCount,
5312 nOffset);
5313
5314 /* Parameters checking:
5315 ucNetworksCount has to be larger than 0*/
5316 if (( 0 == pnoRequest.ucNetworksCount ) ||
5317 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
5318 {
5319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "Network input is not correct");
5320 return VOS_STATUS_E_FAILURE;
5321 }
5322
5323 ptr += nOffset;
5324
5325 for ( i = 0; i < pnoRequest.ucNetworksCount; i++ )
5326 {
5327
5328 pnoRequest.aNetworks[i].ssId.length = 0;
5329
5330 sscanf(ptr,"%hhu %n",
5331 &(pnoRequest.aNetworks[i].ssId.length), &nOffset);
5332
5333 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
5334 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
5335 {
5336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5337 "SSID Len %d is not correct for network %d",
5338 pnoRequest.aNetworks[i].ssId.length, i);
5339 return VOS_STATUS_E_FAILURE;
5340 }
5341
5342 /*Advance to SSID*/
5343 ptr += nOffset;
5344
5345 ucParams = sscanf(ptr,"%32s %lu %lu %hhu %n",
5346 pnoRequest.aNetworks[i].ssId.ssId,
5347 &(pnoRequest.aNetworks[i].authentication),
5348 &(pnoRequest.aNetworks[i].encryption),
5349 &(pnoRequest.aNetworks[i].ucChannelCount),
5350 &nOffset);
5351
5352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5353 "PNO len %d ssid %s auth %d encry %d channel count %d offset %d",
5354 pnoRequest.aNetworks[i].ssId.length,
5355 pnoRequest.aNetworks[i].ssId.ssId,
5356 pnoRequest.aNetworks[i].authentication,
5357 pnoRequest.aNetworks[i].encryption,
5358 pnoRequest.aNetworks[i].ucChannelCount,
5359 nOffset );
5360
5361 if ( 4 != ucParams )
5362 {
5363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
5364 "Incorrect cmd");
5365 return VOS_STATUS_E_FAILURE;
5366 }
5367
5368 /*Advance to channel list*/
5369 ptr += nOffset;
5370
5371 if ( SIR_PNO_MAX_NETW_CHANNELS < pnoRequest.aNetworks[i].ucChannelCount )
5372 {
5373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
5374 "Incorrect number of channels");
5375 return VOS_STATUS_E_FAILURE;
5376 }
5377
5378 if ( 0 != pnoRequest.aNetworks[i].ucChannelCount)
5379 {
5380 for ( j = 0; j < pnoRequest.aNetworks[i].ucChannelCount; j++)
5381 {
5382 sscanf(ptr,"%hhu %n",
5383 &(pnoRequest.aNetworks[i].aChannels[j]), &nOffset);
5384 /*Advance to next channel number*/
5385 ptr += nOffset;
5386 }
5387 }
5388
5389 sscanf(ptr,"%lu %n",
5390 &(pnoRequest.aNetworks[i].bcastNetwType), &nOffset);
5391
5392 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5393 "PNO bcastNetwType %d offset %d",
5394 pnoRequest.aNetworks[i].bcastNetwType,
5395 nOffset );
5396
5397 /*Advance to rssi Threshold*/
5398 ptr += nOffset;
5399
5400 sscanf(ptr,"%hhu %n",
5401 &(pnoRequest.aNetworks[i].rssiThreshold), &nOffset);
5402
5403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5404 "PNO rssi %d offset %d",
5405 pnoRequest.aNetworks[i].rssiThreshold,
5406 nOffset );
5407 /*Advance to next network*/
5408 ptr += nOffset;
5409 }/*For ucNetworkCount*/
5410
5411 ucParams = sscanf(ptr,"%hhu %n",
5412 &(pnoRequest.scanTimers.ucScanTimersCount), &nOffset);
5413
5414 /*Read the scan timers*/
5415 if (( 1 == ucParams )&&( pnoRequest.scanTimers.ucScanTimersCount >= 0 ))
5416 {
5417 ptr += nOffset;
5418
5419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5420 "Scan timer count %d offset %d",
5421 pnoRequest.scanTimers.ucScanTimersCount,
5422 nOffset );
5423
5424 if ( SIR_PNO_MAX_SCAN_TIMERS < pnoRequest.scanTimers.ucScanTimersCount )
5425 {
5426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5427 "Incorrect cmd - too many scan timers");
5428 return VOS_STATUS_E_FAILURE;
5429 }
5430
5431 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++ )
5432 {
5433 ucParams = sscanf(ptr,"%lu %lu %n",
5434 &(pnoRequest.scanTimers.aTimerValues[i].uTimerValue),
5435 &( pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat),
5436 &nOffset);
5437
5438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5439 "PNO Timer value %d Timer repeat %d offset %d",
5440 pnoRequest.scanTimers.aTimerValues[i].uTimerValue,
5441 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat,
5442 nOffset );
5443
5444 if ( 2 != ucParams )
5445 {
5446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5447 "Incorrect cmd - diff params then expected %d", ucParams);
5448 return VOS_STATUS_E_FAILURE;
5449 }
5450
5451 ptr += nOffset;
5452 }
5453
5454 }
5455 else
5456 {
5457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5458 "No scan timers provided param count %d scan timers %d",
5459 ucParams, pnoRequest.scanTimers.ucScanTimersCount );
5460
5461 /*Scan timers defaults to 5 minutes*/
5462 pnoRequest.scanTimers.ucScanTimersCount = 1;
5463 pnoRequest.scanTimers.aTimerValues[0].uTimerValue = 60;
5464 pnoRequest.scanTimers.aTimerValues[0].uTimerRepeat = 0;
5465 }
5466
5467 ucParams = sscanf(ptr,"%hhu %n",
5468 &(ucMode), &nOffset);
5469
5470 pnoRequest.modePNO = ucMode;
5471 /*for LA we just expose suspend option*/
5472 if (( 1 != ucParams )||( ucMode >= SIR_PNO_MODE_MAX ))
5473 {
5474 pnoRequest.modePNO = SIR_PNO_MODE_ON_SUSPEND;
5475 }
5476
5477 sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter), &pnoRequest,
5478 pAdapter->sessionId,
5479 found_pref_network_cb, pAdapter);
5480
5481 return VOS_STATUS_SUCCESS;
5482}/*iw_set_pno*/
5483
5484VOS_STATUS iw_set_rssi_filter(struct net_device *dev, struct iw_request_info *info,
5485 union iwreq_data *wrqu, char *extra, int nOffset)
5486{
5487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5488 v_U8_t rssiThreshold = 0;
5489 v_U8_t nRead;
5490
5491 nRead = sscanf(wrqu->data.pointer + nOffset,"%hhu",
5492 &rssiThreshold);
5493
5494 if ( 1 != nRead )
5495 {
5496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
5497 "Incorrect format");
5498 return VOS_STATUS_E_FAILURE;
5499 }
5500
5501 sme_SetRSSIFilter(WLAN_HDD_GET_HAL_CTX(pAdapter), rssiThreshold);
5502 return VOS_STATUS_SUCCESS;
5503}
5504
5505
5506static int iw_set_pno_priv(struct net_device *dev,
5507 struct iw_request_info *info,
5508 union iwreq_data *wrqu, char *extra)
5509{
5510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5511 "Set PNO Private");
5512 return iw_set_pno(dev,info,wrqu,extra,0);
5513}
5514#endif /*FEATURE_WLAN_SCAN_PNO*/
5515
5516//Common function to SetBand
5517int hdd_setBand_helper(struct net_device *dev, tANI_U8* ptr)
5518{
5519 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5520 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5521 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
5522 tANI_U8 band = 0;
5523 eCsrBand currBand = eCSR_BAND_MAX;
5524
5525 band = ptr[WLAN_HDD_UI_SET_BAND_VALUE_OFFSET] - '0'; /*convert the band value from ascii to integer*/
5526
5527 switch(band)
5528 {
5529 case WLAN_HDD_UI_BAND_AUTO:
5530 band = eCSR_BAND_ALL;
5531 break;
5532 case WLAN_HDD_UI_BAND_5_GHZ:
5533 band = eCSR_BAND_5G;
5534 break;
5535 case WLAN_HDD_UI_BAND_2_4_GHZ:
5536 band = eCSR_BAND_24;
5537 break;
5538 default:
5539 band = eCSR_BAND_MAX;
5540 }
5541
5542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: change band to %u",
5543 __FUNCTION__, band);
5544
5545 if (band == eCSR_BAND_MAX)
5546 {
5547 /* Received change band request with invalid band value */
5548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5549 "%s: Invalid band value %u", __FUNCTION__, band);
5550 return -EIO;
5551 }
5552
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005553 if ( (band == eCSR_BAND_24 && pHddCtx->cfg_ini->nBandCapability==2) ||
5554 (band == eCSR_BAND_5G && pHddCtx->cfg_ini->nBandCapability==1) ||
5555 (band == eCSR_BAND_ALL && pHddCtx->cfg_ini->nBandCapability!=0))
5556 {
5557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
5558 "%s: band value %u violate INI settings %u", __FUNCTION__,
5559 band, pHddCtx->cfg_ini->nBandCapability);
5560 return -EIO;
5561 }
5562
Jeff Johnson295189b2012-06-20 16:38:30 -07005563 if (eHAL_STATUS_SUCCESS != sme_GetFreqBand(hHal, &currBand))
5564 {
5565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5566 "%s: Failed to get current band config",
5567 __FUNCTION__);
5568 return -EIO;
5569 }
5570
5571 if (currBand != band)
5572 {
5573 /* Change band request received.
5574 * Abort pending scan requests, flush the existing scan results,
5575 * and change the band capability
5576 */
5577 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5578 "%s: Current band value = %u, new setting %u ",
5579 __FUNCTION__, currBand, band);
5580
5581 if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)))
5582 {
5583 hdd_station_ctx_t *pHddStaCtx = &(pAdapter)->sessionCtx.station;
5584 eHalStatus status = eHAL_STATUS_SUCCESS;
5585 long lrc;
5586
5587 /* STA already connected on current band, So issue disconnect first,
5588 * then change the band*/
5589
5590 hddLog(VOS_TRACE_LEVEL_INFO,
5591 "%s STA connected in band %u, Changing band to %u, Issuing Disconnect",
5592 __func__, csrGetCurrentBand(hHal), band);
5593
5594 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
5595 INIT_COMPLETION(pAdapter->disconnect_comp_var);
5596
5597 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
5598 pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED);
5599
Jeff Johnson43971f52012-07-17 12:26:56 -07005600 if ( eHAL_STATUS_SUCCESS != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07005601 {
5602 hddLog(VOS_TRACE_LEVEL_ERROR,
5603 "%s csrRoamDisconnect failure, returned %d \n",
5604 __func__, (int)status );
5605 return -EINVAL;
5606 }
5607
5608 lrc = wait_for_completion_interruptible_timeout(
5609 &pAdapter->disconnect_comp_var,
5610 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
5611
5612 if(lrc <= 0) {
5613
5614 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: %s while while waiting for csrRoamDisconnect ",
5615 __FUNCTION__, (0 == lrc) ? "Timeout" : "Interrupt");
5616
5617 return (0 == lrc) ? -ETIMEDOUT : -EINTR;
5618 }
5619 }
5620
5621 hdd_abort_mac_scan(pHddCtx);
5622 sme_ScanFlushResult(hHal, pAdapter->sessionId);
5623 if(eHAL_STATUS_SUCCESS != sme_SetFreqBand(hHal, (eCsrBand)band))
5624 {
5625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
5626 "%s: failed to set the band value to %u ",
5627 __FUNCTION__, band);
5628 return -EINVAL;
5629 }
5630#ifdef CONFIG_CFG80211
5631 wlan_hdd_cfg80211_update_band(pHddCtx->wiphy, (eCsrBand)band);
5632#endif
5633 }
5634 return 0;
5635}
5636
5637static int iw_set_band_config(struct net_device *dev,
5638 struct iw_request_info *info,
5639 union iwreq_data *wrqu, char *extra)
5640{
5641 tANI_U8 *ptr = (tANI_U8*)wrqu->data.pointer;
5642 int ret = 0;
5643
5644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: ", __FUNCTION__);
5645
5646 if (memcmp(ptr, "SETBAND ", 8) == 0)
5647 {
5648 /* Change band request received */
5649 ret = hdd_setBand_helper(dev, ptr);
5650 return ret;
5651
5652 }
5653 return 0;
5654}
5655
5656static int iw_set_power_params_priv(struct net_device *dev,
5657 struct iw_request_info *info,
5658 union iwreq_data *wrqu, char *extra)
5659{
5660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5661 "Set power params Private");
5662 return iw_set_power_params(dev,info,wrqu,extra,0);
5663}
5664
5665
5666
5667/*string based input*/
5668VOS_STATUS iw_set_power_params(struct net_device *dev, struct iw_request_info *info,
5669 union iwreq_data *wrqu, char *extra, int nOffset)
5670{
5671 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5672 tSirSetPowerParamsReq powerRequest;
5673 char *ptr;
5674 v_U8_t ucType;
5675 v_U32_t uTotalSize, uValue;
5676 /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
5677
5678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5679 "Power Params data len %d data %s",
5680 wrqu->data.length,
5681 wrqu->data.pointer);
5682
5683 if (wrqu->data.length <= nOffset )
5684 {
5685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "set power param input is not correct");
5686 return VOS_STATUS_E_FAILURE;
5687 }
5688
5689 uTotalSize = wrqu->data.length - nOffset;
5690
5691 /*-----------------------------------------------------------------------
5692 Input is string based and expected to be like this:
5693
5694 <param_type> <param_value> <param_type> <param_value> ...
5695
5696 e.g:
5697 1 2 2 3 3 0 4 1 5 1
5698
5699 e.g. setting just a few:
5700 1 2 4 1
5701
5702 parameter types:
5703 -----------------------------
5704 1 - Ignore DTIM
5705 2 - Listen Interval
5706 3 - Broadcast Multicas Filter
5707 4 - Beacon Early Termination
5708 5 - Beacon Early Termination Interval
5709 -----------------------------------------------------------------------*/
5710 powerRequest.uIgnoreDTIM = SIR_NOCHANGE_POWER_VALUE;
5711 powerRequest.uListenInterval = SIR_NOCHANGE_POWER_VALUE;
5712 powerRequest.uBcastMcastFilter = SIR_NOCHANGE_POWER_VALUE;
5713 powerRequest.uEnableBET = SIR_NOCHANGE_POWER_VALUE;
5714 powerRequest.uBETInterval = SIR_NOCHANGE_POWER_VALUE;
5715
5716 ptr = (char*)(wrqu->data.pointer + nOffset);
5717
5718 while ( uTotalSize )
5719 {
5720 sscanf(ptr,"%hhu %n", &(ucType), &nOffset);
5721
5722 uTotalSize -= nOffset;
5723
5724 if (!uTotalSize)
5725 {
5726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5727 "Invalid input parametery type : %d with no value at offset %d",
5728 ucType, nOffset);
5729 return VOS_STATUS_E_FAILURE;
5730 }
5731
5732 ptr += nOffset;
5733 sscanf(ptr,"%lu %n", &(uValue), &nOffset);
5734
5735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5736 "Power request parameter %d value %d offset %d",
5737 ucType, uValue, nOffset);
5738
5739 switch (ucType)
5740 {
5741 case eSIR_IGNORE_DTIM:
5742 powerRequest.uIgnoreDTIM = uValue;
5743 break;
5744 case eSIR_LISTEN_INTERVAL:
5745 powerRequest.uListenInterval = uValue;
5746 break;
5747 case eSIR_MCAST_BCAST_FILTER:
5748 powerRequest.uBcastMcastFilter = uValue;
5749 break;
5750 case eSIR_ENABLE_BET:
5751 powerRequest.uEnableBET = uValue;
5752 break;
5753 case eSIR_BET_INTERVAL:
5754 powerRequest.uBETInterval = uValue;
5755 break;
5756 default:
5757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
5758 "Invalid input parametery type : %d with value: %d at offset %d",
5759 ucType, uValue, nOffset);
5760 return VOS_STATUS_E_FAILURE;
5761 }
5762
5763 uTotalSize -= nOffset;
Jeff Johnsone7245742012-09-05 17:12:55 -07005764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
5765 "Power request parameter %d Total size",
5766 uTotalSize);
Jeff Johnson295189b2012-06-20 16:38:30 -07005767 ptr += nOffset;
Jeff Johnsone7245742012-09-05 17:12:55 -07005768 /* This is added for dynamic Tele LI enable (0xF1) /disable (0xF0)*/
5769 if(!(uTotalSize - nOffset) &&
5770 (powerRequest.uListenInterval != SIR_NOCHANGE_POWER_VALUE))
5771 {
5772 uTotalSize = 0;
5773 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005774
5775 }/*Go for as long as we have a valid string*/
5776
5777 /* put the device into full power*/
5778 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_ACTIVE);
5779
5780 /* Apply the power save params*/
5781 sme_SetPowerParams( WLAN_HDD_GET_HAL_CTX(pAdapter), &powerRequest);
5782
5783 /* put the device back to power save*/
5784 wlan_hdd_enter_bmps(pAdapter, DRIVER_POWER_MODE_AUTO);
5785
5786 return VOS_STATUS_SUCCESS;
5787}/*iw_set_power_params*/
5788
5789
5790// Define the Wireless Extensions to the Linux Network Device structure
5791// A number of these routines are NULL (meaning they are not implemented.)
5792
5793static const iw_handler we_handler[] =
5794{
5795 (iw_handler) iw_set_commit, /* SIOCSIWCOMMIT */
5796 (iw_handler) iw_get_name, /* SIOCGIWNAME */
5797 (iw_handler) NULL, /* SIOCSIWNWID */
5798 (iw_handler) NULL, /* SIOCGIWNWID */
5799 (iw_handler) iw_set_freq, /* SIOCSIWFREQ */
5800 (iw_handler) iw_get_freq, /* SIOCGIWFREQ */
5801 (iw_handler) iw_set_mode, /* SIOCSIWMODE */
5802 (iw_handler) iw_get_mode, /* SIOCGIWMODE */
5803 (iw_handler) NULL, /* SIOCSIWSENS */
5804 (iw_handler) NULL, /* SIOCGIWSENS */
5805 (iw_handler) NULL, /* SIOCSIWRANGE */
5806 (iw_handler) iw_get_range, /* SIOCGIWRANGE */
5807 (iw_handler) iw_set_priv, /* SIOCSIWPRIV */
5808 (iw_handler) NULL, /* SIOCGIWPRIV */
5809 (iw_handler) NULL, /* SIOCSIWSTATS */
5810 (iw_handler) NULL, /* SIOCGIWSTATS */
5811 iw_handler_set_spy, /* SIOCSIWSPY */
5812 iw_handler_get_spy, /* SIOCGIWSPY */
5813 iw_handler_set_thrspy, /* SIOCSIWTHRSPY */
5814 iw_handler_get_thrspy, /* SIOCGIWTHRSPY */
5815 (iw_handler) iw_set_ap_address, /* SIOCSIWAP */
5816 (iw_handler) iw_get_ap_address, /* SIOCGIWAP */
5817 (iw_handler) iw_set_mlme, /* SIOCSIWMLME */
5818 (iw_handler) NULL, /* SIOCGIWAPLIST */
5819 (iw_handler) iw_set_scan, /* SIOCSIWSCAN */
5820 (iw_handler) iw_get_scan, /* SIOCGIWSCAN */
5821 (iw_handler) iw_set_essid, /* SIOCSIWESSID */
5822 (iw_handler) iw_get_essid, /* SIOCGIWESSID */
5823 (iw_handler) iw_set_nick, /* SIOCSIWNICKN */
5824 (iw_handler) iw_get_nick, /* SIOCGIWNICKN */
5825 (iw_handler) NULL, /* -- hole -- */
5826 (iw_handler) NULL, /* -- hole -- */
5827 (iw_handler) iw_set_bitrate, /* SIOCSIWRATE */
5828 (iw_handler) iw_get_bitrate, /* SIOCGIWRATE */
5829 (iw_handler) iw_set_rts_threshold,/* SIOCSIWRTS */
5830 (iw_handler) iw_get_rts_threshold,/* SIOCGIWRTS */
5831 (iw_handler) iw_set_frag_threshold, /* SIOCSIWFRAG */
5832 (iw_handler) iw_get_frag_threshold, /* SIOCGIWFRAG */
5833 (iw_handler) iw_set_tx_power, /* SIOCSIWTXPOW */
5834 (iw_handler) iw_get_tx_power, /* SIOCGIWTXPOW */
5835 (iw_handler) iw_set_retry, /* SIOCSIWRETRY */
5836 (iw_handler) iw_get_retry, /* SIOCGIWRETRY */
5837 (iw_handler) iw_set_encode, /* SIOCSIWENCODE */
5838 (iw_handler) iw_get_encode, /* SIOCGIWENCODE */
5839 (iw_handler) iw_set_power_mode, /* SIOCSIWPOWER */
5840 (iw_handler) iw_get_power_mode, /* SIOCGIWPOWER */
5841 (iw_handler) NULL, /* -- hole -- */
5842 (iw_handler) NULL, /* -- hole -- */
5843 (iw_handler) iw_set_genie, /* SIOCSIWGENIE */
5844 (iw_handler) iw_get_genie, /* SIOCGIWGENIE */
5845 (iw_handler) iw_set_auth, /* SIOCSIWAUTH */
5846 (iw_handler) iw_get_auth, /* SIOCGIWAUTH */
5847 (iw_handler) iw_set_encodeext, /* SIOCSIWENCODEEXT */
5848 (iw_handler) iw_get_encodeext, /* SIOCGIWENCODEEXT */
5849 (iw_handler) NULL, /* SIOCSIWPMKSA */
5850};
5851
5852static const iw_handler we_private[] = {
5853
5854 [WLAN_PRIV_SET_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_setint_getnone, //set priv ioctl
5855 [WLAN_PRIV_SET_NONE_GET_INT - SIOCIWFIRSTPRIV] = iw_setnone_getint, //get priv ioctl
5856 [WLAN_PRIV_SET_CHAR_GET_NONE - SIOCIWFIRSTPRIV] = iw_setchar_getnone, //get priv ioctl
5857 [WLAN_PRIV_SET_THREE_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_three_ints_getnone,
5858 [WLAN_PRIV_GET_CHAR_SET_NONE - SIOCIWFIRSTPRIV] = iw_get_char_setnone,
5859 [WLAN_PRIV_SET_NONE_GET_NONE - SIOCIWFIRSTPRIV] = iw_setnone_getnone, //action priv ioctl
5860 [WLAN_PRIV_SET_VAR_INT_GET_NONE - SIOCIWFIRSTPRIV] = iw_set_var_ints_getnone,
5861 [WLAN_PRIV_ADD_TSPEC - SIOCIWFIRSTPRIV] = iw_add_tspec,
5862 [WLAN_PRIV_DEL_TSPEC - SIOCIWFIRSTPRIV] = iw_del_tspec,
5863 [WLAN_PRIV_GET_TSPEC - SIOCIWFIRSTPRIV] = iw_get_tspec,
Jeff Johnsone7245742012-09-05 17:12:55 -07005864#ifdef FEATURE_OEM_DATA_SUPPORT
5865 [WLAN_PRIV_SET_OEM_DATA_REQ - SIOCIWFIRSTPRIV] = iw_set_oem_data_req, //oem data req Specifc
5866 [WLAN_PRIV_GET_OEM_DATA_RSP - SIOCIWFIRSTPRIV] = iw_get_oem_data_rsp, //oem data req Specifc
5867#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005868
5869#ifdef FEATURE_WLAN_WAPI
5870 [WLAN_PRIV_SET_WAPI_MODE - SIOCIWFIRSTPRIV] = iw_qcom_set_wapi_mode,
5871 [WLAN_PRIV_GET_WAPI_MODE - SIOCIWFIRSTPRIV] = iw_qcom_get_wapi_mode,
5872 [WLAN_PRIV_SET_WAPI_ASSOC_INFO - SIOCIWFIRSTPRIV] = iw_qcom_set_wapi_assoc_info,
5873 [WLAN_PRIV_SET_WAPI_KEY - SIOCIWFIRSTPRIV] = iw_qcom_set_wapi_key,
5874 [WLAN_PRIV_SET_WAPI_BKID - SIOCIWFIRSTPRIV] = iw_qcom_set_wapi_bkid,
5875 [WLAN_PRIV_GET_WAPI_BKID - SIOCIWFIRSTPRIV] = iw_qcom_get_wapi_bkid,
5876#endif /* FEATURE_WLAN_WAPI */
5877#ifdef WLAN_FEATURE_VOWIFI_11R
5878 [WLAN_PRIV_SET_FTIES - SIOCIWFIRSTPRIV] = iw_set_fties,
5879#endif
5880 [WLAN_PRIV_SET_HOST_OFFLOAD - SIOCIWFIRSTPRIV] = iw_set_host_offload,
5881 [WLAN_GET_WLAN_STATISTICS - SIOCIWFIRSTPRIV] = iw_get_statistics,
5882 [WLAN_SET_KEEPALIVE_PARAMS - SIOCIWFIRSTPRIV] = iw_set_keepalive_params
5883#ifdef WLAN_FEATURE_PACKET_FILTERING
5884 ,
5885 [WLAN_SET_PACKET_FILTER_PARAMS - SIOCIWFIRSTPRIV] = iw_set_packet_filter_params
5886#endif
5887#ifdef FEATURE_WLAN_SCAN_PNO
5888 ,
5889 [WLAN_SET_PNO - SIOCIWFIRSTPRIV] = iw_set_pno_priv
5890#endif
5891 ,
5892 [WLAN_SET_BAND_CONFIG - SIOCIWFIRSTPRIV] = iw_set_band_config,
5893 [WLAN_PRIV_SET_MCBC_FILTER - SIOCIWFIRSTPRIV] = iw_set_dynamic_mcbc_filter,
5894 [WLAN_PRIV_CLEAR_MCBC_FILTER - SIOCIWFIRSTPRIV] = iw_clear_dynamic_mcbc_filter,
5895 [WLAN_SET_POWER_PARAMS - SIOCIWFIRSTPRIV] = iw_set_power_params_priv,
5896 [WLAN_GET_LINK_SPEED - SIOCIWFIRSTPRIV] = iw_get_linkspeed
5897};
5898
5899/*Maximum command length can be only 15 */
5900static const struct iw_priv_args we_private_args[] = {
5901
5902 /* handlers for main ioctl */
5903 { WLAN_PRIV_SET_INT_GET_NONE,
5904 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5905 0,
5906 "" },
5907
5908 /* handlers for sub-ioctl */
5909 { WE_SET_11D_STATE,
5910 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5911 0,
5912 "set11Dstate" },
5913
5914 { WE_WOWL,
5915 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5916 0,
5917 "wowl" },
5918
5919 { WE_SET_POWER,
5920 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5921 0,
5922 "setPower" },
5923
5924 { WE_SET_MAX_ASSOC,
5925 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5926 0,
5927 "setMaxAssoc" },
5928
5929 { WE_SET_SAP_AUTO_CHANNEL_SELECTION,
5930 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5931 0,
5932 "setAutoChannel" },
5933
5934 { WE_SET_DATA_INACTIVITY_TO,
5935 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5936 0,
5937 "inactivityTO" },
5938
5939 { WE_SET_MAX_TX_POWER,
5940 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5941 0,
5942 "setMaxTxPower" },
5943 /* set Higher DTIM Transition (DTIM1 to DTIM3)
5944 * 1 = enable and 0 = disable */
5945 {
5946 WE_SET_HIGHER_DTIM_TRANSITION,
5947 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5948 0,
5949 "setHDtimTransn" },
5950
5951 { WE_SET_TM_LEVEL,
5952 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5953 0,
5954 "setTmLevel" },
5955
5956 /* handlers for main ioctl */
5957 { WLAN_PRIV_SET_NONE_GET_INT,
5958 0,
5959 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5960 "" },
5961
5962 /* handlers for sub-ioctl */
5963 { WE_GET_11D_STATE,
5964 0,
5965 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5966 "get11Dstate" },
5967
5968 { WE_IBSS_STATUS,
5969 0,
5970 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5971 "getAdhocStatus" },
5972
5973 { WE_PMC_STATE,
5974 0,
5975 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5976 "pmcState" },
5977
5978 { WE_GET_WLAN_DBG,
5979 0,
5980 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5981 "getwlandbg" },
5982
5983 { WE_MODULE_DOWN_IND,
5984 0,
5985 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5986 "moduleDownInd" },
5987
5988 { WE_GET_MAX_ASSOC,
5989 0,
5990 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5991 "getMaxAssoc" },
5992
5993#ifdef FEATURE_WLAN_INTEGRATED_SOC
5994 { WE_GET_WDI_DBG,
5995 0,
5996 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
5997 "getwdidbg" },
5998#endif // FEATURE_WLAN_INTEGRATED_SOC
5999
6000 { WE_GET_SAP_AUTO_CHANNEL_SELECTION,
6001 0,
6002 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6003 "getAutoChannel" },
6004
6005 { WE_GET_CONCURRENCY_MODE,
6006 0,
6007 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6008 "getconcurrency" },
6009
6010 /* handlers for main ioctl */
6011 { WLAN_PRIV_SET_CHAR_GET_NONE,
6012 IW_PRIV_TYPE_CHAR| 512,
6013 0,
6014 "" },
6015
6016 /* handlers for sub-ioctl */
6017 { WE_WOWL_ADD_PTRN,
6018 IW_PRIV_TYPE_CHAR| 512,
6019 0,
6020 "wowlAddPtrn" },
6021
6022 { WE_WOWL_DEL_PTRN,
6023 IW_PRIV_TYPE_CHAR| 512,
6024 0,
6025 "wowlDelPtrn" },
6026
6027#if defined WLAN_FEATURE_VOWIFI
6028 /* handlers for sub-ioctl */
6029 { WE_NEIGHBOR_REPORT_REQUEST,
6030 IW_PRIV_TYPE_CHAR | 512,
6031 0,
6032 "neighbor" },
6033#endif
6034 { WE_SET_AP_WPS_IE,
6035 IW_PRIV_TYPE_CHAR| 512,
6036 0,
6037 "set_ap_wps_ie" },
6038
6039 { WE_SET_CONFIG,
6040 IW_PRIV_TYPE_CHAR| 512,
6041 0,
6042 "setConfig" },
6043
6044 /* handlers for main ioctl */
6045 { WLAN_PRIV_SET_THREE_INT_GET_NONE,
6046 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
6047 0,
6048 "" },
6049
6050 /* handlers for sub-ioctl */
6051 { WE_SET_WLAN_DBG,
6052 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
6053 0,
6054 "setwlandbg" },
6055
6056#ifdef FEATURE_WLAN_INTEGRATED_SOC
6057 { WE_SET_WDI_DBG,
6058 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
6059 0,
6060 "setwdidbg" },
6061#endif // FEATURE_WLAN_INTEGRATED_SOC
6062
6063 { WE_SET_SAP_CHANNELS,
6064 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3,
6065 0,
6066 "setsapchannels" },
6067
6068 /* handlers for main ioctl */
6069 { WLAN_PRIV_GET_CHAR_SET_NONE,
6070 0,
6071 IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
6072 "" },
6073
6074 /* handlers for sub-ioctl */
6075 { WE_WLAN_VERSION,
6076 0,
6077 IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
6078 "version" },
6079 { WE_GET_STATS,
6080 0,
6081 IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
6082 "getStats" },
6083 { WE_GET_CFG,
6084 0,
6085 IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
6086 "getConfig" },
Jeff Johnsone7245742012-09-05 17:12:55 -07006087#ifdef WLAN_FEATURE_11AC
6088 { WE_GET_RSSI,
6089 0,
6090 IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
6091 "getRSSI" },
6092#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006093 { WE_GET_WMM_STATUS,
6094 0,
6095 IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
6096 "getWmmStatus" },
6097 {
6098 WE_GET_CHANNEL_LIST,
6099 0,
6100 IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
6101 "getChannelList" },
6102
6103 /* handlers for main ioctl */
6104 { WLAN_PRIV_SET_NONE_GET_NONE,
6105 0,
6106 0,
6107 "" },
6108
6109 /* handlers for sub-ioctl */
6110 { WE_CLEAR_STATS,
6111 0,
6112 0,
6113 "clearStats" },
6114 { WE_INIT_AP,
6115 0,
6116 0,
6117 "initAP" },
6118 { WE_STOP_AP,
6119 0,
6120 0,
6121 "exitAP" },
6122 { WE_ENABLE_AMP,
6123 0,
6124 0,
6125 "enableAMP" },
6126 { WE_DISABLE_AMP,
6127 0,
6128 0,
6129 "disableAMP" },
Madan Mohan Koyyalamudi8cb53982012-09-28 14:34:47 -07006130 { WE_ENABLE_DXE_STALL_DETECT,
6131 0,
6132 0,
6133 "dxeStallDetect" },
6134 { WE_DISPLAY_DXE_SNAP_SHOT,
6135 0,
6136 0,
6137 "dxeSnapshot" },
Jeff Johnson295189b2012-06-20 16:38:30 -07006138
6139 /* handlers for main ioctl */
6140 { WLAN_PRIV_SET_VAR_INT_GET_NONE,
6141 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
6142 0,
6143 "" },
6144
6145 /* handlers for sub-ioctl */
6146 { WE_LOG_DUMP_CMD,
6147 IW_PRIV_TYPE_INT | MAX_VAR_ARGS,
6148 0,
6149 "dump" },
6150
6151 /* handlers for main ioctl */
6152 { WLAN_PRIV_ADD_TSPEC,
6153 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | HDD_WLAN_WMM_PARAM_COUNT,
6154 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6155 "addTspec" },
6156
6157 /* handlers for main ioctl */
6158 { WLAN_PRIV_DEL_TSPEC,
6159 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6160 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6161 "delTspec" },
6162
6163 /* handlers for main ioctl */
6164 { WLAN_PRIV_GET_TSPEC,
6165 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6166 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6167 "getTspec" },
6168
Jeff Johnsone7245742012-09-05 17:12:55 -07006169#ifdef FEATURE_OEM_DATA_SUPPORT
6170 /* handlers for main ioctl - OEM DATA */
6171 {
6172 WLAN_PRIV_SET_OEM_DATA_REQ,
6173 IW_PRIV_TYPE_BYTE | sizeof(struct iw_oem_data_req) | IW_PRIV_SIZE_FIXED,
6174 0,
6175 "set_oem_data_req" },
6176
6177 /* handlers for main ioctl - OEM DATA */
6178 {
6179 WLAN_PRIV_GET_OEM_DATA_RSP,
6180 0,
6181 IW_PRIV_TYPE_BYTE | MAX_OEM_DATA_RSP_LEN,
6182 "get_oem_data_rsp" },
6183#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006184
6185#ifdef FEATURE_WLAN_WAPI
6186 /* handlers for main ioctl SET_WAPI_MODE */
6187 { WLAN_PRIV_SET_WAPI_MODE,
6188 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6189 0,
6190 "SET_WAPI_MODE" },
6191
6192 /* handlers for main ioctl GET_WAPI_MODE */
6193 { WLAN_PRIV_GET_WAPI_MODE,
6194 0,
6195 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
6196 "GET_WAPI_MODE" },
6197
6198 /* handlers for main ioctl SET_ASSOC_INFO */
6199 { WLAN_PRIV_SET_WAPI_ASSOC_INFO,
6200 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 400,
6201 0,
6202 "SET_WAPI_ASSOC" },
6203
6204 /* handlers for main ioctl SET_WAPI_KEY */
6205 { WLAN_PRIV_SET_WAPI_KEY,
6206 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 71,
6207 0,
6208 "SET_WAPI_KEY" },
6209
6210 /* handlers for main ioctl SET_WAPI_BKID */
6211 { WLAN_PRIV_SET_WAPI_BKID,
6212 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 24,
6213 0,
6214 "SET_WAPI_BKID" },
6215
6216 /* handlers for main ioctl GET_WAPI_BKID */
6217 { WLAN_PRIV_GET_WAPI_BKID,
6218 0,
6219 IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 24,
6220 "GET_WAPI_BKID" },
6221#endif /* FEATURE_WLAN_WAPI */
6222
6223 /* handlers for main ioctl - host offload */
6224 {
6225 WLAN_PRIV_SET_HOST_OFFLOAD,
6226 IW_PRIV_TYPE_BYTE | sizeof(tHostOffloadRequest),
6227 0,
6228 "setHostOffload" },
6229
6230 {
6231 WLAN_GET_WLAN_STATISTICS,
6232 0,
6233 IW_PRIV_TYPE_BYTE | WE_MAX_STR_LEN,
6234 "getWlanStats" },
6235
6236 {
6237 WLAN_SET_KEEPALIVE_PARAMS,
6238 IW_PRIV_TYPE_BYTE | sizeof(tKeepAliveRequest),
6239 0,
6240 "setKeepAlive" },
6241#ifdef WLAN_FEATURE_PACKET_FILTERING
6242 {
6243 WLAN_SET_PACKET_FILTER_PARAMS,
6244 IW_PRIV_TYPE_BYTE | sizeof(tPacketFilterCfg),
6245 0,
6246 "setPktFilter" },
6247#endif
6248#ifdef FEATURE_WLAN_SCAN_PNO
6249 {
6250 WLAN_SET_PNO,
6251 IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
6252 0,
6253 "setpno" },
6254#endif
6255 {
6256 WLAN_SET_BAND_CONFIG,
6257 IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
6258 0,
6259 "SETBAND" },
6260 /* handlers for dynamic MC BC ioctl */
6261 {
6262 WLAN_PRIV_SET_MCBC_FILTER,
6263 IW_PRIV_TYPE_BYTE | sizeof(tMcBcFilterCfg),
6264 0,
6265 "setMCBCFilter" },
6266 {
6267 WLAN_PRIV_CLEAR_MCBC_FILTER,
6268 0,
6269 0,
6270 "clearMCBCFilter" },
6271 {
6272 WLAN_SET_POWER_PARAMS,
6273 IW_PRIV_TYPE_CHAR| WE_MAX_STR_LEN,
6274 0,
6275 "setpowerparams" },
6276 {
6277 WLAN_GET_LINK_SPEED,
6278 IW_PRIV_TYPE_CHAR | 18,
6279 IW_PRIV_TYPE_CHAR | 3, "getLinkSpeed" },
6280};
6281
6282
6283
6284const struct iw_handler_def we_handler_def = {
6285 .num_standard = sizeof(we_handler) / sizeof(we_handler[0]),
6286 .num_private = sizeof(we_private) / sizeof(we_private[0]),
6287 .num_private_args = sizeof(we_private_args) / sizeof(we_private_args[0]),
6288
6289 .standard = (iw_handler *)we_handler,
6290 .private = (iw_handler *)we_private,
6291 .private_args = we_private_args,
6292 .get_wireless_stats = get_wireless_stats,
6293};
6294
6295int hdd_set_wext(hdd_adapter_t *pAdapter)
6296{
6297 hdd_wext_state_t *pwextBuf;
6298 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006299 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006300
6301 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6302
6303 // Now configure the roaming profile links. To SSID and bssid.
6304 pwextBuf->roamProfile.SSIDs.numOfSSIDs = 0;
6305 pwextBuf->roamProfile.SSIDs.SSIDList = &pHddStaCtx->conn_info.SSID;
6306
6307 pwextBuf->roamProfile.BSSIDs.numOfBSSIDs = 0;
6308 pwextBuf->roamProfile.BSSIDs.bssid = &pHddStaCtx->conn_info.bssId;
6309
6310 /*Set the numOfChannels to zero to scan all the channels*/
6311 pwextBuf->roamProfile.ChannelInfo.numOfChannels = 0;
6312 pwextBuf->roamProfile.ChannelInfo.ChannelList = NULL;
6313
6314 /* Default is no encryption */
6315 pwextBuf->roamProfile.EncryptionType.numEntries = 1;
6316 pwextBuf->roamProfile.EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
6317
6318 pwextBuf->roamProfile.mcEncryptionType.numEntries = 1;
6319 pwextBuf->roamProfile.mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_NONE;
6320
6321 pwextBuf->roamProfile.BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
6322
6323 /* Default is no authentication */
6324 pwextBuf->roamProfile.AuthType.numEntries = 1;
6325 pwextBuf->roamProfile.AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM;
6326
6327 pwextBuf->roamProfile.phyMode = eCSR_DOT11_MODE_TAURUS;
6328 pwextBuf->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6329
6330 /*Set the default scan mode*/
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07006331 pHddCtx->scan_info.scan_mode = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -07006332
6333 hdd_clearRoamProfileIe(pAdapter);
6334
6335 return VOS_STATUS_SUCCESS;
6336
6337 }
6338
6339int hdd_register_wext(struct net_device *dev)
6340 {
6341 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6342 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6343 VOS_STATUS status;
6344
6345 ENTER();
6346
6347 // Zero the memory. This zeros the profile structure.
6348 memset(pwextBuf, 0,sizeof(hdd_wext_state_t));
6349
6350 init_completion(&(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->completion_var);
6351
6352
6353 status = hdd_set_wext(pAdapter);
6354
6355 if(!VOS_IS_STATUS_SUCCESS(status)) {
6356
6357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: hdd_set_wext failed!!\n"));
6358 return eHAL_STATUS_FAILURE;
6359 }
6360
6361 if (!VOS_IS_STATUS_SUCCESS(vos_event_init(&pwextBuf->vosevent)))
6362 {
6363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD vos event init failed!!\n"));
6364 return eHAL_STATUS_FAILURE;
6365 }
6366
6367 if (!VOS_IS_STATUS_SUCCESS(vos_event_init(&pwextBuf->scanevent)))
6368 {
6369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, ("ERROR: HDD scan event init failed!!\n"));
6370 return eHAL_STATUS_FAILURE;
6371 }
6372
6373 // Register as a wireless device
6374 dev->wireless_handlers = (struct iw_handler_def *)&we_handler_def;
6375
6376 EXIT();
6377 return 0;
6378}
6379
6380int hdd_UnregisterWext(struct net_device *dev)
6381{
6382#if 0
6383 hdd_wext_state_t *wextBuf;
6384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6385
6386 ENTER();
6387 // Set up the pointer to the Wireless Extensions state structure
6388 wextBuf = pAdapter->pWextState;
6389
6390 // De-allocate the Wireless Extensions state structure
6391 kfree(wextBuf);
6392
6393 // Clear out the pointer to the Wireless Extensions state structure
6394 pAdapter->pWextState = NULL;
6395
6396 EXIT();
6397#endif
6398 dev->wireless_handlers = NULL;
6399 return 0;
6400}
6401
6402