6cfaca00649f3081035a07f91229449872e8f167
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / combo_mt66xx / mt6628 / 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 ** 11 23 2012 yuche.tsai
18 ** [ALPS00398671] [Acer-Tablet] Remove Wi-Fi Direct completely
19 ** Fix bug of WiFi may reboot under user load, when WiFi Direct is removed..
20 ** 
21 ** 09 12 2012 wcpadmin
22 ** [ALPS00276400] Remove MTK copyright and legal header on GPL/LGPL related packages
23 ** .
24 ** 
25 ** 08 30 2012 chinglan.wang
26 ** [ALPS00349664] [6577JB][WIFI] Phone can not connect to AP secured with AES via WPS in 802.11n Only
27 ** .
28  *
29 **
30 */
31
32 /*******************************************************************************
33 *                         C O M P I L E R   F L A G S
34 ********************************************************************************
35 */
36
37 /*******************************************************************************
38 *                    E X T E R N A L   R E F E R E N C E S
39 ********************************************************************************
40 */
41 #include "gl_os.h"
42 #include "debug.h"
43 #include "wlan_lib.h"
44 #include "gl_wext.h"
45 #include "precomp.h"
46
47 /*******************************************************************************
48 *                              C O N S T A N T S
49 ********************************************************************************
50 */
51
52 /*******************************************************************************
53 *                             D A T A   T Y P E S
54 ********************************************************************************
55 */
56
57 /*******************************************************************************
58 *                            P U B L I C   D A T A
59 ********************************************************************************
60 */
61
62 #if CFG_SUPPORT_WAPI
63     extern UINT_8 keyStructBuf[1024];   /* add/remove key shared buffer */
64 #else
65     extern UINT_8 keyStructBuf[100];   /* add/remove key shared buffer */
66 #endif
67
68 /*******************************************************************************
69 *                           P R I V A T E   D A T A
70 ********************************************************************************
71 */
72
73 /*******************************************************************************
74 *                                 M A C R O S
75 ********************************************************************************
76 */
77
78 /*******************************************************************************
79 *                   F U N C T I O N   D E C L A R A T I O N S
80 ********************************************************************************
81 */
82
83 /*******************************************************************************
84 *                              F U N C T I O N S
85 ********************************************************************************
86 */
87
88 /*----------------------------------------------------------------------------*/
89 /*!
90  * @brief This routine is responsible for change STA type between
91  *        1. Infrastructure Client (Non-AP STA)
92  *        2. Ad-Hoc IBSS
93  *
94  * @param
95  *
96  * @retval 0:       successful
97  *         others:  failure
98  */
99 /*----------------------------------------------------------------------------*/
100 int 
101 mtk_cfg80211_change_iface (
102     struct wiphy *wiphy,
103     struct net_device *ndev,
104     enum nl80211_iftype type,
105     u32 *flags,
106     struct vif_params *params
107     )
108 {
109     P_GLUE_INFO_T prGlueInfo = NULL;
110     WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
111     ENUM_PARAM_OP_MODE_T eOpMode;
112     UINT_32 u4BufLen;
113
114     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
115     ASSERT(prGlueInfo);
116
117     if(type == NL80211_IFTYPE_STATION) {
118         eOpMode = NET_TYPE_INFRA;
119     }
120     else if(type == NL80211_IFTYPE_ADHOC) {
121         eOpMode = NET_TYPE_IBSS;
122     }
123     else {
124         return -EINVAL;
125     }
126
127     rStatus = kalIoctl(prGlueInfo,
128             wlanoidSetInfrastructureMode,
129             &eOpMode,
130             sizeof(eOpMode),
131             FALSE,
132             FALSE,
133             TRUE,
134             FALSE,
135             &u4BufLen);
136     
137     if (rStatus != WLAN_STATUS_SUCCESS) {
138         DBGLOG(REQ, WARN, ("set infrastructure mode error:%lx\n", rStatus));
139     }
140
141     /* reset wpa info */
142     prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
143     prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
144     prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
145     prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
146     prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
147 #if CFG_SUPPORT_802_11W
148     prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
149 #endif
150
151     return 0;
152 }
153
154
155 /*----------------------------------------------------------------------------*/
156 /*!
157  * @brief This routine is responsible for adding key 
158  *
159  * @param 
160  *
161  * @retval 0:       successful
162  *         others:  failure
163  */
164 /*----------------------------------------------------------------------------*/
165 int
166 mtk_cfg80211_add_key (
167     struct wiphy *wiphy,
168     struct net_device *ndev,
169     u8 key_index,
170     bool pairwise,
171     const u8 *mac_addr,
172     struct key_params *params
173     )
174 {
175     PARAM_KEY_T rKey;
176     P_GLUE_INFO_T prGlueInfo = NULL;
177     WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
178     INT_32 i4Rslt = -EINVAL;
179     UINT_32 u4BufLen = 0;
180     UINT_8 tmp1[8];
181     UINT_8 tmp2[8];
182
183     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
184     ASSERT(prGlueInfo);
185     
186     kalMemZero(&rKey, sizeof(PARAM_KEY_T));
187
188     rKey.u4KeyIndex = key_index;
189     
190     if(mac_addr) {
191         COPY_MAC_ADDR(rKey.arBSSID, mac_addr);
192         if ((rKey.arBSSID[0] == 0x00) && (rKey.arBSSID[1] == 0x00) && (rKey.arBSSID[2] == 0x00) &&
193             (rKey.arBSSID[3] == 0x00) && (rKey.arBSSID[4] == 0x00) && (rKey.arBSSID[5] == 0x00)) {
194             rKey.arBSSID[0] = 0xff;
195             rKey.arBSSID[1] = 0xff;
196             rKey.arBSSID[2] = 0xff;
197             rKey.arBSSID[3] = 0xff;
198             rKey.arBSSID[4] = 0xff;
199             rKey.arBSSID[5] = 0xff;
200         }
201         if (rKey.arBSSID[0] != 0xFF) {
202             rKey.u4KeyIndex |= BIT(31);
203             if ((rKey.arBSSID[0] != 0x00) || (rKey.arBSSID[1] != 0x00) || (rKey.arBSSID[2] != 0x00) ||
204                 (rKey.arBSSID[3] != 0x00) || (rKey.arBSSID[4] != 0x00) || (rKey.arBSSID[5] != 0x00))
205             rKey.u4KeyIndex |= BIT(30);
206         }
207     }
208     else {
209             rKey.arBSSID[0] = 0xff;
210             rKey.arBSSID[1] = 0xff;
211             rKey.arBSSID[2] = 0xff;
212             rKey.arBSSID[3] = 0xff;
213             rKey.arBSSID[4] = 0xff;
214             rKey.arBSSID[5] = 0xff;
215             //rKey.u4KeyIndex |= BIT(31); //Enable BIT 31 will make tx use bc key id, should use pairwise key id 0 
216     }
217     
218     if(params->key) {
219         //rKey.aucKeyMaterial[0] = kalMemAlloc(params->key_len, VIR_MEM_TYPE);
220         kalMemCopy(rKey.aucKeyMaterial, params->key, params->key_len);
221         if (params->key_len == 32) {
222             kalMemCopy(tmp1, &params->key[16], 8);
223             kalMemCopy(tmp2, &params->key[24], 8);        
224             kalMemCopy(&rKey.aucKeyMaterial[16], tmp2, 8);
225             kalMemCopy(&rKey.aucKeyMaterial[24], tmp1, 8);
226         }
227     }
228
229     rKey.u4KeyLength = params->key_len;
230     rKey.u4Length =  ((UINT_32)&(((P_P2P_PARAM_KEY_T)0)->aucKeyMaterial)) + rKey.u4KeyLength;
231     
232     rStatus = kalIoctl(prGlueInfo,
233             wlanoidSetAddKey,
234             &rKey,
235             rKey.u4Length,
236             FALSE,
237             FALSE,
238             TRUE,
239             FALSE,
240             &u4BufLen);
241     
242     if (rStatus == WLAN_STATUS_SUCCESS)
243         i4Rslt = 0;
244
245     return i4Rslt;
246 }
247
248
249 /*----------------------------------------------------------------------------*/
250 /*!
251  * @brief This routine is responsible for getting key for specified STA
252  *
253  * @param 
254  *
255  * @retval 0:       successful
256  *         others:  failure
257  */
258 /*----------------------------------------------------------------------------*/
259 int 
260 mtk_cfg80211_get_key (
261     struct wiphy *wiphy,
262     struct net_device *ndev,
263     u8 key_index,
264     bool pairwise,
265     const u8 *mac_addr,
266     void *cookie,
267     void (*callback)(void *cookie, struct key_params*)
268     )
269 {
270     P_GLUE_INFO_T prGlueInfo = NULL;
271
272     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
273     ASSERT(prGlueInfo);
274
275 #if 1
276     printk("--> %s()\n", __func__);
277 #endif
278
279     /* not implemented */
280
281     return -EINVAL;
282 }
283
284
285 /*----------------------------------------------------------------------------*/
286 /*!
287  * @brief This routine is responsible for removing key for specified STA
288  *
289  * @param 
290  *
291  * @retval 0:       successful
292  *         others:  failure
293  */
294 /*----------------------------------------------------------------------------*/
295 int
296 mtk_cfg80211_del_key (
297     struct wiphy *wiphy,
298     struct net_device *ndev,
299     u8 key_index,
300     bool pairwise,
301     const u8 *mac_addr
302     )
303 {
304     P_GLUE_INFO_T prGlueInfo = NULL;
305     WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
306     PARAM_REMOVE_KEY_T rRemoveKey;
307     UINT_32 u4BufLen = 0;
308     INT_32 i4Rslt = -EINVAL;
309
310     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
311     ASSERT(prGlueInfo);
312
313     kalMemZero(&rRemoveKey, sizeof(PARAM_REMOVE_KEY_T));
314     if(mac_addr)
315         COPY_MAC_ADDR(rRemoveKey.arBSSID, mac_addr);
316     rRemoveKey.u4KeyIndex = key_index;
317     rRemoveKey.u4Length = sizeof(PARAM_REMOVE_KEY_T);
318     
319
320     rStatus = kalIoctl(prGlueInfo,
321             wlanoidSetRemoveKey,
322             &rRemoveKey,
323             rRemoveKey.u4Length,
324             FALSE,
325             FALSE,
326             TRUE,
327             FALSE,
328             &u4BufLen);
329
330     if (rStatus != WLAN_STATUS_SUCCESS) {
331         DBGLOG(REQ, WARN, ("remove key error:%lx\n", rStatus));
332     }
333     else {
334         i4Rslt = 0;
335     }
336
337     return i4Rslt;
338 }
339
340
341 /*----------------------------------------------------------------------------*/
342 /*!
343  * @brief This routine is responsible for setting default key on an interface
344  *
345  * @param 
346  *
347  * @retval 0:       successful
348  *         others:  failure
349  */
350 /*----------------------------------------------------------------------------*/
351 int 
352 mtk_cfg80211_set_default_key (
353     struct wiphy *wiphy,
354     struct net_device *ndev,
355     u8 key_index,
356     bool unicast,
357     bool multicast
358     )
359 {
360     P_GLUE_INFO_T prGlueInfo = NULL;
361
362     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
363     ASSERT(prGlueInfo);
364
365 #if 1
366     printk("--> %s()\n", __func__);
367 #endif
368
369     /* not implemented */
370
371     return -EINVAL;
372 }
373
374
375 /*----------------------------------------------------------------------------*/
376 /*!
377  * @brief This routine is responsible for getting station information such as RSSI
378  *
379  * @param 
380  *
381  * @retval 0:       successful
382  *         others:  failure
383  */
384 /*----------------------------------------------------------------------------*/
385
386 int
387 mtk_cfg80211_get_station (
388     struct wiphy *wiphy,
389     struct net_device *ndev,
390     u8 *mac,
391     struct station_info *sinfo
392     )
393 {
394     P_GLUE_INFO_T prGlueInfo = NULL;
395     WLAN_STATUS rStatus;
396     PARAM_MAC_ADDRESS arBssid;
397     UINT_32 u4BufLen, u4Rate;
398     INT_32 i4Rssi;
399
400     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
401     ASSERT(prGlueInfo);
402
403     kalMemZero(arBssid, MAC_ADDR_LEN);
404     wlanQueryInformation(prGlueInfo->prAdapter,
405             wlanoidQueryBssid,
406             &arBssid[0],
407             sizeof(arBssid),
408             &u4BufLen);
409
410     /* 1. check BSSID */
411     if(UNEQUAL_MAC_ADDR(arBssid, mac)) {
412         /* wrong MAC address */
413         DBGLOG(REQ, WARN, ("incorrect BSSID: ["MACSTR"] currently connected BSSID["MACSTR"]\n", 
414                     MAC2STR(mac), MAC2STR(arBssid)));
415         return -ENOENT;
416     }
417
418     /* 2. fill TX rate */
419     rStatus = kalIoctl(prGlueInfo,
420         wlanoidQueryLinkSpeed,
421         &u4Rate,
422         sizeof(u4Rate),
423         TRUE,
424         FALSE,
425         FALSE,
426         FALSE,
427         &u4BufLen);
428
429     if (rStatus != WLAN_STATUS_SUCCESS) {
430         DBGLOG(REQ, WARN, ("unable to retrieve link speed\n"));
431     }
432     else {
433         sinfo->filled |= STATION_INFO_TX_BITRATE;
434         sinfo->txrate.legacy = u4Rate / 1000; /* convert from 100bps to 100kbps */
435     }
436
437     if(prGlueInfo->eParamMediaStateIndicated != PARAM_MEDIA_STATE_CONNECTED) {
438         /* not connected */
439         DBGLOG(REQ, WARN, ("not yet connected\n"));
440     }
441     else {
442         /* 3. fill RSSI */
443         rStatus = kalIoctl(prGlueInfo,
444                 wlanoidQueryRssi,
445                 &i4Rssi,
446                 sizeof(i4Rssi),
447                 TRUE,
448                 FALSE,
449                 FALSE,
450                 FALSE,
451                 &u4BufLen);
452         
453         if (rStatus != WLAN_STATUS_SUCCESS) {
454             DBGLOG(REQ, WARN, ("unable to retrieve link speed\n"));
455         }
456         else {
457             sinfo->filled |= STATION_INFO_SIGNAL;
458             //in the cfg80211 layer, the signal is a signed char variable.
459             if(i4Rssi < -128)
460                 sinfo->signal = -128;
461             else
462                 sinfo->signal = i4Rssi; /* dBm */
463         }
464     }
465
466     sinfo->rx_packets = prGlueInfo->rNetDevStats.rx_packets;
467     sinfo->filled |= STATION_INFO_TX_PACKETS;
468     sinfo->tx_packets = prGlueInfo->rNetDevStats.tx_packets;
469     sinfo->filled |= STATION_INFO_TX_FAILED;
470
471 #if 1
472    {
473             WLAN_STATUS rStatus;
474             UINT_32 u4XmitError = 0;
475 //           UINT_32 u4XmitOk = 0;
476 //          UINT_32 u4RecvError = 0;
477 //           UINT_32 u4RecvOk = 0;
478 //           UINT_32 u4BufLen;
479
480            /* @FIX ME: need a more clear way to do this */
481
482
483             rStatus = kalIoctl(prGlueInfo,
484                     wlanoidQueryXmitError,
485                     &u4XmitError,
486                     sizeof(UINT_32),
487                     TRUE,
488                     TRUE,
489                     TRUE,
490                     FALSE,
491                     &u4BufLen);
492
493            prGlueInfo->rNetDevStats.tx_errors = u4XmitError;
494
495    }
496 #else
497          prGlueInfo->rNetDevStats.tx_errors = 0;
498 #endif
499
500     sinfo->tx_failed = prGlueInfo->rNetDevStats.tx_errors;
501
502     return 0;
503 }
504
505
506 /*----------------------------------------------------------------------------*/
507 /*!
508  * @brief This routine is responsible for requesting to do a scan
509  *
510  * @param 
511  *
512  * @retval 0:       successful
513  *         others:  failure
514  */
515 /*----------------------------------------------------------------------------*/
516 int 
517 mtk_cfg80211_scan (
518     struct wiphy *wiphy,
519     struct net_device *ndev,
520     struct cfg80211_scan_request *request
521     )
522 {
523     P_GLUE_INFO_T prGlueInfo = NULL;
524     WLAN_STATUS rStatus;
525     UINT_32 u4BufLen;
526     PARAM_SCAN_REQUEST_EXT_T rScanRequest;
527
528     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
529     ASSERT(prGlueInfo);
530     
531     kalMemZero(&rScanRequest, sizeof(PARAM_SCAN_REQUEST_EXT_T));
532     
533     /* check if there is any pending scan not yet finished */
534     if(prGlueInfo->prScanRequest != NULL) {
535         return -EBUSY;
536     }
537
538     if(request->n_ssids == 0) {
539         rScanRequest.rSsid.u4SsidLen = 0;
540     }
541     else if(request->n_ssids == 1) {
542         COPY_SSID(rScanRequest.rSsid.aucSsid, rScanRequest.rSsid.u4SsidLen, request->ssids[0].ssid, request->ssids[0].ssid_len);
543     }
544     else {
545         return -EINVAL;
546     }
547
548     if(request->ie_len > 0) {
549         rScanRequest.u4IELength = request->ie_len;
550         rScanRequest.pucIE = (PUINT_8)(request->ie);
551     }
552     else {
553         rScanRequest.u4IELength = 0;
554     }
555
556     rStatus = kalIoctl(prGlueInfo,
557         wlanoidSetBssidListScanExt,
558         &rScanRequest,
559         sizeof(PARAM_SCAN_REQUEST_EXT_T),
560         FALSE,
561         FALSE,
562         FALSE,
563         FALSE,
564         &u4BufLen);
565
566     if (rStatus != WLAN_STATUS_SUCCESS) {
567         DBGLOG(REQ, WARN, ("scan error:%lx\n", rStatus));
568         return -EINVAL;
569     }
570
571     prGlueInfo->prScanRequest = request;
572
573     return 0;
574 }
575
576 static UINT_8 wepBuf[48];
577
578 /*----------------------------------------------------------------------------*/
579 /*!
580  * @brief This routine is responsible for requesting to connect to 
581  *        the ESS with the specified parameters
582  *
583  * @param 
584  *
585  * @retval 0:       successful
586  *         others:  failure
587  */
588 /*----------------------------------------------------------------------------*/
589 int
590 mtk_cfg80211_connect (
591     struct wiphy *wiphy,
592     struct net_device *ndev,
593     struct cfg80211_connect_params *sme
594     )
595 {
596     P_GLUE_INFO_T prGlueInfo = NULL;
597     WLAN_STATUS rStatus;
598     UINT_32 u4BufLen;
599     ENUM_PARAM_ENCRYPTION_STATUS_T eEncStatus;
600     ENUM_PARAM_AUTH_MODE_T eAuthMode;
601     UINT_32 cipher;
602     PARAM_SSID_T rNewSsid;
603     BOOLEAN fgCarryWPSIE = FALSE;
604     ENUM_PARAM_OP_MODE_T eOpMode;
605
606     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
607     ASSERT(prGlueInfo);
608
609     if (prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode > NET_TYPE_AUTO_SWITCH)
610                 eOpMode = NET_TYPE_AUTO_SWITCH;
611         else 
612             eOpMode = prGlueInfo->prAdapter->rWifiVar.rConnSettings.eOPMode;
613         
614         rStatus = kalIoctl(prGlueInfo,
615                 wlanoidSetInfrastructureMode,
616                 &eOpMode,
617                 sizeof(eOpMode),
618                 FALSE,
619                 FALSE,
620                 TRUE,
621                 FALSE,
622                 &u4BufLen);
623
624         if (rStatus != WLAN_STATUS_SUCCESS) {
625                 DBGLOG(INIT, INFO, ("wlanoidSetInfrastructureMode fail 0x%lx\n", rStatus));
626                 return -EFAULT;
627         }
628
629         /* after set operation mode, key table are cleared */
630
631         /* reset wpa info */
632         prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
633         prGlueInfo->rWpaInfo.u4KeyMgmt = 0;
634         prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_NONE;
635         prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_NONE;
636         prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
637 #if CFG_SUPPORT_802_11W
638         prGlueInfo->rWpaInfo.u4Mfp = IW_AUTH_MFP_DISABLED;
639 #endif
640
641     if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
642         prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA;
643     else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
644         prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_WPA2;
645     else
646         prGlueInfo->rWpaInfo.u4WpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
647  
648     switch (sme->auth_type) {
649     case NL80211_AUTHTYPE_OPEN_SYSTEM:
650         prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM;
651         break;
652     case NL80211_AUTHTYPE_SHARED_KEY:
653         prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_SHARED_KEY;
654         break;
655     default:
656         prGlueInfo->rWpaInfo.u4AuthAlg = IW_AUTH_ALG_OPEN_SYSTEM | IW_AUTH_ALG_SHARED_KEY;
657         break;
658     }
659
660     if (sme->crypto.n_ciphers_pairwise) {
661         prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4PairwiseKeyCipherSuite[0] = sme->crypto.ciphers_pairwise[0];
662         switch (sme->crypto.ciphers_pairwise[0]) {
663         case WLAN_CIPHER_SUITE_WEP40:
664             prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP40;
665             break;
666         case WLAN_CIPHER_SUITE_WEP104:
667             prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_WEP104;
668             break;
669         case WLAN_CIPHER_SUITE_TKIP:
670             prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_TKIP;
671             break;
672         case WLAN_CIPHER_SUITE_CCMP:
673             prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP;
674             break;
675         case WLAN_CIPHER_SUITE_AES_CMAC:
676             prGlueInfo->rWpaInfo.u4CipherPairwise = IW_AUTH_CIPHER_CCMP;
677             break;
678         default:
679             DBGLOG(REQ, WARN, ("invalid cipher pairwise (%d)\n",
680                    sme->crypto.ciphers_pairwise[0]));
681             return -EINVAL;
682         }
683     }
684
685     if (sme->crypto.cipher_group) {
686         prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.u4GroupKeyCipherSuite = sme->crypto.cipher_group;
687         switch (sme->crypto.cipher_group) {
688         case WLAN_CIPHER_SUITE_WEP40:
689             prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP40;
690             break;          
691         case WLAN_CIPHER_SUITE_WEP104:
692             prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_WEP104;
693             break;
694         case WLAN_CIPHER_SUITE_TKIP:
695             prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_TKIP;
696             break;
697         case WLAN_CIPHER_SUITE_CCMP:
698             prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP;
699             break;
700         case WLAN_CIPHER_SUITE_AES_CMAC:
701             prGlueInfo->rWpaInfo.u4CipherGroup = IW_AUTH_CIPHER_CCMP;
702             break;
703         default:
704             DBGLOG(REQ, WARN, ("invalid cipher group (%d)\n",
705                    sme->crypto.cipher_group));
706             return -EINVAL;
707         }
708     }
709
710     if (sme->crypto.n_akm_suites) {
711         prGlueInfo->prAdapter->rWifiVar.rConnSettings.rRsnInfo.au4AuthKeyMgtSuite[0] = sme->crypto.akm_suites[0];
712         if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA) {
713             switch (sme->crypto.akm_suites[0]) {
714             case WLAN_AKM_SUITE_8021X:
715                 eAuthMode = AUTH_MODE_WPA;
716                 break;
717             case WLAN_AKM_SUITE_PSK:
718                 eAuthMode = AUTH_MODE_WPA_PSK;
719             break;
720             default:
721                 DBGLOG(REQ, WARN, ("invalid cipher group (%d)\n",
722                        sme->crypto.cipher_group));
723                 return -EINVAL;
724             }
725         } else if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_WPA2) {
726             switch (sme->crypto.akm_suites[0]) {
727             case WLAN_AKM_SUITE_8021X:
728             eAuthMode = AUTH_MODE_WPA2;
729             break;
730             case WLAN_AKM_SUITE_PSK:
731             eAuthMode = AUTH_MODE_WPA2_PSK;
732             break;
733             default:
734                 DBGLOG(REQ, WARN, ("invalid cipher group (%d)\n",
735                        sme->crypto.cipher_group));
736                 return -EINVAL;
737             }
738         }
739     }
740
741     if (prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
742         eAuthMode = (prGlueInfo->rWpaInfo.u4AuthAlg == IW_AUTH_ALG_OPEN_SYSTEM) ?
743              AUTH_MODE_OPEN : AUTH_MODE_AUTO_SWITCH;
744     }
745
746     prGlueInfo->rWpaInfo.fgPrivacyInvoke = sme->privacy;
747
748     //prGlueInfo->prAdapter->rWifiVar.rConnSettings.fgWapiMode = FALSE;
749     //prGlueInfo->prAdapter->prGlueInfo->u2WapiAssocInfoIESz = 0;
750     prGlueInfo->fgWpsActive = FALSE;
751     //prGlueInfo->prAdapter->prGlueInfo->u2WSCAssocInfoIELen = 0;
752
753     if (sme->ie && sme->ie_len > 0) {
754         WLAN_STATUS rStatus;
755         UINT_32 u4BufLen;
756         PUINT_8 prDesiredIE = NULL;
757
758 #if CFG_SUPPORT_WAPI
759         rStatus = kalIoctl(prGlueInfo,
760                 wlanoidSetWapiAssocInfo,
761                 sme->ie,
762                 sme->ie_len,
763                 FALSE,
764                 FALSE,
765                 FALSE,
766                 FALSE,
767                 &u4BufLen);
768         
769         if (rStatus != WLAN_STATUS_SUCCESS) {
770             DBGLOG(SEC, WARN, ("[wapi] set wapi assoc info error:%lx\n", rStatus));
771         }
772 #endif
773 #if CFG_SUPPORT_WPS2
774         if (wextSrchDesiredWPSIE(sme->ie,
775                     sme->ie_len,
776                     0xDD,
777                     (PUINT_8 *)&prDesiredIE)) {
778             prGlueInfo->fgWpsActive = TRUE;
779             fgCarryWPSIE = TRUE;
780
781             rStatus = kalIoctl(prGlueInfo,
782                     wlanoidSetWSCAssocInfo,
783                     prDesiredIE,
784                     IE_SIZE(prDesiredIE),
785                     FALSE,
786                     FALSE,
787                     FALSE,
788                     FALSE,
789                     &u4BufLen);
790             if (rStatus != WLAN_STATUS_SUCCESS) {
791                 DBGLOG(SEC, WARN, ("WSC] set WSC assoc info error:%lx\n", rStatus));
792             }
793         }
794 #endif
795     }
796
797     /* clear WSC Assoc IE buffer in case WPS IE is not detected */
798     if(fgCarryWPSIE == FALSE) {
799         kalMemZero(&prGlueInfo->aucWSCAssocInfoIE, 200);
800         prGlueInfo->u2WSCAssocInfoIELen = 0;
801     }
802
803     rStatus = kalIoctl(prGlueInfo,
804             wlanoidSetAuthMode,
805             &eAuthMode,
806             sizeof(eAuthMode),
807             FALSE,
808             FALSE,
809             FALSE,
810             FALSE,
811             &u4BufLen);
812     if (rStatus != WLAN_STATUS_SUCCESS) {
813         DBGLOG(REQ, WARN, ("set auth mode error:%lx\n", rStatus));
814     }
815
816     cipher = prGlueInfo->rWpaInfo.u4CipherGroup | prGlueInfo->rWpaInfo.u4CipherPairwise;
817
818     if (prGlueInfo->rWpaInfo.fgPrivacyInvoke) {
819         if (cipher & IW_AUTH_CIPHER_CCMP) {
820             eEncStatus = ENUM_ENCRYPTION3_ENABLED;
821         }
822         else if (cipher & IW_AUTH_CIPHER_TKIP) {
823             eEncStatus = ENUM_ENCRYPTION2_ENABLED;
824         }
825         else if (cipher & (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) {
826             eEncStatus = ENUM_ENCRYPTION1_ENABLED;
827         }
828         else if (cipher & IW_AUTH_CIPHER_NONE){
829             if (prGlueInfo->rWpaInfo.fgPrivacyInvoke)
830                 eEncStatus = ENUM_ENCRYPTION1_ENABLED;
831             else
832                 eEncStatus = ENUM_ENCRYPTION_DISABLED;
833         }
834         else {
835             eEncStatus = ENUM_ENCRYPTION_DISABLED;
836         }
837     }
838     else {
839         eEncStatus = ENUM_ENCRYPTION_DISABLED;
840     }
841     
842     rStatus = kalIoctl(prGlueInfo,
843             wlanoidSetEncryptionStatus,
844             &eEncStatus,
845             sizeof(eEncStatus),
846             FALSE,
847             FALSE,
848             FALSE,
849             FALSE,
850             &u4BufLen);
851     if (rStatus != WLAN_STATUS_SUCCESS) {
852         DBGLOG(REQ, WARN, ("set encryption mode error:%lx\n", rStatus));
853     }
854
855     if (sme->key_len != 0 && prGlueInfo->rWpaInfo.u4WpaVersion == IW_AUTH_WPA_VERSION_DISABLED) {
856         P_PARAM_WEP_T prWepKey = (P_PARAM_WEP_T) wepBuf;
857         
858         kalMemSet(prWepKey, 0, sizeof(prWepKey));
859         prWepKey->u4Length = 12 + sme->key_len;
860         prWepKey->u4KeyLength = (UINT_32) sme->key_len;
861         prWepKey->u4KeyIndex = (UINT_32) sme->key_idx;
862         prWepKey->u4KeyIndex |= BIT(31);
863         if (prWepKey->u4KeyLength > 32) {
864             DBGLOG(REQ, WARN, ("Too long key length (%u)\n", prWepKey->u4KeyLength));
865             return -EINVAL;
866         }
867         kalMemCopy(prWepKey->aucKeyMaterial, sme->key, prWepKey->u4KeyLength);
868
869         rStatus = kalIoctl(prGlueInfo,
870                      wlanoidSetAddWep,
871                      prWepKey,
872                      prWepKey->u4Length,
873                      FALSE,
874                      FALSE,
875                      TRUE,
876                      FALSE,
877                      &u4BufLen);
878         
879         if (rStatus != WLAN_STATUS_SUCCESS) {
880             DBGLOG(INIT, INFO, ("wlanoidSetAddWep fail 0x%lx\n", rStatus));
881             return -EFAULT;
882         }
883     }
884
885     if(sme->ssid_len > 0) {
886         /* connect by SSID */
887         COPY_SSID(rNewSsid.aucSsid, rNewSsid.u4SsidLen, sme->ssid, sme->ssid_len);
888
889         rStatus = kalIoctl(prGlueInfo,
890                 wlanoidSetSsid,
891                 (PVOID) &rNewSsid,
892                 sizeof(PARAM_SSID_T),
893                 FALSE,
894                 FALSE,
895                 TRUE,
896                 FALSE,
897                 &u4BufLen);
898
899         if (rStatus != WLAN_STATUS_SUCCESS) {
900             DBGLOG(REQ, WARN, ("set SSID:%lx\n", rStatus));
901             return -EINVAL;
902         }
903     }
904     else {
905         /* connect by BSSID */
906         rStatus = kalIoctl(prGlueInfo,
907                 wlanoidSetBssid,
908                 (PVOID) sme->bssid,
909                 sizeof(MAC_ADDR_LEN),
910                 FALSE,
911                 FALSE,
912                 TRUE,
913                 FALSE,
914                 &u4BufLen);
915
916         if (rStatus != WLAN_STATUS_SUCCESS) {
917             DBGLOG(REQ, WARN, ("set BSSID:%lx\n", rStatus));
918             return -EINVAL;
919         }
920     }
921
922     return 0;
923 }
924
925
926 /*----------------------------------------------------------------------------*/
927 /*!
928  * @brief This routine is responsible for requesting to disconnect from
929  *        currently connected ESS
930  *
931  * @param 
932  *
933  * @retval 0:       successful
934  *         others:  failure
935  */
936 /*----------------------------------------------------------------------------*/
937 int 
938 mtk_cfg80211_disconnect (
939     struct wiphy *wiphy,
940     struct net_device *ndev,
941     u16 reason_code
942     )
943 {
944     P_GLUE_INFO_T prGlueInfo = NULL;
945     WLAN_STATUS rStatus;
946     UINT_32 u4BufLen;
947
948     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
949     ASSERT(prGlueInfo);
950
951     rStatus = kalIoctl(prGlueInfo,
952         wlanoidSetDisassociate,
953         NULL,
954         0,
955         FALSE,
956         FALSE,
957         TRUE,
958         FALSE,
959         &u4BufLen);
960
961     if (rStatus != WLAN_STATUS_SUCCESS) {
962         DBGLOG(REQ, WARN, ("disassociate error:%lx\n", rStatus));
963         return -EFAULT;
964     }
965
966     return 0;
967 }
968
969
970 /*----------------------------------------------------------------------------*/
971 /*!
972  * @brief This routine is responsible for requesting to join an IBSS group
973  *
974  * @param 
975  *
976  * @retval 0:       successful
977  *         others:  failure
978  */
979 /*----------------------------------------------------------------------------*/
980 int
981 mtk_cfg80211_join_ibss (
982     struct wiphy *wiphy,
983     struct net_device *ndev,
984     struct cfg80211_ibss_params *params
985     )
986 {
987     PARAM_SSID_T rNewSsid;
988     P_GLUE_INFO_T prGlueInfo = NULL;
989     UINT_32 u4ChnlFreq; /* Store channel or frequency information */
990     UINT_32 u4BufLen = 0;
991     WLAN_STATUS rStatus;
992
993     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
994     ASSERT(prGlueInfo);
995
996     /* set channel */
997     if(params->channel) {
998         u4ChnlFreq = nicChannelNum2Freq(params->channel->hw_value);
999
1000         rStatus = kalIoctl(prGlueInfo,
1001                            wlanoidSetFrequency,
1002                            &u4ChnlFreq,
1003                            sizeof(u4ChnlFreq),
1004                            FALSE,
1005                            FALSE,
1006                            FALSE,
1007                            FALSE,
1008                            &u4BufLen);
1009         if (rStatus != WLAN_STATUS_SUCCESS) {
1010             return -EFAULT;
1011         }
1012     }
1013
1014     /* set SSID */
1015     kalMemCopy(rNewSsid.aucSsid, params->ssid, params->ssid_len);
1016     rStatus = kalIoctl(prGlueInfo,
1017             wlanoidSetSsid,
1018             (PVOID) &rNewSsid,
1019             sizeof(PARAM_SSID_T),
1020             FALSE,
1021             FALSE,
1022             TRUE,
1023             FALSE,
1024             &u4BufLen);
1025
1026     if (rStatus != WLAN_STATUS_SUCCESS) {
1027         DBGLOG(REQ, WARN, ("set SSID:%lx\n", rStatus));
1028         return -EFAULT;
1029     }
1030
1031     return 0;
1032
1033
1034     return -EINVAL;
1035 }
1036
1037
1038 /*----------------------------------------------------------------------------*/
1039 /*!
1040  * @brief This routine is responsible for requesting to leave from IBSS group
1041  *
1042  * @param 
1043  *
1044  * @retval 0:       successful
1045  *         others:  failure
1046  */
1047 /*----------------------------------------------------------------------------*/
1048 int
1049 mtk_cfg80211_leave_ibss (
1050     struct wiphy *wiphy,
1051     struct net_device *ndev
1052     )
1053 {
1054     P_GLUE_INFO_T prGlueInfo = NULL;
1055     WLAN_STATUS rStatus;
1056     UINT_32 u4BufLen;
1057
1058     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1059     ASSERT(prGlueInfo);
1060
1061     rStatus = kalIoctl(prGlueInfo,
1062         wlanoidSetDisassociate,
1063         NULL,
1064         0,
1065         FALSE,
1066         FALSE,
1067         TRUE,
1068         FALSE,
1069         &u4BufLen);
1070
1071     if (rStatus != WLAN_STATUS_SUCCESS) {
1072         DBGLOG(REQ, WARN, ("disassociate error:%lx\n", rStatus));
1073         return -EFAULT;
1074     }
1075
1076     return 0;
1077 }
1078
1079
1080 /*----------------------------------------------------------------------------*/
1081 /*!
1082  * @brief This routine is responsible for requesting to configure 
1083  *        WLAN power managemenet
1084  *
1085  * @param 
1086  *
1087  * @retval 0:       successful
1088  *         others:  failure
1089  */
1090 /*----------------------------------------------------------------------------*/
1091 int
1092 mtk_cfg80211_set_power_mgmt (
1093     struct wiphy *wiphy,
1094     struct net_device *ndev,
1095     bool enabled,
1096     int timeout
1097     )
1098 {
1099     P_GLUE_INFO_T prGlueInfo = NULL;
1100     WLAN_STATUS rStatus;
1101     UINT_32 u4BufLen;
1102     PARAM_POWER_MODE ePowerMode;
1103
1104     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1105     ASSERT(prGlueInfo);
1106
1107     if(enabled) {
1108         if(timeout == -1) {
1109             ePowerMode = Param_PowerModeFast_PSP;
1110         }
1111         else {
1112             ePowerMode = Param_PowerModeMAX_PSP;
1113         }
1114     }
1115     else {
1116         ePowerMode = Param_PowerModeCAM;
1117     }
1118
1119     rStatus = kalIoctl(prGlueInfo,
1120         wlanoidSet802dot11PowerSaveProfile,
1121         &ePowerMode,
1122         sizeof(ePowerMode),
1123         FALSE,
1124         FALSE,
1125         TRUE,
1126         FALSE,
1127         &u4BufLen);
1128
1129     if (rStatus != WLAN_STATUS_SUCCESS) {
1130         DBGLOG(REQ, WARN, ("set_power_mgmt error:%lx\n", rStatus));
1131         return -EFAULT;
1132     }
1133
1134     return 0;
1135 }
1136
1137
1138 /*----------------------------------------------------------------------------*/
1139 /*!
1140  * @brief This routine is responsible for requesting to cache
1141  *        a PMKID for a BSSID
1142  *
1143  * @param 
1144  *
1145  * @retval 0:       successful
1146  *         others:  failure
1147  */
1148 /*----------------------------------------------------------------------------*/
1149 int
1150 mtk_cfg80211_set_pmksa (
1151     struct wiphy *wiphy,
1152     struct net_device *ndev,
1153     struct cfg80211_pmksa *pmksa
1154     )
1155 {
1156     P_GLUE_INFO_T prGlueInfo = NULL;
1157     WLAN_STATUS    rStatus;
1158     UINT_32        u4BufLen;
1159     P_PARAM_PMKID_T  prPmkid;
1160
1161     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1162     ASSERT(prGlueInfo);
1163
1164     prPmkid =(P_PARAM_PMKID_T)kalMemAlloc(8 + sizeof(PARAM_BSSID_INFO_T), VIR_MEM_TYPE);
1165     if (!prPmkid) {
1166         DBGLOG(INIT, INFO, ("Can not alloc memory for IW_PMKSA_ADD\n"));
1167         return -ENOMEM;
1168     }
1169     
1170     prPmkid->u4Length = 8 + sizeof(PARAM_BSSID_INFO_T);
1171     prPmkid->u4BSSIDInfoCount = 1;
1172     kalMemCopy(prPmkid->arBSSIDInfo->arBSSID, pmksa->bssid, 6);
1173     kalMemCopy(prPmkid->arBSSIDInfo->arPMKID, pmksa->pmkid, IW_PMKID_LEN);
1174     
1175     rStatus = kalIoctl(prGlueInfo,
1176                  wlanoidSetPmkid,
1177                  prPmkid,
1178                  sizeof(PARAM_PMKID_T),
1179                  FALSE,
1180                  FALSE,
1181                  FALSE,
1182                  FALSE,
1183                  &u4BufLen);
1184     
1185     if (rStatus != WLAN_STATUS_SUCCESS) {
1186         DBGLOG(INIT, INFO, ("add pmkid error:%lx\n", rStatus));
1187     }
1188     kalMemFree(prPmkid, VIR_MEM_TYPE, 8 + sizeof(PARAM_BSSID_INFO_T));
1189
1190     return 0;
1191 }
1192
1193
1194 /*----------------------------------------------------------------------------*/
1195 /*!
1196  * @brief This routine is responsible for requesting to remove
1197  *        a cached PMKID for a BSSID
1198  *
1199  * @param 
1200  *
1201  * @retval 0:       successful
1202  *         others:  failure
1203  */
1204 /*----------------------------------------------------------------------------*/
1205 int
1206 mtk_cfg80211_del_pmksa (
1207     struct wiphy *wiphy,
1208     struct net_device *ndev,
1209     struct cfg80211_pmksa *pmksa
1210     )
1211 {
1212
1213     return 0;
1214 }
1215
1216
1217 /*----------------------------------------------------------------------------*/
1218 /*!
1219  * @brief This routine is responsible for requesting to flush
1220  *        all cached PMKID
1221  *
1222  * @param 
1223  *
1224  * @retval 0:       successful
1225  *         others:  failure
1226  */
1227 /*----------------------------------------------------------------------------*/
1228 int
1229 mtk_cfg80211_flush_pmksa (
1230     struct wiphy *wiphy,
1231     struct net_device *ndev
1232     )
1233 {
1234     P_GLUE_INFO_T prGlueInfo = NULL;
1235     WLAN_STATUS    rStatus;
1236     UINT_32        u4BufLen;
1237     P_PARAM_PMKID_T  prPmkid;
1238
1239     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1240     ASSERT(prGlueInfo);
1241
1242     prPmkid =(P_PARAM_PMKID_T)kalMemAlloc(8, VIR_MEM_TYPE);
1243     if (!prPmkid) {
1244         DBGLOG(INIT, INFO, ("Can not alloc memory for IW_PMKSA_FLUSH\n"));
1245         return -ENOMEM;
1246     }
1247     
1248     prPmkid->u4Length = 8;
1249     prPmkid->u4BSSIDInfoCount = 0;
1250     
1251     rStatus = kalIoctl(prGlueInfo,
1252                  wlanoidSetPmkid,
1253                  prPmkid,
1254                  sizeof(PARAM_PMKID_T),
1255                  FALSE,
1256                  FALSE,
1257                  FALSE,
1258                  FALSE,
1259                  &u4BufLen);
1260     
1261     if (rStatus != WLAN_STATUS_SUCCESS) {
1262         DBGLOG(INIT, INFO, ("flush pmkid error:%lx\n", rStatus));
1263     }
1264     kalMemFree(prPmkid, VIR_MEM_TYPE, 8);
1265
1266     return 0;
1267 }
1268
1269
1270 /*----------------------------------------------------------------------------*/
1271 /*!
1272  * @brief This routine is responsible for requesting to stay on a 
1273  *        specified channel
1274  *
1275  * @param 
1276  *
1277  * @retval 0:       successful
1278  *         others:  failure
1279  */
1280 /*----------------------------------------------------------------------------*/
1281 int 
1282 mtk_cfg80211_remain_on_channel (
1283     struct wiphy *wiphy,
1284     struct net_device *ndev,
1285     struct ieee80211_channel *chan,
1286     enum nl80211_channel_type channel_type,
1287     unsigned int duration,
1288     u64 *cookie
1289     )
1290 {
1291     P_GLUE_INFO_T prGlueInfo = NULL;
1292
1293     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1294     ASSERT(prGlueInfo);
1295
1296 #if 1
1297     printk("--> %s()\n", __func__);
1298 #endif
1299
1300     /* not implemented */
1301
1302     return -EINVAL;
1303 }
1304
1305
1306 /*----------------------------------------------------------------------------*/
1307 /*!
1308  * @brief This routine is responsible for requesting to cancel staying 
1309  *        on a specified channel
1310  *
1311  * @param 
1312  *
1313  * @retval 0:       successful
1314  *         others:  failure
1315  */
1316 /*----------------------------------------------------------------------------*/
1317 int
1318 mtk_cfg80211_cancel_remain_on_channel (
1319     struct wiphy *wiphy,
1320     struct net_device *ndev,
1321     u64 cookie
1322     )
1323 {
1324     P_GLUE_INFO_T prGlueInfo = NULL;
1325
1326     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1327     ASSERT(prGlueInfo);
1328
1329 #if 1
1330     printk("--> %s()\n", __func__);
1331 #endif
1332
1333     /* not implemented */
1334
1335     return -EINVAL;
1336 }
1337
1338
1339 /*----------------------------------------------------------------------------*/
1340 /*!
1341  * @brief This routine is responsible for requesting to send a management frame
1342  *
1343  * @param 
1344  *
1345  * @retval 0:       successful
1346  *         others:  failure
1347  */
1348 /*----------------------------------------------------------------------------*/
1349 int
1350 mtk_cfg80211_mgmt_tx (
1351     struct wiphy *wiphy,
1352     struct net_device *ndev,
1353     struct ieee80211_channel *channel,
1354     bool offscan,
1355     enum nl80211_channel_type channel_type,
1356     bool channel_type_valid,
1357     unsigned int wait,
1358     const u8 *buf,
1359     size_t len,
1360     bool no_cck,
1361     bool dont_wait_for_ack,
1362     u64 *cookie
1363     )
1364 {
1365     P_GLUE_INFO_T prGlueInfo = NULL;
1366
1367     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1368     ASSERT(prGlueInfo);
1369
1370 #if 1
1371     printk("--> %s()\n", __func__);
1372 #endif
1373
1374     /* not implemented */
1375
1376     return -EINVAL;
1377 }
1378
1379
1380 /*----------------------------------------------------------------------------*/
1381 /*!
1382  * @brief This routine is responsible for requesting to cancel the wait time
1383  *        from transmitting a management frame on another channel
1384  *
1385  * @param 
1386  *
1387  * @retval 0:       successful
1388  *         others:  failure
1389  */
1390 /*----------------------------------------------------------------------------*/
1391 int
1392 mtk_cfg80211_mgmt_tx_cancel_wait (
1393     struct wiphy *wiphy,
1394     struct net_device *ndev,
1395     u64 cookie
1396     )
1397 {
1398     P_GLUE_INFO_T prGlueInfo = NULL;
1399
1400     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1401     ASSERT(prGlueInfo);
1402
1403 #if 1
1404     printk("--> %s()\n", __func__);
1405 #endif
1406
1407     /* not implemented */
1408
1409     return -EINVAL;
1410 }
1411
1412
1413 #if CONFIG_NL80211_TESTMODE
1414
1415 #if CFG_SUPPORT_WAPI
1416 int
1417 mtk_cfg80211_testmode_set_key_ext(
1418     IN struct wiphy *wiphy,
1419     IN void *data,
1420     IN int len)
1421 {
1422     P_GLUE_INFO_T prGlueInfo = NULL;
1423     P_NL80211_DRIVER_SET_KEY_EXTS prParams = (P_NL80211_DRIVER_SET_KEY_EXTS)NULL;
1424     struct iw_encode_exts *prIWEncExt = (struct iw_encode_exts *)NULL;
1425     WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
1426     int     fgIsValid = 0;
1427     UINT_32 u4BufLen = 0;
1428     
1429     P_PARAM_WPI_KEY_T prWpiKey = (P_PARAM_WPI_KEY_T) keyStructBuf;
1430     memset(keyStructBuf, 0, sizeof(keyStructBuf));
1431
1432     ASSERT(wiphy);
1433     
1434     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1435         
1436 #if 1
1437         printk("--> %s()\n", __func__);
1438 #endif
1439
1440     if(data && len) {
1441         prParams = (P_NL80211_DRIVER_SET_KEY_EXTS)data;
1442     }
1443     
1444     if(prParams) {
1445         prIWEncExt = (struct iw_encode_exts *) &prParams->ext;
1446     }
1447
1448     if (prIWEncExt->alg == IW_ENCODE_ALG_SMS4) {
1449         /* KeyID */
1450         prWpiKey->ucKeyID = prParams->key_index;
1451         prWpiKey->ucKeyID --;
1452         if (prWpiKey->ucKeyID > 1) {
1453             /* key id is out of range */
1454             //printk(KERN_INFO "[wapi] add key error: key_id invalid %d\n", prWpiKey->ucKeyID);
1455             return -EINVAL;
1456         }
1457
1458         if (prIWEncExt->key_len != 32) {
1459             /* key length not valid */
1460             //printk(KERN_INFO "[wapi] add key error: key_len invalid %d\n", prIWEncExt->key_len);
1461             return -EINVAL;
1462         }
1463
1464         //printk(KERN_INFO "[wapi] %d ext_flags %d\n", prEnc->flags, prIWEncExt->ext_flags);
1465
1466         if (prIWEncExt->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
1467             prWpiKey->eKeyType = ENUM_WPI_GROUP_KEY;
1468             prWpiKey->eDirection = ENUM_WPI_RX;
1469         }
1470         else if (prIWEncExt->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
1471             prWpiKey->eKeyType = ENUM_WPI_PAIRWISE_KEY;
1472             prWpiKey->eDirection = ENUM_WPI_RX_TX;
1473         }
1474
1475 //#if CFG_SUPPORT_WAPI
1476         //handle_sec_msg_final(prIWEncExt->key, 32, prIWEncExt->key, NULL);
1477 //#endif
1478         /* PN */
1479         memcpy(prWpiKey->aucPN, prIWEncExt->tx_seq, IW_ENCODE_SEQ_MAX_SIZE * 2);
1480
1481         /* BSSID */
1482         memcpy(prWpiKey->aucAddrIndex, prIWEncExt->addr, 6);
1483
1484         memcpy(prWpiKey->aucWPIEK, prIWEncExt->key, 16);
1485         prWpiKey->u4LenWPIEK = 16;
1486
1487         memcpy(prWpiKey->aucWPICK, &prIWEncExt->key[16], 16);
1488         prWpiKey->u4LenWPICK = 16;
1489
1490         rstatus = kalIoctl(prGlueInfo,
1491                      wlanoidSetWapiKey,
1492                      prWpiKey,
1493                      sizeof(PARAM_WPI_KEY_T),
1494                      FALSE,
1495                      FALSE,
1496                      TRUE,
1497                      FALSE,
1498                      &u4BufLen);
1499
1500         if (rstatus != WLAN_STATUS_SUCCESS) {
1501             //printk(KERN_INFO "[wapi] add key error:%lx\n", rStatus);
1502             fgIsValid = -EFAULT;
1503         }
1504
1505     }
1506     return fgIsValid;
1507 }
1508 #endif
1509
1510
1511 int
1512 mtk_cfg80211_testmode_sw_cmd(
1513     IN struct wiphy *wiphy,
1514     IN void *data,
1515     IN int len)
1516 {
1517     P_GLUE_INFO_T prGlueInfo = NULL;
1518     P_NL80211_DRIVER_SW_CMD_PARAMS prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS)NULL;
1519     WLAN_STATUS rstatus = WLAN_STATUS_SUCCESS;
1520     int     fgIsValid = 0;
1521     UINT_32 u4SetInfoLen = 0;
1522
1523     ASSERT(wiphy);
1524
1525     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1526
1527 #if 1
1528         printk("--> %s()\n", __func__);
1529 #endif
1530
1531     if(data && len)
1532         prParams = (P_NL80211_DRIVER_SW_CMD_PARAMS)data;
1533
1534     if(prParams) {
1535         if(prParams->set == 1){
1536             rstatus = kalIoctl(prGlueInfo,
1537                     (PFN_OID_HANDLER_FUNC)wlanoidSetSwCtrlWrite,
1538                     &prParams->adr,
1539                     (UINT_32)8,
1540                     FALSE,
1541                     FALSE,
1542                     TRUE,
1543                     FALSE,
1544                     &u4SetInfoLen);
1545         }
1546     }
1547
1548     if (WLAN_STATUS_SUCCESS != rstatus) {
1549         fgIsValid = -EFAULT;
1550     }
1551  
1552     return fgIsValid;
1553 }
1554
1555 int mtk_cfg80211_testmode_cmd(
1556     IN struct wiphy *wiphy,
1557     IN void *data,
1558     IN int len
1559     )
1560 {
1561     P_GLUE_INFO_T prGlueInfo = NULL;
1562     P_NL80211_DRIVER_TEST_MODE_PARAMS prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS)NULL;
1563     BOOLEAN fgIsValid = 0;
1564
1565     ASSERT(wiphy);
1566
1567     prGlueInfo = (P_GLUE_INFO_T) wiphy_priv(wiphy);
1568
1569 #if 1
1570     printk("--> %s()\n", __func__);
1571 #endif
1572
1573     if(data && len)
1574         prParams = (P_NL80211_DRIVER_TEST_MODE_PARAMS)data;
1575         
1576     /* Clear the version byte */
1577     prParams->index = prParams->index & ~ BITS(24,31);
1578     
1579     if(prParams){
1580         switch(prParams->index){
1581             case 1: /* SW cmd */
1582                 if(mtk_cfg80211_testmode_sw_cmd(wiphy, data, len))
1583                     fgIsValid = TRUE;
1584                 break;
1585             case 2: /* WAPI */
1586 #if CFG_SUPPORT_WAPI
1587                 if(mtk_cfg80211_testmode_set_key_ext(wiphy, data, len))
1588                     fgIsValid = TRUE;
1589 #endif
1590                 break;
1591             default:
1592                 fgIsValid = TRUE;
1593                 break;
1594         }
1595     }
1596
1597     return fgIsValid;
1598 }
1599 #endif
1600