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