OSDN Git Service

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