wifi: renew patch drivers/net/wireless
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rtl8192cu / os_dep / linux / ioctl_cfg80211.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *                                        
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define  _IOCTL_CFG80211_C_
21
22 #include <drv_conf.h>
23 #include <osdep_service.h>
24 #include <drv_types.h>
25 #include <rtw_ioctl.h>
26 #include <rtw_ioctl_set.h>
27 #include <rtw_ioctl_query.h>
28 #include <xmit_osdep.h>
29
30 #ifdef CONFIG_IOCTL_CFG80211
31
32 #include "ioctl_cfg80211.h"     
33
34 #define RTW_MAX_MGMT_TX_CNT (8)
35
36 #define RTW_SCAN_IE_LEN_MAX      2304
37 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535 //ms
38 #define RTW_MAX_NUM_PMKIDS 4
39
40 #define RTW_CH_MAX_2G_CHANNEL               14      /* Max channel in 2G band */
41
42 static const u32 rtw_cipher_suites[] = {
43         WLAN_CIPHER_SUITE_WEP40,
44         WLAN_CIPHER_SUITE_WEP104,
45         WLAN_CIPHER_SUITE_TKIP,
46         WLAN_CIPHER_SUITE_CCMP,
47 #ifdef CONFIG_IEEE80211W
48         WLAN_CIPHER_SUITE_AES_CMAC,
49 #endif //CONFIG_IEEE80211W
50 };
51
52 #define RATETAB_ENT(_rate, _rateid, _flags) \
53         {                                                               \
54                 .bitrate        = (_rate),                              \
55                 .hw_value       = (_rateid),                            \
56                 .flags          = (_flags),                             \
57         }
58
59 #define CHAN2G(_channel, _freq, _flags) {                       \
60         .band                   = IEEE80211_BAND_2GHZ,          \
61         .center_freq            = (_freq),                      \
62         .hw_value               = (_channel),                   \
63         .flags                  = (_flags),                     \
64         .max_antenna_gain       = 0,                            \
65         .max_power              = 30,                           \
66 }
67
68 #define CHAN5G(_channel, _flags) {                              \
69         .band                   = IEEE80211_BAND_5GHZ,          \
70         .center_freq            = 5000 + (5 * (_channel)),      \
71         .hw_value               = (_channel),                   \
72         .flags                  = (_flags),                     \
73         .max_antenna_gain       = 0,                            \
74         .max_power              = 30,                           \
75 }
76
77 static struct ieee80211_rate rtw_rates[] = {
78         RATETAB_ENT(10,  0x1,   0),
79         RATETAB_ENT(20,  0x2,   0),
80         RATETAB_ENT(55,  0x4,   0),
81         RATETAB_ENT(110, 0x8,   0),
82         RATETAB_ENT(60,  0x10,  0),
83         RATETAB_ENT(90,  0x20,  0),
84         RATETAB_ENT(120, 0x40,  0),
85         RATETAB_ENT(180, 0x80,  0),
86         RATETAB_ENT(240, 0x100, 0),
87         RATETAB_ENT(360, 0x200, 0),
88         RATETAB_ENT(480, 0x400, 0),
89         RATETAB_ENT(540, 0x800, 0),
90 };
91
92 #define rtw_a_rates             (rtw_rates + 4)
93 #define RTW_A_RATES_NUM 8
94 #define rtw_g_rates             (rtw_rates + 0)
95 #define RTW_G_RATES_NUM 12
96
97 #define RTW_2G_CHANNELS_NUM 14
98 #define RTW_5G_CHANNELS_NUM 37
99
100 static struct ieee80211_channel rtw_2ghz_channels[] = {
101         CHAN2G(1, 2412, 0),
102         CHAN2G(2, 2417, 0),
103         CHAN2G(3, 2422, 0),
104         CHAN2G(4, 2427, 0),
105         CHAN2G(5, 2432, 0),
106         CHAN2G(6, 2437, 0),
107         CHAN2G(7, 2442, 0),
108         CHAN2G(8, 2447, 0),
109         CHAN2G(9, 2452, 0),
110         CHAN2G(10, 2457, 0),
111         CHAN2G(11, 2462, 0),
112         CHAN2G(12, 2467, 0),
113         CHAN2G(13, 2472, 0),
114         CHAN2G(14, 2484, 0),
115 };
116
117 static struct ieee80211_channel rtw_5ghz_a_channels[] = {
118         CHAN5G(34, 0),          CHAN5G(36, 0),
119         CHAN5G(38, 0),          CHAN5G(40, 0),
120         CHAN5G(42, 0),          CHAN5G(44, 0),
121         CHAN5G(46, 0),          CHAN5G(48, 0),
122         CHAN5G(52, 0),          CHAN5G(56, 0),
123         CHAN5G(60, 0),          CHAN5G(64, 0),
124         CHAN5G(100, 0),         CHAN5G(104, 0),
125         CHAN5G(108, 0),         CHAN5G(112, 0),
126         CHAN5G(116, 0),         CHAN5G(120, 0),
127         CHAN5G(124, 0),         CHAN5G(128, 0),
128         CHAN5G(132, 0),         CHAN5G(136, 0),
129         CHAN5G(140, 0),         CHAN5G(149, 0),
130         CHAN5G(153, 0),         CHAN5G(157, 0),
131         CHAN5G(161, 0),         CHAN5G(165, 0),
132         CHAN5G(184, 0),         CHAN5G(188, 0),
133         CHAN5G(192, 0),         CHAN5G(196, 0),
134         CHAN5G(200, 0),         CHAN5G(204, 0),
135         CHAN5G(208, 0),         CHAN5G(212, 0),
136         CHAN5G(216, 0),
137 };
138
139
140 void rtw_2g_channels_init(struct ieee80211_channel *channels)
141 {
142         _rtw_memcpy((void*)channels, (void*)rtw_2ghz_channels,
143                 sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
144         );
145 }
146
147 void rtw_5g_channels_init(struct ieee80211_channel *channels)
148 {
149         _rtw_memcpy((void*)channels, (void*)rtw_5ghz_a_channels,
150                 sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
151         );
152 }
153
154 void rtw_2g_rates_init(struct ieee80211_rate *rates)
155 {
156         _rtw_memcpy(rates, rtw_g_rates,
157                 sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
158         );
159 }
160
161 void rtw_5g_rates_init(struct ieee80211_rate *rates)
162 {
163         _rtw_memcpy(rates, rtw_a_rates,
164                 sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM
165         );
166 }
167
168 struct ieee80211_supported_band *rtw_spt_band_alloc(
169         enum ieee80211_band band
170         )
171 {
172         struct ieee80211_supported_band *spt_band = NULL;
173         int n_channels, n_bitrates;
174
175         if(band == IEEE80211_BAND_2GHZ)
176         {
177                 n_channels = RTW_2G_CHANNELS_NUM;
178                 n_bitrates = RTW_G_RATES_NUM;
179         }
180         else if(band == IEEE80211_BAND_5GHZ)
181         {
182                 n_channels = RTW_5G_CHANNELS_NUM;
183                 n_bitrates = RTW_A_RATES_NUM;
184         }
185         else
186         {
187                 goto exit;
188         }
189
190         spt_band = (struct ieee80211_supported_band *)rtw_zmalloc(
191                 sizeof(struct ieee80211_supported_band)
192                 + sizeof(struct ieee80211_channel)*n_channels
193                 + sizeof(struct ieee80211_rate)*n_bitrates
194         );
195         if(!spt_band)
196                 goto exit;
197
198         spt_band->channels = (struct ieee80211_channel*)(((u8*)spt_band)+sizeof(struct ieee80211_supported_band));
199         spt_band->bitrates= (struct ieee80211_rate*)(((u8*)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
200         spt_band->band = band;
201         spt_band->n_channels = n_channels;
202         spt_band->n_bitrates = n_bitrates;
203
204         if(band == IEEE80211_BAND_2GHZ)
205         {
206                 rtw_2g_channels_init(spt_band->channels);
207                 rtw_2g_rates_init(spt_band->bitrates);
208         }
209         else if(band == IEEE80211_BAND_5GHZ)
210         {
211                 rtw_5g_channels_init(spt_band->channels);
212                 rtw_5g_rates_init(spt_band->bitrates);
213         }
214
215         //spt_band.ht_cap
216         
217 exit:
218
219         return spt_band;
220 }
221
222 void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
223 {
224         u32 size;
225
226         if(!spt_band)
227                 return;
228         
229         if(spt_band->band == IEEE80211_BAND_2GHZ)
230         {
231                 size = sizeof(struct ieee80211_supported_band)
232                         + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
233                         + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM;
234         }
235         else if(spt_band->band == IEEE80211_BAND_5GHZ)
236         {
237                 size = sizeof(struct ieee80211_supported_band)
238                         + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
239                         + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM;                
240         }
241         else
242         {
243                 
244         }
245         rtw_mfree((u8*)spt_band, size);
246 }
247
248 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
249 static const struct ieee80211_txrx_stypes
250 rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
251         [NL80211_IFTYPE_ADHOC] = {
252                 .tx = 0xffff,
253                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
254         },
255         [NL80211_IFTYPE_STATION] = {
256                 .tx = 0xffff,
257                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
258                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
259         },
260         [NL80211_IFTYPE_AP] = {
261                 .tx = 0xffff,
262                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
263                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
264                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
265                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
266                 BIT(IEEE80211_STYPE_AUTH >> 4) |
267                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
268                 BIT(IEEE80211_STYPE_ACTION >> 4)
269         },
270         [NL80211_IFTYPE_AP_VLAN] = {
271                 /* copy AP */
272                 .tx = 0xffff,
273                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
274                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
275                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
276                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
277                 BIT(IEEE80211_STYPE_AUTH >> 4) |
278                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
279                 BIT(IEEE80211_STYPE_ACTION >> 4)
280         },
281         [NL80211_IFTYPE_P2P_CLIENT] = {
282                 .tx = 0xffff,
283                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
284                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
285         },
286         [NL80211_IFTYPE_P2P_GO] = {
287                 .tx = 0xffff,
288                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
289                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
290                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
291                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
292                 BIT(IEEE80211_STYPE_AUTH >> 4) |
293                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
294                 BIT(IEEE80211_STYPE_ACTION >> 4)
295         },
296 };
297 #endif
298
299 static int rtw_ieee80211_channel_to_frequency(int chan, int band)
300 {
301         /* see 802.11 17.3.8.3.2 and Annex J
302         * there are overlapping channel numbers in 5GHz and 2GHz bands */
303            
304         if (band == IEEE80211_BAND_5GHZ) {
305         if (chan >= 182 && chan <= 196)
306                         return 4000 + chan * 5;
307              else
308                     return 5000 + chan * 5;
309        } else { /* IEEE80211_BAND_2GHZ */
310                 if (chan == 14)
311                         return 2484;
312              else if (chan < 14)
313                         return 2407 + chan * 5;
314              else
315                         return 0; /* not supported */
316         }
317 }
318
319 #define MAX_BSSINFO_LEN 1000
320 static int rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork)
321 {
322         int ret=0;      
323         struct ieee80211_channel *notify_channel;
324         struct cfg80211_bss *bss;
325         //struct ieee80211_supported_band *band;       
326         u16 channel;
327         u32 freq;
328         u64 notify_timestamp;
329         u16 notify_capability;
330         u16 notify_interval;
331         u8 *notify_ie;
332         size_t notify_ielen;
333         s32 notify_signal;
334         u8 buf[MAX_BSSINFO_LEN], *pbuf;
335         size_t len,bssinf_len=0;
336         struct rtw_ieee80211_hdr *pwlanhdr;
337         unsigned short *fctrl;
338         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
339                 
340         struct wireless_dev *wdev = padapter->rtw_wdev;
341         struct wiphy *wiphy = wdev->wiphy;
342         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
343
344
345         //DBG_8192C("%s\n", __func__);
346
347         bssinf_len = pnetwork->network.IELength+sizeof (struct rtw_ieee80211_hdr_3addr);
348         if(bssinf_len > MAX_BSSINFO_LEN){
349                 DBG_871X("%s IE Length too long > %d byte \n",__FUNCTION__,MAX_BSSINFO_LEN);
350                 goto exit;
351         }
352
353         //To reduce PBC Overlap rate
354         //_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
355         if(wdev_to_priv(wdev)->scan_request != NULL)
356         {
357                 u8 *psr=NULL, sr = 0;
358                 NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid;
359                 struct cfg80211_scan_request *request = wdev_to_priv(wdev)->scan_request;
360                 struct cfg80211_ssid *ssids = request->ssids;
361                 u32 wpsielen=0;
362                 u8 *wpsie=NULL; 
363                 
364                 wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
365                 
366                 if(wpsie && wpsielen>0)
367                         psr = rtw_get_wps_attr_content(wpsie,  wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
368                 
369                 if (sr != 0)
370                 {                       
371                         if(request->n_ssids == 1  && request->n_channels == 1) // it means under processing WPS
372                         {
373                                 DBG_8192C("ssid=%s, len=%d\n", pssid->Ssid, pssid->SsidLength);
374                         
375                                 if(pssid->SsidLength == ssids[0].ssid_len &&
376                                         _rtw_memcmp(pssid->Ssid, ssids[0].ssid, ssids[0].ssid_len))
377                                 {
378                                         DBG_871X("%s, got sr and ssid match!\n", __func__);
379                                 }
380                                 else
381                                 {
382                                         if(psr !=NULL)
383                                                 *psr = 0; //clear sr
384                                 
385 #if 0                   
386                                         WLAN_BSSID_EX  *pselect_network = &pnetwork->network;
387                                         struct cfg80211_bss *pselect_bss = NULL;
388                                         struct ieee80211_channel *notify_channel = NULL;
389                                         u32 freq;
390
391                                         DBG_871X("%s, got sr, but ssid mismatch, to remove this bss\n", __func__);
392
393                                         if (pselect_network->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
394                                                 freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
395                                         else
396                                                 freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
397
398                                         notify_channel = ieee80211_get_channel(wiphy, freq);
399                                         pselect_bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
400                                                                 pselect_network->MacAddress, pselect_network->Ssid.Ssid,
401                                                                 pselect_network->Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/, 
402                                                                 0/*WLAN_CAPABILITY_ESS*/);
403
404                                         if(pselect_bss)
405                                         {
406                                                 DBG_871X("%s, got bss for cfg80211 for unlinking bss\n", __func__);
407
408                                                 cfg80211_unlink_bss(wiphy, pselect_bss);
409 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
410                                                 cfg80211_put_bss(wiphy, pselect_bss);
411 #else
412                                                 cfg80211_put_bss(pselect_bss);
413 #endif
414                                                 
415                                         }
416                                         
417                                         goto exit;
418 #endif                                  
419                                 }                       
420                         }                       
421                 }               
422         }
423         //_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
424
425         channel = pnetwork->network.Configuration.DSConfig;
426         if (channel <= RTW_CH_MAX_2G_CHANNEL)
427                 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
428         else
429                 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
430         
431         notify_channel = ieee80211_get_channel(wiphy, freq);
432
433         //rtw_get_timestampe_from_ie()
434         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
435
436         notify_interval = le16_to_cpu(*(u16*)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
437         notify_capability = le16_to_cpu(*(u16*)rtw_get_capability_from_ie(pnetwork->network.IEs));              
438
439         
440         notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_;
441         notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_;
442
443         //We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm)
444         if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
445                 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) {
446                 notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);//dbm
447         } else {
448                 notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);//dbm
449         }
450                 
451 /*
452         DBG_8192C("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
453                         pnetwork->network.MacAddress[0], pnetwork->network.MacAddress[1], pnetwork->network.MacAddress[2],
454                         pnetwork->network.MacAddress[3], pnetwork->network.MacAddress[4], pnetwork->network.MacAddress[5]);
455         DBG_8192C("Channel: %d(%d)\n", channel, freq);
456         DBG_8192C("Capability: %X\n", notify_capability);
457         DBG_8192C("Beacon interval: %d\n", notify_interval);
458         DBG_8192C("Signal: %d\n", notify_signal);
459         DBG_8192C("notify_timestamp: %#018llx\n", notify_timestamp);
460 */
461
462         pbuf = buf;
463         
464         pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;    
465         fctrl = &(pwlanhdr->frame_ctl);
466         *(fctrl) = 0;   
467
468         SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
469         //pmlmeext->mgnt_seq++;
470
471         if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
472                 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);                
473                 SetFrameSubType(pbuf, WIFI_BEACON);
474         } else {
475                 _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
476                 SetFrameSubType(pbuf, WIFI_PROBERSP);
477         }
478
479         _rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
480         _rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
481
482
483         pbuf += sizeof(struct rtw_ieee80211_hdr_3addr); 
484         len = sizeof (struct rtw_ieee80211_hdr_3addr);
485
486         _rtw_memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength);
487         len += pnetwork->network.IELength;
488
489         //#ifdef CONFIG_P2P
490         //if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
491         //{
492         //      DBG_8192C("%s, got p2p_ie\n", __func__);
493         //}
494         //#endif
495         
496
497 #if 1   
498         bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)buf,
499                 len, notify_signal, GFP_ATOMIC);
500 #else                    
501                         
502         bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress,
503                 notify_timestamp, notify_capability, notify_interval, notify_ie,
504                 notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/);
505 #endif
506
507         if (unlikely(!bss)) {
508                 DBG_8192C("rtw_cfg80211_inform_bss error\n");
509                 return -EINVAL;
510         }
511
512 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
513 #ifndef COMPAT_KERNEL_RELEASE
514         //patch for cfg80211, update beacon ies to information_elements
515         if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
516         
517                  if(bss->len_information_elements != bss->len_beacon_ies)
518                  {
519                         bss->information_elements = bss->beacon_ies;                    
520                         bss->len_information_elements =  bss->len_beacon_ies;
521                  }              
522         }
523 #endif //COMPAT_KERNEL_RELEASE
524 #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
525
526 /*      
527         {
528                 if( bss->information_elements == bss->proberesp_ies) 
529                 {
530                         if( bss->len_information_elements !=  bss->len_proberesp_ies)
531                         {
532                                 DBG_8192C("error!, len_information_elements !=  bss->len_proberesp_ies\n");
533                         }
534                                                         
535                 }
536                 else if(bss->len_information_elements <  bss->len_beacon_ies)
537                 {
538                         bss->information_elements = bss->beacon_ies;                    
539                         bss->len_information_elements =  bss->len_beacon_ies;
540                 }
541         }
542 */
543
544 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
545         cfg80211_put_bss(wiphy, bss);
546 #else
547         cfg80211_put_bss(bss);
548 #endif
549
550 exit:   
551         return ret;
552         
553 }
554
555 /*
556         Check the given bss is valid by kernel API cfg80211_get_bss()
557         @padapter : the given adapter
558         
559         return _TRUE if bss is valid,  _FALSE for not found.
560 */
561 int rtw_cfg80211_check_bss(_adapter *padapter)
562 {
563         WLAN_BSSID_EX  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
564         struct cfg80211_bss *bss = NULL;
565         struct ieee80211_channel *notify_channel = NULL;
566         u32 freq;
567
568         if (!(pnetwork) || !(padapter->rtw_wdev))
569                 return _FALSE;
570
571         if (pnetwork->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
572                 freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
573         else
574                 freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
575
576         notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
577         bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
578                         pnetwork->MacAddress, pnetwork->Ssid.Ssid,
579                         pnetwork->Ssid.SsidLength,
580                         WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
581
582         return  (bss!=NULL);
583 }
584
585 void rtw_cfg80211_indicate_connect(_adapter *padapter)
586 {
587         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
588         struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
589         struct wireless_dev *pwdev = padapter->rtw_wdev;
590 #ifdef CONFIG_P2P
591         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
592 #endif
593         struct cfg80211_bss *bss = NULL;
594
595         DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
596         if (pwdev->iftype != NL80211_IFTYPE_STATION
597                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
598                 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
599                 #endif
600         ) {
601                 return;
602         }
603
604         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
605                 return;
606
607 #ifdef CONFIG_P2P
608         if(pwdinfo->driver_interface == DRIVER_CFG80211 )
609         {
610                 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
611                 {
612                         rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
613                         rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
614                         rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
615                         DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
616                 }
617         }
618 #endif //CONFIG_P2P
619
620         #ifdef CONFIG_LAYER2_ROAMING
621         if (rtw_to_roaming(padapter) > 0) {
622                 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
623                 struct wiphy *wiphy = pwdev->wiphy;
624                 struct ieee80211_channel *notify_channel;
625                 u32 freq;
626                 u16 channel = cur_network->network.Configuration.DSConfig;
627
628                 if (channel <= RTW_CH_MAX_2G_CHANNEL)
629                         freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
630                 else
631                         freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
632
633                 notify_channel = ieee80211_get_channel(wiphy, freq);
634                 #endif
635
636                 DBG_871X("%s call cfg80211_roamed\n", __FUNCTION__);
637                 cfg80211_roamed(padapter->pnetdev
638                         #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
639                         , notify_channel
640                         #endif
641                         , cur_network->network.MacAddress
642                         , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
643                         , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
644                         , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
645                         , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
646                         , GFP_ATOMIC);
647         }
648         else 
649         #endif
650         {
651                 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
652                 cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
653                         , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
654                         , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
655                         , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
656                         , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
657                         , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
658                 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
659         }
660 }
661
662 void rtw_cfg80211_indicate_disconnect(_adapter *padapter)
663 {
664         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
665         struct wireless_dev *pwdev = padapter->rtw_wdev;
666 #ifdef CONFIG_P2P
667         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
668 #endif
669
670         DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
671
672         if (pwdev->iftype != NL80211_IFTYPE_STATION 
673                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
674                 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
675                 #endif
676         ) {
677                 return;
678         }
679
680         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
681                 return;
682
683 #ifdef CONFIG_P2P       
684         if( pwdinfo->driver_interface == DRIVER_CFG80211 )
685         {
686                 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
687                 {
688                         _cancel_timer_ex( &pwdinfo->find_phase_timer );
689                         _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
690                         _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
691         
692                         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
693                         rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
694
695                         DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
696                 }
697         }
698 #endif //CONFIG_P2P
699
700         if (!padapter->mlmepriv.not_indic_disco) {
701                 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
702
703                 if(pwdev->sme_state==CFG80211_SME_CONNECTING)
704                         cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0, 
705                                 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
706                 else if(pwdev->sme_state==CFG80211_SME_CONNECTED)
707                         cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
708                 //else
709                         //DBG_8192C("pwdev->sme_state=%d\n", pwdev->sme_state);
710
711                 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
712         }
713 }
714         
715
716 #ifdef CONFIG_AP_MODE
717 static u8 set_pairwise_key(_adapter *padapter, struct sta_info *psta)
718 {
719         struct cmd_obj*                 ph2c;
720         struct set_stakey_parm  *psetstakey_para;
721         struct cmd_priv                         *pcmdpriv=&padapter->cmdpriv;   
722         u8      res=_SUCCESS;
723
724         ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
725         if ( ph2c == NULL){
726                 res= _FAIL;
727                 goto exit;
728         }
729
730         psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm));
731         if(psetstakey_para==NULL){
732                 rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj));
733                 res=_FAIL;
734                 goto exit;
735         }
736
737         init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
738
739
740         psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy;
741
742         _rtw_memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);     
743         
744         _rtw_memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
745
746         
747         res = rtw_enqueue_cmd(pcmdpriv, ph2c);  
748
749 exit:
750
751         return res;
752         
753 }
754
755 static int set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid)
756 {
757         u8 keylen;
758         struct cmd_obj* pcmd;
759         struct setkey_parm *psetkeyparm;
760         struct cmd_priv *pcmdpriv=&(padapter->cmdpriv); 
761         int res=_SUCCESS;
762
763         DBG_8192C("%s\n", __FUNCTION__);
764         
765         pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct       cmd_obj));
766         if(pcmd==NULL){
767                 res= _FAIL;
768                 goto exit;
769         }
770         psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm));
771         if(psetkeyparm==NULL){
772                 rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj));
773                 res= _FAIL;
774                 goto exit;
775         }
776
777         _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
778                 
779         psetkeyparm->keyid=(u8)keyid;
780         if (is_wep_enc(alg))
781                 padapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);
782
783         psetkeyparm->algorithm = alg;
784
785         psetkeyparm->set_tx = 1;
786
787         switch(alg)
788         {
789                 case _WEP40_:                                   
790                         keylen = 5;
791                         break;
792                 case _WEP104_:
793                         keylen = 13;                    
794                         break;
795                 case _TKIP_:
796                 case _TKIP_WTMIC_:              
797                 case _AES_:
798                         keylen = 16;            
799                 default:
800                         keylen = 16;            
801         }
802
803         _rtw_memcpy(&(psetkeyparm->key[0]), key, keylen);
804         
805         pcmd->cmdcode = _SetKey_CMD_;
806         pcmd->parmbuf = (u8 *)psetkeyparm;   
807         pcmd->cmdsz =  (sizeof(struct setkey_parm));  
808         pcmd->rsp = NULL;
809         pcmd->rspsz = 0;
810
811
812         _rtw_init_listhead(&pcmd->list);
813
814         res = rtw_enqueue_cmd(pcmdpriv, pcmd);
815
816 exit:
817
818         return res;
819         
820
821 }
822
823 static int set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid)
824 {       
825         u8 alg;
826
827         switch(keylen)
828         {
829                 case 5:
830                         alg =_WEP40_;                   
831                         break;
832                 case 13:
833                         alg =_WEP104_;                  
834                         break;
835                 default:
836                         alg =_NO_PRIVACY_;                      
837         }
838
839         return set_group_key(padapter, key, alg, keyid);
840
841 }
842
843 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
844 {
845         int ret = 0;
846         u32 wep_key_idx, wep_key_len,wep_total_len;
847         struct sta_info *psta = NULL, *pbcmc_sta = NULL;        
848         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
849         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
850         struct security_priv* psecuritypriv=&(padapter->securitypriv);
851         struct sta_priv *pstapriv = &padapter->stapriv;
852
853         DBG_8192C("%s\n", __FUNCTION__);
854
855         param->u.crypt.err = 0;
856         param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
857
858         //sizeof(struct ieee_param) = 64 bytes;
859         //if (param_len !=  (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
860         if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len)
861         {
862                 ret =  -EINVAL;
863                 goto exit;
864         }
865
866         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
867             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
868             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
869         {
870                 if (param->u.crypt.idx >= WEP_KEYS)
871                 {
872                         ret = -EINVAL;
873                         goto exit;
874                 }       
875         }
876         else 
877         {               
878                 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
879                 if(!psta)
880                 {
881                         //ret = -EINVAL;
882                         DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n");
883                         goto exit;
884                 }                       
885         }
886
887         if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
888         {
889                 //todo:clear default encryption keys
890
891                 DBG_8192C("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
892                 
893                 goto exit;
894         }
895
896
897         if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
898         {               
899                 DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
900                 
901                 wep_key_idx = param->u.crypt.idx;
902                 wep_key_len = param->u.crypt.key_len;
903                                         
904                 DBG_8192C("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
905
906                 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
907                 {
908                         ret = -EINVAL;
909                         goto exit;
910                 }
911                         
912                 if (wep_key_len > 0) 
913                 {                       
914                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
915                 }
916                 
917                 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
918                 {
919                         //wep default key has not been set, so use this key index as default key.
920
921                         psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
922                         psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
923                         psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
924                         
925                         if(wep_key_len == 13)
926                         {
927                                 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
928                                 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
929                         }
930
931                         psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
932                 }
933                         
934                 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
935                                         
936                 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
937
938                 set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx);
939
940                 goto exit;
941                 
942         }
943
944         
945         if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
946         {
947                 if(param->u.crypt.set_tx == 0) //group key
948                 {
949                         if(strcmp(param->u.crypt.alg, "WEP") == 0)
950                         {
951                                 DBG_8192C("%s, set group_key, WEP\n", __FUNCTION__);
952                                 
953                                 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
954                                         
955                                 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
956                                 if(param->u.crypt.key_len==13)
957                                 {                                               
958                                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
959                                 }
960                                 
961                         }
962                         else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
963                         {                                               
964                                 DBG_8192C("%s, set group_key, TKIP\n", __FUNCTION__);
965                                 
966                                 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
967
968                                 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
969                                 
970                                 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
971                                 //set mic key
972                                 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
973                                 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
974
975                                 psecuritypriv->busetkipkey = _TRUE;
976                                                                                         
977                         }
978                         else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
979                         {
980                                 DBG_8192C("%s, set group_key, CCMP\n", __FUNCTION__);
981                         
982                                 psecuritypriv->dot118021XGrpPrivacy = _AES_;
983
984                                 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
985                         }
986                         else
987                         {
988                                 DBG_8192C("%s, set group_key, none\n", __FUNCTION__);
989                                 
990                                 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
991                         }
992
993                         psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
994
995                         psecuritypriv->binstallGrpkey = _TRUE;
996
997                         psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
998                                                                 
999                         set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
1000                         
1001                         pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1002                         if(pbcmc_sta)
1003                         {
1004                                 pbcmc_sta->ieee8021x_blocked = _FALSE;
1005                                 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy                     
1006                         }       
1007                                                 
1008                 }
1009
1010                 goto exit;
1011                 
1012         }       
1013
1014         if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
1015         {
1016                 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
1017                 {
1018                         if(param->u.crypt.set_tx ==1) //pairwise key
1019                         { 
1020                                 _rtw_memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1021                                 
1022                                 if(strcmp(param->u.crypt.alg, "WEP") == 0)
1023                                 {
1024                                         DBG_8192C("%s, set pairwise key, WEP\n", __FUNCTION__);
1025                                         
1026                                         psta->dot118021XPrivacy = _WEP40_;
1027                                         if(param->u.crypt.key_len==13)
1028                                         {                                               
1029                                                 psta->dot118021XPrivacy = _WEP104_;
1030                                         }
1031                                 }
1032                                 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
1033                                 {                                               
1034                                         DBG_8192C("%s, set pairwise key, TKIP\n", __FUNCTION__);
1035                                         
1036                                         psta->dot118021XPrivacy = _TKIP_;
1037                                 
1038                                         //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
1039                                         //set mic key
1040                                         _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1041                                         _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1042
1043                                         psecuritypriv->busetkipkey = _TRUE;
1044                                                                                         
1045                                 }
1046                                 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
1047                                 {
1048
1049                                         DBG_8192C("%s, set pairwise key, CCMP\n", __FUNCTION__);
1050                                         
1051                                         psta->dot118021XPrivacy = _AES_;
1052                                 }
1053                                 else
1054                                 {
1055                                         DBG_8192C("%s, set pairwise key, none\n", __FUNCTION__);
1056                                         
1057                                         psta->dot118021XPrivacy = _NO_PRIVACY_;
1058                                 }
1059                                                 
1060                                 set_pairwise_key(padapter, psta);
1061                                         
1062                                 psta->ieee8021x_blocked = _FALSE;
1063                                         
1064                                 psta->bpairwise_key_installed = _TRUE;
1065                                         
1066                         }                       
1067                         else//group key???
1068                         { 
1069                                 if(strcmp(param->u.crypt.alg, "WEP") == 0)
1070                                 {
1071                                         _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1072                                         
1073                                         psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1074                                         if(param->u.crypt.key_len==13)
1075                                         {                                               
1076                                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1077                                         }
1078                                 }
1079                                 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
1080                                 {                                               
1081                                         psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
1082
1083                                         _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1084                                 
1085                                         //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
1086                                         //set mic key
1087                                         _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
1088                                         _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
1089
1090                                         psecuritypriv->busetkipkey = _TRUE;
1091                                                                                         
1092                                 }
1093                                 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
1094                                 {
1095                                         psecuritypriv->dot118021XGrpPrivacy = _AES_;
1096
1097                                         _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1098                                 }
1099                                 else
1100                                 {
1101                                         psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
1102                                 }
1103
1104                                 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
1105
1106                                 psecuritypriv->binstallGrpkey = _TRUE;  
1107                                                                 
1108                                 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
1109                                                                 
1110                                 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
1111                         
1112                                 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1113                                 if(pbcmc_sta)
1114                                 {
1115                                         pbcmc_sta->ieee8021x_blocked = _FALSE;
1116                                         pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy                     
1117                                 }                                       
1118
1119                         }
1120                         
1121                 }
1122                                 
1123         }
1124
1125 exit:
1126
1127         return ret;
1128         
1129 }
1130 #endif
1131
1132 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
1133 {
1134         int ret = 0;
1135         u32 wep_key_idx, wep_key_len,wep_total_len;
1136         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1137         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;               
1138         struct security_priv *psecuritypriv = &padapter->securitypriv;
1139 #ifdef CONFIG_P2P
1140         struct wifidirect_info* pwdinfo = &padapter->wdinfo;
1141 #endif //CONFIG_P2P
1142
1143 _func_enter_;
1144
1145         DBG_8192C("%s\n", __func__);
1146
1147         param->u.crypt.err = 0;
1148         param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
1149
1150         if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
1151         {
1152                 ret =  -EINVAL;         
1153                 goto exit;
1154         }
1155
1156         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
1157             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
1158             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) 
1159         {
1160                 if (param->u.crypt.idx >= WEP_KEYS
1161 #ifdef CONFIG_IEEE80211W
1162                         && param->u.crypt.idx > BIP_MAX_KEYID
1163 #endif //CONFIG_IEEE80211W
1164                 )
1165                 {
1166                         ret = -EINVAL;
1167                         goto exit;
1168                 }
1169         } else {
1170                 ret = -EINVAL;          
1171                 goto exit;
1172         }
1173
1174         if (strcmp(param->u.crypt.alg, "WEP") == 0)
1175         {
1176                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
1177                 DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n");
1178
1179                 wep_key_idx = param->u.crypt.idx;
1180                 wep_key_len = param->u.crypt.key_len;
1181
1182                 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0))
1183                 {
1184                         ret = -EINVAL;
1185                         goto exit;
1186                 }
1187
1188                 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
1189                 {
1190                         //wep default key has not been set, so use this key index as default key.
1191
1192                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
1193
1194                 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1195                         psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1196                         psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1197
1198                         if(wep_key_len==13)
1199                         {
1200                                 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1201                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1202                         }
1203
1204                         psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
1205                 }
1206                         
1207                 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
1208                         
1209                 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
1210                         
1211                 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
1212
1213                 goto exit;              
1214         }
1215
1216         if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
1217         {
1218                 struct sta_info * psta,*pbcmc_sta;
1219                 struct sta_priv * pstapriv = &padapter->stapriv;
1220
1221                 //DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__);
1222
1223                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
1224                 {
1225                         psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));                         
1226                         if (psta == NULL) {
1227                                 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
1228                                 DBG_8192C("%s, : Obtain Sta_info fail \n", __func__);
1229                         }
1230                         else
1231                         {
1232                                 //Jeff: don't disable ieee8021x_blocked while clearing key
1233                                 if (strcmp(param->u.crypt.alg, "none") != 0) 
1234                                         psta->ieee8021x_blocked = _FALSE;
1235
1236                                 
1237                                 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1238                                                 (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
1239                                 {
1240                                         psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1241                                 }               
1242
1243                                 if(param->u.crypt.set_tx ==1)//pairwise key
1244                                 { 
1245
1246                                         DBG_8192C("%s, : param->u.crypt.set_tx ==1 \n", __func__);
1247                                         
1248                                         _rtw_memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1249                                         
1250                                         if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
1251                                         {                                               
1252                                                 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1253                                                 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1254                                                 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1255
1256                                                 padapter->securitypriv.busetkipkey=_FALSE;
1257                                                 //_set_timer(&padapter->securitypriv.tkip_timer, 50);                                           
1258                                         }
1259
1260                                         //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
1261                                         DBG_871X(" ~~~~set sta key:unicastkey\n");
1262                                         
1263                                         rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE);
1264                                 }
1265                                 else//group key
1266                                 {
1267                                         if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
1268                                         {
1269                                                 _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1270                                                 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
1271                                                 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
1272                                                 padapter->securitypriv.binstallGrpkey = _TRUE;  
1273                                                 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1274                                                 DBG_871X(" ~~~~set sta key:groupkey\n");
1275         
1276                                                 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1277         
1278                                                 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1);
1279                                         }
1280 #ifdef CONFIG_IEEE80211W
1281                                         else if(strcmp(param->u.crypt.alg, "BIP") == 0)
1282                                         {
1283                                                 int no;
1284                                                 //DBG_871X("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx);
1285                                                 //save the IGTK key, length 16 bytes
1286                                                 _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey,  param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1287                                                 /*DBG_871X("IGTK key below:\n");
1288                                                 for(no=0;no<16;no++)
1289                                                         printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
1290                                                 DBG_871X("\n");*/
1291                                                 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
1292                                                 padapter->securitypriv.binstallBIPkey = _TRUE;
1293                                                 DBG_871X(" ~~~~set sta key:IGKT\n");
1294                                         }
1295 #endif //CONFIG_IEEE80211W
1296                                         
1297 #ifdef CONFIG_P2P
1298                                         if(pwdinfo->driver_interface == DRIVER_CFG80211 )
1299                                         {
1300                                                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
1301                                                 {
1302                                                         rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
1303                                                 }
1304                                         }
1305 #endif //CONFIG_P2P
1306                                         
1307                                 }                                               
1308                         }
1309
1310                         pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1311                         if(pbcmc_sta==NULL)
1312                         {
1313                                 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
1314                         }
1315                         else
1316                         {
1317                                 //Jeff: don't disable ieee8021x_blocked while clearing key
1318                                 if (strcmp(param->u.crypt.alg, "none") != 0) 
1319                                         pbcmc_sta->ieee8021x_blocked = _FALSE;
1320                                 
1321                                 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1322                                                 (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
1323                                 {                                                       
1324                                         pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1325                                 }                                       
1326                         }                               
1327                 }
1328                 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
1329                 {               
1330                 }                       
1331         }
1332
1333 exit:
1334
1335         DBG_8192C("%s, ret=%d\n", __func__, ret);
1336         
1337         _func_exit_;
1338         
1339         return ret;     
1340 }
1341
1342 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
1343 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1344                                 u8 key_index, bool pairwise, const u8 *mac_addr,
1345 #else   // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1346                                 u8 key_index, const u8 *mac_addr,
1347 #endif  // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1348                                 struct key_params *params)
1349 {
1350         char *alg_name;
1351         u32 param_len;
1352         struct ieee_param *param = NULL;        
1353         int ret=0;
1354         struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
1355         _adapter *padapter = wiphy_to_adapter(wiphy);
1356         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1357         
1358         DBG_871X(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
1359         DBG_871X("cipher=0x%x\n", params->cipher);
1360         DBG_871X("key_len=0x%x\n", params->key_len);
1361         DBG_871X("seq_len=0x%x\n", params->seq_len);
1362         DBG_871X("key_index=%d\n", key_index);
1363 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1364         DBG_871X("pairwise=%d\n", pairwise);
1365 #endif  // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1366
1367         param_len = sizeof(struct ieee_param) + params->key_len;
1368         param = (struct ieee_param *)rtw_malloc(param_len);
1369         if (param == NULL)
1370                 return -1;
1371         
1372         _rtw_memset(param, 0, param_len);
1373
1374         param->cmd = IEEE_CMD_SET_ENCRYPTION;
1375         _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
1376
1377         switch (params->cipher) {
1378         case IW_AUTH_CIPHER_NONE:
1379                 //todo: remove key 
1380                 //remove = 1;   
1381                 alg_name = "none";
1382                 break;
1383         case WLAN_CIPHER_SUITE_WEP40:
1384         case WLAN_CIPHER_SUITE_WEP104:
1385                 alg_name = "WEP";
1386                 break;
1387         case WLAN_CIPHER_SUITE_TKIP:
1388                 alg_name = "TKIP";
1389                 break;
1390         case WLAN_CIPHER_SUITE_CCMP:
1391                 alg_name = "CCMP";
1392                 break;
1393 #ifdef CONFIG_IEEE80211W
1394         case WLAN_CIPHER_SUITE_AES_CMAC:
1395                 alg_name = "BIP";
1396                 break;
1397 #endif //CONFIG_IEEE80211W
1398         default:        
1399                 return -ENOTSUPP;
1400         }
1401         
1402         strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1403         
1404
1405         if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1406         {
1407                 param->u.crypt.set_tx = 0; //for wpa/wpa2 group key
1408         } else {
1409                 param->u.crypt.set_tx = 1; //for wpa/wpa2 pairwise key
1410         }
1411         
1412         
1413         //param->u.crypt.idx = key_index - 1;
1414         param->u.crypt.idx = key_index;
1415         
1416         if (params->seq_len && params->seq) 
1417         {       
1418                 _rtw_memcpy(param->u.crypt.seq, params->seq, params->seq_len);
1419         }
1420
1421         if(params->key_len && params->key)
1422         {
1423                 param->u.crypt.key_len = params->key_len;               
1424                 _rtw_memcpy(param->u.crypt.key, params->key, params->key_len);
1425         }       
1426
1427         if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1428         {
1429                 ret =  rtw_cfg80211_set_encryption(ndev, param, param_len);     
1430         }
1431         else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1432         {
1433 #ifdef CONFIG_AP_MODE
1434                 if(mac_addr)
1435                         _rtw_memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN);
1436         
1437                 ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
1438 #endif
1439         }
1440         else
1441         {
1442                 DBG_8192C("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
1443                 
1444         }
1445
1446         if(param)
1447         {
1448                 rtw_mfree((u8*)param, param_len);
1449         }
1450
1451         return ret;
1452
1453 }
1454
1455 static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
1456 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1457                                 u8 key_index, bool pairwise, const u8 *mac_addr,
1458 #else   // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1459                                 u8 key_index, const u8 *mac_addr,
1460 #endif  // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1461                                 void *cookie,
1462                                 void (*callback)(void *cookie,
1463                                                  struct key_params*))
1464 {
1465 #if 0
1466         struct iwm_priv *iwm = ndev_to_iwm(ndev);
1467         struct iwm_key *key = &iwm->keys[key_index];
1468         struct key_params params;
1469
1470         IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
1471
1472         memset(&params, 0, sizeof(params));
1473
1474         params.cipher = key->cipher;
1475         params.key_len = key->key_len;
1476         params.seq_len = key->seq_len;
1477         params.seq = key->seq;
1478         params.key = key->key;
1479
1480         callback(cookie, &params);
1481
1482         return key->key_len ? 0 : -ENOENT;
1483 #endif
1484         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
1485         return 0;
1486 }
1487
1488 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
1489 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1490                                 u8 key_index, bool pairwise, const u8 *mac_addr)
1491 #else   // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1492                                 u8 key_index, const u8 *mac_addr)
1493 #endif  // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1494 {
1495         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);         
1496         struct security_priv *psecuritypriv = &padapter->securitypriv;
1497
1498         DBG_871X(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index);
1499
1500         if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
1501         {
1502                 //clear the flag of wep default key set.
1503                 psecuritypriv->bWepDefaultKeyIdxSet = 0;
1504         }
1505
1506         return 0;
1507 }
1508
1509 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
1510         struct net_device *ndev, u8 key_index
1511         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1512         , bool unicast, bool multicast
1513         #endif
1514         )
1515 {
1516         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);         
1517         struct security_priv *psecuritypriv = &padapter->securitypriv;
1518
1519                 DBG_871X(FUNC_NDEV_FMT" key_index=%d"
1520                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1521                 ", unicast=%d, multicast=%d"
1522                 #endif
1523                 ".\n", FUNC_NDEV_ARG(ndev), key_index
1524                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1525                 , unicast, multicast
1526                 #endif
1527                 );
1528
1529         if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) //set wep default key
1530         {
1531                 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1532
1533                 psecuritypriv->dot11PrivacyKeyIndex = key_index;
1534
1535                 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1536                 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1537                 if (psecuritypriv->dot11DefKeylen[key_index] == 13)
1538                 {
1539                         psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1540                         psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1541                 }
1542
1543                 psecuritypriv->bWepDefaultKeyIdxSet = 1; //set the flag to represent that wep default key has been set
1544         }
1545
1546         return 0;
1547
1548 }
1549
1550 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
1551                                     struct net_device *ndev,
1552                                     u8 *mac, struct station_info *sinfo)
1553 {
1554         int ret = 0;
1555         _adapter *padapter = wiphy_to_adapter(wiphy);
1556         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1557         struct sta_info *psta = NULL;
1558         struct sta_priv *pstapriv = &padapter->stapriv;
1559
1560         sinfo->filled = 0;
1561
1562         if (!mac) {
1563                 DBG_871X(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
1564                 ret = -ENOENT;
1565                 goto exit;
1566         }
1567
1568         psta = rtw_get_stainfo(pstapriv, mac);
1569         if (psta == NULL) {
1570                 DBG_8192C("%s, sta_info is null\n", __func__);
1571                 ret = -ENOENT;
1572                 goto exit;
1573         }
1574
1575 #ifdef CONFIG_DEBUG_CFG80211
1576         DBG_871X(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
1577 #endif
1578
1579         //for infra./P2PClient mode
1580         if(     check_fwstate(pmlmepriv, WIFI_STATION_STATE)
1581                 && check_fwstate(pmlmepriv, _FW_LINKED)
1582         )
1583         {
1584                 struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
1585
1586                 if (_rtw_memcmp(mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) {
1587                         DBG_871X("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
1588                         ret = -ENOENT;
1589                         goto exit;
1590                 }
1591
1592                 sinfo->filled |= STATION_INFO_SIGNAL;
1593                 sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
1594
1595                 sinfo->filled |= STATION_INFO_TX_BITRATE;
1596                 sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
1597
1598                 sinfo->filled |= STATION_INFO_RX_PACKETS;
1599                 sinfo->rx_packets = sta_rx_data_pkts(psta);
1600
1601                 sinfo->filled |= STATION_INFO_TX_PACKETS;
1602                 sinfo->tx_packets = psta->sta_stats.tx_pkts;
1603
1604         }
1605
1606         //for Ad-Hoc/AP mode
1607         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
1608                         ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
1609                         ||check_fwstate(pmlmepriv, WIFI_AP_STATE))
1610                 && check_fwstate(pmlmepriv, _FW_LINKED)
1611         )
1612         {
1613                 //TODO: should acquire station info...
1614         }
1615
1616 exit:
1617         return ret;
1618 }
1619
1620 extern int netdev_open(struct net_device *pnetdev);
1621 #ifdef CONFIG_CONCURRENT_MODE
1622 extern int netdev_if2_open(struct net_device *pnetdev);
1623 #endif
1624
1625 /*
1626 enum nl80211_iftype {
1627         NL80211_IFTYPE_UNSPECIFIED,
1628        NL80211_IFTYPE_ADHOC, //1
1629        NL80211_IFTYPE_STATION, //2
1630        NL80211_IFTYPE_AP, //3
1631        NL80211_IFTYPE_AP_VLAN,
1632        NL80211_IFTYPE_WDS,
1633        NL80211_IFTYPE_MONITOR, //6
1634        NL80211_IFTYPE_MESH_POINT,
1635        NL80211_IFTYPE_P2P_CLIENT, //8
1636         NL80211_IFTYPE_P2P_GO, //9
1637        //keep last 
1638        NUM_NL80211_IFTYPES,
1639        NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
1640 };
1641 */
1642 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
1643                                      struct net_device *ndev,
1644                                      enum nl80211_iftype type, u32 *flags,
1645                                      struct vif_params *params)
1646 {
1647         enum nl80211_iftype old_type;
1648         NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
1649         _adapter *padapter = wiphy_to_adapter(wiphy);
1650         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
1651         struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
1652         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1653         _irqL irqL;
1654         _queue *queue = &pmlmepriv->scanned_queue;
1655 #ifdef CONFIG_P2P
1656         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
1657 #endif
1658         int ret = 0;
1659         u8 change = _FALSE;
1660
1661         if (adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE) {
1662                 ret= -EPERM;
1663                 goto exit;
1664         }
1665
1666 #ifdef CONFIG_CONCURRENT_MODE
1667         if(padapter->adapter_type == SECONDARY_ADAPTER)
1668         {
1669                 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev));
1670                 if(netdev_if2_open(ndev) != 0) {
1671                         ret= -EPERM;
1672                         goto exit;
1673                 }
1674         }
1675         else if(padapter->adapter_type == PRIMARY_ADAPTER)
1676 #endif //CONFIG_CONCURRENT_MODE
1677         {
1678                 DBG_871X(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
1679                 if(netdev_open(ndev) != 0) {
1680                         ret= -EPERM;
1681                         goto exit;
1682                 }
1683         }
1684
1685         if(_FAIL == rtw_pwr_wakeup(padapter)) {
1686                 ret= -EPERM;
1687                 goto exit;
1688         }
1689
1690         old_type = rtw_wdev->iftype;
1691         DBG_871X(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
1692                 FUNC_NDEV_ARG(ndev), old_type, type);
1693
1694         if(old_type != type)
1695         {
1696                 change = _TRUE;
1697                 pmlmeext->action_public_rxseq = 0xffff;
1698                 pmlmeext->action_public_dialog_token = 0xff;
1699         }       
1700                 
1701         switch (type) {
1702         case NL80211_IFTYPE_ADHOC:
1703                 networkType = Ndis802_11IBSS;
1704                 break;
1705 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
1706         case NL80211_IFTYPE_P2P_CLIENT:
1707 #endif
1708         case NL80211_IFTYPE_STATION:
1709                 networkType = Ndis802_11Infrastructure;
1710                 #ifdef CONFIG_P2P
1711                 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
1712                 {
1713                         if(change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1714                         {
1715                                 _cancel_timer_ex( &pwdinfo->find_phase_timer );
1716                                 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
1717                                 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
1718
1719                                 //it means remove GO and change mode from AP(GO) to station(P2P DEVICE)
1720                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1721                                 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
1722
1723                                 DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
1724                         }
1725                 }
1726                 #endif //CONFIG_P2P
1727                 break;
1728 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
1729         case NL80211_IFTYPE_P2P_GO:
1730 #endif
1731         case NL80211_IFTYPE_AP:
1732                 networkType = Ndis802_11APMode;
1733                 #ifdef CONFIG_P2P
1734                 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
1735                 {
1736                         if(change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1737                         {
1738                                 //it means P2P Group created, we will be GO and change mode from  P2P DEVICE to AP(GO)
1739                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1740                         }
1741                 }
1742                 #endif //CONFIG_P2P
1743                 break;          
1744         default:
1745                 return -EOPNOTSUPP;
1746         }
1747
1748         rtw_wdev->iftype = type;
1749         
1750         _enter_critical_bh(&pmlmepriv->lock, &irqL);
1751         _enter_critical_bh(&queue->lock, &irqL);
1752         
1753         if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE)
1754         {
1755                 rtw_wdev->iftype = old_type;
1756                 ret = -EPERM;
1757                 _exit_critical_bh(&queue->lock, &irqL);
1758                 _exit_critical_bh(&pmlmepriv->lock, &irqL);
1759                 goto exit;
1760         }
1761         _exit_critical_bh(&queue->lock, &irqL);
1762         _exit_critical_bh(&pmlmepriv->lock, &irqL);
1763
1764         rtw_setopmode_cmd(padapter, networkType);       
1765         
1766 exit:
1767
1768         return ret;
1769 }
1770
1771 void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv, bool aborted)
1772 {
1773         _irqL   irqL;
1774
1775         _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
1776         if(pwdev_priv->scan_request != NULL)
1777         {
1778                 //struct cfg80211_scan_request *scan_request = pwdev_priv->scan_request;
1779         
1780                 #ifdef CONFIG_DEBUG_CFG80211
1781                 DBG_871X("%s with scan req\n", __FUNCTION__);   
1782                 #endif
1783
1784                 //avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
1785                 //if(scan_request == wiphy_to_dev(scan_request->wiphy)->scan_req)
1786                 if(pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
1787                 {
1788                         DBG_8192C("error wiphy compare\n");
1789                 }
1790                 else
1791                 {
1792                         cfg80211_scan_done(pwdev_priv->scan_request, aborted);
1793                 }
1794
1795                 pwdev_priv->scan_request = NULL;
1796                 
1797         } else {
1798                 #ifdef CONFIG_DEBUG_CFG80211
1799                 DBG_871X("%s without scan req\n", __FUNCTION__);
1800                 #endif
1801         }
1802         _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
1803 }
1804
1805 void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
1806 {
1807         _irqL   irqL;
1808         _list                                   *plist, *phead; 
1809         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);     
1810         _queue                          *queue  = &(pmlmepriv->scanned_queue);  
1811         struct  wlan_network    *pnetwork = NULL;
1812         u32 cnt=0;
1813         u32 wait_for_surveydone;
1814         sint wait_status;
1815 #ifdef CONFIG_P2P
1816         struct  wifidirect_info*        pwdinfo = &padapter->wdinfo;
1817 #endif //CONFIG_P2P
1818         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
1819         struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
1820
1821 #ifdef CONFIG_DEBUG_CFG80211
1822         DBG_8192C("%s\n", __func__);
1823 #endif
1824
1825         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1826
1827         phead = get_list_head(queue);
1828         plist = get_next(phead);
1829        
1830         while(1)
1831         {
1832                 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
1833                         break;
1834
1835                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1836
1837                 //report network only if the current channel set contains the channel to which this network belongs
1838                 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
1839                         && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE\r
1840                         && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
1841                 )
1842                 {               
1843                         //ev=translate_scan(padapter, a, pnetwork, ev, stop);
1844                         rtw_cfg80211_inform_bss(padapter, pnetwork);            
1845                 }
1846
1847                 plist = get_next(plist);
1848         
1849         }
1850         
1851         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1852         
1853         //call this after other things have been done
1854         rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev), _FALSE);
1855 }
1856
1857 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
1858 {
1859         int ret = 0;
1860         uint wps_ielen = 0;
1861         u8 *wps_ie;
1862         u32     p2p_ielen = 0;  
1863         u8 *p2p_ie;
1864         u32     wfd_ielen = 0;  
1865         u8 *wfd_ie;
1866         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
1867
1868 #ifdef CONFIG_DEBUG_CFG80211
1869         DBG_8192C("%s, ielen=%d\n", __func__, len);
1870 #endif
1871         
1872         if(len>0)
1873         {
1874                 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
1875                 {
1876                         #ifdef CONFIG_DEBUG_CFG80211
1877                         DBG_8192C("probe_req_wps_ielen=%d\n", wps_ielen);
1878                         #endif
1879                         
1880                         if(pmlmepriv->wps_probe_req_ie)
1881                         {
1882                                 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
1883                                 pmlmepriv->wps_probe_req_ie_len = 0;
1884                                 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
1885                                 pmlmepriv->wps_probe_req_ie = NULL;                     
1886                         }       
1887
1888                         pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
1889                         if ( pmlmepriv->wps_probe_req_ie == NULL) {
1890                                 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
1891                                 return -EINVAL;
1892                         
1893                         }
1894                         _rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
1895                         pmlmepriv->wps_probe_req_ie_len = wps_ielen;
1896                 }
1897
1898                 //buf += wps_ielen;
1899                 //len -= wps_ielen;
1900
1901                 #ifdef CONFIG_P2P
1902                 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen))) 
1903                 {
1904                         struct wifidirect_info *wdinfo = &padapter->wdinfo;
1905                         u32 attr_contentlen = 0;
1906                         u8 listen_ch_attr[5];
1907
1908                         #ifdef CONFIG_DEBUG_CFG80211
1909                         DBG_8192C("probe_req_p2p_ielen=%d\n", p2p_ielen);
1910                         #endif
1911                         
1912                         if(pmlmepriv->p2p_probe_req_ie)
1913                         {
1914                                 u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
1915                                 pmlmepriv->p2p_probe_req_ie_len = 0;
1916                                 rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len);
1917                                 pmlmepriv->p2p_probe_req_ie = NULL;
1918                         }       
1919
1920                         pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen);
1921                         if ( pmlmepriv->p2p_probe_req_ie == NULL) {
1922                                 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
1923                                 return -EINVAL;
1924                         
1925                         }
1926                         _rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
1927                         pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
1928
1929                         if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8*)listen_ch_attr, (uint*) &attr_contentlen)
1930                                 && attr_contentlen == 5)
1931                         {
1932                                 if (wdinfo->listen_channel !=  listen_ch_attr[4]) {
1933                                         DBG_871X(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n",
1934                                                 FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2],
1935                                                 listen_ch_attr[3], listen_ch_attr[4]);
1936                                         wdinfo->listen_channel = listen_ch_attr[4];
1937                                 }
1938                         }
1939                 }
1940                 #endif //CONFIG_P2P
1941                 
1942                 //buf += p2p_ielen;
1943                 //len -= p2p_ielen;
1944
1945                 #ifdef CONFIG_WFD
1946                 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) 
1947                 {
1948                         #ifdef CONFIG_DEBUG_CFG80211
1949                         DBG_8192C("probe_req_wfd_ielen=%d\n", wfd_ielen);
1950                         #endif
1951                         
1952                         if(pmlmepriv->wfd_probe_req_ie)
1953                         {
1954                                 u32 free_len = pmlmepriv->wfd_probe_req_ie_len;
1955                                 pmlmepriv->wfd_probe_req_ie_len = 0;
1956                                 rtw_mfree(pmlmepriv->wfd_probe_req_ie, free_len);
1957                                 pmlmepriv->wfd_probe_req_ie = NULL;
1958                         }       
1959
1960                         pmlmepriv->wfd_probe_req_ie = rtw_malloc(wfd_ielen);
1961                         if ( pmlmepriv->wfd_probe_req_ie == NULL) {
1962                                 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
1963                                 return -EINVAL;
1964                         
1965                         }
1966                         rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);                        
1967                 }
1968                 #endif //CONFIG_WFD
1969                 
1970         }
1971
1972         return ret;
1973         
1974 }
1975
1976 static int cfg80211_rtw_scan(struct wiphy *wiphy
1977         #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
1978         , struct net_device *ndev
1979         #endif
1980         , struct cfg80211_scan_request *request)
1981 {
1982         int i;
1983         u8 _status = _FALSE;
1984         int ret = 0;    
1985         _adapter *padapter = wiphy_to_adapter(wiphy);
1986         struct mlme_priv *pmlmepriv= &padapter->mlmepriv;
1987         NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
1988         struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
1989         _irqL   irqL;
1990         u8 *wps_ie=NULL;
1991         uint wps_ielen=0;       
1992         u8 *p2p_ie=NULL;
1993         uint p2p_ielen=0;
1994         u8 survey_times=3;
1995         u8 survey_times_for_one_ch=6;
1996 #ifdef CONFIG_P2P
1997         struct wifidirect_info *pwdinfo= &(padapter->wdinfo);   
1998 #endif //CONFIG_P2P
1999         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
2000         struct cfg80211_ssid *ssids = request->ssids;
2001         int social_channel = 0, j = 0;
2002         bool need_indicate_scan_done = _FALSE;
2003 #ifdef CONFIG_CONCURRENT_MODE   
2004         PADAPTER pbuddy_adapter = NULL;
2005         struct mlme_priv *pbuddy_mlmepriv = NULL;
2006 #endif //CONFIG_CONCURRENT_MODE
2007
2008 //#ifdef CONFIG_DEBUG_CFG80211
2009         DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
2010 //#endif
2011
2012 #ifdef CONFIG_CONCURRENT_MODE
2013         if (padapter->pbuddy_adapter) {
2014                 pbuddy_adapter = padapter->pbuddy_adapter;
2015                 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);  
2016         }
2017 #endif //CONFIG_CONCURRENT_MODE
2018
2019 #ifdef CONFIG_MP_INCLUDED
2020         if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
2021         {
2022                 ret = -EPERM;
2023                 goto exit;
2024         }
2025 #endif
2026
2027         _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2028         pwdev_priv->scan_request = request;
2029         _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2030
2031         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2032         {
2033 #ifdef CONFIG_DEBUG_CFG80211
2034                 DBG_871X("%s under WIFI_AP_STATE\n", __FUNCTION__);
2035 #endif
2036
2037                 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2038                 {
2039                         DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
2040
2041                         if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
2042                         {
2043                                 DBG_8192C("AP mode process WPS \n");
2044                         }
2045
2046                         need_indicate_scan_done = _TRUE;
2047                         goto check_need_indicate_scan_done;
2048                 }
2049         }
2050
2051         if(_FAIL == rtw_pwr_wakeup(padapter)) {
2052                 need_indicate_scan_done = _TRUE;
2053                 goto check_need_indicate_scan_done;
2054         }
2055
2056         #ifdef CONFIG_P2P
2057         if( pwdinfo->driver_interface == DRIVER_CFG80211 )
2058         {
2059                 if(ssids->ssid != NULL
2060                         && _rtw_memcmp(ssids->ssid, "DIRECT-", 7)
2061                         && rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
2062                 )
2063                 {
2064                         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2065                         {
2066                                 u32 initialgain = 0x30;
2067                                 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
2068                                 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = _TRUE;
2069                                 padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_INITIAL_GAIN, (u8 *)&(initialgain));
2070                                 padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_INITIAL_GAIN, (u8 *)&(initialgain));
2071                         }
2072                         else
2073                         {
2074                                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
2075                                 #ifdef CONFIG_DEBUG_CFG80211
2076                                 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
2077                                 #endif
2078                         }
2079                         rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
2080                 
2081                         if(request->n_channels == 3 &&
2082                                 request->channels[0]->hw_value == 1 &&
2083                                 request->channels[1]->hw_value == 6 &&
2084                                 request->channels[2]->hw_value == 11
2085                         )
2086                         {
2087                                 social_channel = 1;
2088                         }
2089                 }
2090         }
2091         #endif //CONFIG_P2P
2092
2093         if(request->ie && request->ie_len>0)
2094         {
2095                 rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len );
2096         }
2097
2098         if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)
2099         {
2100                 DBG_8192C("%s, bBusyTraffic == _TRUE\n", __func__);
2101                 need_indicate_scan_done = _TRUE;
2102                 goto check_need_indicate_scan_done;
2103         }
2104         if (rtw_is_scan_deny(padapter)){
2105                 DBG_871X(FUNC_ADPT_FMT  ": scan deny\n", FUNC_ADPT_ARG(padapter));
2106                 need_indicate_scan_done = _TRUE;
2107                 goto check_need_indicate_scan_done;
2108         }
2109
2110 #ifdef CONFIG_CONCURRENT_MODE
2111         if(pbuddy_mlmepriv && (pbuddy_mlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))  
2112         {
2113                 DBG_8192C("%s, bBusyTraffic == _TRUE at buddy_intf\n", __func__);
2114                 need_indicate_scan_done = _TRUE;
2115                 goto check_need_indicate_scan_done;
2116         }
2117 #endif //CONFIG_CONCURRENT_MODE
2118
2119         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2120         {
2121                 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
2122                 need_indicate_scan_done = _TRUE;
2123                 goto check_need_indicate_scan_done;
2124         } 
2125
2126 #ifdef CONFIG_CONCURRENT_MODE
2127         if (check_buddy_fwstate(padapter,
2128                 _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
2129         {               
2130                 if(check_buddy_fwstate(padapter, _FW_UNDER_SURVEY))
2131                 {
2132                         DBG_8192C("scanning_via_buddy_intf\n");
2133                         pmlmepriv->scanning_via_buddy_intf = _TRUE;
2134                 }               
2135
2136                 DBG_8192C("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv->fw_state);
2137                 
2138                 need_indicate_scan_done = _TRUE;
2139                 goto check_need_indicate_scan_done;
2140         }
2141 #endif
2142
2143
2144 #ifdef CONFIG_P2P
2145         if( pwdinfo->driver_interface == DRIVER_CFG80211 )
2146         {
2147                 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
2148                 {
2149                         rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
2150                         rtw_free_network_queue(padapter, _TRUE);
2151
2152                         if(social_channel == 0)
2153                                 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
2154                         else
2155                                 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
2156                 }
2157         }
2158 #endif //CONFIG_P2P
2159
2160
2161         _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
2162         //parsing request ssids, n_ssids
2163         for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
2164                 #ifdef CONFIG_DEBUG_CFG80211
2165                 DBG_8192C("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
2166                 #endif
2167                 _rtw_memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
2168                 ssid[i].SsidLength = ssids[i].ssid_len; 
2169         }
2170         
2171
2172         /* parsing channels, n_channels */
2173         _rtw_memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
2174         for (i=0;i<request->n_channels && i<RTW_CHANNEL_SCAN_AMOUNT;i++) {
2175                 #ifdef CONFIG_DEBUG_CFG80211
2176                 DBG_871X(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
2177                 #endif
2178                 ch[i].hw_value = request->channels[i]->hw_value;
2179                 ch[i].flags = request->channels[i]->flags;
2180         }
2181
2182         _enter_critical_bh(&pmlmepriv->lock, &irqL);
2183         if (request->n_channels == 1) {
2184                 for(i=1;i<survey_times_for_one_ch;i++)
2185                         _rtw_memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
2186                 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times_for_one_ch);
2187         } else if (request->n_channels == 2) {
2188                 _rtw_memcpy(&ch[3], &ch[1], sizeof(struct rtw_ieee80211_channel));
2189                 for(i=1;i<survey_times;i++) {
2190                         _rtw_memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
2191                         _rtw_memcpy(&ch[i+3], &ch[3], sizeof(struct rtw_ieee80211_channel));
2192                 }
2193                 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * 2);
2194         } else {
2195                 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
2196         }
2197         _exit_critical_bh(&pmlmepriv->lock, &irqL);
2198
2199
2200         if(_status == _FALSE)
2201         {
2202                 ret = -1;
2203         }
2204
2205 check_need_indicate_scan_done:
2206         if(need_indicate_scan_done)
2207                 rtw_cfg80211_surveydone_event_callback(padapter);
2208
2209 exit:
2210
2211         return ret;
2212         
2213 }
2214
2215 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
2216 {
2217 #if 0
2218         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2219
2220         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
2221             (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
2222                 int ret;
2223
2224                 iwm->conf.rts_threshold = wiphy->rts_threshold;
2225
2226                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
2227                                              CFG_RTS_THRESHOLD,
2228                                              iwm->conf.rts_threshold);
2229                 if (ret < 0)
2230                         return ret;
2231         }
2232
2233         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
2234             (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
2235                 int ret;
2236
2237                 iwm->conf.frag_threshold = wiphy->frag_threshold;
2238
2239                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
2240                                              CFG_FRAG_THRESHOLD,
2241                                              iwm->conf.frag_threshold);
2242                 if (ret < 0)
2243                         return ret;
2244         }
2245 #endif
2246         DBG_8192C("%s\n", __func__);
2247         return 0;
2248 }
2249
2250 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
2251                                   struct cfg80211_ibss_params *params)
2252 {
2253 #if 0
2254         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2255         struct ieee80211_channel *chan = params->channel;
2256
2257         if (!test_bit(IWM_STATUS_READY, &iwm->status))
2258                 return -EIO;
2259
2260         /* UMAC doesn't support creating or joining an IBSS network
2261          * with specified bssid. */
2262         if (params->bssid)
2263                 return -EOPNOTSUPP;
2264
2265         iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
2266         iwm->umac_profile->ibss.band = chan->band;
2267         iwm->umac_profile->ibss.channel = iwm->channel;
2268         iwm->umac_profile->ssid.ssid_len = params->ssid_len;
2269         memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
2270
2271         return iwm_send_mlme_profile(iwm);
2272 #endif  
2273         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2274         return 0;
2275 }
2276
2277 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
2278 {
2279 #if 0
2280         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2281
2282         if (iwm->umac_profile_active)
2283                 return iwm_invalidate_mlme_profile(iwm);
2284 #endif
2285         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2286         return 0;
2287 }
2288
2289 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
2290 {       
2291         DBG_8192C("%s, wpa_version=%d\n", __func__, wpa_version);
2292         
2293         if (!wpa_version) {             
2294                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;           
2295                 return 0;
2296         }
2297
2298
2299         if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
2300         {               
2301                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;         
2302         }
2303
2304 /*
2305         if (wpa_version & NL80211_WPA_VERSION_2)
2306         {               
2307                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2308         }
2309 */
2310
2311         return 0;
2312
2313 }
2314
2315 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
2316                              enum nl80211_auth_type sme_auth_type)
2317 {
2318         DBG_8192C("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
2319
2320
2321         switch (sme_auth_type) {
2322         case NL80211_AUTHTYPE_AUTOMATIC:
2323
2324                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2325
2326                 break;
2327         case NL80211_AUTHTYPE_OPEN_SYSTEM:
2328         
2329                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2330
2331                 if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
2332                         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2333                 
2334                 break;
2335         case NL80211_AUTHTYPE_SHARED_KEY:
2336
2337                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
2338
2339                 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
2340
2341
2342                 break;
2343         default:                
2344                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2345                 //return -ENOTSUPP;
2346         }
2347
2348         return 0;
2349
2350 }
2351
2352 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
2353 {
2354         u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
2355
2356         u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
2357                 &psecuritypriv->dot118021XGrpPrivacy;
2358
2359         DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
2360
2361
2362         if (!cipher) {
2363                 *profile_cipher = _NO_PRIVACY_;
2364                 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
2365                 return 0;
2366         }
2367         
2368         switch (cipher) {
2369         case IW_AUTH_CIPHER_NONE:
2370                 *profile_cipher = _NO_PRIVACY_;
2371                 ndisencryptstatus = Ndis802_11EncryptionDisabled;
2372                 break;
2373         case WLAN_CIPHER_SUITE_WEP40:
2374                 *profile_cipher = _WEP40_;
2375                 ndisencryptstatus = Ndis802_11Encryption1Enabled;
2376                 break;
2377         case WLAN_CIPHER_SUITE_WEP104:
2378                 *profile_cipher = _WEP104_;
2379                 ndisencryptstatus = Ndis802_11Encryption1Enabled;
2380                 break;
2381         case WLAN_CIPHER_SUITE_TKIP:
2382                 *profile_cipher = _TKIP_;
2383                 ndisencryptstatus = Ndis802_11Encryption2Enabled;
2384                 break;
2385         case WLAN_CIPHER_SUITE_CCMP:
2386                 *profile_cipher = _AES_;
2387                 ndisencryptstatus = Ndis802_11Encryption3Enabled;
2388                 break;
2389         default:
2390                 DBG_8192C("Unsupported cipher: 0x%x\n", cipher);
2391                 return -ENOTSUPP;
2392         }
2393
2394         if(ucast)
2395         {
2396                 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
2397                 
2398                 //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
2399                 //      psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2400         }       
2401
2402         return 0;
2403 }
2404
2405 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
2406 {
2407         DBG_8192C("%s, key_mgt=0x%x\n", __func__, key_mgt);
2408
2409         if (key_mgt == WLAN_AKM_SUITE_8021X)
2410                 //*auth_type = UMAC_AUTH_TYPE_8021X;
2411                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2412         else if (key_mgt == WLAN_AKM_SUITE_PSK) {
2413                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2414         } else {
2415                 DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt);
2416                 //return -EINVAL;
2417         }
2418
2419         return 0;
2420 }
2421
2422 static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
2423 {
2424         u8 *buf=NULL, *pos=NULL;        
2425         u32 left;       
2426         int group_cipher = 0, pairwise_cipher = 0;
2427         int ret = 0;
2428         int wpa_ielen=0;
2429         int wpa2_ielen=0;
2430         u8 *pwpa, *pwpa2;
2431         u8 null_addr[]= {0,0,0,0,0,0};
2432
2433         if (pie == NULL || !ielen) {
2434                 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
2435                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2436                 goto exit;
2437         }
2438
2439         if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
2440                 ret = -EINVAL;
2441                 goto exit;
2442         }
2443
2444         buf = rtw_zmalloc(ielen);
2445         if (buf == NULL){
2446                 ret =  -ENOMEM;
2447                 goto exit;
2448         }
2449
2450         _rtw_memcpy(buf, pie , ielen);
2451
2452         //dump
2453         {
2454                 int i;
2455                 DBG_8192C("set wpa_ie(length:%zu):\n", ielen);
2456                 for(i=0;i<ielen;i=i+8)
2457                         DBG_8192C("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n",buf[i],buf[i+1],buf[i+2],buf[i+3],buf[i+4],buf[i+5],buf[i+6],buf[i+7]);
2458         }
2459
2460         pos = buf;
2461         if(ielen < RSN_HEADER_LEN){
2462                 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
2463                 ret  = -1;
2464                 goto exit;
2465         }
2466
2467         pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
2468         if(pwpa && wpa_ielen>0)
2469         {
2470                 if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher) == _SUCCESS)
2471                 {
2472                         padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
2473                         padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
2474                         _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
2475                         
2476                         DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
2477                 }
2478         }
2479
2480         pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
2481         if(pwpa2 && wpa2_ielen>0)
2482         {
2483                 if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher) == _SUCCESS)
2484                 {
2485                         padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
2486                         padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;  
2487                         _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
2488
2489                         DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
2490                 }
2491         }
2492
2493         if (group_cipher == 0)
2494         {
2495                 group_cipher = WPA_CIPHER_NONE;
2496         }
2497         if (pairwise_cipher == 0)
2498         {
2499                 pairwise_cipher = WPA_CIPHER_NONE;
2500         }
2501         
2502         switch(group_cipher)
2503         {
2504                 case WPA_CIPHER_NONE:
2505                         padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
2506                         padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
2507                         break;
2508                 case WPA_CIPHER_WEP40:
2509                         padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
2510                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2511                         break;
2512                 case WPA_CIPHER_TKIP:
2513                         padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
2514                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
2515                         break;
2516                 case WPA_CIPHER_CCMP:
2517                         padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
2518                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
2519                         break;
2520                 case WPA_CIPHER_WEP104: 
2521                         padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
2522                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2523                         break;
2524         }
2525
2526         switch(pairwise_cipher)
2527         {
2528                 case WPA_CIPHER_NONE:
2529                         padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
2530                         padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
2531                         break;
2532                 case WPA_CIPHER_WEP40:
2533                         padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
2534                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2535                         break;
2536                 case WPA_CIPHER_TKIP:
2537                         padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
2538                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
2539                         break;
2540                 case WPA_CIPHER_CCMP:
2541                         padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
2542                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
2543                         break;
2544                 case WPA_CIPHER_WEP104: 
2545                         padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
2546                         padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2547                         break;
2548         }
2549         
2550         {/* handle wps_ie */
2551                 uint wps_ielen; 
2552                 u8 *wps_ie;
2553
2554                 wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
2555                 if (wps_ie && wps_ielen > 0) {
2556                         DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen);
2557                         padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
2558                         _rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
2559                         set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
2560                 } else {
2561                         _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2562                 }
2563         }
2564
2565         #ifdef CONFIG_P2P
2566         {//check p2p_ie for assoc req; 
2567                 uint p2p_ielen=0;
2568                 u8 *p2p_ie;
2569                 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2570
2571                 if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen)))
2572                 {
2573                         #ifdef CONFIG_DEBUG_CFG80211
2574                         DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
2575                         #endif
2576
2577                         if(pmlmepriv->p2p_assoc_req_ie)
2578                         {
2579                                 u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
2580                                 pmlmepriv->p2p_assoc_req_ie_len = 0;
2581                                 rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
2582                                 pmlmepriv->p2p_assoc_req_ie = NULL;
2583                         }
2584
2585                         pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
2586                         if ( pmlmepriv->p2p_assoc_req_ie == NULL) {
2587                                 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
2588                                 goto exit;
2589                         }
2590                         _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
2591                         pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
2592                 }
2593         }
2594         #endif //CONFIG_P2P
2595
2596         #ifdef CONFIG_WFD
2597         {//check wfd_ie for assoc req; 
2598                 uint wfd_ielen=0;
2599                 u8 *wfd_ie;
2600                 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2601
2602                 if(rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen))
2603                 {
2604                         #ifdef CONFIG_DEBUG_CFG80211
2605                         DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
2606                         #endif
2607
2608                         if(pmlmepriv->wfd_assoc_req_ie)
2609                         {
2610                                 u32 free_len = pmlmepriv->wfd_assoc_req_ie_len;
2611                                 pmlmepriv->wfd_assoc_req_ie_len = 0;
2612                                 rtw_mfree(pmlmepriv->wfd_assoc_req_ie, free_len);
2613                                 pmlmepriv->wfd_assoc_req_ie = NULL;
2614                         }
2615
2616                         pmlmepriv->wfd_assoc_req_ie = rtw_malloc(wfd_ielen);
2617                         if ( pmlmepriv->wfd_assoc_req_ie == NULL) {
2618                                 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
2619                                 goto exit;
2620                         }
2621                         rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);                      
2622                 }
2623         }
2624         #endif //CONFIG_WFD
2625
2626         //TKIP and AES disallow multicast packets until installing group key
2627         if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
2628                 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
2629                 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
2630                 //WPS open need to enable multicast
2631                 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
2632                 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
2633
2634         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2635                 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
2636                 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
2637
2638 exit:
2639         if (buf)
2640                 rtw_mfree(buf, ielen);
2641         if (ret)
2642                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2643         return ret;
2644 }
2645
2646 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
2647                                  struct cfg80211_connect_params *sme)
2648 {
2649         int ret=0;
2650         _irqL irqL;     
2651         _list *phead;   
2652         struct wlan_network *pnetwork = NULL;
2653         NDIS_802_11_AUTHENTICATION_MODE authmode;       
2654         NDIS_802_11_SSID ndis_ssid;     
2655         u8 *dst_ssid, *src_ssid;
2656         u8 *dst_bssid, *src_bssid;
2657         //u8 matched_by_bssid=_FALSE;
2658         //u8 matched_by_ssid=_FALSE;
2659         u8 matched=_FALSE;
2660         _adapter *padapter = wiphy_to_adapter(wiphy);
2661         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;      
2662         struct security_priv *psecuritypriv = &padapter->securitypriv;
2663         _queue *queue = &pmlmepriv->scanned_queue;      
2664         
2665         DBG_871X("=>"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2666         DBG_871X("privacy=%d, key=%p, key_len=%d, key_idx=%d\n",
2667                 sme->privacy, sme->key, sme->key_len, sme->key_idx);
2668
2669
2670         if(wdev_to_priv(padapter->rtw_wdev)->block == _TRUE)
2671         {
2672                 ret = -EBUSY;
2673                 DBG_871X("%s wdev_priv.block is set\n", __FUNCTION__);
2674                 goto exit;
2675         }
2676
2677 #ifdef CONFIG_PLATFORM_MSTAR
2678         printk("MStar Android!\n");
2679         if((wdev_to_priv(padapter->rtw_wdev))->bandroid_scan == _FALSE)
2680         {
2681 #ifdef CONFIG_P2P
2682                 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);   
2683                 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2684 #endif //CONFIG_P2P
2685                 {
2686                         ret = -EBUSY;
2687                         printk("Android hasn't attached yet!\n");
2688                         goto exit;
2689                 }       
2690         }
2691 #endif
2692
2693         if(_FAIL == rtw_pwr_wakeup(padapter)) {
2694                 ret= -EPERM;
2695                 goto exit;
2696         }
2697
2698         if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2699                 ret = -EPERM;
2700                 goto exit;
2701         }
2702
2703 #ifdef CONFIG_CONCURRENT_MODE
2704         if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
2705                 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
2706                 ret = -EINVAL;
2707                 goto exit;
2708         }
2709         if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
2710                 rtw_scan_abort(padapter->pbuddy_adapter);
2711         }
2712 #endif
2713
2714         if (!sme->ssid || !sme->ssid_len)
2715         {
2716                 ret = -EINVAL;
2717                 goto exit;
2718         }
2719
2720         if (sme->ssid_len > IW_ESSID_MAX_SIZE){
2721
2722                 ret= -E2BIG;
2723                 goto exit;
2724         }
2725         
2726         _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));                   
2727         ndis_ssid.SsidLength = sme->ssid_len;
2728         _rtw_memcpy(ndis_ssid.Ssid, sme->ssid, sme->ssid_len);
2729
2730         DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
2731         
2732
2733         if (sme->bssid)
2734                 DBG_8192C("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
2735
2736
2737         if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
2738                 ret = -EBUSY;
2739                 DBG_8192C("%s, fw_state=0x%x, goto exit\n", __FUNCTION__, pmlmepriv->fw_state);
2740                 goto exit;              
2741         }
2742         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
2743                 rtw_scan_abort(padapter);
2744         }
2745
2746         psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
2747         psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
2748         psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2749         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
2750         psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2751
2752
2753         ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
2754         if (ret < 0)
2755                 goto exit;
2756
2757         ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
2758         if (ret < 0)
2759                 goto exit;
2760
2761         DBG_8192C("%s, ie_len=%zu\n", __func__, sme->ie_len);
2762                         
2763         ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len);
2764         if (ret < 0)
2765                 goto exit;
2766
2767         if (sme->crypto.n_ciphers_pairwise) {           
2768                 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
2769                 if (ret < 0)
2770                         goto exit;
2771         }
2772
2773         //For WEP Shared auth
2774         if((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared
2775                 || psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && sme->key
2776         )
2777         {
2778                 u32 wep_key_idx, wep_key_len,wep_total_len;
2779                 NDIS_802_11_WEP  *pwep = NULL;
2780                 DBG_871X("%s(): Shared/Auto WEP\n",__FUNCTION__);
2781
2782                 wep_key_idx = sme->key_idx;
2783                 wep_key_len = sme->key_len;
2784
2785                 if (sme->key_idx > WEP_KEYS) {
2786                         ret = -EINVAL;
2787                         goto exit;
2788                 }
2789
2790                 if (wep_key_len > 0) 
2791                 {
2792                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
2793                         wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
2794                         pwep =(NDIS_802_11_WEP   *) rtw_malloc(wep_total_len);
2795                         if(pwep == NULL){
2796                                 DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
2797                                 ret = -ENOMEM;
2798                                 goto exit;
2799                         }
2800
2801                         _rtw_memset(pwep, 0, wep_total_len);
2802
2803                         pwep->KeyLength = wep_key_len;
2804                         pwep->Length = wep_total_len;
2805
2806                         if(wep_key_len==13)
2807                         {
2808                                 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
2809                                 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
2810                         }
2811                 }
2812                 else {          
2813                         ret = -EINVAL;
2814                         goto exit;
2815                 }
2816
2817                 pwep->KeyIndex = wep_key_idx;
2818                 pwep->KeyIndex |= 0x80000000;
2819
2820                 _rtw_memcpy(pwep->KeyMaterial,  (void *)sme->key, pwep->KeyLength);
2821
2822                 if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
2823                 {
2824                         ret = -EOPNOTSUPP ;
2825                 }
2826
2827                 if (pwep) {
2828                         rtw_mfree((u8 *)pwep,wep_total_len);            
2829                 }
2830
2831                 if(ret < 0)
2832                         goto exit;
2833         }
2834
2835         ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
2836         if (ret < 0)
2837                 return ret;
2838
2839         if (sme->crypto.n_akm_suites) {
2840                 ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
2841                 if (ret < 0)
2842                         goto exit;
2843         }
2844
2845         authmode = psecuritypriv->ndisauthtype;
2846         rtw_set_802_11_authentication_mode(padapter, authmode);
2847
2848         //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
2849
2850         if (rtw_set_802_11_connect(padapter, sme->bssid, &ndis_ssid) == _FALSE) {\r
2851                 ret = -1;
2852                 goto exit;
2853         }
2854
2855         DBG_8192C("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy);
2856         
2857 exit:
2858
2859         DBG_8192C("<=%s, ret %d\n",__FUNCTION__, ret);
2860         
2861         return ret;
2862 }
2863
2864 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2865                                    u16 reason_code)
2866 {
2867         _adapter *padapter = wiphy_to_adapter(wiphy);
2868
2869         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2870
2871         rtw_set_roaming(padapter, 0);
2872
2873         if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) 
2874         {
2875                 rtw_scan_abort(padapter);
2876                 LeaveAllPowerSaveMode(padapter);
2877                 rtw_disassoc_cmd(padapter, 500, _FALSE);
2878                 
2879                 DBG_871X("%s...call rtw_indicate_disconnect\n", __FUNCTION__);
2880                 
2881                 padapter->mlmepriv.not_indic_disco = _TRUE;
2882                 rtw_indicate_disconnect(padapter);
2883                 padapter->mlmepriv.not_indic_disco = _FALSE;
2884                 
2885                 rtw_free_assoc_resources(padapter, 1);
2886         }
2887         
2888         return 0;
2889 }
2890
2891 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
2892 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
2893         struct wireless_dev *wdev,
2894 #endif
2895 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE)
2896         enum nl80211_tx_power_setting type, int mbm)
2897 #else
2898         enum tx_power_setting type, int dbm)
2899 #endif
2900 {
2901 #if 0
2902         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2903         int ret;
2904
2905         switch (type) {
2906         case NL80211_TX_POWER_AUTOMATIC:
2907                 return 0;
2908         case NL80211_TX_POWER_FIXED:
2909                 if (mbm < 0 || (mbm % 100))
2910                         return -EOPNOTSUPP;
2911
2912                 if (!test_bit(IWM_STATUS_READY, &iwm->status))
2913                         return 0;
2914
2915                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
2916                                               CFG_TX_PWR_LIMIT_USR,
2917                                               MBM_TO_DBM(mbm) * 2);
2918                 if (ret < 0)
2919                         return ret;
2920
2921                 return iwm_tx_power_trigger(iwm);
2922         default:
2923                 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
2924                 return -EOPNOTSUPP;
2925         }
2926 #endif
2927         DBG_8192C("%s\n", __func__);
2928         return 0;
2929 }
2930
2931 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
2932 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
2933         struct wireless_dev *wdev,
2934 #endif
2935         int *dbm)
2936 {
2937         //_adapter *padapter = wiphy_to_adapter(wiphy);
2938
2939         DBG_8192C("%s\n", __func__);
2940
2941         *dbm = (12);
2942         
2943         return 0;
2944 }
2945
2946 inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
2947 {
2948         struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(adapter->rtw_wdev);
2949         return rtw_wdev_priv->power_mgmt;
2950 }
2951
2952 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
2953                                        struct net_device *ndev,
2954                                        bool enabled, int timeout)
2955 {
2956         _adapter *padapter = wiphy_to_adapter(wiphy);
2957         struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(padapter->rtw_wdev);
2958         
2959         DBG_871X(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
2960                 enabled, timeout);
2961
2962         rtw_wdev_priv->power_mgmt = enabled;
2963
2964         #ifdef CONFIG_LPS
2965         if (!enabled)
2966                 LPS_Leave(padapter);
2967         #endif
2968
2969         return 0;
2970 }
2971
2972 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
2973                                   struct net_device *netdev,
2974                                   struct cfg80211_pmksa *pmksa)
2975 {
2976         u8      index,blInserted = _FALSE;
2977         _adapter        *padapter = wiphy_to_adapter(wiphy);
2978         struct security_priv    *psecuritypriv = &padapter->securitypriv;
2979         u8      strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
2980
2981         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev));
2982
2983         if ( _rtw_memcmp( pmksa->bssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
2984         {
2985                 return -EINVAL;
2986         }
2987
2988         blInserted = _FALSE;
2989         
2990         //overwrite PMKID
2991         for(index=0 ; index<NUM_PMKID_CACHE; index++)
2992         {
2993                 if( _rtw_memcmp( psecuritypriv->PMKIDList[index].Bssid, pmksa->bssid, ETH_ALEN) ==_TRUE )
2994                 { // BSSID is matched, the same AP => rewrite with new PMKID.
2995                         DBG_871X(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(netdev));
2996
2997                         _rtw_memcpy( psecuritypriv->PMKIDList[index].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2998                         psecuritypriv->PMKIDList[index].bUsed = _TRUE;
2999                         psecuritypriv->PMKIDIndex = index+1;
3000                         blInserted = _TRUE;
3001                         break;
3002                 }       
3003         }
3004
3005         if(!blInserted)
3006         {
3007                 // Find a new entry
3008                 DBG_871X(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
3009                         FUNC_NDEV_ARG(netdev), psecuritypriv->PMKIDIndex );
3010
3011                 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, pmksa->bssid, ETH_ALEN);
3012                 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3013
3014                 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
3015                 psecuritypriv->PMKIDIndex++ ;
3016                 if(psecuritypriv->PMKIDIndex==16)
3017                 {
3018                         psecuritypriv->PMKIDIndex =0;
3019                 } 
3020         } 
3021
3022         return 0;
3023 }
3024
3025 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
3026                                   struct net_device *netdev,
3027                                   struct cfg80211_pmksa *pmksa)
3028 {
3029         u8      index, bMatched = _FALSE;
3030         _adapter        *padapter = wiphy_to_adapter(wiphy);
3031         struct security_priv    *psecuritypriv = &padapter->securitypriv;
3032
3033         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev));
3034
3035         for(index=0 ; index<NUM_PMKID_CACHE; index++)
3036         {
3037                 if( _rtw_memcmp( psecuritypriv->PMKIDList[index].Bssid, pmksa->bssid, ETH_ALEN) ==_TRUE )
3038                 { // BSSID is matched, the same AP => Remove this PMKID information and reset it. 
3039                         _rtw_memset( psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN );
3040                         _rtw_memset( psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN );
3041                         psecuritypriv->PMKIDList[index].bUsed = _FALSE;
3042                         bMatched = _TRUE;
3043                         break;
3044                 }       
3045         }
3046
3047         if(_FALSE == bMatched)
3048         {
3049                 DBG_871X(FUNC_NDEV_FMT" do not have matched BSSID\n"
3050                         , FUNC_NDEV_ARG(netdev));
3051                 return -EINVAL;
3052         }
3053
3054         return 0;
3055 }
3056
3057 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
3058                                     struct net_device *netdev)
3059 {
3060         _adapter        *padapter = wiphy_to_adapter(wiphy);
3061         struct security_priv    *psecuritypriv = &padapter->securitypriv;
3062
3063         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev));
3064
3065         _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
3066         psecuritypriv->PMKIDIndex = 0;
3067
3068         return 0;
3069 }
3070
3071 #ifdef CONFIG_AP_MODE
3072 void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
3073 {
3074         s32 freq;
3075         int channel;
3076         struct wireless_dev *pwdev = padapter->rtw_wdev;
3077         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);      
3078         struct net_device *ndev = padapter->pnetdev;
3079
3080         DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
3081
3082 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
3083         {
3084                 struct station_info sinfo;
3085                 u8 ie_offset;
3086                 if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
3087                         ie_offset = _ASOCREQ_IE_OFFSET_;
3088                 else // WIFI_REASSOCREQ
3089                         ie_offset = _REASOCREQ_IE_OFFSET_;
3090         
3091                 sinfo.filled = 0;
3092                 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
3093                 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
3094                 sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
3095                 cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
3096         }
3097 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
3098         channel = pmlmeext->cur_channel;
3099         if (channel <= RTW_CH_MAX_2G_CHANNEL)
3100                 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3101         else
3102                 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3103
3104         #ifdef COMPAT_KERNEL_RELEASE
3105         rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3106         #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3107         rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3108         #else //COMPAT_KERNEL_RELEASE
3109         {
3110                 //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)  when calling cfg80211_send_rx_assoc()
3111                 #ifndef CONFIG_PLATFORM_MSTAR
3112                 pwdev->iftype = NL80211_IFTYPE_STATION;
3113                 #endif //CONFIG_PLATFORM_MSTAR
3114                 DBG_8192C("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
3115                 rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
3116                 DBG_8192C("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
3117                 pwdev->iftype = NL80211_IFTYPE_AP;
3118                 //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
3119         }
3120         #endif //COMPAT_KERNEL_RELEASE
3121 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
3122
3123 }
3124
3125 void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason)
3126 {
3127         s32 freq;
3128         int channel;
3129         u8 *pmgmt_frame;
3130         uint frame_len;
3131         struct rtw_ieee80211_hdr *pwlanhdr;
3132         unsigned short *fctrl;  
3133         u8 mgmt_buf[128] = {0};
3134         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3135         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3136         struct net_device *ndev = padapter->pnetdev;
3137         
3138         DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
3139
3140 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
3141         cfg80211_del_sta(ndev, da, GFP_ATOMIC);
3142 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
3143         channel = pmlmeext->cur_channel;
3144         if (channel <= RTW_CH_MAX_2G_CHANNEL)
3145                 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3146         else
3147                 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3148
3149         pmgmt_frame = mgmt_buf; 
3150         pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
3151
3152         fctrl = &(pwlanhdr->frame_ctl);
3153         *(fctrl) = 0;
3154
3155         //_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3156         //_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3157         _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
3158         _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN);     
3159         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3160
3161         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3162         pmlmeext->mgnt_seq++;
3163         SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
3164
3165         pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
3166         frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
3167
3168         reason = cpu_to_le16(reason);
3169         pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
3170
3171         #ifdef COMPAT_KERNEL_RELEASE
3172         rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
3173         #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3174         rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
3175         #else //COMPAT_KERNEL_RELEASE
3176         cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len); 
3177         //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC);
3178         #endif //COMPAT_KERNEL_RELEASE
3179 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
3180 }
3181
3182 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
3183 {
3184         int ret = 0;
3185
3186         DBG_8192C("%s\n", __func__);
3187         
3188         return ret;
3189 }
3190
3191 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
3192 {
3193         int ret = 0;
3194
3195         DBG_8192C("%s\n", __func__);
3196         
3197         return ret;
3198 }
3199
3200 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
3201 {       
3202         int ret = 0;
3203         int rtap_len;
3204         int qos_len = 0;
3205         int dot11_hdr_len = 24;
3206         int snap_len = 6;
3207         unsigned char *pdata;
3208         u16 frame_ctl;
3209         unsigned char src_mac_addr[6];
3210         unsigned char dst_mac_addr[6];
3211         struct ieee80211_hdr *dot11_hdr;
3212         struct ieee80211_radiotap_header *rtap_hdr;
3213         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3214         
3215         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3216
3217         if (skb)
3218                 rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
3219
3220         if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
3221                 goto fail;
3222
3223         rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
3224         if (unlikely(rtap_hdr->it_version))
3225                 goto fail;
3226
3227         rtap_len = ieee80211_get_radiotap_len(skb->data);
3228         if (unlikely(skb->len < rtap_len))
3229                 goto fail;
3230
3231         if(rtap_len != 14)
3232         {
3233                 DBG_8192C("radiotap len (should be 14): %d\n", rtap_len);
3234                 goto fail;
3235         }       
3236
3237         /* Skip the ratio tap header */
3238         skb_pull(skb, rtap_len);
3239
3240         dot11_hdr = (struct ieee80211_hdr *)skb->data;
3241         frame_ctl = le16_to_cpu(dot11_hdr->frame_control);
3242         /* Check if the QoS bit is set */
3243         if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
3244                 /* Check if this ia a Wireless Distribution System (WDS) frame
3245                  * which has 4 MAC addresses
3246                  */
3247                 if (dot11_hdr->frame_control & 0x0080)
3248                         qos_len = 2;
3249                 if ((dot11_hdr->frame_control & 0x0300) == 0x0300)
3250                         dot11_hdr_len += 6;
3251
3252                 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
3253                 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
3254
3255                 /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
3256                  * for two MAC addresses
3257                  */
3258                 skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
3259                 pdata = (unsigned char*)skb->data;
3260                 memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
3261                 memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
3262
3263                 DBG_8192C("should be eapol packet\n");
3264
3265                 /* Use the real net device to transmit the packet */            
3266                 ret = _rtw_xmit_entry(skb, padapter->pnetdev);
3267
3268                 return ret;
3269
3270         }
3271         else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE))
3272                 == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION)
3273         ) 
3274         {
3275                 //only for action frames
3276                 struct xmit_frame               *pmgntframe;
3277                 struct pkt_attrib       *pattrib;
3278                 unsigned char   *pframe;        
3279                 //u8 category, action, OUI_Subtype, dialogToken=0;
3280                 //unsigned char *frame_body;
3281                 struct rtw_ieee80211_hdr *pwlanhdr;     
3282                 struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
3283                 struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3284                 u8 *buf = skb->data;
3285                 u32 len = skb->len;
3286                 u8 category, action;
3287                 int type = -1;
3288
3289                 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
3290                         DBG_8192C(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
3291                                 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
3292                         goto fail;
3293                 }
3294                 
3295                 DBG_8192C("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
3296                         MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
3297                 #ifdef CONFIG_P2P
3298                 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0)
3299                         goto dump;
3300                 #endif
3301                 if (category == RTW_WLAN_CATEGORY_PUBLIC)
3302                         DBG_871X("RTW_Tx:%s\n", action_public_str(action));
3303                 else
3304                         DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
3305
3306 dump:
3307                 //starting alloc mgmt frame to dump it
3308                 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3309                 {                       
3310                         goto fail;
3311                 }
3312
3313                 //update attribute
3314                 pattrib = &pmgntframe->attrib;
3315                 update_mgntframe_attrib(padapter, pattrib);
3316                 pattrib->retry_ctrl = _FALSE;
3317
3318                 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3319
3320                 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3321
3322                 _rtw_memcpy(pframe, (void*)buf, len);
3323                 #ifdef CONFIG_WFD
3324                 if (type >= 0)
3325                 {
3326                         struct wifi_display_info                *pwfd_info;
3327                         
3328                         pwfd_info = padapter->wdinfo.wfd_info;
3329                         
3330                         if ( _TRUE == pwfd_info->wfd_enable )
3331                         {
3332                                 rtw_append_wfd_ie( padapter, pframe, &len );
3333                         }
3334                 }
3335                 #endif // CONFIG_WFD
3336                 pattrib->pktlen = len;  
3337         
3338                 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3339                 //update seq number
3340                 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
3341                 pattrib->seqnum = pmlmeext->mgnt_seq;
3342                 pmlmeext->mgnt_seq++;
3343
3344         
3345                 pattrib->last_txcmdsz = pattrib->pktlen;
3346         
3347                 dump_mgntframe(padapter, pmgntframe);
3348                 
3349         }
3350         else
3351         {
3352                 DBG_8192C("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE));
3353         }
3354
3355         
3356 fail:
3357         
3358         dev_kfree_skb(skb);
3359
3360         return 0;
3361         
3362 }
3363
3364 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
3365 {
3366         DBG_8192C("%s\n", __func__);
3367 }
3368
3369 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
3370 {
3371         int ret = 0;
3372         
3373         DBG_8192C("%s\n", __func__);
3374         
3375         return ret;
3376 }
3377
3378 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
3379 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
3380         .ndo_open = rtw_cfg80211_monitor_if_open,
3381        .ndo_stop = rtw_cfg80211_monitor_if_close,
3382        .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
3383        #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
3384        .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
3385        #endif
3386        .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,       
3387 };
3388 #endif
3389
3390 static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
3391 {
3392         int ret = 0;
3393         struct net_device* mon_ndev = NULL;
3394         struct wireless_dev* mon_wdev = NULL;
3395         struct rtw_netdev_priv_indicator *pnpi;
3396         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
3397                 
3398         if (!name ) {
3399                 DBG_871X(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
3400                 ret = -EINVAL;
3401                 goto out;
3402         }
3403
3404         if (pwdev_priv->pmon_ndev) {
3405                 DBG_871X(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
3406                         FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
3407                 ret = -EBUSY;
3408                 goto out;
3409         }
3410
3411         mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
3412         if (!mon_ndev) {
3413                 DBG_871X(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
3414                 ret = -ENOMEM;
3415                 goto out;
3416         }
3417
3418         mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
3419         strncpy(mon_ndev->name, name, IFNAMSIZ);
3420         mon_ndev->name[IFNAMSIZ - 1] = 0;
3421         mon_ndev->destructor = rtw_ndev_destructor;
3422         
3423 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
3424         mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
3425 #else
3426         mon_ndev->open = rtw_cfg80211_monitor_if_open;
3427         mon_ndev->stop = rtw_cfg80211_monitor_if_close;
3428         mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry;
3429         mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address;
3430 #endif
3431
3432         pnpi = netdev_priv(mon_ndev);
3433         pnpi->priv = padapter;
3434         pnpi->sizeof_priv = sizeof(_adapter);
3435
3436         /*  wdev */
3437         mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
3438         if (!mon_wdev) {
3439                 DBG_871X(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
3440                 ret = -ENOMEM;
3441                 goto out;
3442         }
3443
3444         mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
3445         mon_wdev->netdev = mon_ndev;
3446         mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
3447         mon_ndev->ieee80211_ptr = mon_wdev;
3448
3449         ret = register_netdevice(mon_ndev);
3450         if (ret) {
3451                 goto out;
3452         }
3453
3454         *ndev = pwdev_priv->pmon_ndev = mon_ndev;
3455         _rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
3456
3457 out:
3458         if (ret && mon_wdev) {
3459                 rtw_mfree((u8*)mon_wdev, sizeof(struct wireless_dev));
3460                 mon_wdev = NULL;
3461         }
3462
3463         if (ret && mon_ndev) {
3464                 free_netdev(mon_ndev);
3465                 *ndev = mon_ndev = NULL;
3466         }
3467
3468         return ret;
3469 }
3470
3471 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3472 static struct wireless_dev *
3473 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
3474 static struct net_device *
3475 #else
3476 static int
3477 #endif
3478         cfg80211_rtw_add_virtual_intf(
3479                 struct wiphy *wiphy,
3480         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
3481                 const char *name,
3482         #else
3483                 char *name,
3484         #endif
3485                 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
3486 {
3487         int ret = 0;
3488         struct net_device* ndev = NULL;
3489         _adapter *padapter = wiphy_to_adapter(wiphy);
3490
3491         DBG_871X(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
3492                 FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
3493
3494         switch (type) {
3495         case NL80211_IFTYPE_ADHOC:
3496         case NL80211_IFTYPE_AP_VLAN:
3497         case NL80211_IFTYPE_WDS:
3498         case NL80211_IFTYPE_MESH_POINT:
3499                 ret = -ENODEV;
3500                 break;
3501         case NL80211_IFTYPE_MONITOR:
3502                 ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
3503                 break;
3504
3505 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3506         case NL80211_IFTYPE_P2P_CLIENT:
3507 #endif
3508         case NL80211_IFTYPE_STATION:
3509                 ret = -ENODEV;
3510                 break;
3511
3512 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3513         case NL80211_IFTYPE_P2P_GO:
3514 #endif
3515         case NL80211_IFTYPE_AP:
3516                 ret = -ENODEV;
3517                 break;
3518         default:
3519                 ret = -ENODEV;
3520                 DBG_871X("Unsupported interface type\n");
3521                 break;
3522         }
3523
3524         DBG_871X(FUNC_ADPT_FMT" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter), ndev, ret);
3525
3526 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3527         return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
3528 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
3529         return ndev ? ndev : ERR_PTR(ret);
3530 #else
3531         return ret;
3532 #endif
3533 }
3534
3535 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
3536 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3537         struct wireless_dev *wdev
3538 #else
3539         struct net_device *ndev
3540 #endif
3541 )
3542 {
3543         struct rtw_wdev_priv *pwdev_priv = (struct rtw_wdev_priv *)wiphy_priv(wiphy);
3544 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3545         struct net_device *ndev;
3546         ndev = wdev ? wdev->netdev : NULL;
3547 #endif
3548
3549         if (!ndev)
3550                 goto exit;
3551
3552         unregister_netdevice(ndev);
3553
3554         if (ndev == pwdev_priv->pmon_ndev) {
3555                 pwdev_priv->pmon_ndev = NULL;
3556                 pwdev_priv->ifname_mon[0] = '\0';
3557                 DBG_871X(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev));
3558         }
3559
3560 exit:
3561         return 0;
3562 }
3563
3564 static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
3565 {
3566         int ret=0;
3567         u8 *pbuf = NULL;
3568         uint len, wps_ielen=0;  
3569         uint p2p_ielen=0;
3570         u8 *p2p_ie;
3571         u8 got_p2p_ie = _FALSE;
3572         struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
3573         //struct sta_priv *pstapriv = &padapter->stapriv;
3574         
3575
3576         DBG_8192C("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
3577
3578         
3579         if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
3580                 return -EINVAL;
3581
3582         if(head_len<24)
3583                 return -EINVAL;
3584         
3585
3586         pbuf = rtw_zmalloc(head_len+tail_len);
3587         if(!pbuf)
3588                 return -ENOMEM;
3589         
3590
3591         //_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
3592
3593         //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
3594         //      pstapriv->max_num_sta = NUM_STA;
3595
3596         
3597         _rtw_memcpy(pbuf, (void *)head+24, head_len-24);// 24=beacon header len.
3598         _rtw_memcpy(pbuf+head_len-24, (void *)tail, tail_len);
3599
3600         len = head_len+tail_len-24;
3601
3602         //check wps ie if inclued
3603         if(rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
3604                 DBG_8192C("add bcn, wps_ielen=%d\n", wps_ielen);
3605
3606 #ifdef CONFIG_P2P
3607         //check p2p ie if inclued
3608         if( adapter->wdinfo.driver_interface == DRIVER_CFG80211 )
3609         {
3610                 //check p2p if enable
3611                 if(rtw_get_p2p_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &p2p_ielen))
3612                 {
3613                         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3614                         struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
3615
3616                         DBG_8192C("got p2p_ie, len=%d\n", p2p_ielen);
3617                         got_p2p_ie = _TRUE;
3618                 
3619                         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3620                         {                       
3621                                 DBG_8192C("Enable P2P function for the first time\n");
3622                                 rtw_p2p_enable(adapter, P2P_ROLE_GO);
3623                                 wdev_to_priv(adapter->rtw_wdev)->p2p_enabled = _TRUE;
3624                         }
3625                         else
3626                         {
3627                                 _cancel_timer_ex( &pwdinfo->find_phase_timer );
3628                                 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
3629                                 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer); 
3630
3631                                 DBG_8192C("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);                  
3632
3633                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
3634                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
3635                                 pwdinfo->intent = 15;           
3636                         }
3637                 }
3638         }
3639 #endif // CONFIG_P2P
3640
3641         /* pbss_network->IEs will not include p2p_ie, wfd ie */
3642         rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
3643         rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
3644
3645         if (rtw_check_beacon_data(adapter, pbuf,  len) == _SUCCESS)
3646         {
3647 #ifdef  CONFIG_P2P              
3648                 //check p2p if enable
3649                 if(got_p2p_ie == _TRUE)
3650                 {
3651                         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3652                         struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
3653                         pwdinfo->operating_channel = pmlmeext->cur_channel;
3654                 }
3655 #endif //CONFIG_P2P
3656                 ret = 0;
3657         }       
3658         else
3659         {
3660                 ret = -EINVAL;
3661         }       
3662         
3663
3664         rtw_mfree(pbuf, head_len+tail_len);     
3665         
3666         return ret;     
3667 }
3668
3669 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE)
3670 static int      cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
3671                               struct beacon_parameters *info)
3672 {
3673         int ret=0;
3674         _adapter *adapter = wiphy_to_adapter(wiphy);
3675
3676         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3677         ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
3678
3679         return ret;
3680 }
3681
3682 static int      cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
3683                               struct beacon_parameters *info)
3684 {
3685         _adapter *padapter = wiphy_to_adapter(wiphy);   
3686         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3687         
3688         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3689
3690         pmlmeext->bstart_bss = _TRUE;
3691
3692         cfg80211_rtw_add_beacon(wiphy, ndev, info);
3693         
3694         return 0;
3695 }
3696
3697 static int      cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
3698 {
3699         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3700         
3701         return 0;
3702 }
3703 #else
3704 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3705                                                                 struct cfg80211_ap_settings *settings)
3706 {
3707         int ret = 0;
3708         _adapter *adapter = wiphy_to_adapter(wiphy);
3709         
3710         DBG_871X(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
3711                 settings->hidden_ssid, settings->auth_type);
3712
3713         ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
3714                 settings->beacon.tail, settings->beacon.tail_len);
3715
3716         adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
3717         
3718         if (settings->ssid && settings->ssid_len) {
3719                 WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
3720                 WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
3721
3722                 if(0)
3723                 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
3724                         settings->ssid, settings->ssid_len,
3725                         pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
3726
3727                 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
3728                 pbss_network->Ssid.SsidLength = settings->ssid_len;
3729                 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
3730                 pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
3731
3732                 if(0)
3733                 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
3734                         pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
3735                         pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
3736         }
3737
3738         return ret;
3739 }
3740
3741 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3742                                 struct cfg80211_beacon_data *info)
3743 {
3744         int ret = 0;
3745         _adapter *adapter = wiphy_to_adapter(wiphy);
3746
3747         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3748
3749         ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
3750
3751         return ret;
3752 }
3753
3754 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3755 {
3756         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3757         return 0;
3758 }
3759
3760 #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
3761
3762 static int      cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
3763                                u8 *mac, struct station_parameters *params)
3764 {
3765         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3766         
3767         return 0;
3768 }
3769
3770 static int      cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
3771                                u8 *mac)
3772 {
3773         int ret=0;      
3774         _irqL irqL;
3775         _list   *phead, *plist;
3776         u8 updated;
3777         struct sta_info *psta = NULL;
3778         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3779         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3780         struct sta_priv *pstapriv = &padapter->stapriv;
3781
3782         DBG_871X("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3783
3784         if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)               
3785         {
3786                 DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
3787                 return -EINVAL;         
3788         }
3789
3790
3791         if(!mac)
3792         {
3793                 DBG_8192C("flush all sta, and cam_entry\n");
3794
3795                 flush_all_cam_entry(padapter);  //clear CAM
3796
3797                 ret = rtw_sta_flush(padapter);
3798                 
3799                 return ret;
3800         }       
3801
3802
3803         DBG_8192C("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
3804
3805         if (mac[0] == 0xff && mac[1] == 0xff &&
3806             mac[2] == 0xff && mac[3] == 0xff &&
3807             mac[4] == 0xff && mac[5] == 0xff) 
3808         {
3809                 return -EINVAL; 
3810         }
3811
3812
3813         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3814         
3815         phead = &pstapriv->asoc_list;
3816         plist = get_next(phead);
3817
3818         //check asoc_queue
3819         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)       
3820         {
3821                 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3822                 
3823                 plist = get_next(plist);        
3824         
3825                 if(_rtw_memcmp(mac, psta->hwaddr, ETH_ALEN))            
3826                 {
3827                         if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE)
3828                         {
3829                                 DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
3830                         }
3831                         else
3832                         {
3833                                 DBG_8192C("free psta=%p, aid=%d\n", psta, psta->aid);
3834
3835                                 rtw_list_delete(&psta->asoc_list);
3836                                 pstapriv->asoc_list_cnt--;
3837
3838                                 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3839                                 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
3840                                 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3841
3842                                 psta = NULL;
3843
3844                                 break;
3845                         }               
3846                                         
3847                 }
3848                 
3849         }
3850
3851         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3852
3853         associated_clients_update(padapter, updated);
3854
3855         DBG_871X("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3856         
3857         return ret;     
3858
3859 }
3860
3861 static int      cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
3862                                   u8 *mac, struct station_parameters *params)
3863 {
3864         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3865         
3866         return 0;
3867 }
3868
3869 static int      cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
3870                                int idx, u8 *mac, struct station_info *sinfo)
3871 {
3872         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3873
3874         //TODO: dump scanned queue
3875
3876         return -ENOENT;
3877 }
3878
3879 static int      cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
3880                               struct bss_parameters *params)
3881 {
3882         u8 i;
3883
3884         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3885 /*
3886         DBG_8192C("use_cts_prot=%d\n", params->use_cts_prot);
3887         DBG_8192C("use_short_preamble=%d\n", params->use_short_preamble);
3888         DBG_8192C("use_short_slot_time=%d\n", params->use_short_slot_time);
3889         DBG_8192C("ap_isolate=%d\n", params->ap_isolate);
3890
3891         DBG_8192C("basic_rates_len=%d\n", params->basic_rates_len);
3892         for(i=0; i<params->basic_rates_len; i++)
3893         {               
3894                 DBG_8192C("basic_rates=%d\n", params->basic_rates[i]);
3895                 
3896         }       
3897 */      
3898         return 0;
3899         
3900 }
3901
3902 static int      cfg80211_rtw_set_channel(struct wiphy *wiphy
3903         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
3904         , struct net_device *ndev
3905         #endif
3906         , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
3907 {
3908         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
3909         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3910         #endif
3911         
3912         return 0;
3913 }
3914
3915 static int      cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
3916                         struct cfg80211_auth_request *req)
3917 {
3918         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3919         
3920         return 0;
3921 }
3922
3923 static int      cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
3924                          struct cfg80211_assoc_request *req)
3925 {
3926         DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3927         
3928         return 0;
3929 }
3930 #endif //CONFIG_AP_MODE
3931
3932 void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
3933 {
3934         int type;
3935         s32 freq;
3936         int channel;
3937         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3938         u8 category, action;
3939
3940         channel = rtw_get_oper_ch(padapter);
3941
3942         DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
3943         #ifdef CONFIG_P2P
3944         type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
3945         if (type >= 0)
3946                 goto indicate;
3947         #endif
3948         rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
3949         DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
3950
3951 indicate:
3952         if (channel <= RTW_CH_MAX_2G_CHANNEL)
3953                 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3954         else
3955                 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3956
3957 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3958         rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3959 #else
3960         cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
3961 #endif
3962 }
3963
3964 void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
3965 {
3966         int type;
3967         s32 freq;
3968         int channel;
3969         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3970         u8 category, action;
3971
3972         channel = rtw_get_oper_ch(padapter);
3973
3974         DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
3975         #ifdef CONFIG_P2P
3976         type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
3977         if (type >= 0) {
3978                 switch (type) {
3979                 case P2P_GO_NEGO_CONF:
3980                 case P2P_PROVISION_DISC_RESP:
3981                 case P2P_INVIT_RESP:
3982                         rtw_set_scan_deny(padapter, 2000);
3983                         rtw_clear_scan_deny(padapter);
3984                 }
3985                 goto indicate;
3986         }
3987         #endif
3988         rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
3989         DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
3990
3991 indicate:
3992         if (channel <= RTW_CH_MAX_2G_CHANNEL)
3993                 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3994         else
3995                 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3996
3997 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3998         rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3999 #else
4000         cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
4001 #endif
4002 }
4003
4004 void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg)
4005 {
4006         s32 freq;
4007         int channel;
4008         struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);       
4009         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(adapter->rtw_wdev);
4010         u8 category, action;
4011
4012         channel = rtw_get_oper_ch(adapter);
4013
4014         rtw_action_frame_parse(frame, frame_len, &category, &action);
4015
4016         DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
4017         if (msg)
4018                 DBG_871X("RTW_Rx:%s\n", msg);
4019         else
4020                 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
4021
4022         if (channel <= RTW_CH_MAX_2G_CHANNEL)
4023                 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
4024         else
4025                 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
4026
4027 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4028         rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
4029 #else
4030         cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
4031 #endif
4032
4033 }
4034
4035 #ifdef CONFIG_P2P
4036 void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
4037 {
4038         u16     wps_devicepassword_id = 0x0000;
4039         uint    wps_devicepassword_id_len = 0;
4040         u8                      wpsie[ 255 ] = { 0x00 }, p2p_ie[ 255 ] = { 0x00 };
4041         uint                    p2p_ielen = 0;
4042         uint                    wpsielen = 0;
4043         u32     devinfo_contentlen = 0;
4044         u8      devinfo_content[64] = { 0x00 };
4045         u16     capability = 0;
4046         uint capability_len = 0;
4047         
4048         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4049         u8                      action = P2P_PUB_ACTION_ACTION;
4050         u8                      dialogToken = 1;
4051         u32                     p2poui = cpu_to_be32(P2POUI);
4052         u8                      oui_subtype = P2P_PROVISION_DISC_REQ;   
4053         u32                     p2pielen = 0;
4054 #ifdef CONFIG_WFD
4055         u32                                     wfdielen = 0;
4056 #endif //CONFIG_WFD             
4057         
4058         struct xmit_frame                       *pmgntframe;
4059         struct pkt_attrib                       *pattrib;
4060         unsigned char                                   *pframe;
4061         struct rtw_ieee80211_hdr        *pwlanhdr;
4062         unsigned short                          *fctrl;
4063         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
4064         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4065         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4066         
4067         struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4068         u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
4069         size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
4070
4071
4072         DBG_871X( "[%s] In\n", __FUNCTION__ );
4073
4074         //prepare for building provision_request frame  
4075         _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
4076         _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
4077         
4078         pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
4079                 
4080         rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
4081         rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
4082         wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
4083
4084         switch(wps_devicepassword_id) 
4085         {
4086                 case WPS_DPID_PIN:
4087                         pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
4088                         break;
4089                 case WPS_DPID_USER_SPEC:
4090                         pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
4091                         break;
4092                 case WPS_DPID_MACHINE_SPEC:
4093                         break;
4094                 case WPS_DPID_REKEY:
4095                         break;
4096                 case WPS_DPID_PBC:
4097                         pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
4098                         break;
4099                 case WPS_DPID_REGISTRAR_SPEC:
4100                         pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
4101                         break;
4102                 default:
4103                         break;
4104         }
4105
4106
4107         if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) )
4108         {       
4109
4110                 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);                                       
4111                 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&capability, &capability_len);
4112                                                 
4113         }
4114
4115
4116         //start to build provision_request frame        
4117         _rtw_memset(wpsie, 0, sizeof(wpsie));
4118         _rtw_memset(p2p_ie, 0, sizeof(p2p_ie));
4119         p2p_ielen = 0;  
4120         
4121         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4122         {
4123                 return;
4124         }
4125
4126         
4127         //update attribute
4128         pattrib = &pmgntframe->attrib;
4129         update_mgntframe_attrib(padapter, pattrib);
4130
4131         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4132
4133         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4134         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4135
4136         fctrl = &(pwlanhdr->frame_ctl);
4137         *(fctrl) = 0;
4138
4139         _rtw_memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
4140         _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);  
4141         _rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
4142
4143         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4144         pmlmeext->mgnt_seq++;
4145         SetFrameSubType(pframe, WIFI_ACTION);
4146
4147         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4148         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4149
4150         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4151         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4152         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4153         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));       
4154         pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));               
4155
4156
4157         //build_prov_disc_request_p2p_ie        
4158         //      P2P OUI
4159         p2pielen = 0;
4160         p2p_ie[ p2pielen++ ] = 0x50;
4161         p2p_ie[ p2pielen++ ] = 0x6F;
4162         p2p_ie[ p2pielen++ ] = 0x9A;
4163         p2p_ie[ p2pielen++ ] = 0x09;    //      WFA P2P v1.0
4164
4165         //      Commented by Albert 20110301
4166         //      According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
4167         //      1. P2P Capability
4168         //      2. Device Info
4169         //      3. Group ID ( When joining an operating P2P Group )
4170
4171         //      P2P Capability ATTR
4172         //      Type:   
4173         p2p_ie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4174
4175         //      Length:
4176         //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4177         RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
4178         p2pielen += 2;
4179
4180         //      Value:
4181         //      Device Capability Bitmap, 1 byte
4182         //      Group Capability Bitmap, 1 byte
4183         _rtw_memcpy(p2p_ie + p2pielen, &capability, 2);
4184         p2pielen += 2;
4185         
4186
4187         //      Device Info ATTR
4188         //      Type:
4189         p2p_ie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4190
4191         //      Length:
4192         //      21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) 
4193         //      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4194         //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4195         RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
4196         p2pielen += 2;
4197
4198         //      Value:
4199         _rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
4200         p2pielen += devinfo_contentlen;
4201
4202
4203         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);                      
4204         //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr);
4205         //pframe += p2pielen;
4206         pattrib->pktlen += p2p_ielen;
4207
4208         wpsielen = 0;
4209         //      WPS OUI
4210         *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4211         wpsielen += 4;
4212
4213         //      WPS version
4214         //      Type:
4215         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4216         wpsielen += 2;
4217
4218         //      Length:
4219         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4220         wpsielen += 2;
4221
4222         //      Value:
4223         wpsie[wpsielen++] = WPS_VERSION_1;      //      Version 1.0
4224
4225         //      Config Method
4226         //      Type:
4227         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
4228         wpsielen += 2;
4229
4230         //      Length:
4231         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4232         wpsielen += 2;
4233
4234         //      Value:
4235         *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
4236         wpsielen += 2;
4237
4238         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4239
4240
4241 #ifdef CONFIG_WFD
4242         wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
4243         pframe += wfdielen;
4244         pattrib->pktlen += wfdielen;
4245 #endif //CONFIG_WFD
4246
4247         pattrib->last_txcmdsz = pattrib->pktlen;
4248
4249         //dump_mgntframe(padapter, pmgntframe);
4250         if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
4251                 DBG_8192C("%s, ack to\n", __func__);
4252
4253         //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
4254         //{
4255         //      DBG_8192C("waiting for p2p peer key-in PIN CODE\n");
4256         //      rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req.
4257         //}     
4258
4259 }
4260
4261 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
4262 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4263         struct wireless_dev *wdev,
4264 #else
4265         struct net_device *ndev,
4266 #endif
4267         struct ieee80211_channel * channel,
4268 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4269         enum nl80211_channel_type channel_type,
4270 #endif
4271         unsigned int duration, u64 *cookie)
4272 {
4273         s32 err = 0;
4274         _adapter *padapter = wiphy_to_adapter(wiphy);
4275         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4276         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4277         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4278         struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4279         u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
4280         u8 ready_on_channel = _FALSE;
4281
4282         DBG_871X(FUNC_ADPT_FMT" ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter), remain_ch, duration);
4283
4284         if(pcfg80211_wdinfo->is_ro_ch == _TRUE)
4285         {
4286                 DBG_8192C("%s, cancel ro ch timer\n", __func__);
4287                 
4288                 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4289
4290 #ifdef CONFIG_CONCURRENT_MODE
4291                 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);                   
4292 #endif //CONFIG_CONCURRENT_MODE 
4293
4294                 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
4295         }
4296
4297         pcfg80211_wdinfo->is_ro_ch = _TRUE;
4298
4299         if(_FAIL == rtw_pwr_wakeup(padapter)) {
4300                 err = -EFAULT;
4301                 goto exit;
4302         }
4303
4304         _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
4305         #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4306         pcfg80211_wdinfo->remain_on_ch_type= channel_type;
4307         #endif
4308         pcfg80211_wdinfo->remain_on_ch_cookie= *cookie;
4309
4310         rtw_scan_abort(padapter);
4311 #ifdef CONFIG_CONCURRENT_MODE           
4312         if(rtw_buddy_adapter_up(padapter))      
4313                 rtw_scan_abort(padapter->pbuddy_adapter);                       
4314 #endif //CONFIG_CONCURRENT_MODE
4315
4316         //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
4317         if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4318         {
4319                 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
4320                 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = _TRUE;
4321         }
4322         else
4323         {
4324                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4325 #ifdef CONFIG_DEBUG_CFG80211            
4326                 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
4327 #endif
4328         }
4329
4330
4331         rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
4332         
4333         
4334         if(duration < 400)
4335                 duration = duration*3;//extend from exper.
4336
4337
4338 #ifdef  CONFIG_CONCURRENT_MODE
4339         if(check_buddy_fwstate(padapter, _FW_LINKED) &&
4340                 (duration<pwdinfo->ext_listen_interval)) 
4341         {
4342                 duration = duration +   pwdinfo->ext_listen_interval;
4343         }
4344 #endif
4345
4346         pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter);
4347
4348         if(rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) >= 0) {
4349 #ifdef  CONFIG_CONCURRENT_MODE
4350                 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4351                 {
4352                         PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;                     
4353                         struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;    
4354
4355                         if(remain_ch != pbuddy_mlmeext->cur_channel)
4356                         {       
4357                                 if(ATOMIC_READ(&pwdev_priv->switch_ch_to)==1 ||
4358                                         (remain_ch != pmlmeext->cur_channel))
4359                                 {
4360                                         DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);           
4361                                         issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
4362                                 
4363                                         ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
4364                         
4365                                         DBG_8192C("%s, set switch ch timer, duration=%d\n", __func__, duration-pwdinfo->ext_listen_interval);
4366                                         _set_timer(&pwdinfo->ap_p2p_switch_timer, duration-pwdinfo->ext_listen_interval);       
4367                                 }                       
4368                         }
4369                 
4370                         ready_on_channel = _TRUE;
4371                         //pmlmeext->cur_channel = remain_ch;                    
4372                         //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4373                 }else 
4374 #endif //CONFIG_CONCURRENT_MODE
4375                 if(remain_ch != pmlmeext->cur_channel )
4376                 {
4377                         ready_on_channel = _TRUE;
4378                         //pmlmeext->cur_channel = remain_ch;                    
4379                         //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4380                 }
4381         } else {
4382                 DBG_871X("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__, remain_ch);
4383         }
4384         
4385
4386         //call this after other things have been done
4387 #ifdef  CONFIG_CONCURRENT_MODE  
4388         if(ATOMIC_READ(&pwdev_priv->ro_ch_to)==1 ||
4389                 (remain_ch != pmlmeext->cur_channel))
4390         {
4391                 u8 co_channel = 0xff;
4392                 ATOMIC_SET(&pwdev_priv->ro_ch_to, 0);
4393 #endif
4394
4395                 if(ready_on_channel == _TRUE)
4396                 {                       
4397                         if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) )
4398                                 pmlmeext->cur_channel = remain_ch;
4399                         
4400 #ifdef  CONFIG_CONCURRENT_MODE
4401                         co_channel = rtw_get_oper_ch(padapter);
4402
4403                         if(co_channel !=remain_ch)
4404 #endif
4405                         {
4406                                 if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic)
4407                                         set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);                  
4408                         }
4409                 }
4410                 DBG_8192C("%s, set ro ch timer, duration=%d\n", __func__, duration);
4411                 _set_timer( &pcfg80211_wdinfo->remain_on_ch_timer, duration);
4412
4413 #ifdef  CONFIG_CONCURRENT_MODE
4414         }
4415 #endif
4416
4417         rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type, duration, GFP_KERNEL);
4418
4419 exit:
4420         if (err)
4421                 pcfg80211_wdinfo->is_ro_ch = _FALSE;
4422
4423         return err;
4424 }
4425
4426 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
4427 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4428         struct wireless_dev *wdev,
4429 #else
4430         struct net_device *ndev,
4431 #endif
4432         u64 cookie)
4433 {
4434         s32 err = 0;
4435         _adapter *padapter = wiphy_to_adapter(wiphy);
4436         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4437         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4438         struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
4439         struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4440
4441         DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
4442
4443         if (pcfg80211_wdinfo->is_ro_ch == _TRUE) {
4444                 DBG_8192C("%s, cancel ro ch timer\n", __func__);
4445                 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4446                 #ifdef CONFIG_CONCURRENT_MODE
4447                 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
4448                 #endif
4449                 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
4450         }
4451
4452         #if 0
4453         //      Disable P2P Listen State
4454         if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
4455         {
4456                 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4457                 {
4458                         _cancel_timer_ex( &pwdinfo->find_phase_timer );
4459                         _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
4460                         _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
4461                         
4462                         rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
4463                         _rtw_memset(pwdinfo, 0x00, sizeof(struct wifidirect_info));
4464                 }
4465         }
4466         else
4467         #endif
4468         {
4469                  rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
4470 #ifdef CONFIG_DEBUG_CFG80211             
4471                  DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
4472 #endif
4473         }
4474         pcfg80211_wdinfo->is_ro_ch = _FALSE;
4475
4476         return err;
4477 }
4478
4479 #endif //CONFIG_P2P
4480
4481 static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, const u8 *buf, size_t len)
4482 {
4483         struct xmit_frame       *pmgntframe;
4484         struct pkt_attrib       *pattrib;
4485         unsigned char   *pframe;
4486         int ret = _FAIL;
4487         bool ack = _TRUE;
4488         struct rtw_ieee80211_hdr *pwlanhdr;
4489         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4490         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
4491         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
4492         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4493         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4494         //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4495
4496         if(_FAIL == rtw_pwr_wakeup(padapter)) {
4497                 ret = -EFAULT;
4498                 goto exit;
4499         }
4500
4501         rtw_set_scan_deny(padapter, 1000);
4502
4503         rtw_scan_abort(padapter);
4504         #ifdef CONFIG_CONCURRENT_MODE           
4505         if(rtw_buddy_adapter_up(padapter))      
4506                 rtw_scan_abort(padapter->pbuddy_adapter);
4507         #endif /* CONFIG_CONCURRENT_MODE */
4508
4509         if (padapter->cfg80211_wdinfo.is_ro_ch == _TRUE) {
4510                 //DBG_8192C("%s, cancel ro ch timer\n", __func__);
4511                 //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4512                 //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE;
4513                 #ifdef CONFIG_CONCURRENT_MODE                   
4514                 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
4515                 {
4516                         DBG_8192C("%s, extend ro ch time\n", __func__);
4517                         _set_timer( &padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
4518                 }       
4519                 #endif //CONFIG_CONCURRENT_MODE                 
4520         }
4521
4522 #ifdef CONFIG_CONCURRENT_MODE
4523         if (check_buddy_fwstate(padapter, _FW_LINKED )) {
4524                 u8 co_channel=0xff;
4525                 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;                     
4526                 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;    
4527
4528                 co_channel = rtw_get_oper_ch(padapter);
4529
4530                 if (tx_ch != pbuddy_mlmeext->cur_channel) {
4531
4532                         u16 ext_listen_period;
4533
4534                         if (ATOMIC_READ(&pwdev_priv->switch_ch_to)==1) {
4535                                 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
4536                                 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
4537
4538                                 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
4539
4540                                 //DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
4541                                 //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
4542                         }
4543
4544                         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
4545                         {
4546                                 ext_listen_period = 500;// 500ms
4547                         }       
4548                         else
4549                         {                               
4550                                 ext_listen_period = pwdinfo->ext_listen_period;
4551                         }
4552
4553                         DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period);
4554                         _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period);   
4555                         
4556                 }
4557
4558                 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
4559                         pmlmeext->cur_channel = tx_ch;
4560
4561                 if (tx_ch != co_channel)
4562                         set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4563         }else 
4564 #endif //CONFIG_CONCURRENT_MODE
4565         //if (tx_ch != pmlmeext->cur_channel) {
4566         if(tx_ch != rtw_get_oper_ch(padapter)) {
4567                 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
4568                         pmlmeext->cur_channel = tx_ch;
4569                 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4570         }
4571
4572         //starting alloc mgmt frame to dump it
4573         if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4574         {
4575                 //ret = -ENOMEM;
4576                 ret = _FAIL;
4577                 goto exit;
4578         }
4579
4580         //update attribute
4581         pattrib = &pmgntframe->attrib;
4582         update_mgntframe_attrib(padapter, pattrib);
4583         pattrib->retry_ctrl = _FALSE;
4584
4585         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4586
4587         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4588
4589         _rtw_memcpy(pframe, (void*)buf, len);
4590         pattrib->pktlen = len;  
4591         
4592         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4593         //update seq number
4594         pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
4595         pattrib->seqnum = pmlmeext->mgnt_seq;
4596         pmlmeext->mgnt_seq++;
4597
4598 #ifdef CONFIG_WFD
4599         {
4600                 struct wifi_display_info        *pwfd_info;
4601                         
4602                 pwfd_info = padapter->wdinfo.wfd_info;
4603                         
4604                 if ( _TRUE == pwfd_info->wfd_enable )
4605                 {
4606                         rtw_append_wfd_ie( padapter, pframe, &pattrib->pktlen );
4607                 }
4608         }
4609 #endif // CONFIG_WFD
4610         
4611         pattrib->last_txcmdsz = pattrib->pktlen;
4612
4613         if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS) 
4614         {
4615                 ack = _FALSE;
4616                 ret = _FAIL;
4617
4618                 #ifdef CONFIG_DEBUG_CFG80211
4619                 DBG_8192C("%s, ack == _FAIL\n", __func__);
4620                 #endif
4621         }
4622         else 
4623         {
4624                 #ifdef CONFIG_DEBUG_CFG80211
4625                 DBG_8192C("%s, ack=%d, ok!\n", __func__, ack);
4626                 #endif
4627                 ret = _SUCCESS;
4628         }
4629         
4630 exit:
4631
4632         #ifdef CONFIG_DEBUG_CFG80211
4633         DBG_8192C("%s, ret=%d\n", __func__, ret);
4634         #endif
4635         
4636         return ret;             
4637         
4638 }
4639
4640 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
4641 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4642         struct wireless_dev *wdev,
4643 #else
4644         struct net_device *ndev,
4645 #endif
4646         struct ieee80211_channel *chan,
4647 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
4648         bool offchan,
4649 #endif
4650 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4651         enum nl80211_channel_type channel_type,
4652         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4653         bool channel_type_valid,
4654         #endif
4655 #endif
4656 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
4657         unsigned int wait,
4658 #endif
4659         const u8 *buf, size_t len,
4660 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
4661         bool no_cck,
4662 #endif
4663 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
4664         bool dont_wait_for_ack,
4665 #endif
4666         u64 *cookie)
4667 {
4668         _adapter *padapter = (_adapter *)wiphy_to_adapter(wiphy);
4669         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4670         int ret = 0;
4671         int tx_ret;
4672         u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
4673         u32 dump_cnt = 0;
4674         bool ack = _TRUE;
4675         u8 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
4676         u8 category, action;
4677         int type = (-1);
4678         u32 start = rtw_get_current_time();
4679
4680         /* cookie generation */
4681         *cookie = (unsigned long) buf;
4682
4683 #ifdef CONFIG_DEBUG_CFG80211
4684         DBG_871X(FUNC_ADPT_FMT" len=%zu, ch=%d"
4685         #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4686                 ", ch_type=%d"
4687                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)    
4688                 ", channel_type_valid=%d"
4689                 #endif
4690         #endif
4691                 "\n", FUNC_ADPT_ARG(padapter),
4692                 len, tx_ch
4693         #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4694                 , channel_type
4695                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)    
4696                 , channel_type_valid
4697                 #endif
4698         #endif
4699         );
4700 #endif /* CONFIG_DEBUG_CFG80211 */
4701
4702         /* indicate ack before issue frame to avoid racing with rsp frame */
4703 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4704         rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL);
4705 #elif  (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
4706         cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
4707 #endif
4708
4709         if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
4710                 DBG_8192C(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
4711                         le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
4712                 goto exit;
4713         }
4714
4715         DBG_8192C("RTW_Tx:tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
4716         #ifdef CONFIG_P2P
4717         if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0) {
4718                 goto dump;
4719         }
4720         #endif
4721         if (category == RTW_WLAN_CATEGORY_PUBLIC)
4722                 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
4723         else
4724                 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
4725
4726 dump:
4727         do {
4728                 dump_cnt++;
4729                 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
4730         } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
4731
4732         if (tx_ret != _SUCCESS || dump_cnt > 1) {
4733                 DBG_871X(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
4734                         tx_ret==_SUCCESS?"OK":"FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
4735         }
4736
4737         switch (type) {
4738         case P2P_GO_NEGO_CONF:
4739                 rtw_clear_scan_deny(padapter);
4740                 break;
4741         case P2P_INVIT_RESP:
4742                 if (pwdev_priv->invit_info.flags & BIT(0)
4743                         && pwdev_priv->invit_info.status == 0) 
4744                 {
4745                         DBG_871X(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
4746                                 FUNC_ADPT_ARG(padapter));
4747                         rtw_set_scan_deny(padapter, 5000);
4748                         rtw_pwr_wakeup_ex(padapter, 5000);
4749                         rtw_clear_scan_deny(padapter);
4750                 }
4751                 break;
4752         }       
4753
4754 exit:
4755         return ret;
4756 }
4757
4758 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
4759 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
4760         struct wireless_dev *wdev,
4761 #else
4762         struct net_device *ndev,
4763 #endif
4764         u16 frame_type, bool reg)
4765 {
4766         _adapter *adapter = wiphy_to_adapter(wiphy);
4767
4768 #ifdef CONFIG_DEBUG_CFG80211
4769         DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
4770                 frame_type, reg);
4771 #endif
4772
4773         if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
4774                 return;
4775
4776         return;
4777 }
4778
4779 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
4780 {       
4781         int ret = 0;
4782         uint wps_ielen = 0;
4783         u8 *wps_ie;
4784         u32     p2p_ielen = 0;
4785         u8 wps_oui[8]={0x0,0x50,0xf2,0x04};     
4786         u8 *p2p_ie;
4787         u32     wfd_ielen = 0;  
4788         u8 *wfd_ie;
4789         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4790         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4791         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4792
4793         DBG_871X(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
4794         
4795         if(len>0)
4796         {
4797                 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
4798                 {       
4799                         #ifdef CONFIG_DEBUG_CFG80211
4800                         DBG_8192C("bcn_wps_ielen=%d\n", wps_ielen);
4801                         #endif
4802                 
4803                         if(pmlmepriv->wps_beacon_ie)
4804                         {
4805                                 u32 free_len = pmlmepriv->wps_beacon_ie_len;
4806                                 pmlmepriv->wps_beacon_ie_len = 0;
4807                                 rtw_mfree(pmlmepriv->wps_beacon_ie, free_len);
4808                                 pmlmepriv->wps_beacon_ie = NULL;                        
4809                         }       
4810
4811                         pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen);
4812                         if ( pmlmepriv->wps_beacon_ie == NULL) {
4813                                 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
4814                                 return -EINVAL;
4815                         
4816                         }
4817                         
4818                         _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
4819                         pmlmepriv->wps_beacon_ie_len = wps_ielen;
4820         
4821                         update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
4822
4823                 }
4824
4825                 //buf += wps_ielen;
4826                 //len -= wps_ielen;
4827
4828                 #ifdef CONFIG_P2P
4829                 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
4830                 {
4831                         #ifdef CONFIG_DEBUG_CFG80211
4832                         DBG_8192C("bcn_p2p_ielen=%d\n", p2p_ielen);
4833                         #endif
4834                 
4835                         if(pmlmepriv->p2p_beacon_ie)
4836                         {
4837                                 u32 free_len = pmlmepriv->p2p_beacon_ie_len;
4838                                 pmlmepriv->p2p_beacon_ie_len = 0;
4839                                 rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len);
4840                                 pmlmepriv->p2p_beacon_ie = NULL;                        
4841                         }       
4842
4843                         pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen);
4844                         if ( pmlmepriv->p2p_beacon_ie == NULL) {
4845                                 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
4846                                 return -EINVAL;
4847                         
4848                         }
4849                         
4850                         _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
4851                         pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
4852                         
4853                 }
4854                 #endif //CONFIG_P2P
4855                 
4856                 //buf += p2p_ielen;
4857                 //len -= p2p_ielen;
4858
4859                 #ifdef CONFIG_WFD
4860                 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) 
4861                 {
4862                         #ifdef CONFIG_DEBUG_CFG80211
4863                         DBG_8192C("bcn_wfd_ielen=%d\n", wfd_ielen);
4864                         #endif
4865                         
4866                         if(pmlmepriv->wfd_beacon_ie)
4867                         {
4868                                 u32 free_len = pmlmepriv->wfd_beacon_ie_len;
4869                                 pmlmepriv->wfd_beacon_ie_len = 0;
4870                                 rtw_mfree(pmlmepriv->wfd_beacon_ie, free_len);
4871                                 pmlmepriv->wfd_beacon_ie = NULL;
4872                         }       
4873
4874                         pmlmepriv->wfd_beacon_ie = rtw_malloc(wfd_ielen);
4875                         if ( pmlmepriv->wfd_beacon_ie == NULL) {
4876                                 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
4877                                 return -EINVAL;
4878                         
4879                         }
4880                         rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);                      
4881                 }
4882                 #endif //CONFIG_WFD
4883                 
4884                 pmlmeext->bstart_bss = _TRUE;
4885                 
4886         }
4887
4888         return ret;
4889         
4890 }
4891
4892 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
4893 {
4894         int ret = 0;
4895         uint wps_ielen = 0;
4896         u8 *wps_ie;
4897         u32     p2p_ielen = 0;  
4898         u8 *p2p_ie;
4899         u32     wfd_ielen = 0;  
4900         u8 *wfd_ie;
4901         _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
4902         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);    
4903
4904 #ifdef CONFIG_DEBUG_CFG80211
4905         DBG_8192C("%s, ielen=%d\n", __func__, len);
4906 #endif
4907         
4908         if(len>0)
4909         {
4910                 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
4911                 {       
4912                         uint    attr_contentlen = 0;
4913                         u16     uconfig_method, *puconfig_method = NULL;
4914
4915                         #ifdef CONFIG_DEBUG_CFG80211                    
4916                         DBG_8192C("probe_resp_wps_ielen=%d\n", wps_ielen);
4917                         #endif
4918
4919                         if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
4920                         {
4921                                 u8 sr = 0;
4922                                 rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
4923
4924                                 if (sr != 0)
4925                                 {
4926                                         DBG_871X("%s, got sr\n", __func__);
4927                                 }
4928                                 else
4929                                 {
4930                                         DBG_8192C("GO mode process WPS under site-survey,  sr no set\n");
4931                                         return ret;
4932                                 }
4933                         }
4934
4935                         if(pmlmepriv->wps_probe_resp_ie)
4936                         {
4937                                 u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
4938                                 pmlmepriv->wps_probe_resp_ie_len = 0;
4939                                 rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len);
4940                                 pmlmepriv->wps_probe_resp_ie = NULL;                    
4941                         }       
4942
4943                         pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen);
4944                         if ( pmlmepriv->wps_probe_resp_ie == NULL) {
4945                                 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
4946                                 return -EINVAL;
4947                         
4948                         }
4949                         
4950                         //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode 
4951                         if ( (puconfig_method = (u16*)rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen)) != NULL )
4952                         {
4953                                 #ifdef CONFIG_DEBUG_CFG80211            
4954                                 //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method));
4955                                 #endif
4956                                 
4957                                 uconfig_method = WPS_CM_PUSH_BUTTON;
4958                                 uconfig_method = cpu_to_be16( uconfig_method );
4959
4960                                 *puconfig_method |= uconfig_method;                     
4961                         }
4962                         
4963                         _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
4964                         pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
4965                         
4966                 }
4967
4968                 //buf += wps_ielen;
4969                 //len -= wps_ielen;
4970
4971                 #ifdef CONFIG_P2P
4972                 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen))) 
4973                 {
4974                         u8 is_GO = _FALSE;                      
4975                         u32 attr_contentlen = 0;
4976                         u16 cap_attr=0;
4977
4978                         #ifdef CONFIG_DEBUG_CFG80211
4979                         DBG_8192C("probe_resp_p2p_ielen=%d\n", p2p_ielen);
4980                         #endif                  
4981
4982                         //Check P2P Capability ATTR
4983                         if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) )
4984                         {
4985                                 u8 grp_cap=0;
4986                                 //DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
4987                                 cap_attr = le16_to_cpu(cap_attr);
4988                                 grp_cap = (u8)((cap_attr >> 8)&0xff);
4989                                 
4990                                 is_GO = (grp_cap&BIT(0)) ? _TRUE:_FALSE;
4991
4992                                 if(is_GO)
4993                                         DBG_8192C("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
4994                         }
4995
4996
4997                         if(is_GO == _FALSE)
4998                         {
4999                                 if(pmlmepriv->p2p_probe_resp_ie)
5000                                 {
5001                                         u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
5002                                         pmlmepriv->p2p_probe_resp_ie_len = 0;
5003                                         rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len);
5004                                         pmlmepriv->p2p_probe_resp_ie = NULL;            
5005                                 }       
5006
5007                                 pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen);
5008                                 if ( pmlmepriv->p2p_probe_resp_ie == NULL) {
5009                                         DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
5010                                         return -EINVAL;
5011                                 
5012                                 }
5013                                 _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
5014                                 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
5015                         }               
5016                         else
5017                         {
5018                                 if(pmlmepriv->p2p_go_probe_resp_ie)
5019                                 {
5020                                         u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
5021                                         pmlmepriv->p2p_go_probe_resp_ie_len = 0;
5022                                         rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len);
5023                                         pmlmepriv->p2p_go_probe_resp_ie = NULL;                 
5024                                 }       
5025
5026                                 pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen);
5027                                 if ( pmlmepriv->p2p_go_probe_resp_ie == NULL) {
5028                                         DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
5029                                         return -EINVAL;
5030                         
5031                                 }
5032                                 _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
5033                                 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
5034                         }
5035                         
5036                 }
5037                 #endif //CONFIG_P2P
5038                 
5039                 //buf += p2p_ielen;
5040                 //len -= p2p_ielen;
5041
5042                 #ifdef CONFIG_WFD
5043                 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) 
5044                 {
5045                         #ifdef CONFIG_DEBUG_CFG80211
5046                         DBG_8192C("probe_resp_wfd_ielen=%d\n", wfd_ielen);
5047                         #endif
5048                         
5049                         if(pmlmepriv->wfd_probe_resp_ie)
5050                         {
5051                                 u32 free_len = pmlmepriv->wfd_probe_resp_ie_len;
5052                                 pmlmepriv->wfd_probe_resp_ie_len = 0;
5053                                 rtw_mfree(pmlmepriv->wfd_probe_resp_ie, free_len);
5054                                 pmlmepriv->wfd_probe_resp_ie = NULL;
5055                         }       
5056
5057                         pmlmepriv->wfd_probe_resp_ie = rtw_malloc(wfd_ielen);
5058                         if ( pmlmepriv->wfd_probe_resp_ie == NULL) {
5059                                 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
5060                                 return -EINVAL;
5061                         
5062                         }
5063                         rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);                      
5064                 }
5065                 #endif //CONFIG_WFD
5066                 
5067         }
5068
5069         return ret;
5070         
5071 }
5072
5073 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
5074 {
5075         int ret = 0;
5076         _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
5077         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5078
5079         DBG_8192C("%s, ielen=%d\n", __func__, len);
5080         
5081         if(len>0)
5082         {
5083                 if(pmlmepriv->wps_assoc_resp_ie)
5084                 {
5085                         u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
5086                         pmlmepriv->wps_assoc_resp_ie_len = 0;
5087                         rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len);
5088                         pmlmepriv->wps_assoc_resp_ie = NULL;
5089                 }       
5090
5091                 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(len);
5092                 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
5093                         DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
5094                         return -EINVAL;
5095                         
5096                 }
5097                 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len);
5098                 pmlmepriv->wps_assoc_resp_ie_len = len;
5099         }
5100
5101         return ret;
5102         
5103 }
5104
5105 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
5106         int type)
5107 {
5108         int ret = 0;
5109         uint wps_ielen = 0;
5110         u32     p2p_ielen = 0;
5111
5112 #ifdef CONFIG_DEBUG_CFG80211
5113         DBG_8192C("%s, ielen=%d\n", __func__, len);
5114 #endif
5115
5116         if(     (rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen>0))
5117                 #ifdef CONFIG_P2P
5118                 || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen>0))
5119                 #endif
5120         )               
5121         {       
5122                 if (net != NULL) 
5123                 {
5124                         switch (type) 
5125                         {
5126                                 case 0x1: //BEACON
5127                                 ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
5128                                 break;
5129                                 case 0x2: //PROBE_RESP
5130                                 ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
5131                                 break;
5132                                 case 0x4: //ASSOC_RESP
5133                                 ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
5134                                 break;
5135                         }               
5136                 }
5137         }       
5138
5139         return ret;
5140         
5141 }
5142
5143 static struct cfg80211_ops rtw_cfg80211_ops = {
5144         .change_virtual_intf = cfg80211_rtw_change_iface,
5145         .add_key = cfg80211_rtw_add_key,
5146         .get_key = cfg80211_rtw_get_key,
5147         .del_key = cfg80211_rtw_del_key,
5148         .set_default_key = cfg80211_rtw_set_default_key,
5149         .get_station = cfg80211_rtw_get_station,
5150         .scan = cfg80211_rtw_scan,
5151         .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
5152         .connect = cfg80211_rtw_connect,
5153         .disconnect = cfg80211_rtw_disconnect,
5154         .join_ibss = cfg80211_rtw_join_ibss,
5155         .leave_ibss = cfg80211_rtw_leave_ibss,
5156         .set_tx_power = cfg80211_rtw_set_txpower,
5157         .get_tx_power = cfg80211_rtw_get_txpower,
5158         .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
5159         .set_pmksa = cfg80211_rtw_set_pmksa,
5160         .del_pmksa = cfg80211_rtw_del_pmksa,
5161         .flush_pmksa = cfg80211_rtw_flush_pmksa,
5162         
5163 #ifdef CONFIG_AP_MODE
5164         .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
5165         .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
5166
5167         #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
5168         .add_beacon = cfg80211_rtw_add_beacon,
5169         .set_beacon = cfg80211_rtw_set_beacon,
5170         .del_beacon = cfg80211_rtw_del_beacon,
5171         #else
5172         .start_ap = cfg80211_rtw_start_ap,
5173         .change_beacon = cfg80211_rtw_change_beacon,
5174         .stop_ap = cfg80211_rtw_stop_ap,
5175         #endif
5176         
5177         .add_station = cfg80211_rtw_add_station,
5178         .del_station = cfg80211_rtw_del_station,
5179         .change_station = cfg80211_rtw_change_station,
5180         .dump_station = cfg80211_rtw_dump_station,
5181         .change_bss = cfg80211_rtw_change_bss,
5182         #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
5183         .set_channel = cfg80211_rtw_set_channel,
5184         #endif
5185         //.auth = cfg80211_rtw_auth,
5186         //.assoc = cfg80211_rtw_assoc,  
5187 #endif //CONFIG_AP_MODE
5188
5189 #ifdef CONFIG_P2P
5190         .remain_on_channel = cfg80211_rtw_remain_on_channel,
5191         .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
5192 #endif
5193
5194 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)     
5195         .mgmt_tx = cfg80211_rtw_mgmt_tx,
5196         .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
5197 #elif  (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
5198         .action = cfg80211_rtw_mgmt_tx,
5199 #endif
5200 };
5201
5202 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
5203 {
5204
5205 #define MAX_BIT_RATE_40MHZ_MCS15        300     /* Mbps */
5206 #define MAX_BIT_RATE_40MHZ_MCS7         150     /* Mbps */
5207
5208         ht_cap->ht_supported = _TRUE;
5209
5210         ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
5211                                         IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
5212                                         IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
5213
5214         /*
5215          *Maximum length of AMPDU that the STA can receive.
5216          *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
5217          */
5218         ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5219
5220         /*Minimum MPDU start spacing , */
5221         ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5222
5223         ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5224
5225         /*
5226          *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
5227          *base on ant_num
5228          *rx_mask: RX mask
5229          *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
5230          *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
5231          *if rx_ant >=3 rx_mask[2]=0xff;
5232          *if BW_40 rx_mask[4]=0x01;
5233          *highest supported RX rate
5234          */
5235         if(rf_type == RF_1T1R)
5236         {
5237                 ht_cap->mcs.rx_mask[0] = 0xFF;
5238                 ht_cap->mcs.rx_mask[1] = 0x00;
5239                 ht_cap->mcs.rx_mask[4] = 0x01;
5240
5241                 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
5242         }
5243         else if((rf_type == RF_1T2R) || (rf_type==RF_2T2R))
5244         {
5245                 ht_cap->mcs.rx_mask[0] = 0xFF;
5246                 ht_cap->mcs.rx_mask[1] = 0xFF;
5247                 ht_cap->mcs.rx_mask[4] = 0x01;
5248
5249                 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
5250         }
5251         else
5252         {
5253                 DBG_8192C("%s, error rf_type=%d\n", __func__, rf_type);
5254         }       
5255         
5256 }
5257
5258 void rtw_cfg80211_init_wiphy(_adapter *padapter)
5259 {
5260         u8 rf_type;
5261         struct ieee80211_supported_band *bands;
5262         struct wireless_dev *pwdev = padapter->rtw_wdev;
5263         struct wiphy *wiphy = pwdev->wiphy;
5264         
5265         rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
5266
5267         DBG_8192C("%s:rf_type=%d\n", __func__, rf_type);
5268
5269         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
5270         {
5271                 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
5272                 if(bands)
5273                         rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type);
5274         }
5275
5276         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
5277         {
5278                 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
5279                 if(bands)
5280                         rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type);
5281         }
5282 }
5283
5284 /*
5285 struct ieee80211_iface_limit rtw_limits[] = {
5286         { .max = 1, .types = BIT(NL80211_IFTYPE_STATION)
5287                                         | BIT(NL80211_IFTYPE_ADHOC)
5288 #ifdef CONFIG_AP_MODE
5289                                         | BIT(NL80211_IFTYPE_AP)
5290 #endif
5291 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
5292                                         | BIT(NL80211_IFTYPE_P2P_CLIENT)
5293                                         | BIT(NL80211_IFTYPE_P2P_GO)
5294 #endif
5295         },
5296         {.max = 1, .types = BIT(NL80211_IFTYPE_MONITOR)},
5297 };
5298
5299 struct ieee80211_iface_combination rtw_combinations = {
5300         .limits = rtw_limits,
5301         .n_limits = ARRAY_SIZE(rtw_limits),
5302         .max_interfaces = 2,
5303         .num_different_channels = 1,
5304 };
5305 */
5306
5307 static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy)
5308 {
5309
5310         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5311
5312         wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
5313         wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;   
5314         wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
5315
5316 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)     
5317         wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
5318 #endif
5319         
5320         wiphy->interface_modes =        BIT(NL80211_IFTYPE_STATION)
5321                                                                 | BIT(NL80211_IFTYPE_ADHOC)
5322 #ifdef CONFIG_AP_MODE
5323                                                                 | BIT(NL80211_IFTYPE_AP)
5324                                                                 | BIT(NL80211_IFTYPE_MONITOR)
5325 #endif
5326 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
5327                                                                 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5328                                                                 | BIT(NL80211_IFTYPE_P2P_GO)
5329 #endif
5330                                                                 ;
5331
5332 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)    
5333 #ifdef CONFIG_AP_MODE
5334         wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
5335 #endif //CONFIG_AP_MODE 
5336 #endif          
5337
5338 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
5339         wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
5340 #endif
5341
5342         /*
5343         wiphy->iface_combinations = &rtw_combinations;
5344         wiphy->n_iface_combinations = 1;
5345         */
5346
5347         wiphy->cipher_suites = rtw_cipher_suites;
5348         wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
5349
5350         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
5351                 wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
5352         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
5353                 wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
5354         
5355 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
5356         wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
5357 #endif
5358
5359 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
5360         wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
5361         wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
5362 #endif
5363
5364         if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
5365                 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
5366         else 
5367                 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
5368 }
5369
5370 int rtw_wdev_alloc(_adapter *padapter, struct device *dev)
5371 {
5372         int ret = 0;
5373         struct wiphy *wiphy;
5374         struct wireless_dev *wdev;
5375         struct rtw_wdev_priv *pwdev_priv;
5376         struct net_device *pnetdev = padapter->pnetdev;
5377         
5378         DBG_8192C("%s(padapter=%p)\n", __func__, padapter);
5379
5380         /* wiphy */
5381         wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wdev_priv));
5382         if (!wiphy) {
5383                 DBG_8192C("Couldn't allocate wiphy device\n");
5384                 ret = -ENOMEM;
5385                 goto exit;
5386         }
5387         set_wiphy_dev(wiphy, dev);
5388         rtw_cfg80211_preinit_wiphy(padapter, wiphy);
5389
5390         ret = wiphy_register(wiphy);
5391         if (ret < 0) {
5392                 DBG_8192C("Couldn't register wiphy device\n");
5393                 goto free_wiphy;
5394         }
5395
5396         /*  wdev */
5397         wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
5398         if (!wdev) {
5399                 DBG_8192C("Couldn't allocate wireless device\n");
5400                 ret = -ENOMEM;
5401                 goto unregister_wiphy;
5402         }
5403         wdev->wiphy = wiphy;
5404         wdev->netdev = pnetdev;
5405         //wdev->iftype = NL80211_IFTYPE_STATION;
5406         wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
5407         padapter->rtw_wdev = wdev;
5408         pnetdev->ieee80211_ptr = wdev;
5409
5410         //init pwdev_priv
5411         pwdev_priv = wdev_to_priv(wdev);
5412         pwdev_priv->rtw_wdev = wdev;
5413         pwdev_priv->pmon_ndev = NULL;
5414         pwdev_priv->ifname_mon[0] = '\0';
5415         pwdev_priv->padapter = padapter;
5416         pwdev_priv->scan_request = NULL;
5417         _rtw_spinlock_init(&pwdev_priv->scan_req_lock);
5418                 
5419         pwdev_priv->p2p_enabled = _FALSE;
5420         pwdev_priv->provdisc_req_issued = _FALSE;
5421         rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
5422         rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
5423                 
5424         pwdev_priv->bandroid_scan = _FALSE;
5425
5426         if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
5427                 pwdev_priv->power_mgmt = _TRUE;
5428         else
5429                 pwdev_priv->power_mgmt = _FALSE;
5430         
5431 #ifdef CONFIG_CONCURRENT_MODE
5432         ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);       
5433         ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);   
5434 #endif
5435
5436         return ret;
5437
5438         rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
5439 unregister_wiphy:
5440         wiphy_unregister(wiphy);
5441  free_wiphy:
5442         wiphy_free(wiphy);
5443 exit:
5444         return ret;
5445         
5446 }
5447
5448 void rtw_wdev_free(struct wireless_dev *wdev)
5449 {
5450         struct rtw_wdev_priv *pwdev_priv;
5451
5452         DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
5453
5454         if (!wdev)
5455                 return;
5456
5457         pwdev_priv = wdev_to_priv(wdev);
5458
5459         rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
5460         rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
5461         
5462         wiphy_free(wdev->wiphy);
5463
5464         rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
5465 }
5466
5467 void rtw_wdev_unregister(struct wireless_dev *wdev)
5468 {
5469         struct rtw_wdev_priv *pwdev_priv;
5470
5471         DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
5472
5473         if (!wdev)
5474                 return;
5475
5476         pwdev_priv = wdev_to_priv(wdev);
5477
5478         rtw_cfg80211_indicate_scan_done(pwdev_priv, _TRUE);
5479
5480         if (pwdev_priv->pmon_ndev) {
5481                 DBG_8192C("%s, unregister monitor interface\n", __func__);
5482                 unregister_netdev(pwdev_priv->pmon_ndev);
5483         }
5484
5485         wiphy_unregister(wdev->wiphy);
5486 }
5487
5488 #endif //CONFIG_IOCTL_CFG80211
5489