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