import PULS_20180308
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / connectivity / conn_soc / drv_wlan / mt_wifi / wlan / os / linux / gl_cfg80211.c
1 /*
2 ** $Id: @(#) gl_cfg80211.c@@
3 */
4
5 /*! \file gl_cfg80211.c
6 \brief Main routines for supporintg MT6620 cfg80211 control interface
7
8 This file contains the support routines of Linux driver for MediaTek Inc. 802.11
9 Wireless LAN Adapters.
10 */
11
12
13
14 /*
15 ** $Log: gl_cfg80211.c $
16 **
17 ** 09 05 2013 cp.wu
18 ** correct length to pass to wlanoidSetBssid()
19 **
20 ** 09 04 2013 cp.wu
21 ** fix typo
22 **
23 ** 09 03 2013 cp.wu
24 ** add path for reassociation
25 **
26 ** 11 23 2012 yuche.tsai
27 ** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely
28 ** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed..
29 **
30 ** 09 12 2012 wcpadmin
31 ** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages
32 ** .
33 **
34 ** 08 30 2012 chinglan.wang
35 ** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only
36 ** .
37 *
38 **
39 */
40
41 /*******************************************************************************
42 * C O M P I L E R F L A G S
43 ********************************************************************************
44 */
45
46 /*******************************************************************************
47 * E X T E R N A L R E F E R E N C E S
48 ********************************************************************************
49 */
50 #include "gl_os.h"
51 #include "debug.h"
52 #include "wlan_lib.h"
53 #include "gl_wext.h"
54 #include "precomp.h"
55 #include <linux/can/netlink.h>
56 #include <net/netlink.h>
57 #include <net/cfg80211.h>
58 #include "gl_cfg80211.h"
59
60 /*******************************************************************************
61 * C O N S T A N T S
62 ********************************************************************************
63 */
64
65 /*******************************************************************************
66 * D A T A T Y P E S
67 ********************************************************************************
68 */
69
70 /*******************************************************************************
71 * P U B L I C D A T A
72 ********************************************************************************
73 */
74
75 #if CFG_SUPPORT_WAPI
76 extern UINT_8 keyStructBuf[1024]; /* add/remove key shared buffer */
77 #else
78 extern UINT_8 keyStructBuf[100]; /* add/remove key shared buffer */
79 #endif
80 /* workaround for some ANR CRs. if suppliant is blocked longer than 10s, wifi hal will tell wifiMonitor
81 to teminate. for the case which can block supplicant 10s is to del key more than 5 times. the root cause
82 is that there is no resource in TC4, so del key command was not able to set, and then oid
83 timeout was happed. if we found the root cause why fw couldn't release TC resouce, we will remove this
84 workaround */
85 static UINT_8 gucKeyIndex = 255;
86
87 /*******************************************************************************
88 * P R I V A T E D A T A
89 ********************************************************************************
90 */
91
92 /*******************************************************************************
93 * M A C R O S
94 ********************************************************************************
95 */
96
97 /*******************************************************************************
98 * F U N C T I O N D E C L A R A T I O N S
99 ********************************************************************************
100 */
101 extern void wlanHandleSystemResume(void);
102 extern void wlanHandleSystemSuspend(void);
103 extern void p2pHandleSystemResume(void);
104 extern void p2pHandleSystemSuspend(void);
105
106 /*******************************************************************************
107 * F U N C T I O N S
108 ********************************************************************************
109 */
110
111 /*----------------------------------------------------------------------------*/
112 /*!
113 * @brief This routine is responsible for change STA type between
114 * 1. Infrastructure Client (Non-AP STA)
115 * 2. Ad-Hoc IBSS
116 *
117 * @param
118 *
119 * @retval 0: successful
120 * others: failure
121 */
122 /*----------------------------------------------------------------------------*/
123 int
124 mtk_cfg80211_change_iface (
125 struct wiphy *wiphy,
126 struct net_device *ndev,
127 enum nl80211_iftype type,
128 u32 *flags,
129 struct vif_params *params
130 )
131 {
132 P_GLUE_INFO_T prGlueInfo = NULL;
133 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
134 ENUM_PARAM_OP_MODE_T eOpMode;
135 UINT_32 u4BufLen;
136
137 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
138 ASSERT(prGlueInfo);
139
140 if(type == NL80211_IFTYPE_STATION) {
141 eOpMode = NET_TYPE_INFRA;
142 }
143 else if(type == NL80211_IFTYPE_ADHOC) {
144 eOpMode = NET_TYPE_IBSS;
145 }
146 else {
147 return -EINVAL;
148 }
149
150 rStatus = kalIoctl(prGlueInfo,
151 wlanoidSetInfrastructureMode,
152 &eOpMode,
153 sizeof(eOpMode),
154 FALSE,
155 FALSE,
156 TRUE,
157 FALSE,
158 &u4BufLen);
159
160 if (rStatus != WLAN_STATUS_SUCCESS) {
161 DBGLOG(REQ, WARN, ("set infrastructure mode error:%x\n", rStatus));
162 }
163
164 /* reset wpa info */
165 prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
166 prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
167 prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
168 prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
169 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
170 #if CFG_SUPPORT_802_11W
171 prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
172 #endif
173
174 return 0;
175 }
176
177
178 /*----------------------------------------------------------------------------*/
179 /*!
180 * @brief This routine is responsible for adding key
181 *
182 * @param
183 *
184 * @retval 0: successful
185 * others: failure
186 */
187 /*----------------------------------------------------------------------------*/
188 int
189 mtk_cfg80211_add_key (
190 struct wiphy *wiphy,
191 struct net_device *ndev,
192 u8 key_index,
193 bool pairwise,
194 const u8 *mac_addr,
195 struct key_params *params
196 )
197 {
198 PARAM_KEY_T rKey;
199 P_GLUE_INFO_T prGlueInfo = NULL;
200 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
201 INT_32 i4Rslt = -EINVAL;
202 UINT_32 u4BufLen = 0;
203 UINT_8 tmp1[8];
204 UINT_8 tmp2[8];
205
206 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
207 ASSERT(prGlueInfo);
208
209 kalMemZero(&rKey, sizeof(PARAM_KEY_T));
210
211 rKey.u4KeyIndex = key_index;
212
213 if(mac_addr) {
214 COPY_MAC_ADDR(rKey.arBSSID, mac_addr);
215 if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) &&
216 (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) {
217 rKey.arBSSID[0] = 0xff;
218 rKey.arBSSID[1] = 0xff;
219 rKey.arBSSID[2] = 0xff;
220 rKey.arBSSID[3] = 0xff;
221 rKey.arBSSID[4] = 0xff;
222 rKey.arBSSID[5] = 0xff;
223 }
224 if (rKey.arBSSID[0] != 0xFF) {
225 rKey.u4KeyIndex |= BIT(31);
226 if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) ||
227 (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00))
228 rKey.u4KeyIndex |= BIT(30);
229 }
230 }
231 else {
232 rKey.arBSSID[0] = 0xff;
233 rKey.arBSSID[1] = 0xff;
234 rKey.arBSSID[2] = 0xff;
235 rKey.arBSSID[3] = 0xff;
236 rKey.arBSSID[4] = 0xff;
237 rKey.arBSSID[5] = 0xff;
238 //rKey.u4KeyIndex |= BIT(31); //Enable BIT 31 will make tx use bc key id, should use pairwise key id 0
239 }
240
241 if(params->key) {
242 //rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE);
243 kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len);
244 if (params->key_len == 32) {
245 kalMemCopy(tmp1, &params->key[16], 8);
246 kalMemCopy(tmp2, &params->key[24], 8);
247 kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8);
248 kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8);
249 }
250 }
251
252 rKey.u4KeyLength = params->key_len;
253 rKey.u4Length = ((ULONG)&(((P_P2P_PARAM_KEY_T)0)->aucKeyMaterial)) + rKey.u4KeyLength;
254
255 rStatus = kalIoctl(prGlueInfo,
256 wlanoidSetAddKey,
257 &rKey,
258 rKey.u4Length,
259 FALSE,
260 FALSE,
261 TRUE,
262 FALSE,
263 &u4BufLen);
264
265 if (rStatus == WLAN_STATUS_SUCCESS)
266 i4Rslt = 0;
267
268 return i4Rslt;
269 }
270
271
272 /*----------------------------------------------------------------------------*/
273 /*!
274 * @brief This routine is responsible for getting key for specified STA
275 *
276 * @param
277 *
278 * @retval 0: successful
279 * others: failure
280 */
281 /*----------------------------------------------------------------------------*/
282 int
283 mtk_cfg80211_get_key (
284 struct wiphy *wiphy,
285 struct net_device *ndev,
286 u8 key_index,
287 bool pairwise,
288 const u8 *mac_addr,
289 void *cookie,
290 void (*callback)(void *cookie, struct key_params*)
291 )
292 {
293 P_GLUE_INFO_T prGlueInfo = NULL;
294
295 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
296 ASSERT(prGlueInfo);
297
298 #if 1
299 printk("--> %s()\n", __func__);
300 #endif
301
302 /* not implemented */
303
304 return -EINVAL;
305 }
306
307
308 /*----------------------------------------------------------------------------*/
309 /*!
310 * @brief This routine is responsible for removing key for specified STA
311 *
312 * @param
313 *
314 * @retval 0: successful
315 * others: failure
316 */
317 /*----------------------------------------------------------------------------*/
318 int
319 mtk_cfg80211_del_key (
320 struct wiphy *wiphy,
321 struct net_device *ndev,
322 u8 key_index,
323 bool pairwise,
324 const u8 *mac_addr
325 )
326 {
327 P_GLUE_INFO_T prGlueInfo = NULL;
328 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
329 PARAM_REMOVE_KEY_T rRemoveKey;
330 UINT_32 u4BufLen = 0;
331 INT_32 i4Rslt = -EINVAL;
332
333 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
334 ASSERT(prGlueInfo);
335
336 kalMemZero(&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T));
337 if(mac_addr)
338 COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr);
339 else if (key_index > gucKeyIndex) {/* bypass the next remove key operation */
340 gucKeyIndex = key_index;
341 return -EBUSY;
342 }
343 else /* new operation, reset gucKeyIndex */
344 gucKeyIndex = 255;
345 rRemoveKey.u4KeyIndex = key_index;
346 rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T);
347
348
349 rStatus = kalIoctl(prGlueInfo,
350 wlanoidSetRemoveKey,
351 &rRemoveKey,
352 rRemoveKey.u4Length,
353 FALSE,
354 FALSE,
355 TRUE,
356 FALSE,
357 &u4BufLen);
358
359 if (rStatus != WLAN_STATUS_SUCCESS) {
360 DBGLOG(REQ, WARN, ("remove key error:%x\n", rStatus));
361 if (WLAN_STATUS_FAILURE == rStatus && mac_addr) {
362 i4Rslt = -EBUSY;
363 gucKeyIndex = key_index;
364 }
365 }
366 else {
367 gucKeyIndex = 255;
368 i4Rslt = 0;
369 }
370
371 return i4Rslt;
372 }
373
374
375 /*----------------------------------------------------------------------------*/
376 /*!
377 * @brief This routine is responsible for setting default key on an interface
378 *
379 * @param
380 *
381 * @retval 0: successful
382 * others: failure
383 */
384 /*----------------------------------------------------------------------------*/
385 int
386 mtk_cfg80211_set_default_key (
387 struct wiphy *wiphy,
388 struct net_device *ndev,
389 u8 key_index,
390 bool unicast,
391 bool multicast
392 )
393 {
394 P_GLUE_INFO_T prGlueInfo = NULL;
395
396 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
397 ASSERT(prGlueInfo);
398
399 #if 1
400 printk("--> %s()\n", __func__);
401 #endif
402
403 /* not implemented */
404
405 return WLAN_STATUS_SUCCESS;
406 }
407
408
409 /*----------------------------------------------------------------------------*/
410 /*!
411 * @brief This routine is responsible for setting set_default_mgmt_ke on an interface
412 *
413 * @param
414 *
415 * @retval 0: successful
416 * others: failure
417 */
418 /*----------------------------------------------------------------------------*/
419 int
420 mtk_cfg80211_set_default_mgmt_key(
421 struct wiphy *wiphy,
422 struct net_device *netdev,
423 u8 key_index
424 )
425 {
426 return 0;
427 }
428
429
430 /*----------------------------------------------------------------------------*/
431 /*!
432 * @brief This routine is responsible for getting station information such as RSSI
433 *
434 * @param
435 *
436 * @retval 0: successful
437 * others: failure
438 */
439 /*----------------------------------------------------------------------------*/
440
441 int
442 mtk_cfg80211_get_station (
443 struct wiphy *wiphy,
444 struct net_device *ndev,
445 u8 *mac,
446 struct station_info *sinfo
447 )
448 {
449 P_GLUE_INFO_T prGlueInfo = NULL;
450 WLAN_STATUS rStatus;
451 PARAM_MAC_ADDRESS arBssid;
452 UINT_32 u4BufLen, u4Rate;
453 UINT_32 u8diffTxBad,u8diffRetry;
454 INT_32 i4Rssi;
455 PARAM_802_11_STATISTICS_STRUCT_T rStatistics;
456
457 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
458 ASSERT(prGlueInfo);
459
460 kalMemZero(arBssid, MAC_ADDR_LEN);
461 wlanQueryInformation(prGlueInfo->prAdapter,
462 wlanoidQueryBssid,
463 &arBssid[0],
464 sizeof(arBssid),
465 &u4BufLen);
466
467 /* 1. check BSSID */
468 if(UNEQUAL_MAC_ADDR(arBssid, mac)) {
469 /* wrong MAC address */
470 DBGLOG(REQ, WARN, ("incorrect BSSID: ["MACSTR"] currently connected BSSID["MACSTR"]\n",
471 MAC2STR(mac), MAC2STR(arBssid)));
472 return -ENOENT;
473 }
474
475 /* 2. fill TX rate */
476 rStatus = kalIoctl(prGlueInfo,
477 wlanoidQueryLinkSpeed,
478 &u4Rate,
479 sizeof(u4Rate),
480 TRUE,
481 FALSE,
482 FALSE,
483 FALSE,
484 &u4BufLen);
485
486 if (rStatus != WLAN_STATUS_SUCCESS) {
487 DBGLOG(REQ, WARN, ("unable to retrieve link speed\n"));
488 }
489 else {
490 sinfo->filled |= STATION_INFO_TX_BITRATE;
491 sinfo->txrate.legacy = u4Rate / 1000; /* convert from 100bps to 100kbps */
492 }
493
494 if(prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) {
495 /* not connected */
496 DBGLOG(REQ, WARN, ("not yet connected\n"));
497 }
498 else {
499 /* 3. fill RSSI */
500 rStatus = kalIoctl(prGlueInfo,
501 wlanoidQueryRssi,
502 &i4Rssi,
503 sizeof(i4Rssi),
504 TRUE,
505 FALSE,
506 FALSE,
507 FALSE,
508 &u4BufLen);
509
510 if (rStatus != WLAN_STATUS_SUCCESS) {
511 DBGLOG(REQ, WARN, ("unable to retrieve link speed\n"));
512 }
513 else {
514 sinfo->filled |= STATION_INFO_SIGNAL;
515 //in the cfg80211 layer, the signal is a signed char variable.
516 if(i4Rssi < -128)
517 sinfo->signal = -128;
518 else
519 sinfo->signal = i4Rssi; /* dBm */
520 }
521 sinfo->rx_packets = prGlueInfo->rNetDevStats.rx_packets;
522
523 /* 4. Fill Tx OK and Tx Bad */
524
525 sinfo->filled |= STATION_INFO_TX_PACKETS;
526 sinfo->filled |= STATION_INFO_TX_FAILED;
527 {
528 WLAN_STATUS rStatus;
529 kalMemZero(&rStatistics, sizeof(rStatistics));
530 /* Get Tx OK/Fail cnt from AIS statistic counter */
531 rStatus = kalIoctl(prGlueInfo,
532 wlanoidQueryStatisticsPL,
533 &rStatistics,
534 sizeof(rStatistics),
535 TRUE,
536 TRUE,
537 TRUE,
538 FALSE,
539 &u4BufLen);
540
541 if (rStatus != WLAN_STATUS_SUCCESS) {
542 DBGLOG(REQ, WARN, ("unable to retrieive statistic\n"));
543 printk("unable to retrieve statics");
544 }
545 else {
546 INT_32 i4RssiThreshold = -85; /* set rssi threshold -85dBm */
547 UINT_32 u4LinkspeedThreshold = 55; /* set link speed threshold 5.5Mbps */
548 BOOLEAN fgWeighted = 0;
549
550 /* calculate difference */
551 u8diffTxBad = rStatistics.rFailedCount.QuadPart - prGlueInfo->u8Statistic[0];
552 u8diffRetry = rStatistics.rRetryCount.QuadPart - prGlueInfo->u8Statistic[1];
553 /* restore counters */
554 prGlueInfo->u8Statistic[0] = rStatistics.rFailedCount.QuadPart;
555 prGlueInfo->u8Statistic[1] = rStatistics.rRetryCount.QuadPart;
556
557 /* check threshold is valid */
558 if(prGlueInfo->fgPoorlinkValid){
559 if(prGlueInfo->i4RssiThreshold)
560 i4RssiThreshold = prGlueInfo->i4RssiThreshold;
561 if(prGlueInfo->u4LinkspeedThreshold)
562 u4LinkspeedThreshold = prGlueInfo->u4LinkspeedThreshold;
563 }
564 /* add weighted to fail counter */
565 if(sinfo->txrate.legacy < u4LinkspeedThreshold || sinfo->signal < i4RssiThreshold ){
566 prGlueInfo->u8TotalFailCnt += (u8diffTxBad*16 + u8diffRetry);
567 fgWeighted = 1;
568 }else{
569 prGlueInfo->u8TotalFailCnt += u8diffTxBad;
570 }
571 /* report counters */
572 prGlueInfo->rNetDevStats.tx_packets = rStatistics.rTransmittedFragmentCount.QuadPart ;
573 prGlueInfo->rNetDevStats.tx_errors = prGlueInfo->u8TotalFailCnt;
574
575 sinfo->tx_packets = prGlueInfo->rNetDevStats.tx_packets;
576 sinfo->tx_failed = prGlueInfo->rNetDevStats.tx_errors;
577
578 printk("poorlink get state G(%d)F(%d)dbad(%d)dretry(%d)LT(%d)RT(%d)W(%d)(%d)\n",
579 sinfo->tx_packets,
580 sinfo->tx_failed,
581 (int)u8diffTxBad,
582 (int)u8diffRetry,
583 sinfo->txrate.legacy,
584 sinfo->signal,
585 (int)fgWeighted,
586 (int)rStatistics.rMultipleRetryCount.QuadPart);
587 }
588 }
589
590 }
591 return 0;
592 }
593
594
595 /*----------------------------------------------------------------------------*/
596 /*!
597 * @brief This routine is responsible for adding a station information
598 *
599 * @param
600 *
601 * @retval 0: successful
602 * others: failure
603 */
604 /*----------------------------------------------------------------------------*/
605 int
606 mtk_cfg80211_change_station (
607 struct wiphy *wiphy,
608 struct net_device *ndev,
609 u8 *mac,
610 struct station_parameters *params
611 )
612 {
613 #if (CFG_SUPPORT_TDLS == 1)
614 /*
615 EX: In supplicant,
616 (Supplicant) wpa_tdls_process_tpk_m3() ->
617 (Supplicant) wpa_tdls_enable_link() ->
618 (Supplicant) wpa_sm_tdls_peer_addset() ->
619 (Supplicant) ..tdls_peer_addset() ->
620 (Supplicant) wpa_supplicant_tdls_peer_addset() ->
621 (Supplicant) wpa_drv_sta_add() ->
622 (Supplicant) ..sta_add() ->
623 (Supplicant) wpa_driver_nl80211_sta_add() ->
624 (NL80211) nl80211_set_station() ->
625 (Driver) mtk_cfg80211_change_station()
626
627 if nl80211_set_station fails, supplicant will tear down the link.
628 */
629 P_GLUE_INFO_T prGlueInfo;
630 TDLS_CMD_PEER_UPDATE_T rCmdUpdate;
631 WLAN_STATUS rStatus;
632 UINT_32 u4BufLen, u4Temp;
633
634
635 /* sanity check */
636 if ((wiphy == NULL) || (mac == NULL) || (params == NULL))
637 return -EINVAL;
638
639 DBGLOG(TDLS, INFO, ("%s: 0x%p 0x%x\n",
640 __FUNCTION__, params->supported_rates, params->sta_flags_set));
641
642 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
643 return -EOPNOTSUPP;
644
645 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
646 if (prGlueInfo == NULL)
647 return -EINVAL;
648
649 /* TODO: check if we are station mode, not AP mode */
650
651 /* init */
652 kalMemZero(&rCmdUpdate, sizeof(rCmdUpdate));
653 kalMemCopy(rCmdUpdate.aucPeerMac, mac, 6);
654
655 if (params->supported_rates != NULL)
656 {
657 u4Temp = params->supported_rates_len;
658 if (u4Temp > TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX)
659 {
660 u4Temp = TDLS_CMD_PEER_UPDATE_SUP_RATE_MAX;
661 DBGLOG(TDLS, ERROR, ("%s sup rate too long: %d\n",
662 __FUNCTION__, params->supported_rates_len));
663 }
664 kalMemCopy(rCmdUpdate.aucSupRate, params->supported_rates, u4Temp);
665 rCmdUpdate.u2SupRateLen = u4Temp;
666 }
667
668 /*
669 In supplicant, only recognize WLAN_EID_QOS 46, not 0xDD WMM
670 So force to support UAPSD here.
671 */
672 rCmdUpdate.UapsdBitmap = 0x0F; /*params->uapsd_queues;*/
673 rCmdUpdate.UapsdMaxSp = 0; /*params->max_sp;*/
674
675 DBGLOG(TDLS, INFO, ("%s: UapsdBitmap=0x%x UapsdMaxSp=%d\n",
676 __FUNCTION__, rCmdUpdate.UapsdBitmap, rCmdUpdate.UapsdMaxSp));
677
678 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
679 rCmdUpdate.u2Capability = params->capability;
680
681 if (params->ext_capab != NULL)
682 {
683 u4Temp = params->ext_capab_len;
684 if (u4Temp > TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN)
685 {
686 u4Temp = TDLS_CMD_PEER_UPDATE_EXT_CAP_MAXLEN;
687 DBGLOG(TDLS, ERROR, ("%s ext_capab too long: %d\n",
688 __FUNCTION__, params->ext_capab_len));
689 }
690 kalMemCopy(rCmdUpdate.aucExtCap, params->ext_capab, u4Temp);
691 rCmdUpdate.u2ExtCapLen = u4Temp;
692 }
693 #endif
694
695 if (params->ht_capa != NULL)
696 {
697 DBGLOG(TDLS, INFO, ("%s: peer is 11n device\n",
698 __FUNCTION__));
699
700 rCmdUpdate.rHtCap.u2CapInfo = params->ht_capa->cap_info;
701 rCmdUpdate.rHtCap.ucAmpduParamsInfo = params->ht_capa->ampdu_params_info;
702 rCmdUpdate.rHtCap.u2ExtHtCapInfo = params->ht_capa->extended_ht_cap_info;
703 rCmdUpdate.rHtCap.u4TxBfCapInfo = params->ht_capa->tx_BF_cap_info;
704 rCmdUpdate.rHtCap.ucAntennaSelInfo = params->ht_capa->antenna_selection_info;
705 kalMemCopy(rCmdUpdate.rHtCap.rMCS.arRxMask,
706 params->ht_capa->mcs.rx_mask,
707 sizeof(rCmdUpdate.rHtCap.rMCS.arRxMask));
708 rCmdUpdate.rHtCap.rMCS.u2RxHighest = params->ht_capa->mcs.rx_highest;
709 rCmdUpdate.rHtCap.rMCS.ucTxParams = params->ht_capa->mcs.tx_params;
710 rCmdUpdate.fgIsSupHt = TRUE;
711 }
712
713 /* update a TDLS peer record */
714 rStatus = kalIoctl(prGlueInfo,
715 TdlsexPeerUpdate,
716 &rCmdUpdate,
717 sizeof(TDLS_CMD_PEER_UPDATE_T),
718 FALSE,
719 FALSE,
720 FALSE,
721 FALSE,
722 &u4BufLen);
723
724 if (rStatus != WLAN_STATUS_SUCCESS) {
725 DBGLOG(TDLS, ERROR, ("%s update error:%x\n", __FUNCTION__, rStatus));
726 return -EINVAL;
727 }
728 #endif /* CFG_SUPPORT_TDLS */
729
730 return 0;
731 }
732
733
734 /*----------------------------------------------------------------------------*/
735 /*!
736 * @brief This routine is responsible for adding a station information
737 *
738 * @param
739 *
740 * @retval 0: successful
741 * others: failure
742 */
743 /*----------------------------------------------------------------------------*/
744 int
745 mtk_cfg80211_add_station (
746 struct wiphy *wiphy,
747 struct net_device *ndev,
748 u8 *mac,
749 struct station_parameters *params
750 )
751 {
752 #if (CFG_SUPPORT_TDLS == 1)
753 /* from supplicant -- wpa_supplicant_tdls_peer_addset() */
754 P_GLUE_INFO_T prGlueInfo;
755 TDLS_CMD_PEER_ADD_T rCmdCreate;
756 WLAN_STATUS rStatus;
757 UINT_32 u4BufLen;
758
759
760 if ((wiphy == NULL) || (mac == NULL) || (params == NULL))
761 return -EINVAL;
762
763 /*
764 wpa_sm_tdls_peer_addset(sm, peer->addr, 1, 0, 0, NULL, 0, NULL, NULL, 0,
765 NULL, 0);
766
767 wpa_sm_tdls_peer_addset(struct wpa_sm *sm, const u8 *addr, int add,
768 u16 aid, u16 capability, const u8 *supp_rates,
769 size_t supp_rates_len,
770 const struct ieee80211_ht_capabilities *ht_capab,
771 const struct ieee80211_vht_capabilities *vht_capab,
772 u8 qosinfo, const u8 *ext_capab, size_t ext_capab_len)
773
774 Only MAC address of the peer is valid.
775 */
776
777 DBGLOG(TDLS, INFO, ("%s: 0x%p %d\n",
778 __FUNCTION__, params->supported_rates, params->supported_rates_len));
779
780 /* sanity check */
781 if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
782 return -EOPNOTSUPP;
783
784 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
785 if (prGlueInfo == NULL)
786 return -EINVAL;
787
788 /* TODO: check if we are station mode, not AP mode */
789
790 /* init */
791 kalMemZero(&rCmdCreate, sizeof(rCmdCreate));
792 kalMemCopy(rCmdCreate.aucPeerMac, mac, 6);
793
794 #if 0
795 rCmdCreate.eNetTypeIndex = NETWORK_TYPE_AIS_INDEX;
796
797 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
798 rCmdCreate.u2CapInfo = params->capability;
799 #endif
800
801 DBGLOG(TDLS, INFO, ("<tdls_cmd> %s: capability = 0x%x\n",
802 __FUNCTION__, rCmdCreate.u2CapInfo));
803
804 if ((params->supported_rates != NULL) &&
805 (params->supported_rates_len != 0))
806 {
807 UINT32 u4Idx;
808
809 DBGLOG(TDLS, INFO, ("<tdls_cmd> %s: sup rate = 0x",
810 __FUNCTION__));
811
812 rIeSup.ucId = ELEM_ID_SUP_RATES;
813 rIeSup.ucLength = params->supported_rates_len;
814 for(u4Idx=0; u4Idx<rIeSup.ucLength; u4Idx++)
815 {
816 rIeSup.aucSupportedRates[u4Idx] = params->supported_rates[u4Idx];
817 DBGLOG(TDLS, INFO, ("%x ", rIeSup.aucSupportedRates[u4Idx]));
818 }
819 DBGLOG(TDLS, INFO, ("\n"));
820
821 rateGetRateSetFromIEs(&rIeSup,
822 NULL,
823 &rCmdCreate.u2OperationalRateSet,
824 &rCmdCreate.u2BSSBasicRateSet,
825 &rCmdCreate.fgIsUnknownBssBasicRate);
826 }
827
828 /* phy type */
829 #endif
830
831 /* create a TDLS peer record */
832 rStatus = kalIoctl(prGlueInfo,
833 TdlsexPeerAdd,
834 &rCmdCreate,
835 sizeof(TDLS_CMD_PEER_ADD_T),
836 FALSE,
837 FALSE,
838 FALSE,
839 FALSE,
840 &u4BufLen);
841
842 if (rStatus != WLAN_STATUS_SUCCESS)
843 {
844 DBGLOG(TDLS, ERROR, ("%s create error:%x\n", __FUNCTION__, rStatus));
845 return -EINVAL;
846 }
847 #endif /* CFG_SUPPORT_TDLS */
848
849 return 0;
850 }
851
852
853 /*----------------------------------------------------------------------------*/
854 /*!
855 * @brief This routine is responsible for deleting a station information
856 *
857 * @param
858 *
859 * @retval 0: successful
860 * others: failure
861 *
862 * @other
863 * must implement if you have add_station().
864 */
865 /*----------------------------------------------------------------------------*/
866 int
867 mtk_cfg80211_del_station (
868 struct wiphy *wiphy,
869 struct net_device *ndev,
870 u8 *mac
871 )
872 {
873 return 0;
874 }
875
876
877 /*----------------------------------------------------------------------------*/
878 /*!
879 * @brief This routine is responsible for requesting to do a scan
880 *
881 * @param
882 *
883 * @retval 0: successful
884 * others: failure
885 */
886 /*----------------------------------------------------------------------------*/
887 static PARAM_SCAN_REQUEST_EXT_T rScanRequest;
888 int
889 mtk_cfg80211_scan (
890 struct wiphy *wiphy,
891 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
892 struct net_device *ndev,
893 #endif /* LINUX_VERSION_CODE */
894 struct cfg80211_scan_request *request
895 )
896 {
897 P_GLUE_INFO_T prGlueInfo = NULL;
898 WLAN_STATUS rStatus;
899 UINT_32 u4BufLen;
900 // PARAM_SCAN_REQUEST_EXT_T rScanRequest;
901
902 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
903 ASSERT(prGlueInfo);
904
905 DBGLOG(REQ, INFO, ("mtk_cfg80211_scan\n"));
906 kalMemZero(&rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T));
907
908 /* check if there is any pending scan not yet finished */
909 if(prGlueInfo->prScanRequest != NULL) {
910 DBGLOG(REQ, INFO, ("prGlueInfo->prScanRequest != NULL\n"));
911 return -EBUSY;
912 }
913
914 if(request->n_ssids == 0) {
915 rScanRequest.rSsid.u4SsidLen = 0;
916 }
917 else if(request->n_ssids == 1) {
918 COPY_SSID(rScanRequest.rSsid.aucSsid, rScanRequest.rSsid.u4SsidLen, request->ssids[0].ssid, request->ssids[0].ssid_len);
919 }
920 else {
921 DBGLOG(REQ, INFO, ("request->n_ssids:%d\n", request->n_ssids));
922 return -EINVAL;
923 }
924
925 if(request->ie_len > 0) {
926 rScanRequest.u4IELength = request->ie_len;
927 rScanRequest.pucIE = (PUINT_8)(request->ie);
928 }
929 else {
930 rScanRequest.u4IELength = 0;
931 }
932
933 prGlueInfo->prScanRequest = request;
934
935 rStatus = kalIoctl(prGlueInfo,
936 wlanoidSetBssidListScanExt,
937 &rScanRequest,
938 sizeof(PARAM_SCAN_REQUEST_EXT_T),
939 FALSE,
940 FALSE,
941 FALSE,
942 FALSE,
943 &u4BufLen);
944
945 if (rStatus != WLAN_STATUS_SUCCESS) {
946 DBGLOG(REQ, INFO, ("scan error:%x\n", rStatus));
947 prGlueInfo->prScanRequest = NULL;
948 return -EINVAL;
949 }
950
951 return 0;
952 }
953
954 static UINT_8 wepBuf[48];
955
956 /*----------------------------------------------------------------------------*/
957 /*!
958 * @brief This routine is responsible for requesting to connect to
959 * the ESS with the specified parameters
960 *
961 * @param
962 *
963 * @retval 0: successful
964 * others: failure
965 */
966 /*----------------------------------------------------------------------------*/
967 int
968 mtk_cfg80211_connect (
969 struct wiphy *wiphy,
970 struct net_device *ndev,
971 struct cfg80211_connect_params *sme
972 )
973 {
974 P_GLUE_INFO_T prGlueInfo = NULL;
975 WLAN_STATUS rStatus;
976 UINT_32 u4BufLen;
977 ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
978 ENUM_PARAM_AUTH_MODE_T eAuthMode;
979 UINT_32 cipher;
980 PARAM_SSID_T rNewSsid;
981 BOOLEAN fgCarryWPSIE = FALSE;
982 ENUM_PARAM_OP_MODE_T eOpMode;
983
984 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
985 ASSERT(prGlueInfo);
986
987 DBGLOG(REQ, INFO, ("[wlan] mtk_cfg80211_connect %p %zu\n",
988 sme->ie, sme->ie_len));
989
990 if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH)
991 eOpMode = NET_TYPE_AUTO_SWITCH;
992 else
993 eOpMode = prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode;
994
995 rStatus = kalIoctl(prGlueInfo,
996 wlanoidSetInfrastructureMode,
997 &eOpMode,
998 sizeof(eOpMode),
999 FALSE,
1000 FALSE,
1001 TRUE,
1002 FALSE,
1003 &u4BufLen);
1004
1005 if (rStatus != WLAN_STATUS_SUCCESS) {
1006 DBGLOG(INIT, INFO, ("wlanoidSetInfrastructureMode fail 0x%x\n", rStatus));
1007 return -EFAULT;
1008 }
1009
1010 /* after set operation mode, key table are cleared */
1011
1012 /* reset wpa info */
1013 prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
1014 prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
1015 prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
1016 prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
1017 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
1018 #if CFG_SUPPORT_802_11W
1019 prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
1020 #endif
1021
1022 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1023 prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA;
1024 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1025 prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA2;
1026 else
1027 prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
1028
1029 switch (sme->auth_type) {
1030 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1031 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
1032 break;
1033 case NL80211_AUTHTYPE_SHARED_KEY:
1034 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY;
1035 break;
1036 default:
1037 prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY;
1038 break;
1039 }
1040
1041 if (sme->crypto.n_ciphers_pairwise) {
1042 prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] = sme->crypto.ciphers_pairwise[0];
1043 switch (sme->crypto.ciphers_pairwise[0]) {
1044 case WLAN_CIPHER_SUITE_WEP40:
1045 prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP40;
1046 break;
1047 case WLAN_CIPHER_SUITE_WEP104:
1048 prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104;
1049 break;
1050 case WLAN_CIPHER_SUITE_TKIP:
1051 prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_TKIP;
1052 break;
1053 case WLAN_CIPHER_SUITE_CCMP:
1054 prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP;
1055 break;
1056 case WLAN_CIPHER_SUITE_AES_CMAC:
1057 prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP;
1058 break;
1059 default:
1060 DBGLOG(REQ, WARN, ("invalid cipher pairwise (%d)\n",
1061 sme->crypto.ciphers_pairwise[0]));
1062 return -EINVAL;
1063 }
1064 }
1065
1066 if (sme->crypto.cipher_group) {
1067 prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite = sme->crypto.cipher_group;
1068 switch (sme->crypto.cipher_group) {
1069 case WLAN_CIPHER_SUITE_WEP40:
1070 prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP40;
1071 break;
1072 case WLAN_CIPHER_SUITE_WEP104:
1073 prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104;
1074 break;
1075 case WLAN_CIPHER_SUITE_TKIP:
1076 prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_TKIP;
1077 break;
1078 case WLAN_CIPHER_SUITE_CCMP:
1079 prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP;
1080 break;
1081 case WLAN_CIPHER_SUITE_AES_CMAC:
1082 prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP;
1083 break;
1084 default:
1085 DBGLOG(REQ, WARN, ("invalid cipher group (%d)\n",
1086 sme->crypto.cipher_group));
1087 return -EINVAL;
1088 }
1089 }
1090
1091 if (sme->crypto.n_akm_suites) {
1092 prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] = sme->crypto.akm_suites[0];
1093 if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) {
1094 switch (sme->crypto.akm_suites[0]) {
1095 case WLAN_AKM_SUITE_8021X:
1096 eAuthMode = AUTH_MODE_WPA;
1097 break;
1098 case WLAN_AKM_SUITE_PSK:
1099 eAuthMode = AUTH_MODE_WPA_PSK;
1100 break;
1101 default:
1102 DBGLOG(REQ, WARN, ("invalid cipher group (%d)\n",
1103 sme->crypto.cipher_group));
1104 return -EINVAL;
1105 }
1106 } else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) {
1107 switch (sme->crypto.akm_suites[0]) {
1108 case WLAN_AKM_SUITE_8021X:
1109 eAuthMode = AUTH_MODE_WPA2;
1110 break;
1111 case WLAN_AKM_SUITE_PSK:
1112 eAuthMode = AUTH_MODE_WPA2_PSK;
1113 break;
1114 default:
1115 DBGLOG(REQ, WARN, ("invalid cipher group (%d)\n",
1116 sme->crypto.cipher_group));
1117 return -EINVAL;
1118 }
1119 }
1120 }
1121
1122 if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
1123 eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ?
1124 AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH;
1125 }
1126
1127 prGlueInfo->rWpaInfo.fgPrivacyInvoke = sme->privacy;
1128
1129 prGlueInfo->fgWpsActive = FALSE;
1130 #if CFG_SUPPORT_HOTSPOT_2_0
1131 prGlueInfo->fgConnectHS20AP = FALSE;
1132 #endif
1133
1134 if (sme->ie && sme->ie_len > 0) {
1135 WLAN_STATUS rStatus;
1136 UINT_32 u4BufLen;
1137 PUINT_8 prDesiredIE = NULL;
1138
1139 #if CFG_SUPPORT_WAPI
1140 if (wextSrchDesiredWAPIIE(sme->ie,
1141 sme->ie_len, (PUINT_8 *)&prDesiredIE)){
1142 rStatus = kalIoctl(prGlueInfo,
1143 wlanoidSetWapiAssocInfo,
1144 prDesiredIE,
1145 IE_SIZE(prDesiredIE),
1146 FALSE,
1147 FALSE,
1148 FALSE,
1149 FALSE,
1150 &u4BufLen);
1151
1152 if (rStatus != WLAN_STATUS_SUCCESS) {
1153 DBGLOG(SEC, WARN, ("[wapi] set wapi assoc info error:%x\n", rStatus));
1154 }
1155 }
1156 #endif
1157
1158 DBGLOG(REQ, INFO, ("[wlan] wlanoidSetWapiAssocInfo: .fgWapiMode = %d\n",
1159 prGlueInfo->prAdapter->rWifiVar.rConnSettings.fgWapiMode));
1160
1161 #if CFG_SUPPORT_WPS2
1162 if (wextSrchDesiredWPSIE(sme->ie,
1163 sme->ie_len,
1164 0xDD,
1165 (PUINT_8 *)&prDesiredIE)) {
1166 prGlueInfo->fgWpsActive = TRUE;
1167 fgCarryWPSIE = TRUE;
1168
1169 rStatus = kalIoctl(prGlueInfo,
1170 wlanoidSetWSCAssocInfo,
1171 prDesiredIE,
1172 IE_SIZE(prDesiredIE),
1173 FALSE,
1174 FALSE,
1175 FALSE,
1176 FALSE,
1177 &u4BufLen);
1178 if (rStatus != WLAN_STATUS_SUCCESS) {
1179 DBGLOG(SEC, WARN, ("WSC] set WSC assoc info error:%x\n", rStatus));
1180 }
1181 }
1182 #endif
1183
1184 #if CFG_SUPPORT_HOTSPOT_2_0
1185 if (wextSrchDesiredHS20IE(sme->ie,
1186 sme->ie_len,
1187 (PUINT_8 *)&prDesiredIE)) {
1188 rStatus = kalIoctl(prGlueInfo,
1189 wlanoidSetHS20Info,
1190 prDesiredIE,
1191 IE_SIZE(prDesiredIE),
1192 FALSE,
1193 FALSE,
1194 TRUE,
1195 FALSE,
1196 &u4BufLen);
1197 if (rStatus != WLAN_STATUS_SUCCESS) {
1198 //printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus);
1199 }
1200 }
1201 if (wextSrchDesiredInterworkingIE(sme->ie,
1202 sme->ie_len,
1203 (PUINT_8 *)&prDesiredIE)) {
1204 rStatus = kalIoctl(prGlueInfo,
1205 wlanoidSetInterworkingInfo,
1206 prDesiredIE,
1207 IE_SIZE(prDesiredIE),
1208 FALSE,
1209 FALSE,
1210 TRUE,
1211 FALSE,
1212 &u4BufLen);
1213 if (rStatus != WLAN_STATUS_SUCCESS) {
1214 //printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus);
1215 }
1216 }
1217 if (wextSrchDesiredRoamingConsortiumIE(sme->ie,
1218 sme->ie_len,
1219 (PUINT_8 *)&prDesiredIE)) {
1220 rStatus = kalIoctl(prGlueInfo,
1221 wlanoidSetRoamingConsortiumIEInfo,
1222 prDesiredIE,
1223 IE_SIZE(prDesiredIE),
1224 FALSE,
1225 FALSE,
1226 TRUE,
1227 FALSE,
1228 &u4BufLen);
1229 if (rStatus != WLAN_STATUS_SUCCESS) {
1230 //printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus);
1231 }
1232 }
1233 #endif
1234 }
1235
1236 /* clear WSC Assoc IE buffer in case WPS IE is not detected */
1237 if(fgCarryWPSIE == FALSE) {
1238 kalMemZero(&prGlueInfo->aucWSCAssocInfoIE, 200);
1239 prGlueInfo->u2WSCAssocInfoIELen = 0;
1240 }
1241
1242 rStatus = kalIoctl(prGlueInfo,
1243 wlanoidSetAuthMode,
1244 &eAuthMode,
1245 sizeof(eAuthMode),
1246 FALSE,
1247 FALSE,
1248 FALSE,
1249 FALSE,
1250 &u4BufLen);
1251 if (rStatus != WLAN_STATUS_SUCCESS) {
1252 DBGLOG(REQ, WARN, ("set auth mode error:%x\n", rStatus));
1253 }
1254
1255 cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise;
1256
1257 if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) {
1258 if (cipher & IW_AUTH_CIPHER_CCMP) {
1259 eEncStatus = ENUM_ENCRYPTION3_ENABLED;
1260 }
1261 else if (cipher & IW_AUTH_CIPHER_TKIP) {
1262 eEncStatus = ENUM_ENCRYPTION2_ENABLED;
1263 }
1264 else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) {
1265 eEncStatus = ENUM_ENCRYPTION1_ENABLED;
1266 }
1267 else if (cipher & IW_AUTH_CIPHER_NONE){
1268 if (prGlueInfo->rWpaInfo.fgPrivacyInvoke)
1269 eEncStatus = ENUM_ENCRYPTION1_ENABLED;
1270 else
1271 eEncStatus = ENUM_ENCRYPTION_DISABLED;
1272 }
1273 else {
1274 eEncStatus = ENUM_ENCRYPTION_DISABLED;
1275 }
1276 }
1277 else {
1278 eEncStatus = ENUM_ENCRYPTION_DISABLED;
1279 }
1280
1281 rStatus = kalIoctl(prGlueInfo,
1282 wlanoidSetEncryptionStatus,
1283 &eEncStatus,
1284 sizeof(eEncStatus),
1285 FALSE,
1286 FALSE,
1287 FALSE,
1288 FALSE,
1289 &u4BufLen);
1290 if (rStatus != WLAN_STATUS_SUCCESS) {
1291 DBGLOG(REQ, WARN, ("set encryption mode error:%x\n", rStatus));
1292 }
1293
1294 if (sme->key_len != 0 && prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
1295 P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf;
1296
1297 prWepKey->u4Length = 12 + sme->key_len;
1298 prWepKey->u4KeyLength = (UINT_32) sme->key_len;
1299 prWepKey->u4KeyIndex = (UINT_32) sme->key_idx;
1300 prWepKey->u4KeyIndex |= BIT(31);
1301 if (prWepKey->u4KeyLength > 32) {
1302 DBGLOG(REQ, WARN, ("Too long key length (%u)\n", prWepKey->u4KeyLength));
1303 return -EINVAL;
1304 }
1305 kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength);
1306
1307 rStatus = kalIoctl(prGlueInfo,
1308 wlanoidSetAddWep,
1309 prWepKey,
1310 prWepKey->u4Length,
1311 FALSE,
1312 FALSE,
1313 TRUE,
1314 FALSE,
1315 &u4BufLen);
1316
1317 if (rStatus != WLAN_STATUS_SUCCESS) {
1318 DBGLOG(INIT, INFO, ("wlanoidSetAddWep fail 0x%x\n", rStatus));
1319 return -EFAULT;
1320 }
1321 }
1322
1323 if(sme->ssid_len > 0) {
1324 /* connect by SSID */
1325 COPY_SSID(rNewSsid.aucSsid, rNewSsid.u4SsidLen, sme->ssid, sme->ssid_len);
1326
1327 rStatus = kalIoctl(prGlueInfo,
1328 wlanoidSetSsid,
1329 (PVOID) &rNewSsid,
1330 sizeof(PARAM_SSID_T),
1331 FALSE,
1332 FALSE,
1333 TRUE,
1334 FALSE,
1335 &u4BufLen);
1336
1337 if (rStatus != WLAN_STATUS_SUCCESS) {
1338 DBGLOG(REQ, WARN, ("set SSID:%x\n", rStatus));
1339 return -EINVAL;
1340 }
1341 }
1342 else {
1343 /* connect by BSSID */
1344 rStatus = kalIoctl(prGlueInfo,
1345 wlanoidSetBssid,
1346 (PVOID) sme->bssid,
1347 MAC_ADDR_LEN,
1348 FALSE,
1349 FALSE,
1350 TRUE,
1351 FALSE,
1352 &u4BufLen);
1353
1354 if (rStatus != WLAN_STATUS_SUCCESS) {
1355 DBGLOG(REQ, WARN, ("set BSSID:%x\n", rStatus));
1356 return -EINVAL;
1357 }
1358 }
1359
1360 return 0;
1361 }
1362
1363
1364 /*----------------------------------------------------------------------------*/
1365 /*!
1366 * @brief This routine is responsible for requesting to disconnect from
1367 * currently connected ESS
1368 *
1369 * @param
1370 *
1371 * @retval 0: successful
1372 * others: failure
1373 */
1374 /*----------------------------------------------------------------------------*/
1375 int
1376 mtk_cfg80211_disconnect (
1377 struct wiphy *wiphy,
1378 struct net_device *ndev,
1379 u16 reason_code
1380 )
1381 {
1382 P_GLUE_INFO_T prGlueInfo = NULL;
1383 WLAN_STATUS rStatus;
1384 UINT_32 u4BufLen;
1385
1386 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1387 ASSERT(prGlueInfo);
1388
1389 rStatus = kalIoctl(prGlueInfo,
1390 wlanoidSetDisassociate,
1391 NULL,
1392 0,
1393 FALSE,
1394 FALSE,
1395 TRUE,
1396 FALSE,
1397 &u4BufLen);
1398
1399 if (rStatus != WLAN_STATUS_SUCCESS) {
1400 DBGLOG(REQ, WARN, ("disassociate error:%x\n", rStatus));
1401 return -EFAULT;
1402 }
1403
1404 return 0;
1405 }
1406
1407
1408 /*----------------------------------------------------------------------------*/
1409 /*!
1410 * @brief This routine is responsible for requesting to join an IBSS group
1411 *
1412 * @param
1413 *
1414 * @retval 0: successful
1415 * others: failure
1416 */
1417 /*----------------------------------------------------------------------------*/
1418 int
1419 mtk_cfg80211_join_ibss (
1420 struct wiphy *wiphy,
1421 struct net_device *ndev,
1422 struct cfg80211_ibss_params *params
1423 )
1424 {
1425 PARAM_SSID_T rNewSsid;
1426 P_GLUE_INFO_T prGlueInfo = NULL;
1427 UINT_32 u4ChnlFreq; /* Store channel or frequency information */
1428 UINT_32 u4BufLen = 0;
1429 WLAN_STATUS rStatus;
1430 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
1431 struct ieee80211_channel *channel = NULL;
1432 #endif
1433
1434 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1435 ASSERT(prGlueInfo);
1436
1437 /* set channel */
1438 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
1439 if(params->chandef.chan)
1440 channel = params->chandef.chan;
1441 if(channel) {
1442 u4ChnlFreq = nicChannelNum2Freq(channel->hw_value);
1443 #else
1444
1445 if(params->channel) {
1446 u4ChnlFreq = nicChannelNum2Freq(params->channel->hw_value);
1447 #endif
1448 rStatus = kalIoctl(prGlueInfo,
1449 wlanoidSetFrequency,
1450 &u4ChnlFreq,
1451 sizeof(u4ChnlFreq),
1452 FALSE,
1453 FALSE,
1454 FALSE,
1455 FALSE,
1456 &u4BufLen);
1457 if (rStatus != WLAN_STATUS_SUCCESS) {
1458 return -EFAULT;
1459 }
1460 }
1461
1462 /* set SSID */
1463 kalMemCopy(rNewSsid.aucSsid, params->ssid, params->ssid_len);
1464 rStatus = kalIoctl(prGlueInfo,
1465 wlanoidSetSsid,
1466 (PVOID) &rNewSsid,
1467 sizeof(PARAM_SSID_T),
1468 FALSE,
1469 FALSE,
1470 TRUE,
1471 FALSE,
1472 &u4BufLen);
1473
1474 if (rStatus != WLAN_STATUS_SUCCESS) {
1475 DBGLOG(REQ, WARN, ("set SSID:%x\n", rStatus));
1476 return -EFAULT;
1477 }
1478
1479 return 0;
1480
1481
1482 return -EINVAL;
1483 }
1484
1485
1486 /*----------------------------------------------------------------------------*/
1487 /*!
1488 * @brief This routine is responsible for requesting to leave from IBSS group
1489 *
1490 * @param
1491 *
1492 * @retval 0: successful
1493 * others: failure
1494 */
1495 /*----------------------------------------------------------------------------*/
1496 int
1497 mtk_cfg80211_leave_ibss (
1498 struct wiphy *wiphy,
1499 struct net_device *ndev
1500 )
1501 {
1502 P_GLUE_INFO_T prGlueInfo = NULL;
1503 WLAN_STATUS rStatus;
1504 UINT_32 u4BufLen;
1505
1506 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1507 ASSERT(prGlueInfo);
1508
1509 rStatus = kalIoctl(prGlueInfo,
1510 wlanoidSetDisassociate,
1511 NULL,
1512 0,
1513 FALSE,
1514 FALSE,
1515 TRUE,
1516 FALSE,
1517 &u4BufLen);
1518
1519 if (rStatus != WLAN_STATUS_SUCCESS) {
1520 DBGLOG(REQ, WARN, ("disassociate error:%x\n", rStatus));
1521 return -EFAULT;
1522 }
1523
1524 return 0;
1525 }
1526
1527
1528 /*----------------------------------------------------------------------------*/
1529 /*!
1530 * @brief This routine is responsible for requesting to configure
1531 * WLAN power managemenet
1532 *
1533 * @param
1534 *
1535 * @retval 0: successful
1536 * others: failure
1537 */
1538 /*----------------------------------------------------------------------------*/
1539 int
1540 mtk_cfg80211_set_power_mgmt (
1541 struct wiphy *wiphy,
1542 struct net_device *ndev,
1543 bool enabled,
1544 int timeout
1545 )
1546 {
1547 P_GLUE_INFO_T prGlueInfo = NULL;
1548 WLAN_STATUS rStatus;
1549 UINT_32 u4BufLen;
1550 PARAM_POWER_MODE ePowerMode;
1551
1552 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1553 ASSERT(prGlueInfo);
1554
1555 if(enabled) {
1556 if(timeout == -1) {
1557 ePowerMode = Param_PowerModeFast_PSP;
1558 }
1559 else {
1560 ePowerMode = Param_PowerModeMAX_PSP;
1561 }
1562 }
1563 else {
1564 ePowerMode = Param_PowerModeCAM;
1565 }
1566
1567 rStatus = kalIoctl(prGlueInfo,
1568 wlanoidSet802dot11PowerSaveProfile,
1569 &ePowerMode,
1570 sizeof(ePowerMode),
1571 FALSE,
1572 FALSE,
1573 TRUE,
1574 FALSE,
1575 &u4BufLen);
1576
1577 if (rStatus != WLAN_STATUS_SUCCESS) {
1578 DBGLOG(REQ, WARN, ("set_power_mgmt error:%x\n", rStatus));
1579 return -EFAULT;
1580 }
1581
1582 return 0;
1583 }
1584
1585
1586 /*----------------------------------------------------------------------------*/
1587 /*!
1588 * @brief This routine is responsible for requesting to cache
1589 * a PMKID for a BSSID
1590 *
1591 * @param
1592 *
1593 * @retval 0: successful
1594 * others: failure
1595 */
1596 /*----------------------------------------------------------------------------*/
1597 int
1598 mtk_cfg80211_set_pmksa (
1599 struct wiphy *wiphy,
1600 struct net_device *ndev,
1601 struct cfg80211_pmksa *pmksa
1602 )
1603 {
1604 P_GLUE_INFO_T prGlueInfo = NULL;
1605 WLAN_STATUS rStatus;
1606 UINT_32 u4BufLen;
1607 P_PARAM_PMKID_T prPmkid;
1608
1609 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1610 ASSERT(prGlueInfo);
1611
1612 prPmkid =(P_PARAM_PMKID_T)kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE);
1613 if (!prPmkid) {
1614 DBGLOG(INIT, INFO, ("Can not alloc memory for IW_PMKSA_ADD\n"));
1615 return -ENOMEM;
1616 }
1617
1618 prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T);
1619 prPmkid->u4BSSIDInfoCount = 1;
1620 kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, pmksa->bssid, 6);
1621 kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, pmksa->pmkid, IW_PMKID_LEN);
1622
1623 rStatus = kalIoctl(prGlueInfo,
1624 wlanoidSetPmkid,
1625 prPmkid,
1626 sizeof(PARAM_PMKID_T),
1627 FALSE,
1628 FALSE,
1629 FALSE,
1630 FALSE,
1631 &u4BufLen);
1632
1633 if (rStatus != WLAN_STATUS_SUCCESS) {
1634 DBGLOG(INIT, INFO, ("add pmkid error:%x\n", rStatus));
1635 }
1636 kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T));
1637
1638 return 0;
1639 }
1640
1641
1642 /*----------------------------------------------------------------------------*/
1643 /*!
1644 * @brief This routine is responsible for requesting to remove
1645 * a cached PMKID for a BSSID
1646 *
1647 * @param
1648 *
1649 * @retval 0: successful
1650 * others: failure
1651 */
1652 /*----------------------------------------------------------------------------*/
1653 int
1654 mtk_cfg80211_del_pmksa (
1655 struct wiphy *wiphy,
1656 struct net_device *ndev,
1657 struct cfg80211_pmksa *pmksa
1658 )
1659 {
1660
1661 return 0;
1662 }
1663
1664
1665 /*----------------------------------------------------------------------------*/
1666 /*!
1667 * @brief This routine is responsible for requesting to flush
1668 * all cached PMKID
1669 *
1670 * @param
1671 *
1672 * @retval 0: successful
1673 * others: failure
1674 */
1675 /*----------------------------------------------------------------------------*/
1676 int
1677 mtk_cfg80211_flush_pmksa (
1678 struct wiphy *wiphy,
1679 struct net_device *ndev
1680 )
1681 {
1682 P_GLUE_INFO_T prGlueInfo = NULL;
1683 WLAN_STATUS rStatus;
1684 UINT_32 u4BufLen;
1685 P_PARAM_PMKID_T prPmkid;
1686
1687 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1688 ASSERT(prGlueInfo);
1689
1690 prPmkid =(P_PARAM_PMKID_T)kalMemAlloc(8, VIR_MEM_TYPE);
1691 if (!prPmkid) {
1692 DBGLOG(INIT, INFO, ("Can not alloc memory for IW_PMKSA_FLUSH\n"));
1693 return -ENOMEM;
1694 }
1695
1696 prPmkid->u4Length = 8;
1697 prPmkid->u4BSSIDInfoCount = 0;
1698
1699 rStatus = kalIoctl(prGlueInfo,
1700 wlanoidSetPmkid,
1701 prPmkid,
1702 sizeof(PARAM_PMKID_T),
1703 FALSE,
1704 FALSE,
1705 FALSE,
1706 FALSE,
1707 &u4BufLen);
1708
1709 if (rStatus != WLAN_STATUS_SUCCESS) {
1710 DBGLOG(INIT, INFO, ("flush pmkid error:%x\n", rStatus));
1711 }
1712 kalMemFree(prPmkid, VIR_MEM_TYPE, 8);
1713
1714 return 0;
1715 }
1716
1717
1718 void
1719 mtk_cfg80211_mgmt_frame_register (
1720 IN struct wiphy *wiphy,
1721 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
1722 IN struct net_device *dev,
1723 #else
1724 IN struct wireless_dev *wdev,
1725 #endif
1726 IN u16 frame_type,
1727 IN bool reg
1728 )
1729 {
1730 #if 0
1731 P_MSG_P2P_MGMT_FRAME_REGISTER_T prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T)NULL;
1732 #endif
1733 P_GLUE_INFO_T prGlueInfo = (P_GLUE_INFO_T)NULL;
1734
1735 do {
1736
1737 DBGLOG(INIT, LOUD, ("mtk_cfg80211_mgmt_frame_register\n"));
1738
1739 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1740
1741 switch (frame_type) {
1742 case MAC_FRAME_PROBE_REQ:
1743 if (reg) {
1744 prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_PROBE_REQ;
1745 DBGLOG(INIT, LOUD, ("Open packet filer probe request\n"));
1746 }
1747 else {
1748 prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_PROBE_REQ;
1749 DBGLOG(INIT, LOUD, ("Close packet filer probe request\n"));
1750 }
1751 break;
1752 case MAC_FRAME_ACTION:
1753 if (reg) {
1754 prGlueInfo->u4OsMgmtFrameFilter |= PARAM_PACKET_FILTER_ACTION_FRAME;
1755 DBGLOG(INIT, LOUD, ("Open packet filer action frame.\n"));
1756 }
1757 else {
1758 prGlueInfo->u4OsMgmtFrameFilter &= ~PARAM_PACKET_FILTER_ACTION_FRAME;
1759 DBGLOG(INIT, LOUD, ("Close packet filer action frame.\n"));
1760 }
1761 break;
1762 default:
1763 printk("Ask frog to add code for mgmt:%x\n", frame_type);
1764 break;
1765 }
1766
1767 if (prGlueInfo->prAdapter != NULL){
1768
1769 /* prGlueInfo->ulFlag |= GLUE_FLAG_FRAME_FILTER_AIS; */
1770 set_bit(GLUE_FLAG_FRAME_FILTER_AIS_BIT, &prGlueInfo->ulFlag);
1771
1772 /* wake up main thread */
1773 wake_up_interruptible(&prGlueInfo->waitq);
1774
1775 if (in_interrupt()) {
1776 DBGLOG(INIT, TRACE, ("It is in interrupt level\n"));
1777 }
1778 }
1779
1780 #if 0
1781
1782
1783 prMgmtFrameRegister = (P_MSG_P2P_MGMT_FRAME_REGISTER_T)cnmMemAlloc(prGlueInfo->prAdapter,
1784 RAM_TYPE_MSG,
1785 sizeof(MSG_P2P_MGMT_FRAME_REGISTER_T));
1786
1787 if (prMgmtFrameRegister == NULL) {
1788 ASSERT(FALSE);
1789 break;
1790 }
1791
1792 prMgmtFrameRegister->rMsgHdr.eMsgId = MID_MNY_P2P_MGMT_FRAME_REGISTER;
1793
1794 prMgmtFrameRegister->u2FrameType = frame_type;
1795 prMgmtFrameRegister->fgIsRegister = reg;
1796
1797 mboxSendMsg(prGlueInfo->prAdapter,
1798 MBOX_ID_0,
1799 (P_MSG_HDR_T)prMgmtFrameRegister,
1800 MSG_SEND_METHOD_BUF);
1801
1802 #endif
1803
1804 } while (FALSE);
1805
1806 return;
1807 } /* mtk_cfg80211_mgmt_frame_register */
1808
1809
1810 /*----------------------------------------------------------------------------*/
1811 /*!
1812 * @brief This routine is responsible for requesting to stay on a
1813 * specified channel
1814 *
1815 * @param
1816 *
1817 * @retval 0: successful
1818 * others: failure
1819 */
1820 /*----------------------------------------------------------------------------*/
1821 int
1822 mtk_cfg80211_remain_on_channel (
1823 struct wiphy *wiphy,
1824 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
1825 struct net_device *ndev,
1826 #else
1827 struct wireless_dev *wdev,
1828 #endif /* LINUX_VERSION_CODE */
1829 struct ieee80211_channel *chan,
1830 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
1831 enum nl80211_channel_type channel_type,
1832 #endif /* LINUX_VERSION_CODE */
1833 unsigned int duration,
1834 u64 *cookie
1835 )
1836 {
1837 P_GLUE_INFO_T prGlueInfo = NULL;
1838 INT_32 i4Rslt = -EINVAL;
1839 P_MSG_REMAIN_ON_CHANNEL_T prMsgChnlReq = (P_MSG_REMAIN_ON_CHANNEL_T)NULL;
1840
1841 do {
1842 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
1843 if ((wiphy == NULL) ||
1844 (ndev == NULL) ||
1845 (chan == NULL) ||
1846 (cookie == NULL)) {
1847 break;
1848 }
1849 #else
1850 if ((wiphy == NULL) ||
1851 (wdev == NULL) ||
1852 (chan == NULL) ||
1853 (cookie == NULL)) {
1854 break;
1855 }
1856 #endif
1857
1858 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1859 ASSERT(prGlueInfo);
1860
1861 #if 1
1862 printk("--> %s()\n", __func__);
1863 #endif
1864
1865 *cookie = prGlueInfo->u8Cookie++;
1866
1867 prMsgChnlReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_REMAIN_ON_CHANNEL_T));
1868
1869 if (prMsgChnlReq == NULL) {
1870 ASSERT(FALSE);
1871 i4Rslt = -ENOMEM;
1872 break;
1873 }
1874
1875 prMsgChnlReq->rMsgHdr.eMsgId = MID_MNY_AIS_REMAIN_ON_CHANNEL;
1876 prMsgChnlReq->u8Cookie = *cookie;
1877 prMsgChnlReq->u4DurationMs = duration;
1878
1879 prMsgChnlReq->ucChannelNum = nicFreq2ChannelNum(chan->center_freq * 1000);
1880
1881 switch (chan->band) {
1882 case IEEE80211_BAND_2GHZ:
1883 prMsgChnlReq->eBand = BAND_2G4;
1884 break;
1885 case IEEE80211_BAND_5GHZ:
1886 prMsgChnlReq->eBand = BAND_5G;
1887 break;
1888 default:
1889 prMsgChnlReq->eBand = BAND_2G4;
1890 break;
1891 }
1892
1893 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
1894 switch (channel_type) {
1895 case NL80211_CHAN_NO_HT:
1896 prMsgChnlReq->eSco = CHNL_EXT_SCN;
1897 break;
1898 case NL80211_CHAN_HT20:
1899 prMsgChnlReq->eSco = CHNL_EXT_SCN;
1900 break;
1901 case NL80211_CHAN_HT40MINUS:
1902 prMsgChnlReq->eSco = CHNL_EXT_SCA;
1903 break;
1904 case NL80211_CHAN_HT40PLUS:
1905 prMsgChnlReq->eSco = CHNL_EXT_SCB;
1906 break;
1907 default:
1908 ASSERT(FALSE);
1909 prMsgChnlReq->eSco = CHNL_EXT_SCN;
1910 break;
1911 }
1912 #endif
1913 mboxSendMsg(prGlueInfo->prAdapter,
1914 MBOX_ID_0,
1915 (P_MSG_HDR_T)prMsgChnlReq,
1916 MSG_SEND_METHOD_BUF);
1917
1918 i4Rslt = 0;
1919 } while (FALSE);
1920
1921 return i4Rslt;
1922 }
1923
1924
1925 /*----------------------------------------------------------------------------*/
1926 /*!
1927 * @brief This routine is responsible for requesting to cancel staying
1928 * on a specified channel
1929 *
1930 * @param
1931 *
1932 * @retval 0: successful
1933 * others: failure
1934 */
1935 /*----------------------------------------------------------------------------*/
1936 int
1937 mtk_cfg80211_cancel_remain_on_channel (
1938 struct wiphy *wiphy,
1939 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
1940 struct net_device *ndev,
1941 #else
1942 struct wireless_dev *wdev,
1943 #endif /* LINUX_VERSION_CODE */
1944 u64 cookie
1945 )
1946 {
1947 P_GLUE_INFO_T prGlueInfo = NULL;
1948 INT_32 i4Rslt = -EINVAL;
1949 P_MSG_CANCEL_REMAIN_ON_CHANNEL_T prMsgChnlAbort = (P_MSG_CANCEL_REMAIN_ON_CHANNEL_T)NULL;
1950
1951 do {
1952 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
1953 if ((wiphy == NULL) || (ndev == NULL)) {
1954 break;
1955 }
1956 #else
1957 if ((wiphy == NULL) || (wdev == NULL)) {
1958 break;
1959 }
1960 #endif
1961
1962 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1963 ASSERT(prGlueInfo);
1964
1965 #if 1
1966 printk("--> %s()\n", __func__);
1967 #endif
1968
1969 prMsgChnlAbort = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_CANCEL_REMAIN_ON_CHANNEL_T));
1970
1971 if (prMsgChnlAbort == NULL) {
1972 ASSERT(FALSE);
1973 i4Rslt = -ENOMEM;
1974 break;
1975 }
1976
1977 prMsgChnlAbort->rMsgHdr.eMsgId = MID_MNY_AIS_CANCEL_REMAIN_ON_CHANNEL;
1978 prMsgChnlAbort->u8Cookie = cookie;
1979
1980 mboxSendMsg(prGlueInfo->prAdapter,
1981 MBOX_ID_0,
1982 (P_MSG_HDR_T)prMsgChnlAbort,
1983 MSG_SEND_METHOD_BUF);
1984
1985 i4Rslt = 0;
1986 } while (FALSE);
1987
1988 return i4Rslt;
1989 }
1990
1991
1992 /*----------------------------------------------------------------------------*/
1993 /*!
1994 * @brief This routine is responsible for requesting to send a management frame
1995 *
1996 * @param
1997 *
1998 * @retval 0: successful
1999 * others: failure
2000 */
2001 /*----------------------------------------------------------------------------*/
2002 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
2003 int
2004 mtk_cfg80211_mgmt_tx (
2005 struct wiphy *wiphy,
2006 struct net_device *ndev,
2007 struct ieee80211_channel *channel,
2008 bool offscan,
2009 enum nl80211_channel_type channel_type,
2010 bool channel_type_valid,
2011 unsigned int wait,
2012 const u8 *buf,
2013 size_t len,
2014 bool no_cck,
2015 bool dont_wait_for_ack,
2016 u64 *cookie
2017 )
2018 #else
2019 int
2020 mtk_cfg80211_mgmt_tx (
2021 struct wiphy *wiphy,
2022 struct wireless_dev *wdev,
2023 struct ieee80211_channel *channel,
2024 bool offscan,
2025 unsigned int wait,
2026 const u8 *buf,
2027 size_t len,
2028 bool no_cck,
2029 bool dont_wait_for_ack,
2030 u64 *cookie
2031 )
2032 #endif /* LINUX_VERSION_CODE */
2033 {
2034 P_GLUE_INFO_T prGlueInfo = NULL;
2035 INT_32 i4Rslt = -EINVAL;
2036 P_MSG_MGMT_TX_REQUEST_T prMsgTxReq = (P_MSG_MGMT_TX_REQUEST_T)NULL;
2037 P_MSDU_INFO_T prMgmtFrame = (P_MSDU_INFO_T)NULL;
2038 PUINT_8 pucFrameBuf = (PUINT_8)NULL;
2039
2040 do {
2041 #if 1
2042 printk("--> %s()\n", __func__);
2043 #endif
2044
2045 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
2046 if ((wiphy == NULL) ||
2047 (buf == NULL) ||
2048 (len == 0) ||
2049 (ndev == NULL) ||
2050 (cookie == NULL)) {
2051 break;
2052 }
2053 #else
2054 if ((wiphy == NULL) ||
2055 (buf == NULL) ||
2056 (len == 0) ||
2057 (wdev == NULL) ||
2058 (cookie == NULL)) {
2059 break;
2060 }
2061 #endif
2062
2063 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
2064 ASSERT(prGlueInfo);
2065
2066 *cookie = prGlueInfo->u8Cookie++;
2067
2068 /* Channel & Channel Type & Wait time are ignored. */
2069 prMsgTxReq = cnmMemAlloc(prGlueInfo->prAdapter, RAM_TYPE_MSG, sizeof(MSG_MGMT_TX_REQUEST_T));
2070
2071 if (prMsgTxReq == NULL) {
2072 ASSERT(FALSE);
2073 i4Rslt = -ENOMEM;
2074 break;
2075 }
2076
2077 prMsgTxReq->fgNoneCckRate = FALSE;
2078 prMsgTxReq->fgIsWaitRsp = TRUE;
2079
2080 prMgmtFrame = cnmMgtPktAlloc(prGlueInfo->prAdapter, (UINT_32)(len + MAC_TX_RESERVED_FIELD));
2081
2082 if ((prMsgTxReq->prMgmtMsduInfo = prMgmtFrame) == NULL) {
2083 ASSERT(FALSE);
2084 i4Rslt = -ENOMEM;
2085 break;
2086 }
2087
2088 prMsgTxReq->u8Cookie = *cookie;
2089 prMsgTxReq->rMsgHdr.eMsgId = MID_MNY_AIS_MGMT_TX;
2090
2091 pucFrameBuf = (PUINT_8)((ULONG)prMgmtFrame->prPacket + MAC_TX_RESERVED_FIELD);
2092
2093 kalMemCopy(pucFrameBuf, buf, len);
2094
2095 prMgmtFrame->u2FrameLength = len;
2096
2097 mboxSendMsg(prGlueInfo->prAdapter,
2098 MBOX_ID_0,
2099 (P_MSG_HDR_T)prMsgTxReq,
2100 MSG_SEND_METHOD_BUF);
2101
2102 i4Rslt = 0;
2103 } while (FALSE);
2104
2105 if ((i4Rslt != 0) && (prMsgTxReq != NULL)) {
2106 if (prMsgTxReq->prMgmtMsduInfo != NULL) {
2107 cnmMgtPktFree(prGlueInfo->prAdapter, prMsgTxReq->prMgmtMsduInfo);
2108 }
2109
2110 cnmMemFree(prGlueInfo->prAdapter, prMsgTxReq);
2111 }
2112
2113 return i4Rslt;
2114 }
2115
2116
2117 /*----------------------------------------------------------------------------*/
2118 /*!
2119 * @brief This routine is responsible for requesting to cancel the wait time
2120 * from transmitting a management frame on another channel
2121 *
2122 * @param
2123 *
2124 * @retval 0: successful
2125 * others: failure
2126 */
2127 /*----------------------------------------------------------------------------*/
2128 int
2129 mtk_cfg80211_mgmt_tx_cancel_wait (
2130 struct wiphy *wiphy,
2131 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
2132 struct net_device *ndev,
2133 #else
2134 struct wireless_dev *wdev,
2135 #endif /* LINUX_VERSION_CODE */
2136 u64 cookie
2137 )
2138 {
2139 P_GLUE_INFO_T prGlueInfo = NULL;
2140
2141 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
2142 ASSERT(prGlueInfo);
2143
2144 #if 1
2145 printk("--> %s()\n", __func__);
2146 #endif
2147
2148 /* not implemented */
2149
2150 return -EINVAL;
2151 }
2152
2153
2154 /*----------------------------------------------------------------------------*/
2155 /*!
2156 * @brief This routine is responsible for handling association request
2157 *
2158 * @param
2159 *
2160 * @retval 0: successful
2161 * others: failure
2162 */
2163 /*----------------------------------------------------------------------------*/
2164 int
2165 mtk_cfg80211_assoc (
2166 struct wiphy *wiphy,
2167 struct net_device *ndev,
2168 struct cfg80211_assoc_request *req
2169 )
2170 {
2171 P_GLUE_INFO_T prGlueInfo = NULL;
2172 PARAM_MAC_ADDRESS arBssid;
2173 #if CFG_SUPPORT_HOTSPOT_2_0
2174 PUINT_8 prDesiredIE = NULL;
2175 #endif
2176 WLAN_STATUS rStatus;
2177 UINT_32 u4BufLen;
2178
2179 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
2180 ASSERT(prGlueInfo);
2181
2182 kalMemZero(arBssid, MAC_ADDR_LEN);
2183 wlanQueryInformation(prGlueInfo->prAdapter,
2184 wlanoidQueryBssid,
2185 &arBssid[0],
2186 sizeof(arBssid),
2187 &u4BufLen);
2188
2189 /* 1. check BSSID */
2190 if(UNEQUAL_MAC_ADDR(arBssid, req->bss->bssid)) {
2191 /* wrong MAC address */
2192 DBGLOG(REQ, WARN, ("incorrect BSSID: ["MACSTR"] currently connected BSSID["MACSTR"]\n",
2193 MAC2STR(req->bss->bssid), MAC2STR(arBssid)));
2194 return -ENOENT;
2195 }
2196
2197 if (req->ie && req->ie_len > 0) {
2198 #if CFG_SUPPORT_HOTSPOT_2_0
2199 if (wextSrchDesiredHS20IE((PUINT_8)req->ie,
2200 req->ie_len,
2201 (PUINT_8 *)&prDesiredIE)) {
2202 rStatus = kalIoctl(prGlueInfo,
2203 wlanoidSetHS20Info,
2204 prDesiredIE,
2205 IE_SIZE(prDesiredIE),
2206 FALSE,
2207 FALSE,
2208 TRUE,
2209 FALSE,
2210 &u4BufLen);
2211 if (rStatus != WLAN_STATUS_SUCCESS) {
2212 //printk(KERN_INFO "[HS20] set HS20 assoc info error:%lx\n", rStatus);
2213 }
2214 }
2215
2216 if (wextSrchDesiredInterworkingIE((PUINT_8)req->ie,
2217 req->ie_len,
2218 (PUINT_8 *)&prDesiredIE)) {
2219 rStatus = kalIoctl(prGlueInfo,
2220 wlanoidSetInterworkingInfo,
2221 prDesiredIE,
2222 IE_SIZE(prDesiredIE),
2223 FALSE,
2224 FALSE,
2225 TRUE,
2226 FALSE,
2227 &u4BufLen);
2228 if (rStatus != WLAN_STATUS_SUCCESS) {
2229 //printk(KERN_INFO "[HS20] set Interworking assoc info error:%lx\n", rStatus);
2230 }
2231 }
2232
2233 if (wextSrchDesiredRoamingConsortiumIE((PUINT_8)req->ie,
2234 req->ie_len,
2235 (PUINT_8 *)&prDesiredIE)) {
2236 rStatus = kalIoctl(prGlueInfo,
2237 wlanoidSetRoamingConsortiumIEInfo,
2238 prDesiredIE,
2239 IE_SIZE(prDesiredIE),
2240 FALSE,
2241 FALSE,
2242 TRUE,
2243 FALSE,
2244 &u4BufLen);
2245 if (rStatus != WLAN_STATUS_SUCCESS) {
2246 //printk(KERN_INFO "[HS20] set RoamingConsortium assoc info error:%lx\n", rStatus);
2247 }
2248 }
2249 #endif
2250 }
2251
2252 rStatus = kalIoctl(prGlueInfo,
2253 wlanoidSetBssid,
2254 (PVOID) req->bss->bssid,
2255 MAC_ADDR_LEN,
2256 FALSE,
2257 FALSE,
2258 TRUE,
2259 FALSE,
2260 &u4BufLen);
2261
2262 if (rStatus != WLAN_STATUS_SUCCESS) {
2263 DBGLOG(REQ, WARN, ("set BSSID:%x\n", rStatus));
2264 return -EINVAL;
2265 }
2266
2267 return 0;
2268 }
2269
2270
2271 #if CONFIG_NL80211_TESTMODE
2272 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
2273 #define NLA_PUT(skb, attrtype, attrlen, data) \
2274 do { \
2275 if (unlikely(nla_put(skb, attrtype, attrlen, data) < 0)) \
2276 goto nla_put_failure; \
2277 } while(0)
2278
2279 #define NLA_PUT_TYPE(skb, type, attrtype, value) \
2280 do { \
2281 type __tmp = value; \
2282 NLA_PUT(skb, attrtype, sizeof(type), &__tmp); \
2283 } while(0)
2284
2285 #define NLA_PUT_U8(skb, attrtype, value) \
2286 NLA_PUT_TYPE(skb, u8, attrtype, value)
2287
2288 #define NLA_PUT_U16(skb, attrtype, value) \
2289 NLA_PUT_TYPE(skb, u16, attrtype, value)
2290
2291 #define NLA_PUT_U32(skb, attrtype, value) \
2292 NLA_PUT_TYPE(skb, u32, attrtype, value)
2293
2294 #define NLA_PUT_U64(skb, attrtype, value) \
2295 NLA_PUT_TYPE(skb, u64, attrtype, value)
2296
2297 #endif
2298
2299 #if CFG_SUPPORT_WAPI
2300 int
2301 mtk_cfg80211_testmode_set_key_ext(
2302 IN struct wiphy *wiphy,
2303 IN void *data,
2304 IN int len)
2305 {
2306 P_GLUE_INFO_T prGlueInfo = NULL;
2307 P_NL80211_DRIVER_SET_KEY_EXTS prParams = (P_NL80211_DRIVER_SET_KEY_EXTS)NULL;
2308 struct iw_encode_exts *prIWEncExt = (struct iw_encode_exts *)NULL;
2309 WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
2310 int fgIsValid = 0;
2311 UINT_32 u4BufLen = 0;
2312
2313 P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf;
2314 memset(keyStructBuf, 0, sizeof(keyStructBuf));
2315
2316 ASSERT(wiphy);
2317
2318 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
2319
2320 #if 1
2321 printk("--> %s()\n", __func__);
2322 #endif
2323
2324 if(data && len) {
2325 prParams = (P_NL80211_DRIVER_SET_KEY_EXTS)data;
2326 }
2327
2328 if(prParams) {
2329 prIWEncExt = (struct iw_encode_exts *) &prParams->ext;
2330 }
2331
2332 if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) {
2333 /* KeyID */
2334 prWpiKey->ucKeyID = prParams->key_index;
2335 prWpiKey->ucKeyID --;
2336 if (prWpiKey->ucKeyID > 1) {
2337 /* key id is out of range */
2338 //printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID);
2339 return -EINVAL;
2340 }
2341
2342 if (prIWEncExt->key_len != 32) {
2343 /* key length not valid */
2344 //printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len);
2345 return -EINVAL;
2346 }
2347
2348 //printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags);
2349
2350 if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
2351 prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY;
2352 prWpiKey->eDirection = ENUM_WPI_RX;
2353 }
2354 else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
2355 prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY;
2356 prWpiKey->eDirection = ENUM_WPI_RX_TX;
2357 }
2358
2359 //#if CFG_SUPPORT_WAPI
2360 //handle_sec_msg_final(prIWEncExt->key, 32, prIWEncExt->key, NULL);
2361 //#endif
2362 /* PN */
2363 memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE * 2);
2364
2365 /* BSSID */
2366 memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr, 6);
2367
2368 memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16);
2369 prWpiKey->u4LenWPIEK = 16;
2370
2371 memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16);
2372 prWpiKey->u4LenWPICK = 16;
2373
2374 rstatus = kalIoctl(prGlueInfo,
2375 wlanoidSetWapiKey,
2376 prWpiKey,
2377 sizeof(PARAM_WPI_KEY_T),
2378 FALSE,
2379 FALSE,
2380 TRUE,
2381 FALSE,
2382 &u4BufLen);
2383
2384 if (rstatus != WLAN_STATUS_SUCCESS) {
2385 //printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus);
2386 fgIsValid = -EFAULT;
2387 }
2388
2389 }
2390 return fgIsValid;
2391 }
2392 #endif
2393
2394 int
2395 mtk_cfg80211_testmode_get_sta_statistics(
2396 IN struct wiphy *wiphy,
2397 IN void *data,
2398 IN int len,
2399 IN P_GLUE_INFO_T prGlueInfo)
2400 {
2401 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2402 INT_32 i4Status = -EINVAL;
2403 UINT_32 u4BufLen;
2404 UINT_32 u4LinkScore;
2405 UINT_32 u4TotalError;
2406 UINT_32 u4TxExceedThresholdCount;
2407 UINT_32 u4TxTotalCount;
2408
2409 P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL;
2410 PARAM_GET_STA_STA_STATISTICS rQueryStaStatistics;
2411 struct sk_buff *skb;
2412
2413 ASSERT(wiphy);
2414 ASSERT(prGlueInfo);
2415
2416 if(data && len) {
2417 prParams = (P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS)data;
2418 }
2419
2420 if(!prParams->aucMacAddr) {
2421 DBGLOG(QM, TRACE,("%s MAC Address is NULL\n", __FUNCTION__));
2422 return -EINVAL;
2423 }
2424
2425 skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1);
2426
2427 if(!skb) {
2428 DBGLOG(QM, TRACE, ("%s allocate skb failed:%x\n", __FUNCTION__, rStatus));
2429 return -ENOMEM;
2430 }
2431
2432 DBGLOG(QM, TRACE,("Get ["MACSTR"] STA statistics\n", MAC2STR(prParams->aucMacAddr)));
2433
2434 kalMemZero(&rQueryStaStatistics, sizeof(rQueryStaStatistics));
2435 COPY_MAC_ADDR(rQueryStaStatistics.aucMacAddr, prParams->aucMacAddr);
2436
2437 rStatus = kalIoctl(prGlueInfo,
2438 wlanoidQueryStaStatistics,
2439 &rQueryStaStatistics,
2440 sizeof(rQueryStaStatistics),
2441 TRUE,
2442 FALSE,
2443 TRUE,
2444 TRUE,
2445 &u4BufLen);
2446
2447 /* Calcute Link Score */
2448 u4TxExceedThresholdCount = rQueryStaStatistics.u4TxExceedThresholdCount;
2449 u4TxTotalCount = rQueryStaStatistics.u4TxTotalCount;
2450 u4TotalError = rQueryStaStatistics.u4TxFailCount + rQueryStaStatistics.u4TxLifeTimeoutCount;
2451
2452 /* u4LinkScore 10~100 , ExceedThreshold ratio 0~90 only */
2453 /* u4LinkScore 0~9 , Drop packet ratio 0~9 and all packets exceed threshold */
2454 if(u4TxTotalCount) {
2455 if(u4TxExceedThresholdCount <= u4TxTotalCount) {
2456 u4LinkScore = (90 - ((u4TxExceedThresholdCount * 90) / u4TxTotalCount)) ;
2457 }
2458 else {
2459 u4LinkScore = 0;
2460 }
2461 }
2462 else {
2463 u4LinkScore = 90;
2464 }
2465
2466 u4LinkScore += 10;
2467
2468 if(u4LinkScore == 10) {
2469
2470 if(u4TotalError<=u4TxTotalCount) {
2471 u4LinkScore = (10 - ((u4TotalError * 10) / u4TxTotalCount)) ;
2472 }
2473 else {
2474 u4LinkScore = 0;
2475 }
2476
2477 }
2478
2479 if(u4LinkScore>100) {
2480 u4LinkScore = 100;
2481 }
2482
2483
2484 NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);
2485 NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_VERSION, NL80211_DRIVER_TESTMODE_VERSION);
2486 NLA_PUT(skb, NL80211_TESTMODE_STA_STATISTICS_MAC, MAC_ADDR_LEN, prParams->aucMacAddr);
2487 NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_LINK_SCORE, u4LinkScore);
2488 NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FLAG, rQueryStaStatistics.u4Flag);
2489
2490 /* FW part STA link status */
2491 NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_PER, rQueryStaStatistics.ucPer);
2492 NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_RSSI, rQueryStaStatistics.ucRcpi);
2493 NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_PHY_MODE, rQueryStaStatistics.u4PhyMode);
2494 NLA_PUT_U16(skb, NL80211_TESTMODE_STA_STATISTICS_TX_RATE, rQueryStaStatistics.u2LinkSpeed);
2495 NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_FAIL_CNT, rQueryStaStatistics.u4TxFailCount);
2496 NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TIMEOUT_CNT, rQueryStaStatistics.u4TxLifeTimeoutCount);
2497 NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_AIR_TIME, rQueryStaStatistics.u4TxAverageAirTime);
2498
2499 /* Driver part link status */
2500 NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_TOTAL_CNT, rQueryStaStatistics.u4TxTotalCount);
2501 NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_THRESHOLD_CNT, rQueryStaStatistics.u4TxExceedThresholdCount);
2502 NLA_PUT_U32(skb, NL80211_TESTMODE_STA_STATISTICS_AVG_PROCESS_TIME, rQueryStaStatistics.u4TxAverageProcessTime);
2503
2504 /* Network counter */
2505 NLA_PUT(
2506 skb,
2507 NL80211_TESTMODE_STA_STATISTICS_TC_EMPTY_CNT_ARRAY,
2508 sizeof(rQueryStaStatistics.au4TcResourceEmptyCount),
2509 rQueryStaStatistics.au4TcResourceEmptyCount);
2510
2511 /* Sta queue length */
2512 NLA_PUT(
2513 skb,
2514 NL80211_TESTMODE_STA_STATISTICS_TC_QUE_LEN_ARRAY,
2515 sizeof(rQueryStaStatistics.au4TcQueLen),
2516 rQueryStaStatistics.au4TcQueLen);
2517
2518 /* Global QM counter */
2519 NLA_PUT(
2520 skb,
2521 NL80211_TESTMODE_STA_STATISTICS_TC_AVG_QUE_LEN_ARRAY,
2522 sizeof(rQueryStaStatistics.au4TcAverageQueLen),
2523 rQueryStaStatistics.au4TcAverageQueLen);
2524
2525 NLA_PUT(
2526 skb,
2527 NL80211_TESTMODE_STA_STATISTICS_TC_CUR_QUE_LEN_ARRAY,
2528 sizeof(rQueryStaStatistics.au4TcCurrentQueLen),
2529 rQueryStaStatistics.au4TcCurrentQueLen);
2530
2531 /* Reserved field */
2532 NLA_PUT(
2533 skb,
2534 NL80211_TESTMODE_STA_STATISTICS_RESERVED_ARRAY,
2535 sizeof(rQueryStaStatistics.au4Reserved),
2536 rQueryStaStatistics.au4Reserved);
2537
2538 i4Status = cfg80211_testmode_reply(skb);
2539
2540 nla_put_failure:
2541 return i4Status;
2542 }
2543
2544 int
2545 mtk_cfg80211_testmode_get_link_detection(
2546 IN struct wiphy *wiphy,
2547 IN void *data,
2548 IN int len,
2549 IN P_GLUE_INFO_T prGlueInfo)
2550 {
2551
2552
2553 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2554 INT_32 i4Status = -EINVAL;
2555 UINT_32 u4BufLen;
2556
2557 PARAM_802_11_STATISTICS_STRUCT_T rStatistics;
2558 struct sk_buff *skb;
2559
2560 ASSERT(wiphy);
2561 ASSERT(prGlueInfo);
2562
2563 skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1);
2564
2565 if(!skb) {
2566 DBGLOG(QM, TRACE, ("%s allocate skb failed:%x\n", __FUNCTION__, rStatus));
2567 return -ENOMEM;
2568 }
2569
2570 kalMemZero(&rStatistics, sizeof(rStatistics));
2571
2572 rStatus = kalIoctl(prGlueInfo,
2573 wlanoidQueryStatistics,
2574 &rStatistics,
2575 sizeof(rStatistics),
2576 TRUE,
2577 TRUE,
2578 TRUE,
2579 FALSE,
2580 &u4BufLen);
2581
2582 NLA_PUT_U8(skb, NL80211_TESTMODE_STA_STATISTICS_INVALID, 0);
2583 NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_FAIL_CNT, rStatistics.rFailedCount.QuadPart);
2584 NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_RETRY_CNT, rStatistics.rRetryCount.QuadPart);
2585 NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_TX_MULTI_RETRY_CNT, rStatistics.rMultipleRetryCount.QuadPart);
2586 NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_ACK_FAIL_CNT, rStatistics.rACKFailureCount.QuadPart);
2587 NLA_PUT_U64(skb, NL80211_TESTMODE_LINK_FCS_ERR_CNT, rStatistics.rFCSErrorCount.QuadPart);
2588
2589 i4Status = cfg80211_testmode_reply(skb);
2590
2591 nla_put_failure:
2592 return i4Status;
2593 }
2594
2595 int
2596 mtk_cfg80211_testmode_sw_cmd(
2597 IN struct wiphy *wiphy,
2598 IN void *data,
2599 IN int len)
2600 {
2601 P_GLUE_INFO_T prGlueInfo = NULL;
2602 P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS)NULL;
2603 WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
2604 int fgIsValid = 0;
2605 UINT_32 u4SetInfoLen = 0;
2606
2607 ASSERT(wiphy);
2608
2609 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
2610
2611 #if 1
2612 printk("--> %s()\n", __func__);
2613 #endif
2614
2615 if(data && len)
2616 prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS)data;
2617
2618 if(prParams) {
2619 if(prParams->set == 1){
2620 rstatus = kalIoctl(prGlueInfo,
2621 (PFN_OID_HANDLER_FUNC)wlanoidSetSwCtrlWrite,
2622 &prParams->adr,
2623 (UINT_32)8,
2624 FALSE,
2625 FALSE,
2626 TRUE,
2627 FALSE,
2628 &u4SetInfoLen);
2629 }
2630 }
2631
2632 if (WLAN_STATUS_SUCCESS != rstatus) {
2633 fgIsValid = -EFAULT;
2634 }
2635
2636 return fgIsValid;
2637 }
2638
2639
2640 #if CFG_SUPPORT_HOTSPOT_2_0
2641 int
2642 mtk_cfg80211_testmode_hs20_cmd(
2643 IN struct wiphy *wiphy,
2644 IN void *data,
2645 IN int len)
2646 {
2647 P_GLUE_INFO_T prGlueInfo = NULL;
2648 struct wpa_driver_hs20_data_s *prParams = NULL;
2649 WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
2650 int fgIsValid = 0;
2651 UINT_32 u4SetInfoLen = 0;
2652
2653 ASSERT(wiphy);
2654
2655 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
2656
2657 #if 1
2658 printk("--> %s()\n", __func__);
2659 #endif
2660
2661 if(data && len)
2662 prParams = (struct wpa_driver_hs20_data_s *)data;
2663
2664 printk("[%s] Cmd Type (%d)\n", __func__, prParams->CmdType);
2665
2666 if(prParams) {
2667 int i;
2668
2669 switch(prParams->CmdType){
2670 case HS20_CMD_ID_SET_BSSID_POOL:
2671 printk("[%s] fgBssidPoolIsEnable (%d)\n", __func__, prParams->hs20_set_bssid_pool.fgBssidPoolIsEnable);
2672 printk("[%s] ucNumBssidPool (%d)\n", __func__, prParams->hs20_set_bssid_pool.ucNumBssidPool);
2673
2674 for(i=0; i<prParams->hs20_set_bssid_pool.ucNumBssidPool; i++){
2675 printk("[%s][%d]["MACSTR"]\n", __func__, i, MAC2STR(prParams->hs20_set_bssid_pool.arBssidPool[i]));
2676 }
2677 rstatus = kalIoctl(prGlueInfo,
2678 (PFN_OID_HANDLER_FUNC)wlanoidSetHS20BssidPool,
2679 &prParams->hs20_set_bssid_pool,
2680 sizeof(struct param_hs20_set_bssid_pool),
2681 FALSE,
2682 FALSE,
2683 TRUE,
2684 FALSE,
2685 &u4SetInfoLen);
2686 break;
2687 default :
2688 printk("[%s] Unknown Cmd Type (%d)\n", __func__, prParams->CmdType);
2689 rstatus = WLAN_STATUS_FAILURE;
2690
2691 }
2692
2693 }
2694
2695 if (WLAN_STATUS_SUCCESS != rstatus) {
2696 fgIsValid = -EFAULT;
2697 }
2698
2699 return fgIsValid;
2700 }
2701
2702 #endif
2703 int
2704 mtk_cfg80211_testmode_set_poorlink_param(
2705 IN struct wiphy *wiphy,
2706 IN void *data,
2707 IN int len,
2708 IN P_GLUE_INFO_T prGlueInfo)
2709 {
2710 int fgIsValid = 0;
2711 P_NL80211_DRIVER_POORLINK_PARAMS prParams = NULL;
2712
2713 ASSERT(wiphy);
2714 ASSERT(prGlueInfo);
2715
2716 if(data && len) {
2717 prParams = (P_NL80211_DRIVER_POORLINK_PARAMS)data;
2718 }
2719 if(prParams->ucLinkSpeed)
2720 prGlueInfo->u4LinkspeedThreshold = prParams->ucLinkSpeed*10;
2721 if(prParams->cRssi)
2722 prGlueInfo->i4RssiThreshold = prParams->cRssi;
2723 if(!prGlueInfo->fgPoorlinkValid)
2724 prGlueInfo->fgPoorlinkValid = 1;
2725 #if 0
2726 printk("poorlink set param valid(%d)rssi(%d)linkspeed(%d)\n",
2727 prGlueInfo->fgPoorlinkValid,
2728 prGlueInfo->i4RssiThreshold,
2729 prGlueInfo->u4LinkspeedThreshold
2730 );
2731 #endif
2732
2733 return fgIsValid;
2734
2735 }
2736
2737 int mtk_cfg80211_testmode_cmd(
2738 IN struct wiphy *wiphy,
2739 IN void *data,
2740 IN int len
2741 )
2742 {
2743 P_GLUE_INFO_T prGlueInfo = NULL;
2744 P_NL80211_DRIVER_TEST_MODE_PARAMS prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS)NULL;
2745 INT_32 i4Status = -EINVAL;
2746 #if CFG_SUPPORT_HOTSPOT_2_0
2747 BOOLEAN fgIsValid = 0;
2748 #endif
2749
2750 ASSERT(wiphy);
2751
2752 prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
2753
2754 if(data && len) {
2755 prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS)data;
2756 }
2757 else {
2758 DBGLOG(REQ, ERROR, ("mtk_cfg80211_testmode_cmd, data is NULL\n"));
2759 return i4Status;
2760 }
2761
2762 /* Clear the version byte */
2763 prParams->index = prParams->index & ~ BITS(24,31);
2764
2765 if(prParams){
2766 switch(prParams->index){
2767 case TESTMODE_CMD_ID_SW_CMD: /* SW cmd */
2768 i4Status = mtk_cfg80211_testmode_sw_cmd(wiphy, data, len);
2769 break;
2770 case TESTMODE_CMD_ID_WAPI: /* WAPI */
2771 #if CFG_SUPPORT_WAPI
2772 i4Status = mtk_cfg80211_testmode_set_key_ext(wiphy, data, len);
2773 #endif
2774 break;
2775 case TESTMODE_CMD_ID_SUSPEND:
2776 {
2777 P_NL80211_DRIVER_SUSPEND_PARAMS prParams = (P_NL80211_DRIVER_SUSPEND_PARAMS)data;
2778
2779 if (prParams->suspend == 1){
2780 wlanHandleSystemSuspend();
2781 if (prGlueInfo->prAdapter->fgIsP2PRegistered)
2782 p2pHandleSystemSuspend();
2783 i4Status = 0;
2784 } else if (prParams->suspend == 0) {
2785 wlanHandleSystemResume();
2786 if (prGlueInfo->prAdapter->fgIsP2PRegistered)
2787 p2pHandleSystemResume();
2788 i4Status = 0;
2789 }
2790 break;
2791 }
2792 case TESTMODE_CMD_ID_STATISTICS:
2793 i4Status = mtk_cfg80211_testmode_get_sta_statistics(wiphy, data, len, prGlueInfo);
2794 break;
2795 case TESTMODE_CMD_ID_LINK_DETECT:
2796 i4Status = mtk_cfg80211_testmode_get_link_detection(wiphy, data, len, prGlueInfo);
2797 break;
2798 case TESTMODE_CMD_ID_POORLINK:
2799 i4Status = mtk_cfg80211_testmode_set_poorlink_param(wiphy, data, len, prGlueInfo);
2800 break;
2801
2802 #if CFG_SUPPORT_HOTSPOT_2_0
2803 case TESTMODE_CMD_ID_HS20:
2804 if(mtk_cfg80211_testmode_hs20_cmd(wiphy, data, len))
2805 fgIsValid = TRUE;
2806 break;
2807 #endif
2808 default:
2809 i4Status = -EINVAL;
2810 break;
2811 }
2812 }
2813
2814 return i4Status;
2815 }
2816 int
2817 mtk_cfg80211_testmode_get_scan_done(
2818 IN struct wiphy *wiphy,
2819 IN void *data,
2820 IN int len,
2821 IN P_GLUE_INFO_T prGlueInfo)
2822 {
2823 #define NL80211_TESTMODE_P2P_SCANDONE_INVALID 0
2824 #define NL80211_TESTMODE_P2P_SCANDONE_STATUS 1
2825 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2826 INT_32 i4Status = -EINVAL,READY_TO_BEAM=0;
2827
2828
2829 // P_NL80211_DRIVER_GET_STA_STATISTICS_PARAMS prParams = NULL;
2830 struct sk_buff *skb;
2831
2832 ASSERT(wiphy);
2833 ASSERT(prGlueInfo);
2834
2835 skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(UINT_32) );
2836 READY_TO_BEAM=(UINT_32)(prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone)&(!prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest);
2837 DBGLOG(QM, TRACE, ("NFC:GOInitialDone[%d] and P2PScanning[%d]\n",prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsGOInitialDone,prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->rScanReqInfo.fgIsScanRequest));
2838
2839
2840 if(!skb) {
2841 DBGLOG(QM, TRACE, ("%s allocate skb failed:%x\n", __FUNCTION__, rStatus));
2842 return -ENOMEM;
2843 }
2844
2845
2846
2847
2848 NLA_PUT_U8(skb, NL80211_TESTMODE_P2P_SCANDONE_INVALID, 0);
2849 NLA_PUT_U32(skb, NL80211_TESTMODE_P2P_SCANDONE_STATUS, READY_TO_BEAM);
2850
2851
2852 i4Status = cfg80211_testmode_reply(skb);
2853
2854 nla_put_failure:
2855 return i4Status;
2856 }
2857 #if CFG_AUTO_CHANNEL_SEL_SUPPORT
2858
2859 mtk_cfg80211_testmode_get_lte_channel(
2860 IN struct wiphy *wiphy,
2861 IN void *data,
2862 IN int len,
2863 IN P_GLUE_INFO_T prGlueInfo)
2864 {
2865
2866 BOOLEAN fgIsReady=FALSE,fgIsFistRecord=TRUE;
2867 BOOLEAN fgIsPureAP;
2868
2869
2870 UINT_8 ucIdx=0,ucMax_24G_Chn_List=11 ,i=0;
2871
2872 INT_32 i4Status = -EINVAL;
2873 UINT_32 u4BufLen;
2874 UINT_32 AcsChnRepot[4];
2875
2876 struct sk_buff *skb;
2877
2878 WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
2879
2880
2881 P_PARAM_GET_CHN_LOAD prParams = NULL;
2882 PARAM_GET_CHN_LOAD rQueryLTEChn;
2883 PARAM_PREFER_CHN_INFO PreferChannels[2];
2884 P_PARAM_CHN_LOAD_INFO prChnLoad;
2885
2886
2887 P_DOMAIN_INFO_ENTRY prDomainInfo;
2888 P_DOMAIN_SUBBAND_INFO prSubband;
2889 RF_CHANNEL_INFO_T aucChannelList[14];
2890
2891
2892 ASSERT(wiphy);
2893 ASSERT(prGlueInfo);
2894
2895
2896 //HotSpot Mode
2897 fgIsPureAP=prGlueInfo->prAdapter->rWifiVar.prP2pFsmInfo->fgIsApMode;
2898
2899 if(data && len) {
2900 prParams = (P_NL80211_DRIVER_GET_LTE_PARAMS)data;
2901 }
2902
2903 //Prepare Reply skb buffer
2904 skb = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(PARAM_GET_STA_STA_STATISTICS) + 1);
2905 if(!skb) {
2906 DBGLOG(QM, TRACE, ("%s allocate skb failed:%x\n", __FUNCTION__, rStatus));
2907 return -ENOMEM;
2908 }
2909
2910 DBGLOG(P2P, INFO,("[Auto Channel]Get LTE Channels\n"));
2911
2912 kalMemZero(&rQueryLTEChn, sizeof(rQueryLTEChn));
2913
2914 //Query LTE Safe Channels
2915 rStatus = kalIoctl(prGlueInfo,
2916 wlanoidQueryACSChannelList,
2917 &rQueryLTEChn,
2918 sizeof(rQueryLTEChn),
2919 TRUE,
2920 FALSE,
2921 TRUE,
2922 TRUE,
2923 &u4BufLen);
2924
2925 {
2926 fgIsReady=prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.fgDataReadyBit;
2927 PreferChannels[0].u2APNum=0xFFFF;
2928 PreferChannels[1].u2APNum=0xFFFF;
2929 //In LTE Mode, Hotspot pick up channels from ch4.
2930 #ifdef CONFIG_MTK_LTE_SUPPORT
2931 if (fgIsPureAP) {
2932 ucIdx=3; //SKIP LTE Channels 1~3
2933 }
2934 #endif
2935 //Get the Maximun channel List in 2.4G Bands
2936
2937 prDomainInfo = rlmDomainGetDomainInfo(prGlueInfo->prAdapter);
2938 ASSERT(prDomainInfo);
2939
2940 // 2. Get current domain channel list
2941 rlmDomainGetChnlList(prGlueInfo->prAdapter,
2942 BAND_2G4,
2943 14,
2944 &ucMax_24G_Chn_List,
2945 aucChannelList);
2946 for(ucIdx;ucIdx< ucMax_24G_Chn_List;ucIdx++) {
2947
2948 prChnLoad= (P_PARAM_CHN_LOAD_INFO)&(prGlueInfo->prAdapter->rWifiVar.rChnLoadInfo.rEachChnLoad[ucIdx]);
2949 if (PreferChannels[0].u2APNum >= prChnLoad->u2APNum ) {
2950 PreferChannels[1].ucChannel=PreferChannels[0].ucChannel;
2951 PreferChannels[1].u2APNum=PreferChannels[0].u2APNum;
2952
2953 PreferChannels[0].ucChannel=ucIdx;
2954 PreferChannels[0].u2APNum=prChnLoad->u2APNum;
2955 }
2956 else {
2957 if (fgIsFistRecord==1 || PreferChannels[1].u2APNum >= prChnLoad->u2APNum) {
2958 fgIsFistRecord=FALSE;
2959 PreferChannels[1].ucChannel=prChnLoad->ucChannel;
2960 PreferChannels[1].u2APNum=prChnLoad->u2APNum;
2961 }
2962 }
2963 DBGLOG(P2P, INFO,("[Auto Channel] AP Num: Channel[%d]=%d\n",ucIdx+1,prChnLoad->u2APNum));
2964 }
2965 //AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1-1] =BITS((rQueryLTEChn.rLteSafeChnList.ucChannelLow-1),(rQueryLTEChn.rLteSafeChnList.ucChannelHigh-1));
2966 AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1-1]=fgIsReady?BIT(31):0;
2967 AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1-1]|=BIT(PreferChannels[1].ucChannel) | BIT(PreferChannels[0].ucChannel);
2968 }
2969
2970 //ToDo: Support 5G Channel Selection
2971 AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34-1] =0x11223344;
2972 AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149-1] =0x55667788;
2973 AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184-1] =0x99AABBCC;
2974
2975
2976 NLA_PUT_U8(skb, NL80211_TESTMODE_AVAILABLE_CHAN_INVALID, 0);
2977 NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1, AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_2G_BASE_1-1]);
2978 NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34, AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_34-1]);
2979 NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149, AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_149-1]);
2980 NLA_PUT_U32(skb, NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184, AcsChnRepot[NL80211_TESTMODE_AVAILABLE_CHAN_5G_BASE_184-1]);
2981
2982 DBGLOG(P2P, INFO,("[Auto Channel]Relpy AcsChanInfo[%x:%x:%x:%x]\n",AcsChnRepot[0],AcsChnRepot[1],AcsChnRepot[2],AcsChnRepot[3]));
2983
2984 i4Status = cfg80211_testmode_reply(skb);
2985
2986 nla_put_failure:
2987 return i4Status;
2988
2989 }
2990 #endif
2991 #endif
2992