net: wireless: rockchip_wlan: add rtl8723ds support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723ds / os_dep / linux / ioctl_cfg80211.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define  _IOCTL_CFG80211_C_
21
22 #include <drv_types.h>
23
24 #ifdef CONFIG_IOCTL_CFG80211
25
26 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
27 #define STATION_INFO_SIGNAL             BIT(NL80211_STA_INFO_SIGNAL)
28 #define STATION_INFO_TX_BITRATE         BIT(NL80211_STA_INFO_TX_BITRATE)
29 #define STATION_INFO_RX_PACKETS         BIT(NL80211_STA_INFO_RX_PACKETS)
30 #define STATION_INFO_TX_PACKETS         BIT(NL80211_STA_INFO_TX_PACKETS)
31 #define STATION_INFO_ASSOC_REQ_IES      0
32 #endif /* Linux kernel >= 4.0.0 */
33
34 #include <rtw_wifi_regd.h>
35
36 #define RTW_MAX_MGMT_TX_CNT (8)
37 #define RTW_MAX_MGMT_TX_MS_GAS (500)
38
39 #define RTW_SCAN_IE_LEN_MAX      2304
40 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 5000 /* ms */
41 #define RTW_MAX_NUM_PMKIDS 4
42
43 #define RTW_CH_MAX_2G_CHANNEL               14      /* Max channel in 2G band */
44
45 #ifdef CONFIG_WAPI_SUPPORT
46
47 #ifndef WLAN_CIPHER_SUITE_SMS4
48 #define WLAN_CIPHER_SUITE_SMS4          0x00147201
49 #endif
50
51 #ifndef WLAN_AKM_SUITE_WAPI_PSK
52 #define WLAN_AKM_SUITE_WAPI_PSK         0x000FAC04
53 #endif
54
55 #ifndef WLAN_AKM_SUITE_WAPI_CERT
56 #define WLAN_AKM_SUITE_WAPI_CERT        0x000FAC12
57 #endif
58
59 #ifndef NL80211_WAPI_VERSION_1
60 #define NL80211_WAPI_VERSION_1          (1 << 2)
61 #endif
62
63 #endif /* CONFIG_WAPI_SUPPORT */
64
65 #ifdef CONFIG_RTW_80211R
66 #define WLAN_AKM_SUITE_FT_8021X         0x000FAC03
67 #define WLAN_AKM_SUITE_FT_PSK                   0x000FAC04
68 #endif
69
70 static const u32 rtw_cipher_suites[] = {
71         WLAN_CIPHER_SUITE_WEP40,
72         WLAN_CIPHER_SUITE_WEP104,
73         WLAN_CIPHER_SUITE_TKIP,
74         WLAN_CIPHER_SUITE_CCMP,
75 #ifdef CONFIG_WAPI_SUPPORT
76         WLAN_CIPHER_SUITE_SMS4,
77 #endif /* CONFIG_WAPI_SUPPORT */
78 #ifdef CONFIG_IEEE80211W
79         WLAN_CIPHER_SUITE_AES_CMAC,
80 #endif /* CONFIG_IEEE80211W */
81 };
82
83 #define RATETAB_ENT(_rate, _rateid, _flags) \
84         {                                                               \
85                 .bitrate        = (_rate),                              \
86                 .hw_value       = (_rateid),                            \
87                 .flags          = (_flags),                             \
88         }
89
90 #define CHAN2G(_channel, _freq, _flags) {                       \
91                 .band                   = IEEE80211_BAND_2GHZ,          \
92                 .center_freq            = (_freq),                      \
93                 .hw_value               = (_channel),                   \
94                 .flags                  = (_flags),                     \
95                 .max_antenna_gain       = 0,                            \
96                 .max_power              = 30,                           \
97         }
98
99 #define CHAN5G(_channel, _flags) {                              \
100                 .band                   = IEEE80211_BAND_5GHZ,          \
101                 .center_freq            = 5000 + (5 * (_channel)),      \
102                 .hw_value               = (_channel),                   \
103                 .flags                  = (_flags),                     \
104                 .max_antenna_gain       = 0,                            \
105                 .max_power              = 30,                           \
106         }
107
108 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
109 /* if wowlan is not supported, kernel generate a disconnect at each suspend
110  * cf: /net/wireless/sysfs.c, so register a stub wowlan.
111  * Moreover wowlan has to be enabled via a the nl80211_set_wowlan callback.
112  * (from user space, e.g. iw phy0 wowlan enable)
113  */
114 static const struct wiphy_wowlan_support wowlan_stub = {
115         .flags = WIPHY_WOWLAN_ANY,
116         .n_patterns = 0,
117         .pattern_max_len = 0,
118         .pattern_min_len = 0,
119 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
120         .max_pkt_offset = 0,
121 #endif
122 };
123 #endif
124
125 static struct ieee80211_rate rtw_rates[] = {
126         RATETAB_ENT(10,  0x1,   0),
127         RATETAB_ENT(20,  0x2,   0),
128         RATETAB_ENT(55,  0x4,   0),
129         RATETAB_ENT(110, 0x8,   0),
130         RATETAB_ENT(60,  0x10,  0),
131         RATETAB_ENT(90,  0x20,  0),
132         RATETAB_ENT(120, 0x40,  0),
133         RATETAB_ENT(180, 0x80,  0),
134         RATETAB_ENT(240, 0x100, 0),
135         RATETAB_ENT(360, 0x200, 0),
136         RATETAB_ENT(480, 0x400, 0),
137         RATETAB_ENT(540, 0x800, 0),
138 };
139
140 #define rtw_a_rates             (rtw_rates + 4)
141 #define RTW_A_RATES_NUM 8
142 #define rtw_g_rates             (rtw_rates + 0)
143 #define RTW_G_RATES_NUM 12
144
145 #define RTW_2G_CHANNELS_NUM 14
146 #define RTW_5G_CHANNELS_NUM 37
147
148 static struct ieee80211_channel rtw_2ghz_channels[] = {
149         CHAN2G(1, 2412, 0),
150         CHAN2G(2, 2417, 0),
151         CHAN2G(3, 2422, 0),
152         CHAN2G(4, 2427, 0),
153         CHAN2G(5, 2432, 0),
154         CHAN2G(6, 2437, 0),
155         CHAN2G(7, 2442, 0),
156         CHAN2G(8, 2447, 0),
157         CHAN2G(9, 2452, 0),
158         CHAN2G(10, 2457, 0),
159         CHAN2G(11, 2462, 0),
160         CHAN2G(12, 2467, 0),
161         CHAN2G(13, 2472, 0),
162         CHAN2G(14, 2484, 0),
163 };
164
165 static struct ieee80211_channel rtw_5ghz_a_channels[] = {
166         CHAN5G(34, 0),          CHAN5G(36, 0),
167         CHAN5G(38, 0),          CHAN5G(40, 0),
168         CHAN5G(42, 0),          CHAN5G(44, 0),
169         CHAN5G(46, 0),          CHAN5G(48, 0),
170         CHAN5G(52, 0),          CHAN5G(56, 0),
171         CHAN5G(60, 0),          CHAN5G(64, 0),
172         CHAN5G(100, 0),         CHAN5G(104, 0),
173         CHAN5G(108, 0),         CHAN5G(112, 0),
174         CHAN5G(116, 0),         CHAN5G(120, 0),
175         CHAN5G(124, 0),         CHAN5G(128, 0),
176         CHAN5G(132, 0),         CHAN5G(136, 0),
177         CHAN5G(140, 0),         CHAN5G(149, 0),
178         CHAN5G(153, 0),         CHAN5G(157, 0),
179         CHAN5G(161, 0),         CHAN5G(165, 0),
180         CHAN5G(184, 0),         CHAN5G(188, 0),
181         CHAN5G(192, 0),         CHAN5G(196, 0),
182         CHAN5G(200, 0),         CHAN5G(204, 0),
183         CHAN5G(208, 0),         CHAN5G(212, 0),
184         CHAN5G(216, 0),
185 };
186
187
188 void rtw_2g_channels_init(struct ieee80211_channel *channels)
189 {
190         _rtw_memcpy((void *)channels, (void *)rtw_2ghz_channels,
191                 sizeof(struct ieee80211_channel) * RTW_2G_CHANNELS_NUM
192         );
193 }
194
195 void rtw_5g_channels_init(struct ieee80211_channel *channels)
196 {
197         _rtw_memcpy((void *)channels, (void *)rtw_5ghz_a_channels,
198                 sizeof(struct ieee80211_channel) * RTW_5G_CHANNELS_NUM
199         );
200 }
201
202 void rtw_2g_rates_init(struct ieee80211_rate *rates)
203 {
204         _rtw_memcpy(rates, rtw_g_rates,
205                 sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM
206         );
207 }
208
209 void rtw_5g_rates_init(struct ieee80211_rate *rates)
210 {
211         _rtw_memcpy(rates, rtw_a_rates,
212                 sizeof(struct ieee80211_rate) * RTW_A_RATES_NUM
213         );
214 }
215
216 struct ieee80211_supported_band *rtw_spt_band_alloc(
217         enum ieee80211_band band
218 )
219 {
220         struct ieee80211_supported_band *spt_band = NULL;
221         int n_channels, n_bitrates;
222
223         if (band == IEEE80211_BAND_2GHZ) {
224                 n_channels = RTW_2G_CHANNELS_NUM;
225                 n_bitrates = RTW_G_RATES_NUM;
226         } else if (band == IEEE80211_BAND_5GHZ) {
227                 n_channels = RTW_5G_CHANNELS_NUM;
228                 n_bitrates = RTW_A_RATES_NUM;
229         } else
230                 goto exit;
231
232         spt_band = (struct ieee80211_supported_band *)rtw_zmalloc(
233                 sizeof(struct ieee80211_supported_band)
234                 + sizeof(struct ieee80211_channel) * n_channels
235                 + sizeof(struct ieee80211_rate) * n_bitrates
236         );
237         if (!spt_band)
238                 goto exit;
239
240         spt_band->channels = (struct ieee80211_channel *)(((u8 *)spt_band) + sizeof(struct ieee80211_supported_band));
241         spt_band->bitrates = (struct ieee80211_rate *)(((u8 *)spt_band->channels) + sizeof(struct ieee80211_channel) * n_channels);
242         spt_band->band = band;
243         spt_band->n_channels = n_channels;
244         spt_band->n_bitrates = n_bitrates;
245
246         if (band == IEEE80211_BAND_2GHZ) {
247                 rtw_2g_channels_init(spt_band->channels);
248                 rtw_2g_rates_init(spt_band->bitrates);
249         } else if (band == IEEE80211_BAND_5GHZ) {
250                 rtw_5g_channels_init(spt_band->channels);
251                 rtw_5g_rates_init(spt_band->bitrates);
252         }
253
254         /* spt_band.ht_cap */
255
256 exit:
257
258         return spt_band;
259 }
260
261 void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
262 {
263         u32 size = 0;
264
265         if (!spt_band)
266                 return;
267
268         if (spt_band->band == IEEE80211_BAND_2GHZ) {
269                 size = sizeof(struct ieee80211_supported_band)
270                         + sizeof(struct ieee80211_channel) * RTW_2G_CHANNELS_NUM
271                         + sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM;
272         } else if (spt_band->band == IEEE80211_BAND_5GHZ) {
273                 size = sizeof(struct ieee80211_supported_band)
274                         + sizeof(struct ieee80211_channel) * RTW_5G_CHANNELS_NUM
275                         + sizeof(struct ieee80211_rate) * RTW_A_RATES_NUM;
276         } else {
277
278         }
279         rtw_mfree((u8 *)spt_band, size);
280 }
281
282 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
283 static const struct ieee80211_txrx_stypes
284         rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
285         [NL80211_IFTYPE_ADHOC] = {
286                 .tx = 0xffff,
287                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
288         },
289         [NL80211_IFTYPE_STATION] = {
290                 .tx = 0xffff,
291                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
292                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
293         },
294         [NL80211_IFTYPE_AP] = {
295                 .tx = 0xffff,
296                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
297                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
298                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
299                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
300                 BIT(IEEE80211_STYPE_AUTH >> 4) |
301                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
302                 BIT(IEEE80211_STYPE_ACTION >> 4)
303         },
304         [NL80211_IFTYPE_AP_VLAN] = {
305                 /* copy AP */
306                 .tx = 0xffff,
307                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
308                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
309                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
310                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
311                 BIT(IEEE80211_STYPE_AUTH >> 4) |
312                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
313                 BIT(IEEE80211_STYPE_ACTION >> 4)
314         },
315         [NL80211_IFTYPE_P2P_CLIENT] = {
316                 .tx = 0xffff,
317                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
318                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
319         },
320         [NL80211_IFTYPE_P2P_GO] = {
321                 .tx = 0xffff,
322                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
323                 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
324                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
325                 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
326                 BIT(IEEE80211_STYPE_AUTH >> 4) |
327                 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
328                 BIT(IEEE80211_STYPE_ACTION >> 4)
329         },
330 #if defined(RTW_DEDICATED_P2P_DEVICE)
331         [NL80211_IFTYPE_P2P_DEVICE] = {
332                 .tx = 0xffff,
333                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
334                         BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
335         },
336 #endif
337 };
338 #endif
339
340 static u64 rtw_get_systime_us(void)
341 {
342 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
343         struct timespec ts;
344         get_monotonic_boottime(&ts);
345         return ((u64)ts.tv_sec * 1000000) + ts.tv_nsec / 1000;
346 #else
347         struct timeval tv;
348         do_gettimeofday(&tv);
349         return ((u64)tv.tv_sec * 1000000) + tv.tv_usec;
350 #endif
351 }
352
353 /* Try to remove non target BSS's SR to reduce PBC overlap rate */
354 static int rtw_cfg80211_clear_wps_sr_of_non_target_bss(_adapter *padapter, struct wlan_network *pnetwork, struct cfg80211_ssid *req_ssid)
355 {
356         struct rtw_wdev_priv *wdev_data = adapter_wdev_data(padapter);
357         int ret = 0;
358         u8 *psr = NULL, sr = 0;
359         NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid;
360         u32 wpsielen = 0;
361         u8 *wpsie = NULL;
362
363         if (pssid->SsidLength == req_ssid->ssid_len
364                 && _rtw_memcmp(pssid->Ssid, req_ssid->ssid, req_ssid->ssid_len) == _TRUE)
365                 goto exit;
366
367         wpsie = rtw_get_wps_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_
368                 , pnetwork->network.IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
369         if (wpsie && wpsielen > 0)
370                 psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, &sr, NULL);
371
372         if (psr && sr) {
373                 if (0)
374                         RTW_INFO("clear sr of non target bss:%s("MAC_FMT")\n"
375                                 , pssid->Ssid, MAC_ARG(pnetwork->network.MacAddress));
376                 *psr = 0; /* clear sr */
377                 ret = 1;
378         }
379
380 exit:
381         return ret;
382 }
383
384 #define MAX_BSSINFO_LEN 1000
385 struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork)
386 {
387         struct ieee80211_channel *notify_channel;
388         struct cfg80211_bss *bss = NULL;
389         /* struct ieee80211_supported_band *band;       */
390         u16 channel;
391         u32 freq;
392         u64 notify_timestamp;
393         u16 notify_capability;
394         u16 notify_interval;
395         u8 *notify_ie;
396         size_t notify_ielen;
397         s32 notify_signal;
398         /* u8 buf[MAX_BSSINFO_LEN]; */
399
400         u8 *pbuf;
401         size_t buf_size = MAX_BSSINFO_LEN;
402         size_t len, bssinf_len = 0;
403         struct rtw_ieee80211_hdr *pwlanhdr;
404         unsigned short *fctrl;
405         u8      bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
406
407         struct wireless_dev *wdev = padapter->rtw_wdev;
408         struct wiphy *wiphy = wdev->wiphy;
409         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
410
411         pbuf = rtw_zmalloc(buf_size);
412         if (pbuf == NULL) {
413                 RTW_INFO("%s pbuf allocate failed  !!\n", __FUNCTION__);
414                 return bss;
415         }
416
417         /* RTW_INFO("%s\n", __func__); */
418
419         bssinf_len = pnetwork->network.IELength + sizeof(struct rtw_ieee80211_hdr_3addr);
420         if (bssinf_len > buf_size) {
421                 RTW_INFO("%s IE Length too long > %zu byte\n", __FUNCTION__, buf_size);
422                 goto exit;
423         }
424
425 #ifndef CONFIG_WAPI_SUPPORT
426         {
427                 u16 wapi_len = 0;
428
429                 if (rtw_get_wapi_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &wapi_len) > 0) {
430                         if (wapi_len > 0) {
431                                 RTW_INFO("%s, no support wapi!\n", __FUNCTION__);
432                                 goto exit;
433                         }
434                 }
435         }
436 #endif /* !CONFIG_WAPI_SUPPORT */
437
438         channel = pnetwork->network.Configuration.DSConfig;
439         freq = rtw_ch2freq(channel);
440         notify_channel = ieee80211_get_channel(wiphy, freq);
441
442         if (0)
443                 notify_timestamp = le64_to_cpu(*(u64 *)rtw_get_timestampe_from_ie(pnetwork->network.IEs));
444         else
445                 notify_timestamp = rtw_get_systime_us();
446
447         notify_interval = le16_to_cpu(*(u16 *)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
448         notify_capability = le16_to_cpu(*(u16 *)rtw_get_capability_from_ie(pnetwork->network.IEs));
449
450         notify_ie = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
451         notify_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
452
453         /* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) */
454         if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
455                 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
456                 notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength); /* dbm */
457         } else {
458                 notify_signal = 100 * translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength); /* dbm */
459         }
460
461 #if 0
462         RTW_INFO("bssid: "MAC_FMT"\n", MAC_ARG(pnetwork->network.MacAddress));
463         RTW_INFO("Channel: %d(%d)\n", channel, freq);
464         RTW_INFO("Capability: %X\n", notify_capability);
465         RTW_INFO("Beacon interval: %d\n", notify_interval);
466         RTW_INFO("Signal: %d\n", notify_signal);
467         RTW_INFO("notify_timestamp: %llu\n", notify_timestamp);
468 #endif
469
470         /* pbuf = buf; */
471
472         pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;
473         fctrl = &(pwlanhdr->frame_ctl);
474         *(fctrl) = 0;
475
476         SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
477         /* pmlmeext->mgnt_seq++; */
478
479         if (pnetwork->network.Reserved[0] == 1) { /* WIFI_BEACON */
480                 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
481                 SetFrameSubType(pbuf, WIFI_BEACON);
482         } else {
483                 _rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN);
484                 SetFrameSubType(pbuf, WIFI_PROBERSP);
485         }
486
487         _rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
488         _rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
489
490
491         /* pbuf += sizeof(struct rtw_ieee80211_hdr_3addr); */
492         len = sizeof(struct rtw_ieee80211_hdr_3addr);
493         _rtw_memcpy((pbuf + len), pnetwork->network.IEs, pnetwork->network.IELength);
494         *((u64 *)(pbuf + len)) = cpu_to_le64(notify_timestamp);
495
496         len += pnetwork->network.IELength;
497
498         #if defined(CONFIG_P2P) && 0
499         if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
500                 RTW_INFO("%s, got p2p_ie\n", __func__);
501         #endif
502
503 #if 1
504         bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)pbuf,
505                                         len, notify_signal, GFP_ATOMIC);
506 #else
507
508         bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress,
509                 notify_timestamp, notify_capability, notify_interval, notify_ie,
510                 notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/);
511 #endif
512
513         if (unlikely(!bss)) {
514                 RTW_INFO(FUNC_ADPT_FMT" bss NULL\n", FUNC_ADPT_ARG(padapter));
515                 goto exit;
516         }
517
518 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38))
519 #ifndef COMPAT_KERNEL_RELEASE
520         /* patch for cfg80211, update beacon ies to information_elements */
521         if (pnetwork->network.Reserved[0] == 1) { /* WIFI_BEACON */
522
523                 if (bss->len_information_elements != bss->len_beacon_ies) {
524                         bss->information_elements = bss->beacon_ies;
525                         bss->len_information_elements =  bss->len_beacon_ies;
526                 }
527         }
528 #endif /* COMPAT_KERNEL_RELEASE */
529 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38) */
530
531 #if 0
532         {
533                 if (bss->information_elements == bss->proberesp_ies) {
534                         if (bss->len_information_elements !=  bss->len_proberesp_ies)
535                                 RTW_INFO("error!, len_information_elements != bss->len_proberesp_ies\n");
536                 } else if (bss->len_information_elements <  bss->len_beacon_ies) {
537                         bss->information_elements = bss->beacon_ies;
538                         bss->len_information_elements =  bss->len_beacon_ies;
539                 }
540         }
541 #endif
542 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
543         cfg80211_put_bss(wiphy, bss);
544 #else
545         cfg80211_put_bss(bss);
546 #endif
547
548 exit:
549         if (pbuf)
550                 rtw_mfree(pbuf, buf_size);
551         return bss;
552
553 }
554
555 /*
556         Check the given bss is valid by kernel API cfg80211_get_bss()
557         @padapter : the given adapter
558
559         return _TRUE if bss is valid,  _FALSE for not found.
560 */
561 int rtw_cfg80211_check_bss(_adapter *padapter)
562 {
563         WLAN_BSSID_EX  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
564         struct cfg80211_bss *bss = NULL;
565         struct ieee80211_channel *notify_channel = NULL;
566         u32 freq;
567
568         if (!(pnetwork) || !(padapter->rtw_wdev))
569                 return _FALSE;
570
571         freq = rtw_ch2freq(pnetwork->Configuration.DSConfig);
572         notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
573         bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
574                         pnetwork->MacAddress, pnetwork->Ssid.Ssid,
575                         pnetwork->Ssid.SsidLength,
576 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
577                         pnetwork->InfrastructureMode == Ndis802_11Infrastructure?IEEE80211_BSS_TYPE_ESS:IEEE80211_BSS_TYPE_IBSS,
578                         IEEE80211_PRIVACY(pnetwork->Privacy));
579 #else
580                         pnetwork->InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS, pnetwork->InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS);
581 #endif
582
583 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
584         cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
585 #else
586         cfg80211_put_bss(bss);
587 #endif
588
589         return bss != NULL;
590 }
591
592 void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter)
593 {
594         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
595         struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
596         struct wireless_dev *pwdev = padapter->rtw_wdev;
597         struct cfg80211_bss *bss = NULL;
598 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
599         struct wiphy *wiphy = pwdev->wiphy;
600         int freq = 2412;
601         struct ieee80211_channel *notify_channel;
602 #endif
603
604         RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
605
606 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
607         freq = rtw_ch2freq(cur_network->network.Configuration.DSConfig);
608
609         if (0)
610                 RTW_INFO("chan: %d, freq: %d\n", cur_network->network.Configuration.DSConfig, freq);
611 #endif
612
613         if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
614                 return;
615
616         if (!rtw_cfg80211_check_bss(padapter)) {
617                 WLAN_BSSID_EX  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
618                 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
619
620                 if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
621
622                         _rtw_memcpy(&cur_network->network, pnetwork, sizeof(WLAN_BSSID_EX));
623                         if (cur_network) {
624                                 if (!rtw_cfg80211_inform_bss(padapter, cur_network))
625                                         RTW_INFO(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
626                                 else
627                                         RTW_INFO(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
628                         } else {
629                                 RTW_INFO("cur_network is not exist!!!\n");
630                                 return ;
631                         }
632                 } else {
633                         if (scanned == NULL)
634                                 rtw_warn_on(1);
635
636                         if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
637                                 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
638                         ) {
639                                 if (!rtw_cfg80211_inform_bss(padapter, scanned))
640                                         RTW_INFO(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
641                                 else {
642                                         /* RTW_INFO(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); */
643                                 }
644                         } else {
645                                 RTW_INFO("scanned & pnetwork compare fail\n");
646                                 rtw_warn_on(1);
647                         }
648                 }
649
650                 if (!rtw_cfg80211_check_bss(padapter))
651                         RTW_PRINT(FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
652         }
653         /* notify cfg80211 that device joined an IBSS */
654 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
655         notify_channel = ieee80211_get_channel(wiphy, freq);
656         cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, notify_channel, GFP_ATOMIC);
657 #else
658         cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, GFP_ATOMIC);
659 #endif
660 }
661
662 void rtw_cfg80211_indicate_connect(_adapter *padapter)
663 {
664         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
665         struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
666         struct wireless_dev *pwdev = padapter->rtw_wdev;
667 #ifdef CONFIG_P2P
668         struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
669 #endif
670         struct cfg80211_bss *bss = NULL;
671
672         RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
673         if (pwdev->iftype != NL80211_IFTYPE_STATION
674                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
675                 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
676                 #endif
677         )
678                 return;
679
680         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
681                 return;
682
683 #ifdef CONFIG_P2P
684         if (pwdinfo->driver_interface == DRIVER_CFG80211) {
685                 #if !RTW_P2P_GROUP_INTERFACE
686                 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
687                         rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
688                         rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
689                         rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
690                         RTW_INFO("%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));
691                 }
692                 #endif
693         }
694 #endif /* CONFIG_P2P */
695
696         if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) {
697                 WLAN_BSSID_EX  *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
698                 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
699
700                 /* RTW_INFO(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter)); */
701
702                 if (scanned == NULL) {
703                         rtw_warn_on(1);
704                         goto check_bss;
705                 }
706
707                 if (_rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
708                         && _rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
709                 ) {
710                         if (!rtw_cfg80211_inform_bss(padapter, scanned))
711                                 RTW_INFO(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
712                         else {
713                                 /* RTW_INFO(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); */
714                         }
715                 } else {
716                         RTW_INFO("scanned: %s("MAC_FMT"), cur: %s("MAC_FMT")\n",
717                                 scanned->network.Ssid.Ssid, MAC_ARG(scanned->network.MacAddress),
718                                 pnetwork->Ssid.Ssid, MAC_ARG(pnetwork->MacAddress)
719                         );
720                         rtw_warn_on(1);
721                 }
722         }
723
724 check_bss:
725         if (!rtw_cfg80211_check_bss(padapter))
726                 RTW_PRINT(FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
727
728         if (rtw_to_roam(padapter) > 0) {
729                 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
730                 struct wiphy *wiphy = pwdev->wiphy;
731                 struct ieee80211_channel *notify_channel;
732                 u32 freq;
733                 u16 channel = cur_network->network.Configuration.DSConfig;
734
735                 freq = rtw_ch2freq(channel);
736                 notify_channel = ieee80211_get_channel(wiphy, freq);
737                 #endif
738
739                 RTW_INFO(FUNC_ADPT_FMT" call cfg80211_roamed\n", FUNC_ADPT_ARG(padapter));
740                 cfg80211_roamed(padapter->pnetdev
741                         #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
742                         , notify_channel
743                         #endif
744                         , cur_network->network.MacAddress
745                         , pmlmepriv->assoc_req + sizeof(struct rtw_ieee80211_hdr_3addr) + 2
746                         , pmlmepriv->assoc_req_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 2
747                         , pmlmepriv->assoc_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6
748                         , pmlmepriv->assoc_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6
749                         , GFP_ATOMIC);
750 #ifdef CONFIG_RTW_80211R
751                 if ((rtw_to_roam(padapter) > 0) && rtw_chk_ft_flags(padapter, RTW_FT_SUPPORTED))
752                         rtw_set_ft_status(padapter, RTW_FT_ASSOCIATED_STA);
753 #endif
754         } else {
755                 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
756                 RTW_INFO("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
757                 #endif
758                 cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
759                         , pmlmepriv->assoc_req + sizeof(struct rtw_ieee80211_hdr_3addr) + 2
760                         , pmlmepriv->assoc_req_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 2
761                         , pmlmepriv->assoc_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6
762                         , pmlmepriv->assoc_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6
763                         , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
764                 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
765                 RTW_INFO("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
766                 #endif
767         }
768 }
769
770 void rtw_cfg80211_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generated)
771 {
772         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
773         struct wireless_dev *pwdev = padapter->rtw_wdev;
774 #ifdef CONFIG_P2P
775         struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
776 #endif
777
778         RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
779
780         /*always replace privated definitions with wifi reserved value 0*/
781         if ((reason == WLAN_REASON_ACTIVE_ROAM) || (reason == WLAN_REASON_JOIN_WRONG_CHANNEL) || (reason == WLAN_REASON_EXPIRATION_CHK))
782                 reason = 0;
783
784         if (pwdev->iftype != NL80211_IFTYPE_STATION
785                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
786                 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
787                 #endif
788         )
789                 return;
790
791         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
792                 return;
793
794 #ifdef CONFIG_P2P
795         if (pwdinfo->driver_interface == DRIVER_CFG80211) {
796                 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
797                         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
798
799                         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
800                         if (pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
801                         #endif
802                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
803
804                         RTW_INFO("%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));
805                 }
806         }
807 #endif /* CONFIG_P2P */
808
809         #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
810         if (!padapter->mlmepriv.not_indic_disco || padapter->ndev_unregistering) {
811         #else
812         {
813         #endif
814                 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
815                 RTW_INFO("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
816
817                 if (pwdev->sme_state == CFG80211_SME_CONNECTING)
818                         cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
819                                 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
820                 else if (pwdev->sme_state == CFG80211_SME_CONNECTED) {
821                         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
822                         cfg80211_disconnected(padapter->pnetdev, reason, NULL, 0, locally_generated, GFP_ATOMIC);
823                         #else
824                         cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
825                         #endif
826                 }
827                 #if 0
828                 else
829                         RTW_INFO("pwdev->sme_state=%d\n", pwdev->sme_state);
830                 #endif
831
832                 RTW_INFO("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
833                 #else
834
835                 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
836                         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
837                         RTW_INFO(FUNC_ADPT_FMT" call cfg80211_disconnected\n", FUNC_ADPT_ARG(padapter));
838                         cfg80211_disconnected(padapter->pnetdev, reason, NULL, 0, locally_generated, GFP_ATOMIC);
839                         #else
840                         RTW_INFO(FUNC_ADPT_FMT" call cfg80211_disconnected\n", FUNC_ADPT_ARG(padapter));
841                         cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
842                         #endif
843                 } else {
844                         RTW_INFO(FUNC_ADPT_FMT" call cfg80211_connect_result\n", FUNC_ADPT_ARG(padapter));
845                         cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
846                                 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC);
847                 }
848                 #endif
849         }
850 }
851
852
853 #ifdef CONFIG_AP_MODE
854 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
855 {
856         int ret = 0;
857         u32 wep_key_idx, wep_key_len, wep_total_len;
858         struct sta_info *psta = NULL, *pbcmc_sta = NULL;
859         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
860         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
861         struct security_priv *psecuritypriv = &(padapter->securitypriv);
862         struct sta_priv *pstapriv = &padapter->stapriv;
863
864         RTW_INFO("%s\n", __FUNCTION__);
865
866         param->u.crypt.err = 0;
867         param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
868
869         /* sizeof(struct ieee_param) = 64 bytes; */
870         /* if (param_len !=  (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) */
871         if (param_len !=  sizeof(struct ieee_param) + param->u.crypt.key_len) {
872                 ret =  -EINVAL;
873                 goto exit;
874         }
875
876         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
877             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
878             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
879                 if (param->u.crypt.idx >= WEP_KEYS
880 #ifdef CONFIG_IEEE80211W
881                         && param->u.crypt.idx > BIP_MAX_KEYID
882 #endif /* CONFIG_IEEE80211W */
883                 ) {
884                         ret = -EINVAL;
885                         goto exit;
886                 }
887         } else {
888                 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
889                 if (!psta) {
890                         /* ret = -EINVAL; */
891                         RTW_INFO("rtw_set_encryption(), sta has already been removed or never been added\n");
892                         goto exit;
893                 }
894         }
895
896         if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
897                 /* todo:clear default encryption keys */
898
899                 RTW_INFO("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
900
901                 goto exit;
902         }
903
904
905         if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
906                 RTW_INFO("r871x_set_encryption, crypt.alg = WEP\n");
907
908                 wep_key_idx = param->u.crypt.idx;
909                 wep_key_len = param->u.crypt.key_len;
910
911                 RTW_INFO("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
912
913                 if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
914                         ret = -EINVAL;
915                         goto exit;
916                 }
917
918                 if (wep_key_len > 0)
919                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
920
921                 if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
922                         /* wep default key has not been set, so use this key index as default key. */
923
924                         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
925                         psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
926                         psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
927                         psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
928
929                         if (wep_key_len == 13) {
930                                 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
931                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
932                         }
933
934                         psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
935                 }
936
937                 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
938
939                 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
940
941                 rtw_ap_set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx, 1);
942
943                 goto exit;
944
945         }
946
947
948         if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /* group key */
949                 if (param->u.crypt.set_tx == 0) { /* group key */
950                         if (strcmp(param->u.crypt.alg, "WEP") == 0) {
951                                 RTW_INFO("%s, set group_key, WEP\n", __FUNCTION__);
952
953                                 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
954
955                                 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
956                                 if (param->u.crypt.key_len == 13)
957                                         psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
958
959                         } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
960                                 RTW_INFO("%s, set group_key, TKIP\n", __FUNCTION__);
961
962                                 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
963
964                                 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
965
966                                 /* DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); */
967                                 /* set mic key */
968                                 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
969                                 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
970
971                                 psecuritypriv->busetkipkey = _TRUE;
972
973                         } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
974                                 RTW_INFO("%s, set group_key, CCMP\n", __FUNCTION__);
975
976                                 psecuritypriv->dot118021XGrpPrivacy = _AES_;
977
978                                 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
979                         }
980 #ifdef CONFIG_IEEE80211W
981                         else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
982                                 int no;
983
984                                 RTW_INFO("BIP key_len=%d , index=%d\n", param->u.crypt.key_len, param->u.crypt.idx);
985                                 /* save the IGTK key, length 16 bytes */
986                                 _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
987                                 /* RTW_INFO("IGTK key below:\n");
988                                 for(no=0;no<16;no++)
989                                         printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
990                                 RTW_INFO("\n"); */
991                                 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
992                                 padapter->securitypriv.binstallBIPkey = _TRUE;
993                                 RTW_INFO(" ~~~~set sta key:IGKT\n");
994                                 goto exit;
995                         }
996 #endif /* CONFIG_IEEE80211W */
997                         else {
998                                 RTW_INFO("%s, set group_key, none\n", __FUNCTION__);
999
1000                                 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
1001                         }
1002
1003                         psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
1004
1005                         psecuritypriv->binstallGrpkey = _TRUE;
1006
1007                         psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* !!! */
1008
1009                         rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
1010
1011                         pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
1012                         if (pbcmc_sta) {
1013                                 pbcmc_sta->ieee8021x_blocked = _FALSE;
1014                                 pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy                   */
1015                         }
1016
1017                 }
1018
1019                 goto exit;
1020
1021         }
1022
1023         if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */
1024                 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1025                         if (param->u.crypt.set_tx == 1) { /* pairwise key */
1026                                 _rtw_memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1027
1028                                 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
1029                                         RTW_INFO("%s, set pairwise key, WEP\n", __FUNCTION__);
1030
1031                                         psta->dot118021XPrivacy = _WEP40_;
1032                                         if (param->u.crypt.key_len == 13)
1033                                                 psta->dot118021XPrivacy = _WEP104_;
1034                                 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
1035                                         RTW_INFO("%s, set pairwise key, TKIP\n", __FUNCTION__);
1036
1037                                         psta->dot118021XPrivacy = _TKIP_;
1038
1039                                         /* DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); */
1040                                         /* set mic key */
1041                                         _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1042                                         _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1043
1044                                         psecuritypriv->busetkipkey = _TRUE;
1045
1046                                 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
1047
1048                                         RTW_INFO("%s, set pairwise key, CCMP\n", __FUNCTION__);
1049
1050                                         psta->dot118021XPrivacy = _AES_;
1051                                 } else {
1052                                         RTW_INFO("%s, set pairwise key, none\n", __FUNCTION__);
1053
1054                                         psta->dot118021XPrivacy = _NO_PRIVACY_;
1055                                 }
1056
1057                                 rtw_ap_set_pairwise_key(padapter, psta);
1058
1059                                 psta->ieee8021x_blocked = _FALSE;
1060
1061                                 psta->bpairwise_key_installed = _TRUE;
1062
1063                         } else { /* group key??? */
1064                                 if (strcmp(param->u.crypt.alg, "WEP") == 0) {
1065                                         _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1066
1067                                         psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1068                                         if (param->u.crypt.key_len == 13)
1069                                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1070                                 } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
1071                                         psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
1072
1073                                         _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1074
1075                                         /* DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len); */
1076                                         /* set mic key */
1077                                         _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
1078                                         _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
1079
1080                                         psecuritypriv->busetkipkey = _TRUE;
1081
1082                                 } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
1083                                         psecuritypriv->dot118021XGrpPrivacy = _AES_;
1084
1085                                         _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1086                                 } else
1087                                         psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
1088
1089                                 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
1090
1091                                 psecuritypriv->binstallGrpkey = _TRUE;
1092
1093                                 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* !!! */
1094
1095                                 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
1096
1097                                 pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
1098                                 if (pbcmc_sta) {
1099                                         pbcmc_sta->ieee8021x_blocked = _FALSE;
1100                                         pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy                   */
1101                                 }
1102
1103                         }
1104
1105                 }
1106
1107         }
1108
1109 exit:
1110
1111         return ret;
1112
1113 }
1114 #endif
1115
1116 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
1117 {
1118         int ret = 0;
1119         u32 wep_key_idx, wep_key_len, wep_total_len;
1120         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1121         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
1122         struct security_priv *psecuritypriv = &padapter->securitypriv;
1123 #ifdef CONFIG_P2P
1124         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1125 #endif /* CONFIG_P2P */
1126
1127
1128         RTW_INFO("%s\n", __func__);
1129
1130         param->u.crypt.err = 0;
1131         param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
1132
1133         if (param_len < (u32)((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) {
1134                 ret =  -EINVAL;
1135                 goto exit;
1136         }
1137
1138         if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
1139             param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
1140             param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
1141                 if (param->u.crypt.idx >= WEP_KEYS
1142 #ifdef CONFIG_IEEE80211W
1143                         && param->u.crypt.idx > BIP_MAX_KEYID
1144 #endif /* CONFIG_IEEE80211W */
1145                 ) {
1146                         ret = -EINVAL;
1147                         goto exit;
1148                 }
1149         } else {
1150 #ifdef CONFIG_WAPI_SUPPORT
1151                 if (strcmp(param->u.crypt.alg, "SMS4"))
1152 #endif
1153                 {
1154                         ret = -EINVAL;
1155                         goto exit;
1156                 }
1157         }
1158
1159         if (strcmp(param->u.crypt.alg, "WEP") == 0) {
1160                 RTW_INFO("wpa_set_encryption, crypt.alg = WEP\n");
1161
1162                 wep_key_idx = param->u.crypt.idx;
1163                 wep_key_len = param->u.crypt.key_len;
1164
1165                 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0)) {
1166                         ret = -EINVAL;
1167                         goto exit;
1168                 }
1169
1170                 if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
1171                         /* wep default key has not been set, so use this key index as default key. */
1172
1173                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
1174
1175                         psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1176                         psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1177                         psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1178
1179                         if (wep_key_len == 13) {
1180                                 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1181                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1182                         }
1183
1184                         psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
1185                 }
1186
1187                 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
1188
1189                 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
1190
1191                 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, _TRUE);
1192
1193                 goto exit;
1194         }
1195
1196         if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */
1197                 struct sta_info *psta, *pbcmc_sta;
1198                 struct sta_priv *pstapriv = &padapter->stapriv;
1199
1200                 /* RTW_INFO("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X\n", __func__); */
1201
1202                 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) { /* sta mode */
1203 #ifdef CONFIG_RTW_80211R
1204                         if ((rtw_to_roam(padapter) > 0) && rtw_chk_ft_flags(padapter, RTW_FT_SUPPORTED))
1205                                 psta = rtw_get_stainfo(pstapriv, pmlmepriv->assoc_bssid);
1206                         else
1207 #endif
1208                                 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
1209                         if (psta == NULL) {
1210                                 /* DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
1211                                 RTW_INFO("%s, : Obtain Sta_info fail\n", __func__);
1212                         } else {
1213                                 /* Jeff: don't disable ieee8021x_blocked while clearing key */
1214                                 if (strcmp(param->u.crypt.alg, "none") != 0)
1215                                         psta->ieee8021x_blocked = _FALSE;
1216
1217
1218                                 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
1219                                     (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
1220                                         psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1221
1222                                 if (param->u.crypt.set_tx == 1) { /* pairwise key */
1223
1224                                         RTW_INFO("%s, : param->u.crypt.set_tx ==1\n", __func__);
1225
1226                                         _rtw_memcpy(psta->dot118021x_UncstKey.skey,  param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1227
1228                                         if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
1229                                                 /* DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); */
1230                                                 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1231                                                 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1232
1233                                                 padapter->securitypriv.busetkipkey = _FALSE;
1234                                                 /* _set_timer(&padapter->securitypriv.tkip_timer, 50);                                           */
1235                                         }
1236                                         psta->bpairwise_key_installed = _TRUE;
1237 #ifdef CONFIG_RTW_80211R
1238                                         psta->ft_pairwise_key_installed = _TRUE;
1239 #endif
1240                                         /* DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len)); */
1241                                         RTW_INFO(" ~~~~set sta key:unicastkey\n");
1242
1243                                         rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE);
1244                                 } else { /* group key */
1245                                         if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
1246                                                 _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey,  param->u.crypt.key,
1247                                                         (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1248                                                 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
1249                                                 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
1250                                                 padapter->securitypriv.binstallGrpkey = _TRUE;
1251                                                 /* DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len)); */
1252                                                 RTW_INFO(" ~~~~set sta key:groupkey\n");
1253
1254                                                 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1255                                                 rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, _TRUE);
1256                                         }
1257 #ifdef CONFIG_IEEE80211W
1258                                         else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
1259                                                 int no;
1260                                                 /* RTW_INFO("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx); */
1261                                                 /* save the IGTK key, length 16 bytes */
1262                                                 _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey,  param->u.crypt.key,
1263                                                         (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1264                                                 /*RTW_INFO("IGTK key below:\n");
1265                                                 for(no=0;no<16;no++)
1266                                                         printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
1267                                                 RTW_INFO("\n");*/
1268                                                 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
1269                                                 padapter->securitypriv.binstallBIPkey = _TRUE;
1270                                                 RTW_INFO(" ~~~~set sta key:IGKT\n");
1271                                         }
1272 #endif /* CONFIG_IEEE80211W */
1273
1274 #ifdef CONFIG_P2P
1275                                         if (pwdinfo->driver_interface == DRIVER_CFG80211) {
1276                                                 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
1277                                                         rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
1278                                         }
1279 #endif /* CONFIG_P2P */
1280
1281                                 }
1282                         }
1283
1284                         pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
1285                         if (pbcmc_sta == NULL) {
1286                                 /* DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
1287                         } else {
1288                                 /* Jeff: don't disable ieee8021x_blocked while clearing key */
1289                                 if (strcmp(param->u.crypt.alg, "none") != 0)
1290                                         pbcmc_sta->ieee8021x_blocked = _FALSE;
1291
1292                                 if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
1293                                     (padapter->securitypriv.ndisencryptstatus ==  Ndis802_11Encryption3Enabled))
1294                                         pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1295                         }
1296                 } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */
1297                 }
1298         }
1299
1300 #ifdef CONFIG_WAPI_SUPPORT
1301         if (strcmp(param->u.crypt.alg, "SMS4") == 0) {
1302                 PRT_WAPI_T                      pWapiInfo = &padapter->wapiInfo;
1303                 PRT_WAPI_STA_INFO       pWapiSta;
1304                 u8                                      WapiASUEPNInitialValueSrc[16] = {0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
1305                 u8                                      WapiAEPNInitialValueSrc[16] = {0x37, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
1306                 u8                                      WapiAEMultiCastPNInitialValueSrc[16] = {0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C, 0x36, 0x5C} ;
1307
1308                 if (param->u.crypt.set_tx == 1) {
1309                         list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1310                                 if (_rtw_memcmp(pWapiSta->PeerMacAddr, param->sta_addr, 6)) {
1311                                         _rtw_memcpy(pWapiSta->lastTxUnicastPN, WapiASUEPNInitialValueSrc, 16);
1312
1313                                         pWapiSta->wapiUsk.bSet = true;
1314                                         _rtw_memcpy(pWapiSta->wapiUsk.dataKey, param->u.crypt.key, 16);
1315                                         _rtw_memcpy(pWapiSta->wapiUsk.micKey, param->u.crypt.key + 16, 16);
1316                                         pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
1317                                         pWapiSta->wapiUsk.bTxEnable = true;
1318
1319                                         _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue, WapiAEPNInitialValueSrc, 16);
1320                                         _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue, WapiAEPNInitialValueSrc, 16);
1321                                         _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue, WapiAEPNInitialValueSrc, 16);
1322                                         _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue, WapiAEPNInitialValueSrc, 16);
1323                                         _rtw_memcpy(pWapiSta->lastRxUnicastPN, WapiAEPNInitialValueSrc, 16);
1324                                         pWapiSta->wapiUskUpdate.bTxEnable = false;
1325                                         pWapiSta->wapiUskUpdate.bSet = false;
1326
1327                                         if (psecuritypriv->sw_encrypt == false || psecuritypriv->sw_decrypt == false) {
1328                                                 /* set unicast key for ASUE */
1329                                                 rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
1330                                         }
1331                                 }
1332                         }
1333                 } else {
1334                         list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1335                                 if (_rtw_memcmp(pWapiSta->PeerMacAddr, get_bssid(pmlmepriv), 6)) {
1336                                         pWapiSta->wapiMsk.bSet = true;
1337                                         _rtw_memcpy(pWapiSta->wapiMsk.dataKey, param->u.crypt.key, 16);
1338                                         _rtw_memcpy(pWapiSta->wapiMsk.micKey, param->u.crypt.key + 16, 16);
1339                                         pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
1340                                         pWapiSta->wapiMsk.bTxEnable = false;
1341                                         if (!pWapiSta->bSetkeyOk)
1342                                                 pWapiSta->bSetkeyOk = true;
1343                                         pWapiSta->bAuthenticateInProgress = false;
1344
1345                                         _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
1346
1347                                         if (psecuritypriv->sw_decrypt == false) {
1348                                                 /* set rx broadcast key for ASUE */
1349                                                 rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
1350                                         }
1351                                 }
1352
1353                         }
1354                 }
1355         }
1356 #endif
1357
1358
1359 exit:
1360
1361         RTW_INFO("%s, ret=%d\n", __func__, ret);
1362
1363
1364         return ret;
1365 }
1366
1367 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
1368 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1369         u8 key_index, bool pairwise, const u8 *mac_addr,
1370 #else   /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) */
1371         u8 key_index, const u8 *mac_addr,
1372 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) */
1373         struct key_params *params)
1374 {
1375         char *alg_name;
1376         u32 param_len;
1377         struct ieee_param *param = NULL;
1378         int ret = 0;
1379         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1380         struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
1381         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1382 #ifdef CONFIG_TDLS
1383         struct sta_info *ptdls_sta;
1384 #endif /* CONFIG_TDLS */
1385
1386         RTW_INFO(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
1387         RTW_INFO("cipher=0x%x\n", params->cipher);
1388         RTW_INFO("key_len=0x%x\n", params->key_len);
1389         RTW_INFO("seq_len=0x%x\n", params->seq_len);
1390         RTW_INFO("key_index=%d\n", key_index);
1391 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1392         RTW_INFO("pairwise=%d\n", pairwise);
1393 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) */
1394
1395         param_len = sizeof(struct ieee_param) + params->key_len;
1396         param = (struct ieee_param *)rtw_malloc(param_len);
1397         if (param == NULL)
1398                 return -1;
1399
1400         _rtw_memset(param, 0, param_len);
1401
1402         param->cmd = IEEE_CMD_SET_ENCRYPTION;
1403         _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
1404
1405         switch (params->cipher) {
1406         case IW_AUTH_CIPHER_NONE:
1407                 /* todo: remove key */
1408                 /* remove = 1;   */
1409                 alg_name = "none";
1410                 break;
1411         case WLAN_CIPHER_SUITE_WEP40:
1412         case WLAN_CIPHER_SUITE_WEP104:
1413                 alg_name = "WEP";
1414                 break;
1415         case WLAN_CIPHER_SUITE_TKIP:
1416                 alg_name = "TKIP";
1417                 break;
1418         case WLAN_CIPHER_SUITE_CCMP:
1419                 alg_name = "CCMP";
1420                 break;
1421 #ifdef CONFIG_IEEE80211W
1422         case WLAN_CIPHER_SUITE_AES_CMAC:
1423                 alg_name = "BIP";
1424                 break;
1425 #endif /* CONFIG_IEEE80211W */
1426 #ifdef CONFIG_WAPI_SUPPORT
1427         case WLAN_CIPHER_SUITE_SMS4:
1428                 alg_name = "SMS4";
1429                 if (pairwise == NL80211_KEYTYPE_PAIRWISE) {
1430                         if (key_index != 0 && key_index != 1) {
1431                                 ret = -ENOTSUPP;
1432                                 goto addkey_end;
1433                         }
1434                         _rtw_memcpy((void *)param->sta_addr, (void *)mac_addr, ETH_ALEN);
1435                 } else
1436                         RTW_INFO("mac_addr is null\n");
1437                 RTW_INFO("rtw_wx_set_enc_ext: SMS4 case\n");
1438                 break;
1439 #endif
1440
1441         default:
1442                 ret = -ENOTSUPP;
1443                 goto addkey_end;
1444         }
1445
1446         strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1447
1448
1449         if (!mac_addr || is_broadcast_ether_addr(mac_addr)) {
1450                 param->u.crypt.set_tx = 0; /* for wpa/wpa2 group key */
1451         } else {
1452                 param->u.crypt.set_tx = 1; /* for wpa/wpa2 pairwise key */
1453         }
1454
1455
1456         /* param->u.crypt.idx = key_index - 1; */
1457         param->u.crypt.idx = key_index;
1458
1459         if (params->seq_len && params->seq)
1460                 _rtw_memcpy(param->u.crypt.seq, (u8 *)params->seq, params->seq_len);
1461
1462         if (params->key_len && params->key) {
1463                 param->u.crypt.key_len = params->key_len;
1464                 _rtw_memcpy(param->u.crypt.key, (u8 *)params->key, params->key_len);
1465         }
1466
1467         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
1468 #ifdef CONFIG_TDLS
1469                 if (rtw_tdls_is_driver_setup(padapter) == _FALSE && mac_addr) {
1470                         ptdls_sta = rtw_get_stainfo(&padapter->stapriv, (void *)mac_addr);
1471                         if (ptdls_sta != NULL && ptdls_sta->tdls_sta_state) {
1472                                 _rtw_memcpy(ptdls_sta->tpk.tk, params->key, params->key_len);
1473                                 rtw_tdls_set_key(padapter, ptdls_sta);
1474                                 goto addkey_end;
1475                         }
1476                 }
1477 #endif /* CONFIG_TDLS */
1478
1479                 ret =  rtw_cfg80211_set_encryption(ndev, param, param_len);
1480         } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1481 #ifdef CONFIG_AP_MODE
1482                 if (mac_addr)
1483                         _rtw_memcpy(param->sta_addr, (void *)mac_addr, ETH_ALEN);
1484
1485                 ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
1486 #endif
1487         } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE
1488                 || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE
1489         ) {
1490                 /* RTW_INFO("@@@@@@@@@@ fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype); */
1491                 ret =  rtw_cfg80211_set_encryption(ndev, param, param_len);
1492         } else
1493                 RTW_INFO("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
1494
1495
1496 addkey_end:
1497         if (param)
1498                 rtw_mfree((u8 *)param, param_len);
1499
1500         return ret;
1501
1502 }
1503
1504 static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
1505 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1506         u8 key_index, bool pairwise, const u8 *mac_addr,
1507 #else   /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) */
1508         u8 key_index, const u8 *mac_addr,
1509 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) */
1510         void *cookie,
1511         void (*callback)(void *cookie, struct key_params *))
1512 {
1513 #if 0
1514         struct iwm_priv *iwm = ndev_to_iwm(ndev);
1515         struct iwm_key *key = &iwm->keys[key_index];
1516         struct key_params params;
1517
1518         IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
1519
1520         memset(&params, 0, sizeof(params));
1521
1522         params.cipher = key->cipher;
1523         params.key_len = key->key_len;
1524         params.seq_len = key->seq_len;
1525         params.seq = key->seq;
1526         params.key = key->key;
1527
1528         callback(cookie, &params);
1529
1530         return key->key_len ? 0 : -ENOENT;
1531 #endif
1532         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
1533         return 0;
1534 }
1535
1536 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
1537 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1538                                 u8 key_index, bool pairwise, const u8 *mac_addr)
1539 #else   /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) */
1540                                 u8 key_index, const u8 *mac_addr)
1541 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) */
1542 {
1543         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1544         struct security_priv *psecuritypriv = &padapter->securitypriv;
1545
1546         RTW_INFO(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index);
1547
1548         if (key_index == psecuritypriv->dot11PrivacyKeyIndex) {
1549                 /* clear the flag of wep default key set. */
1550                 psecuritypriv->bWepDefaultKeyIdxSet = 0;
1551         }
1552
1553         return 0;
1554 }
1555
1556 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
1557         struct net_device *ndev, u8 key_index
1558         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
1559         , bool unicast, bool multicast
1560         #endif
1561 )
1562 {
1563         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1564         struct security_priv *psecuritypriv = &padapter->securitypriv;
1565
1566 #define SET_DEF_KEY_PARAM_FMT " key_index=%d"
1567 #define SET_DEF_KEY_PARAM_ARG , key_index
1568 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
1569         #define SET_DEF_KEY_PARAM_FMT_2_6_38 ", unicast=%d, multicast=%d"
1570         #define SET_DEF_KEY_PARAM_ARG_2_6_38 , unicast, multicast
1571 #else
1572         #define SET_DEF_KEY_PARAM_FMT_2_6_38 ""
1573         #define SET_DEF_KEY_PARAM_ARG_2_6_38
1574 #endif
1575
1576         RTW_INFO(FUNC_NDEV_FMT
1577                 SET_DEF_KEY_PARAM_FMT
1578                 SET_DEF_KEY_PARAM_FMT_2_6_38
1579                 "\n", FUNC_NDEV_ARG(ndev)
1580                 SET_DEF_KEY_PARAM_ARG
1581                 SET_DEF_KEY_PARAM_ARG_2_6_38
1582         );
1583
1584         if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) { /* set wep default key */
1585                 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1586
1587                 psecuritypriv->dot11PrivacyKeyIndex = key_index;
1588
1589                 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1590                 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1591                 if (psecuritypriv->dot11DefKeylen[key_index] == 13) {
1592                         psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1593                         psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1594                 }
1595
1596                 psecuritypriv->bWepDefaultKeyIdxSet = 1; /* set the flag to represent that wep default key has been set */
1597         }
1598
1599         return 0;
1600
1601 }
1602 #if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
1603 static int cfg80211_rtw_set_rekey_data(struct wiphy *wiphy,
1604         struct net_device *ndev,
1605         struct cfg80211_gtk_rekey_data *data)
1606 {
1607         /*int i;*/
1608         struct sta_info *psta;
1609         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1610         struct mlme_priv   *pmlmepriv = &padapter->mlmepriv;
1611         struct sta_priv *pstapriv = &padapter->stapriv;
1612         struct security_priv *psecuritypriv = &(padapter->securitypriv);
1613
1614         psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
1615         if (psta == NULL) {
1616                 RTW_INFO("%s, : Obtain Sta_info fail\n", __func__);
1617                 return -1;
1618         }
1619
1620         _rtw_memcpy(psta->kek, data->kek, NL80211_KEK_LEN);
1621         /*printk("\ncfg80211_rtw_set_rekey_data KEK:");
1622         for(i=0;i<NL80211_KEK_LEN; i++)
1623                 printk(" %02x ", psta->kek[i]);*/
1624         _rtw_memcpy(psta->kck, data->kck, NL80211_KCK_LEN);
1625         /*printk("\ncfg80211_rtw_set_rekey_data KCK:");
1626         for(i=0;i<NL80211_KCK_LEN; i++)
1627                 printk(" %02x ", psta->kck[i]);*/
1628         _rtw_memcpy(psta->replay_ctr, data->replay_ctr, NL80211_REPLAY_CTR_LEN);
1629         psecuritypriv->binstallKCK_KEK = _TRUE;
1630         /*printk("\nREPLAY_CTR: ");
1631         for(i=0;i<RTW_REPLAY_CTR_LEN; i++)
1632                 printk(" %02x ", psta->replay_ctr[i]);*/
1633
1634         return 0;
1635 }
1636 #endif /*CONFIG_GTK_OL*/
1637 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
1638         struct net_device *ndev,
1639 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
1640         u8 *mac,
1641 #else
1642         const u8 *mac,
1643 #endif
1644         struct station_info *sinfo)
1645 {
1646         int ret = 0;
1647         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1648         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1649         struct sta_info *psta = NULL;
1650         struct sta_priv *pstapriv = &padapter->stapriv;
1651
1652         sinfo->filled = 0;
1653
1654         if (!mac) {
1655                 RTW_INFO(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
1656                 ret = -ENOENT;
1657                 goto exit;
1658         }
1659
1660         psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
1661         if (psta == NULL) {
1662                 RTW_INFO("%s, sta_info is null\n", __func__);
1663                 ret = -ENOENT;
1664                 goto exit;
1665         }
1666
1667 #ifdef CONFIG_DEBUG_CFG80211
1668         RTW_INFO(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
1669 #endif
1670
1671         /* for infra./P2PClient mode */
1672         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
1673                 && check_fwstate(pmlmepriv, _FW_LINKED)
1674         ) {
1675                 struct wlan_network  *cur_network = &(pmlmepriv->cur_network);
1676
1677                 if (_rtw_memcmp((u8 *)mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) {
1678                         RTW_INFO("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
1679                         ret = -ENOENT;
1680                         goto exit;
1681                 }
1682
1683                 sinfo->filled |= STATION_INFO_SIGNAL;
1684                 sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
1685
1686                 sinfo->filled |= STATION_INFO_TX_BITRATE;
1687                 sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
1688
1689                 sinfo->filled |= STATION_INFO_RX_PACKETS;
1690                 sinfo->rx_packets = sta_rx_data_pkts(psta);
1691
1692                 sinfo->filled |= STATION_INFO_TX_PACKETS;
1693                 sinfo->tx_packets = psta->sta_stats.tx_pkts;
1694
1695         }
1696
1697         /* for Ad-Hoc/AP mode */
1698         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
1699                 || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
1700                 || check_fwstate(pmlmepriv, WIFI_AP_STATE))
1701                 && check_fwstate(pmlmepriv, _FW_LINKED)
1702         ) {
1703                 /* TODO: should acquire station info... */
1704         }
1705
1706 exit:
1707         return ret;
1708 }
1709
1710 extern int netdev_open(struct net_device *pnetdev);
1711
1712 #if 0
1713 enum nl80211_iftype {
1714         NL80211_IFTYPE_UNSPECIFIED,
1715         NL80211_IFTYPE_ADHOC, /* 1 */
1716         NL80211_IFTYPE_STATION, /* 2 */
1717         NL80211_IFTYPE_AP, /* 3 */
1718         NL80211_IFTYPE_AP_VLAN,
1719         NL80211_IFTYPE_WDS,
1720         NL80211_IFTYPE_MONITOR, /* 6 */
1721         NL80211_IFTYPE_MESH_POINT,
1722         NL80211_IFTYPE_P2P_CLIENT, /* 8 */
1723         NL80211_IFTYPE_P2P_GO, /* 9 */
1724         /* keep last */
1725         NUM_NL80211_IFTYPES,
1726         NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
1727 };
1728 #endif
1729 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
1730                                      struct net_device *ndev,
1731                                      enum nl80211_iftype type, u32 *flags,
1732                                      struct vif_params *params)
1733 {
1734         enum nl80211_iftype old_type;
1735         NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
1736         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1737         struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
1738         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
1739 #ifdef CONFIG_P2P
1740         struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1741         u8 is_p2p = _FALSE;
1742 #endif
1743         int ret = 0;
1744         u8 change = _FALSE;
1745
1746         RTW_INFO(FUNC_NDEV_FMT" type=%d\n", FUNC_NDEV_ARG(ndev), type);
1747
1748         if (adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE) {
1749                 ret = -EPERM;
1750                 goto exit;
1751         }
1752
1753
1754         RTW_INFO(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
1755         if (netdev_open(ndev) != 0) {
1756                 RTW_INFO(FUNC_NDEV_FMT" call netdev_open fail\n", FUNC_NDEV_ARG(ndev));
1757                 ret = -EPERM;
1758                 goto exit;
1759         }
1760
1761
1762         if (_FAIL == rtw_pwr_wakeup(padapter)) {
1763                 RTW_INFO(FUNC_NDEV_FMT" call rtw_pwr_wakeup fail\n", FUNC_NDEV_ARG(ndev));
1764                 ret = -EPERM;
1765                 goto exit;
1766         }
1767
1768         old_type = rtw_wdev->iftype;
1769         RTW_INFO(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
1770                 FUNC_NDEV_ARG(ndev), old_type, type);
1771
1772         if (old_type != type) {
1773                 change = _TRUE;
1774                 pmlmeext->action_public_rxseq = 0xffff;
1775                 pmlmeext->action_public_dialog_token = 0xff;
1776         }
1777
1778         /* initial default type */
1779         ndev->type = ARPHRD_ETHER;
1780
1781         switch (type) {
1782         case NL80211_IFTYPE_ADHOC:
1783                 networkType = Ndis802_11IBSS;
1784                 break;
1785
1786         #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
1787         case NL80211_IFTYPE_P2P_CLIENT:
1788                 is_p2p = _TRUE;
1789         #endif
1790         case NL80211_IFTYPE_STATION:
1791                 networkType = Ndis802_11Infrastructure;
1792
1793                 #ifdef CONFIG_P2P
1794                 if (change && pwdinfo->driver_interface == DRIVER_CFG80211) {
1795                         if (is_p2p == _TRUE)
1796                                 rtw_p2p_enable(padapter, P2P_ROLE_CLIENT);
1797                         #if !RTW_P2P_GROUP_INTERFACE
1798                         else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)
1799                                         || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
1800                         ) {
1801                                 /* it means remove GC/GO and change mode from GC/GO to station(P2P DEVICE) */
1802                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1803                         }
1804                         #endif
1805                 }
1806                 #endif /* CONFIG_P2P */
1807
1808                 break;
1809
1810         #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
1811         case NL80211_IFTYPE_P2P_GO:
1812                 is_p2p = _TRUE;
1813         #endif
1814         case NL80211_IFTYPE_AP:
1815                 networkType = Ndis802_11APMode;
1816
1817                 #ifdef CONFIG_P2P
1818                 if (change && pwdinfo->driver_interface == DRIVER_CFG80211) {
1819                         if (is_p2p == _TRUE)
1820                                 rtw_p2p_enable(padapter, P2P_ROLE_GO);
1821                         #if !RTW_P2P_GROUP_INTERFACE
1822                         else if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
1823                                 /* it means P2P Group created, we will be GO and change mode from  P2P DEVICE to AP(GO) */
1824                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1825                         }
1826                         #endif
1827                 }
1828                 #endif /* CONFIG_P2P */
1829
1830                 break;
1831
1832         case NL80211_IFTYPE_MONITOR:
1833                 networkType = Ndis802_11Monitor;
1834 #if 0
1835                 ndev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */
1836 #endif
1837                 ndev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */
1838                 break;
1839         default:
1840                 ret = -EOPNOTSUPP;
1841                 goto exit;
1842         }
1843
1844         rtw_wdev->iftype = type;
1845
1846         if (rtw_set_802_11_infrastructure_mode(padapter, networkType) == _FALSE) {
1847                 rtw_wdev->iftype = old_type;
1848                 ret = -EPERM;
1849                 goto exit;
1850         }
1851
1852         rtw_setopmode_cmd(padapter, networkType, _TRUE);
1853
1854 exit:
1855
1856         RTW_INFO(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret);
1857         return ret;
1858 }
1859
1860 void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted)
1861 {
1862         struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
1863         _irqL   irqL;
1864
1865         _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
1866         if (pwdev_priv->scan_request != NULL) {
1867                 #ifdef CONFIG_DEBUG_CFG80211
1868                 RTW_INFO("%s with scan req\n", __FUNCTION__);
1869                 #endif
1870
1871                 /* avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); */
1872                 if (pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
1873                         RTW_INFO("error wiphy compare\n");
1874                 else
1875                         cfg80211_scan_done(pwdev_priv->scan_request, aborted);
1876
1877                 pwdev_priv->scan_request = NULL;
1878         } else {
1879                 #ifdef CONFIG_DEBUG_CFG80211
1880                 RTW_INFO("%s without scan req\n", __FUNCTION__);
1881                 #endif
1882         }
1883         _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
1884 }
1885
1886 u32 rtw_cfg80211_wait_scan_req_empty(_adapter *adapter, u32 timeout_ms)
1887 {
1888         struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
1889         u8 empty = _FALSE;
1890         u32 start;
1891         u32 pass_ms;
1892
1893         start = rtw_get_current_time();
1894
1895         while (rtw_get_passing_time_ms(start) <= timeout_ms) {
1896
1897                 if (RTW_CANNOT_RUN(adapter))
1898                         break;
1899
1900                 if (!wdev_priv->scan_request) {
1901                         empty = _TRUE;
1902                         break;
1903                 }
1904
1905                 rtw_msleep_os(10);
1906         }
1907
1908         pass_ms = rtw_get_passing_time_ms(start);
1909
1910         if (empty == _FALSE && pass_ms > timeout_ms)
1911                 RTW_PRINT(FUNC_ADPT_FMT" pass_ms:%u, timeout\n"
1912                         , FUNC_ADPT_ARG(adapter), pass_ms);
1913
1914         return pass_ms;
1915 }
1916
1917 void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork)
1918 {
1919         struct wireless_dev *pwdev = padapter->rtw_wdev;
1920         struct wiphy *wiphy = pwdev->wiphy;
1921         struct cfg80211_bss *bss = NULL;
1922         WLAN_BSSID_EX select_network = pnetwork->network;
1923
1924         bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
1925                 select_network.MacAddress, select_network.Ssid.Ssid,
1926                 select_network.Ssid.SsidLength,
1927 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
1928                 select_network.InfrastructureMode == Ndis802_11Infrastructure?IEEE80211_BSS_TYPE_ESS:IEEE80211_BSS_TYPE_IBSS,
1929                 IEEE80211_PRIVACY(select_network.Privacy));
1930 #else
1931                 select_network.InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS,
1932                 select_network.InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS);
1933 #endif
1934
1935         if (bss) {
1936                 cfg80211_unlink_bss(wiphy, bss);
1937                 RTW_INFO("%s(): cfg80211_unlink %s!! () ", __func__, select_network.Ssid.Ssid);
1938 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
1939                 cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
1940 #else
1941                 cfg80211_put_bss(bss);
1942 #endif
1943         }
1944         return;
1945 }
1946
1947 /* if target wps scan ongoing, target_ssid is filled */
1948 int rtw_cfg80211_is_target_wps_scan(struct cfg80211_scan_request *scan_req, struct cfg80211_ssid *target_ssid)
1949 {
1950         int ret = 0;
1951
1952         if (scan_req->n_ssids != 1
1953                 || scan_req->ssids[0].ssid_len == 0
1954                 || scan_req->n_channels != 1
1955         )
1956                 goto exit;
1957
1958         /* under target WPS scan */
1959         _rtw_memcpy(target_ssid, scan_req->ssids, sizeof(struct cfg80211_ssid));
1960         ret = 1;
1961
1962 exit:
1963         return ret;
1964 }
1965
1966 static void _rtw_cfg80211_surveydone_event_callback(_adapter *padapter, struct cfg80211_scan_request *scan_req)
1967 {
1968         _irqL   irqL;
1969         _list                                   *plist, *phead;
1970         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
1971         _queue                          *queue  = &(pmlmepriv->scanned_queue);
1972         struct  wlan_network    *pnetwork = NULL;
1973         u32 cnt = 0;
1974         u32 wait_for_surveydone;
1975         sint wait_status;
1976         struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
1977         struct cfg80211_ssid target_ssid;
1978         u8 target_wps_scan = 0;
1979
1980 #ifdef CONFIG_DEBUG_CFG80211
1981         RTW_INFO("%s\n", __func__);
1982 #endif
1983
1984         if (scan_req)
1985                 target_wps_scan = rtw_cfg80211_is_target_wps_scan(scan_req, &target_ssid);
1986         else {
1987                 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
1988                 if (pwdev_priv->scan_request != NULL)
1989                         target_wps_scan = rtw_cfg80211_is_target_wps_scan(pwdev_priv->scan_request, &target_ssid);
1990                 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
1991         }
1992
1993         _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1994
1995         phead = get_list_head(queue);
1996         plist = get_next(phead);
1997
1998         while (1) {
1999                 if (rtw_end_of_queue_search(phead, plist) == _TRUE)
2000                         break;
2001
2002                 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2003
2004                 /* report network only if the current channel set contains the channel to which this network belongs */
2005                 if (rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
2006                         && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
2007                         && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
2008                 ) {
2009                         if (target_wps_scan)
2010                                 rtw_cfg80211_clear_wps_sr_of_non_target_bss(padapter, pnetwork, &target_ssid);
2011                         rtw_cfg80211_inform_bss(padapter, pnetwork);
2012                 }
2013 #if 0
2014                 /* check ralink testbed RSN IE length */
2015                 {
2016                         if (_rtw_memcmp(pnetwork->network.Ssid.Ssid, "Ralink_11n_AP", 13)) {
2017                                 uint ie_len = 0;
2018                                 u8 *p = NULL;
2019                                 p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
2020                                 RTW_INFO("ie_len=%d\n", ie_len);
2021                         }
2022                 }
2023 #endif
2024                 plist = get_next(plist);
2025
2026         }
2027
2028         _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2029 }
2030
2031 inline void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
2032 {
2033         _rtw_cfg80211_surveydone_event_callback(padapter, NULL);
2034 }
2035
2036 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
2037 {
2038         int ret = 0;
2039         uint wps_ielen = 0;
2040         u8 *wps_ie;
2041         u32     p2p_ielen = 0;
2042         u8 *p2p_ie;
2043         u32     wfd_ielen = 0;
2044         u8 *wfd_ie;
2045         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2046
2047 #ifdef CONFIG_DEBUG_CFG80211
2048         RTW_INFO("%s, ielen=%d\n", __func__, len);
2049 #endif
2050
2051         if (len > 0) {
2052                 wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen);
2053                 if (wps_ie) {
2054                         #ifdef CONFIG_DEBUG_CFG80211
2055                         RTW_INFO("probe_req_wps_ielen=%d\n", wps_ielen);
2056                         #endif
2057
2058                         if (pmlmepriv->wps_probe_req_ie) {
2059                                 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
2060                                 pmlmepriv->wps_probe_req_ie_len = 0;
2061                                 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
2062                                 pmlmepriv->wps_probe_req_ie = NULL;
2063                         }
2064
2065                         pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
2066                         if (pmlmepriv->wps_probe_req_ie == NULL) {
2067                                 RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
2068                                 return -EINVAL;
2069
2070                         }
2071                         _rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
2072                         pmlmepriv->wps_probe_req_ie_len = wps_ielen;
2073                 }
2074
2075                 /* buf += wps_ielen; */
2076                 /* len -= wps_ielen; */
2077
2078                 #ifdef CONFIG_P2P
2079                 p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen);
2080                 if (p2p_ie) {
2081                         struct wifidirect_info *wdinfo = &padapter->wdinfo;
2082                         u32 attr_contentlen = 0;
2083                         u8 listen_ch_attr[5];
2084
2085                         #ifdef CONFIG_DEBUG_CFG80211
2086                         RTW_INFO("probe_req_p2p_ielen=%d\n", p2p_ielen);
2087                         #endif
2088
2089                         if (pmlmepriv->p2p_probe_req_ie) {
2090                                 u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
2091                                 pmlmepriv->p2p_probe_req_ie_len = 0;
2092                                 rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len);
2093                                 pmlmepriv->p2p_probe_req_ie = NULL;
2094                         }
2095
2096                         pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen);
2097                         if (pmlmepriv->p2p_probe_req_ie == NULL) {
2098                                 RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
2099                                 return -EINVAL;
2100
2101                         }
2102                         _rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
2103                         pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
2104
2105                         if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8 *)listen_ch_attr, (uint *) &attr_contentlen)
2106                                 && attr_contentlen == 5) {
2107                                 if (wdinfo->listen_channel !=  listen_ch_attr[4]) {
2108                                         RTW_INFO(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n",
2109                                                 FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2],
2110                                                 listen_ch_attr[3], listen_ch_attr[4]);
2111                                         wdinfo->listen_channel = listen_ch_attr[4];
2112                                 }
2113                         }
2114                 }
2115                 #endif /* CONFIG_P2P */
2116
2117                 #ifdef CONFIG_WFD
2118                 wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen);
2119                 if (wfd_ie) {
2120                         #ifdef CONFIG_DEBUG_CFG80211
2121                         RTW_INFO("probe_req_wfd_ielen=%d\n", wfd_ielen);
2122                         #endif
2123
2124                         if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_REQ_IE, wfd_ie, wfd_ielen) != _SUCCESS)
2125                                 return -EINVAL;
2126                 }
2127                 #endif /* CONFIG_WFD */
2128         }
2129
2130         return ret;
2131
2132 }
2133
2134 #ifdef CONFIG_CONCURRENT_MODE
2135 u8 rtw_cfg80211_scan_via_buddy(_adapter *padapter, struct cfg80211_scan_request *request)
2136 {
2137         int i;
2138         u8 ret = _FALSE;
2139         _adapter *iface = NULL;
2140         _irqL   irqL;
2141         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
2142         struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
2143         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2144
2145         for (i = 0; i < dvobj->iface_nums; i++) {
2146                 struct mlme_priv *buddy_mlmepriv;
2147                 struct rtw_wdev_priv *buddy_wdev_priv;
2148
2149                 iface = dvobj->padapters[i];
2150                 if (iface == NULL)
2151                         continue;
2152
2153                 if (iface == padapter)
2154                         continue;
2155
2156                 if (rtw_is_adapter_up(iface) == _FALSE)
2157                         continue;
2158
2159                 buddy_mlmepriv = &iface->mlmepriv;
2160                 if (!check_fwstate(buddy_mlmepriv, _FW_UNDER_SURVEY))
2161                         continue;
2162
2163                 buddy_wdev_priv = adapter_wdev_data(iface);
2164                 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2165                 _enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
2166                 if (buddy_wdev_priv->scan_request) {
2167                         pmlmepriv->scanning_via_buddy_intf = _TRUE;
2168                         _enter_critical_bh(&pmlmepriv->lock, &irqL);
2169                         set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
2170                         _exit_critical_bh(&pmlmepriv->lock, &irqL);
2171                         pwdev_priv->scan_request = request;
2172                         ret = _TRUE;
2173                 }
2174                 _exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
2175                 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2176
2177                 if (ret == _TRUE)
2178                         goto exit;
2179         }
2180
2181 exit:
2182         return ret;
2183 }
2184
2185 void rtw_cfg80211_indicate_scan_done_for_buddy(_adapter *padapter, bool bscan_aborted)
2186 {
2187         int i;
2188         u8 ret = 0;
2189         _adapter *iface = NULL;
2190         _irqL   irqL;
2191         struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
2192         struct mlme_priv *mlmepriv;
2193         struct rtw_wdev_priv *wdev_priv;
2194         bool indicate_buddy_scan;
2195
2196         for (i = 0; i < dvobj->iface_nums; i++) {
2197                 iface = dvobj->padapters[i];
2198                 if ((iface) && rtw_is_adapter_up(iface)) {
2199
2200                         if (iface == padapter)
2201                                 continue;
2202
2203                         mlmepriv = &(iface->mlmepriv);
2204                         wdev_priv = adapter_wdev_data(iface);
2205
2206                         indicate_buddy_scan = _FALSE;
2207                         _enter_critical_bh(&wdev_priv->scan_req_lock, &irqL);
2208                         if (wdev_priv->scan_request && mlmepriv->scanning_via_buddy_intf == _TRUE) {
2209                                 mlmepriv->scanning_via_buddy_intf = _FALSE;
2210                                 clr_fwstate(mlmepriv, _FW_UNDER_SURVEY);
2211                                 indicate_buddy_scan = _TRUE;
2212                         }
2213                         _exit_critical_bh(&wdev_priv->scan_req_lock, &irqL);
2214
2215                         if (indicate_buddy_scan == _TRUE) {
2216                                 rtw_cfg80211_surveydone_event_callback(iface);
2217                                 rtw_indicate_scan_done(iface, bscan_aborted);
2218                         }
2219
2220                 }
2221         }
2222 }
2223 #endif /* CONFIG_CONCURRENT_MODE */
2224
2225 static int cfg80211_rtw_scan(struct wiphy *wiphy
2226         #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
2227         , struct net_device *ndev
2228         #endif
2229         , struct cfg80211_scan_request *request)
2230 {
2231         int i, chan_num = 0;
2232         u8 _status = _FALSE;
2233         int ret = 0;
2234         NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
2235         struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
2236         struct rtw_ieee80211_channel *pch;
2237         _irqL   irqL;
2238         u8 *wps_ie = NULL;
2239         uint wps_ielen = 0;
2240         u8 *p2p_ie = NULL;
2241         uint p2p_ielen = 0;
2242         u8 survey_times = 3;
2243         u8 survey_times_for_one_ch = 6;
2244         struct cfg80211_ssid *ssids = request->ssids;
2245         int social_channel = 0, j = 0;
2246         bool need_indicate_scan_done = _FALSE;
2247         bool ps_denied = _FALSE;
2248
2249         _adapter *padapter;
2250         struct wireless_dev *wdev;
2251         struct rtw_wdev_priv *pwdev_priv;
2252         struct mlme_priv *pmlmepriv;
2253 #ifdef CONFIG_P2P
2254         struct wifidirect_info *pwdinfo;
2255 #endif /* CONFIG_P2P */
2256
2257 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2258         wdev = request->wdev;
2259         #if defined(RTW_DEDICATED_P2P_DEVICE)
2260         if (wdev == wiphy_to_pd_wdev(wiphy))
2261                 padapter = wiphy_to_adapter(wiphy);
2262         else
2263         #endif
2264         if (wdev_to_ndev(wdev))
2265                 padapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
2266         else {
2267                 ret = -EINVAL;
2268                 goto exit;
2269         }
2270 #else
2271         if (ndev == NULL) {
2272                 ret = -EINVAL;
2273                 goto exit;
2274         }
2275         padapter = (_adapter *)rtw_netdev_priv(ndev);
2276         wdev = ndev_to_wdev(ndev);
2277 #endif
2278
2279         pwdev_priv = adapter_wdev_data(padapter);
2280         pmlmepriv = &padapter->mlmepriv;
2281 #ifdef CONFIG_P2P
2282         pwdinfo = &(padapter->wdinfo);
2283 #endif /* CONFIG_P2P */
2284
2285         RTW_INFO(FUNC_ADPT_FMT"%s\n", FUNC_ADPT_ARG(padapter)
2286                 , wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : "");
2287
2288 #ifdef CONFIG_MP_INCLUDED
2289         if (rtw_mi_mp_mode_check(padapter)) {
2290                 RTW_INFO("MP mode block Scan request\n");
2291                 ret = -EPERM;
2292                 goto exit;
2293         }
2294 #endif
2295
2296         if (adapter_wdev_data(padapter)->block_scan == _TRUE) {
2297                 RTW_INFO(FUNC_ADPT_FMT" wdev_priv.block_scan is set\n", FUNC_ADPT_ARG(padapter));
2298                 need_indicate_scan_done = _TRUE;
2299                 goto check_need_indicate_scan_done;
2300         }
2301
2302         rtw_ps_deny(padapter, PS_DENY_SCAN);
2303         ps_denied = _TRUE;
2304         if (_FAIL == rtw_pwr_wakeup(padapter)) {
2305                 need_indicate_scan_done = _TRUE;
2306                 goto check_need_indicate_scan_done;
2307         }
2308
2309 #ifdef CONFIG_P2P
2310         if (pwdinfo->driver_interface == DRIVER_CFG80211) {
2311                 if (ssids->ssid != NULL
2312                         && _rtw_memcmp(ssids->ssid, "DIRECT-", 7)
2313                         && rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
2314                 ) {
2315                         if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2316                                 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
2317                         else {
2318                                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
2319                                 #ifdef CONFIG_DEBUG_CFG80211
2320                                 RTW_INFO("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
2321                                 #endif
2322                         }
2323                         rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
2324
2325                         if (request->n_channels == 3 &&
2326                                 request->channels[0]->hw_value == 1 &&
2327                                 request->channels[1]->hw_value == 6 &&
2328                                 request->channels[2]->hw_value == 11
2329                         )
2330                                 social_channel = 1;
2331                 }
2332         }
2333 #endif /*CONFIG_P2P*/
2334
2335         if (request->ie && request->ie_len > 0)
2336                 rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len);
2337
2338         if (rtw_is_scan_deny(padapter)) {
2339                 RTW_INFO(FUNC_ADPT_FMT  ": scan deny\n", FUNC_ADPT_ARG(padapter));
2340                 need_indicate_scan_done = _TRUE;
2341                 goto check_need_indicate_scan_done;
2342         }
2343
2344         /* check fw state*/
2345         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
2346
2347 #ifdef CONFIG_DEBUG_CFG80211
2348                 RTW_INFO(FUNC_ADPT_FMT" under WIFI_AP_STATE\n", FUNC_ADPT_ARG(padapter));
2349 #endif
2350
2351                 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS | _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) {
2352                         RTW_INFO("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
2353
2354                         if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
2355                                 RTW_INFO("AP mode process WPS\n");
2356
2357                         need_indicate_scan_done = _TRUE;
2358                         goto check_need_indicate_scan_done;
2359                 }
2360         }
2361
2362         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
2363                 RTW_INFO("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
2364                 need_indicate_scan_done = _TRUE;
2365                 goto check_need_indicate_scan_done;
2366         } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
2367                 RTW_INFO("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
2368                 ret = -EBUSY;
2369                 goto check_need_indicate_scan_done;
2370         }
2371
2372 #ifdef CONFIG_CONCURRENT_MODE
2373         if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING | WIFI_UNDER_WPS)) {
2374                 RTW_INFO("%s exit due to buddy_intf's mlme state under linking or wps\n", __func__);
2375                 need_indicate_scan_done = _TRUE;
2376                 goto check_need_indicate_scan_done;
2377
2378         } else if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_SURVEY)) {
2379                 bool scan_via_buddy = rtw_cfg80211_scan_via_buddy(padapter, request);
2380
2381                 if (scan_via_buddy == _FALSE)
2382                         need_indicate_scan_done = _TRUE;
2383
2384                 goto check_need_indicate_scan_done;
2385         }
2386 #endif /* CONFIG_CONCURRENT_MODE */
2387
2388         /* busy traffic check*/
2389         if (rtw_mi_busy_traffic_check(padapter, _TRUE)) {
2390                 need_indicate_scan_done = _TRUE;
2391                 goto check_need_indicate_scan_done;
2392         }
2393
2394 #ifdef CONFIG_P2P
2395         if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
2396                 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
2397                 rtw_free_network_queue(padapter, _TRUE);
2398
2399                 if (social_channel == 0)
2400                         rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
2401                 else
2402                         rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
2403         }
2404 #endif /* CONFIG_P2P */
2405
2406
2407         _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID) * RTW_SSID_SCAN_AMOUNT);
2408         /* parsing request ssids, n_ssids */
2409         for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
2410                 #ifdef CONFIG_DEBUG_CFG80211
2411                 RTW_INFO("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
2412                 #endif
2413                 _rtw_memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
2414                 ssid[i].SsidLength = ssids[i].ssid_len;
2415         }
2416
2417         /* parsing channels, n_channels */
2418         _rtw_memset(ch, 0, sizeof(struct rtw_ieee80211_channel) * RTW_CHANNEL_SCAN_AMOUNT);
2419         for (i = 0; i < request->n_channels && i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
2420                 #ifdef CONFIG_DEBUG_CFG80211
2421                 RTW_INFO(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
2422                 #endif
2423                 ch[i].hw_value = request->channels[i]->hw_value;
2424                 ch[i].flags = request->channels[i]->flags;
2425         }
2426
2427         if (request->n_channels == 1) {
2428                 for (i = 1; i < survey_times_for_one_ch; i++)
2429                         _rtw_memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
2430                 pch = ch;
2431                 chan_num = survey_times_for_one_ch;
2432         } else if (request->n_channels <= 4) {
2433                 for (j = request->n_channels - 1; j >= 0; j--)
2434                         for (i = 0; i < survey_times; i++)
2435                                 _rtw_memcpy(&ch[j * survey_times + i], &ch[j], sizeof(struct rtw_ieee80211_channel));
2436                 pch = ch;
2437                 chan_num = survey_times * request->n_channels;
2438         } else {
2439                 pch = ch;
2440                 chan_num = request->n_channels;
2441         }
2442
2443         _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2444         _enter_critical_bh(&pmlmepriv->lock, &irqL);
2445         _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, pch, chan_num);
2446         if (_status == _SUCCESS)
2447                 pwdev_priv->scan_request = request;
2448         else
2449                 ret = -1;
2450         _exit_critical_bh(&pmlmepriv->lock, &irqL);
2451         _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2452
2453 check_need_indicate_scan_done:
2454         if (_TRUE == need_indicate_scan_done) {
2455                 _rtw_cfg80211_surveydone_event_callback(padapter, request);
2456                 cfg80211_scan_done(request, 0);
2457         }
2458
2459 cancel_ps_deny:
2460         if (ps_denied == _TRUE)
2461                 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
2462
2463 exit:
2464         return ret;
2465
2466 }
2467
2468 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
2469 {
2470 #if 0
2471         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2472
2473         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
2474             (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
2475                 int ret;
2476
2477                 iwm->conf.rts_threshold = wiphy->rts_threshold;
2478
2479                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
2480                                 CFG_RTS_THRESHOLD,
2481                                 iwm->conf.rts_threshold);
2482                 if (ret < 0)
2483                         return ret;
2484         }
2485
2486         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
2487             (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
2488                 int ret;
2489
2490                 iwm->conf.frag_threshold = wiphy->frag_threshold;
2491
2492                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
2493                                 CFG_FRAG_THRESHOLD,
2494                                 iwm->conf.frag_threshold);
2495                 if (ret < 0)
2496                         return ret;
2497         }
2498 #endif
2499         RTW_INFO("%s\n", __func__);
2500         return 0;
2501 }
2502
2503
2504
2505 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
2506 {
2507         RTW_INFO("%s, wpa_version=%d\n", __func__, wpa_version);
2508
2509         if (!wpa_version) {
2510                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2511                 return 0;
2512         }
2513
2514
2515         if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
2516                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
2517
2518 #if 0
2519         if (wpa_version & NL80211_WPA_VERSION_2)
2520                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2521 #endif
2522
2523         #ifdef CONFIG_WAPI_SUPPORT
2524         if (wpa_version & NL80211_WAPI_VERSION_1)
2525                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWAPI;
2526         #endif
2527
2528         return 0;
2529
2530 }
2531
2532 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
2533                 enum nl80211_auth_type sme_auth_type)
2534 {
2535         RTW_INFO("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
2536
2537
2538         switch (sme_auth_type) {
2539         case NL80211_AUTHTYPE_AUTOMATIC:
2540
2541                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2542
2543                 break;
2544         case NL80211_AUTHTYPE_OPEN_SYSTEM:
2545
2546                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2547
2548                 if (psecuritypriv->ndisauthtype > Ndis802_11AuthModeWPA)
2549                         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2550
2551 #ifdef CONFIG_WAPI_SUPPORT
2552                 if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI)
2553                         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
2554 #endif
2555
2556                 break;
2557         case NL80211_AUTHTYPE_SHARED_KEY:
2558
2559                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
2560
2561                 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
2562
2563
2564                 break;
2565         default:
2566                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2567                 /* return -ENOTSUPP; */
2568         }
2569
2570         return 0;
2571
2572 }
2573
2574 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
2575 {
2576         u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
2577
2578         u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
2579                 &psecuritypriv->dot118021XGrpPrivacy;
2580
2581         RTW_INFO("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
2582
2583
2584         if (!cipher) {
2585                 *profile_cipher = _NO_PRIVACY_;
2586                 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
2587                 return 0;
2588         }
2589
2590         switch (cipher) {
2591         case IW_AUTH_CIPHER_NONE:
2592                 *profile_cipher = _NO_PRIVACY_;
2593                 ndisencryptstatus = Ndis802_11EncryptionDisabled;
2594 #ifdef CONFIG_WAPI_SUPPORT
2595                 if (psecuritypriv->dot11PrivacyAlgrthm == _SMS4_)
2596                         *profile_cipher = _SMS4_;
2597 #endif
2598                 break;
2599         case WLAN_CIPHER_SUITE_WEP40:
2600                 *profile_cipher = _WEP40_;
2601                 ndisencryptstatus = Ndis802_11Encryption1Enabled;
2602                 break;
2603         case WLAN_CIPHER_SUITE_WEP104:
2604                 *profile_cipher = _WEP104_;
2605                 ndisencryptstatus = Ndis802_11Encryption1Enabled;
2606                 break;
2607         case WLAN_CIPHER_SUITE_TKIP:
2608                 *profile_cipher = _TKIP_;
2609                 ndisencryptstatus = Ndis802_11Encryption2Enabled;
2610                 break;
2611         case WLAN_CIPHER_SUITE_CCMP:
2612                 *profile_cipher = _AES_;
2613                 ndisencryptstatus = Ndis802_11Encryption3Enabled;
2614                 break;
2615 #ifdef CONFIG_WAPI_SUPPORT
2616         case WLAN_CIPHER_SUITE_SMS4:
2617                 *profile_cipher = _SMS4_;
2618                 ndisencryptstatus = Ndis802_11_EncrypteionWAPI;
2619                 break;
2620 #endif
2621         default:
2622                 RTW_INFO("Unsupported cipher: 0x%x\n", cipher);
2623                 return -ENOTSUPP;
2624         }
2625
2626         if (ucast) {
2627                 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
2628
2629                 /* if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_) */
2630                 /*      psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; */
2631         }
2632
2633         return 0;
2634 }
2635
2636 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
2637 {
2638         RTW_INFO("%s, key_mgt=0x%x\n", __func__, key_mgt);
2639
2640         if (key_mgt == WLAN_AKM_SUITE_8021X) {
2641                 /* *auth_type = UMAC_AUTH_TYPE_8021X; */
2642                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2643                 psecuritypriv->rsn_akm_suite_type = 1;
2644         } else if (key_mgt == WLAN_AKM_SUITE_PSK) {
2645                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2646                 psecuritypriv->rsn_akm_suite_type = 2;
2647         }
2648 #ifdef CONFIG_WAPI_SUPPORT
2649         else if (key_mgt == WLAN_AKM_SUITE_WAPI_PSK)
2650                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
2651         else if (key_mgt == WLAN_AKM_SUITE_WAPI_CERT)
2652                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
2653 #endif
2654 #ifdef CONFIG_RTW_80211R
2655         else if (key_mgt == WLAN_AKM_SUITE_FT_8021X) {
2656                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2657                 psecuritypriv->rsn_akm_suite_type = 3;
2658         } else if (key_mgt == WLAN_AKM_SUITE_FT_PSK) {
2659                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2660                 psecuritypriv->rsn_akm_suite_type = 4;
2661         }
2662 #endif
2663         else {
2664                 RTW_INFO("Invalid key mgt: 0x%x\n", key_mgt);
2665                 /* return -EINVAL; */
2666         }
2667
2668         return 0;
2669 }
2670
2671 static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
2672 {
2673         u8 *buf = NULL, *pos = NULL;
2674         u32 left;
2675         int group_cipher = 0, pairwise_cipher = 0;
2676         int ret = 0;
2677         int wpa_ielen = 0;
2678         int wpa2_ielen = 0;
2679         u8 *pwpa, *pwpa2;
2680         u8 null_addr[] = {0, 0, 0, 0, 0, 0};
2681
2682         if (pie == NULL || !ielen) {
2683                 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
2684                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2685                 goto exit;
2686         }
2687
2688         if (ielen > MAX_WPA_IE_LEN + MAX_WPS_IE_LEN + MAX_P2P_IE_LEN) {
2689                 ret = -EINVAL;
2690                 goto exit;
2691         }
2692
2693         buf = rtw_zmalloc(ielen);
2694         if (buf == NULL) {
2695                 ret =  -ENOMEM;
2696                 goto exit;
2697         }
2698
2699         _rtw_memcpy(buf, pie , ielen);
2700
2701         /* dump */
2702         {
2703                 int i;
2704                 RTW_INFO("set wpa_ie(length:%zu):\n", ielen);
2705                 for (i = 0; i < ielen; i = i + 8)
2706                         RTW_INFO("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]);
2707         }
2708
2709         pos = buf;
2710         if (ielen < RSN_HEADER_LEN) {
2711                 ret  = -1;
2712                 goto exit;
2713         }
2714
2715         pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
2716         if (pwpa && wpa_ielen > 0) {
2717                 if (rtw_parse_wpa_ie(pwpa, wpa_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
2718                         padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2719                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
2720                         _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen + 2);
2721
2722                         RTW_INFO("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
2723                 }
2724         }
2725
2726         pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
2727         if (pwpa2 && wpa2_ielen > 0) {
2728                 if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
2729                         padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2730                         padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2731                         _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen + 2);
2732
2733                         RTW_INFO("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
2734                 }
2735         }
2736
2737         if (group_cipher == 0)
2738                 group_cipher = WPA_CIPHER_NONE;
2739         if (pairwise_cipher == 0)
2740                 pairwise_cipher = WPA_CIPHER_NONE;
2741
2742         switch (group_cipher) {
2743         case WPA_CIPHER_NONE:
2744                 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
2745                 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
2746                 break;
2747         case WPA_CIPHER_WEP40:
2748                 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
2749                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2750                 break;
2751         case WPA_CIPHER_TKIP:
2752                 padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
2753                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
2754                 break;
2755         case WPA_CIPHER_CCMP:
2756                 padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
2757                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
2758                 break;
2759         case WPA_CIPHER_WEP104:
2760                 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
2761                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2762                 break;
2763         }
2764
2765         switch (pairwise_cipher) {
2766         case WPA_CIPHER_NONE:
2767                 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2768                 padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
2769                 break;
2770         case WPA_CIPHER_WEP40:
2771                 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
2772                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2773                 break;
2774         case WPA_CIPHER_TKIP:
2775                 padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
2776                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
2777                 break;
2778         case WPA_CIPHER_CCMP:
2779                 padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
2780                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
2781                 break;
2782         case WPA_CIPHER_WEP104:
2783                 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
2784                 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2785                 break;
2786         }
2787
2788         {/* handle wps_ie */
2789                 uint wps_ielen;
2790                 u8 *wps_ie;
2791
2792                 wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
2793                 if (wps_ie && wps_ielen > 0) {
2794                         RTW_INFO("got wps_ie, wps_ielen:%u\n", wps_ielen);
2795                         padapter->securitypriv.wps_ie_len = wps_ielen < MAX_WPS_IE_LEN ? wps_ielen : MAX_WPS_IE_LEN;
2796                         _rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
2797                         set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
2798                 } else
2799                         _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2800         }
2801
2802         #ifdef CONFIG_P2P
2803         {/* check p2p_ie for assoc req; */
2804                 uint p2p_ielen = 0;
2805                 u8 *p2p_ie;
2806                 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2807
2808                 p2p_ie = rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen);
2809                 if (p2p_ie) {
2810                         #ifdef CONFIG_DEBUG_CFG80211
2811                         RTW_INFO("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
2812                         #endif
2813
2814                         if (pmlmepriv->p2p_assoc_req_ie) {
2815                                 u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
2816                                 pmlmepriv->p2p_assoc_req_ie_len = 0;
2817                                 rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
2818                                 pmlmepriv->p2p_assoc_req_ie = NULL;
2819                         }
2820
2821                         pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
2822                         if (pmlmepriv->p2p_assoc_req_ie == NULL) {
2823                                 RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
2824                                 goto exit;
2825                         }
2826                         _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
2827                         pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
2828                 }
2829         }
2830         #endif /* CONFIG_P2P */
2831
2832         #ifdef CONFIG_WFD
2833         {
2834                 uint wfd_ielen = 0;
2835                 u8 *wfd_ie;
2836                 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2837
2838                 wfd_ie = rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen);
2839                 if (wfd_ie) {
2840                         #ifdef CONFIG_DEBUG_CFG80211
2841                         RTW_INFO("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
2842                         #endif
2843
2844                         if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_REQ_IE, wfd_ie, wfd_ielen) != _SUCCESS)
2845                                 goto exit;
2846                 }
2847         }
2848         #endif /* CONFIG_WFD */
2849
2850         /* TKIP and AES disallow multicast packets until installing group key */
2851         if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
2852                 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
2853                 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
2854                 /* WPS open need to enable multicast */
2855                 /* || check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) */
2856                 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
2857
2858
2859 exit:
2860         if (buf)
2861                 rtw_mfree(buf, ielen);
2862         if (ret)
2863                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2864
2865         return ret;
2866 }
2867
2868 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
2869                                   struct cfg80211_ibss_params *params)
2870 {
2871         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
2872         NDIS_802_11_SSID ndis_ssid;
2873         struct security_priv *psecuritypriv = &padapter->securitypriv;
2874         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2875         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2876         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2877         WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
2878 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
2879         struct cfg80211_chan_def *pch_def;
2880 #endif
2881         struct ieee80211_channel *pch;
2882         int ret = 0;
2883
2884 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
2885         pch_def = (struct cfg80211_chan_def *)(&params->chandef);
2886         pch = (struct ieee80211_channel *) pch_def->chan;
2887 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
2888         pch = (struct ieee80211_channel *)(params->channel);
2889 #endif
2890
2891         if (!params->ssid || !params->ssid_len) {
2892                 ret = -EINVAL;
2893                 goto exit;
2894         }
2895
2896         if (params->ssid_len > IW_ESSID_MAX_SIZE) {
2897                 ret = -E2BIG;
2898                 goto exit;
2899         }
2900
2901         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2902                 ret = -EPERM;
2903                 goto exit;
2904         }
2905
2906         rtw_ps_deny(padapter, PS_DENY_JOIN);
2907         if (_FAIL == rtw_pwr_wakeup(padapter)) {
2908                 ret = -EPERM;
2909                 goto cancel_ps_deny;
2910         }
2911
2912 #ifdef CONFIG_CONCURRENT_MODE
2913         if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING)) {
2914                 RTW_INFO("%s, but buddy_intf is under linking\n", __FUNCTION__);
2915                 ret = -EINVAL;
2916                 goto cancel_ps_deny;
2917         }
2918         rtw_mi_buddy_scan_abort(padapter, _TRUE); /* OR rtw_mi_scan_abort(padapter, _TRUE);*/
2919 #endif /*CONFIG_CONCURRENT_MODE*/
2920
2921
2922         _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
2923         ndis_ssid.SsidLength = params->ssid_len;
2924         _rtw_memcpy(ndis_ssid.Ssid, (u8 *)params->ssid, params->ssid_len);
2925
2926         /* RTW_INFO("ssid=%s, len=%zu\n", ndis_ssid.Ssid, params->ssid_len); */
2927
2928         psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
2929         psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
2930         psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2931         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
2932         psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2933
2934         ret = rtw_cfg80211_set_auth_type(psecuritypriv, NL80211_AUTHTYPE_OPEN_SYSTEM);
2935         rtw_set_802_11_authentication_mode(padapter, psecuritypriv->ndisauthtype);
2936
2937         RTW_INFO("%s: center_freq = %d\n", __func__, pch->center_freq);
2938         pmlmeext->cur_channel = rtw_freq2ch(pch->center_freq);
2939
2940         if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
2941                 ret = -1;
2942                 goto cancel_ps_deny;
2943         }
2944
2945 cancel_ps_deny:
2946         rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2947 exit:
2948         return ret;
2949 }
2950
2951 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
2952 {
2953         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
2954         struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
2955         enum nl80211_iftype old_type;
2956         int ret = 0;
2957
2958         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2959
2960         #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
2961         padapter->mlmepriv.not_indic_disco = _TRUE;
2962         #endif
2963
2964         old_type = rtw_wdev->iftype;
2965
2966         rtw_set_to_roam(padapter, 0);
2967
2968         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
2969                 rtw_scan_abort(padapter);
2970                 LeaveAllPowerSaveMode(padapter);
2971
2972                 rtw_wdev->iftype = NL80211_IFTYPE_STATION;
2973
2974                 if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) == _FALSE) {
2975                         rtw_wdev->iftype = old_type;
2976                         ret = -EPERM;
2977                         goto leave_ibss;
2978                 }
2979                 rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure, _TRUE);
2980         }
2981
2982 leave_ibss:
2983         #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
2984         padapter->mlmepriv.not_indic_disco = _FALSE;
2985         #endif
2986
2987         return 0;
2988 }
2989
2990 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
2991                                 struct cfg80211_connect_params *sme)
2992 {
2993         int ret = 0;
2994         _irqL irqL;
2995         _list *phead;
2996         struct wlan_network *pnetwork = NULL;
2997         NDIS_802_11_AUTHENTICATION_MODE authmode;
2998         NDIS_802_11_SSID ndis_ssid;
2999         u8 *dst_ssid, *src_ssid;
3000         u8 *dst_bssid, *src_bssid;
3001         /* u8 matched_by_bssid=_FALSE; */
3002         /* u8 matched_by_ssid=_FALSE; */
3003         u8 matched = _FALSE;
3004         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3005         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3006         struct security_priv *psecuritypriv = &padapter->securitypriv;
3007         _queue *queue = &pmlmepriv->scanned_queue;
3008
3009 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
3010         padapter->mlmepriv.not_indic_disco = _TRUE;
3011 #endif
3012
3013         RTW_INFO("=>"FUNC_NDEV_FMT" - Start to Connection\n", FUNC_NDEV_ARG(ndev));
3014         RTW_INFO("privacy=%d, key=%p, key_len=%d, key_idx=%d, auth_type=%d\n",
3015                 sme->privacy, sme->key, sme->key_len, sme->key_idx, sme->auth_type);
3016
3017
3018         if (adapter_wdev_data(padapter)->block == _TRUE) {
3019                 ret = -EBUSY;
3020                 RTW_INFO("%s wdev_priv.block is set\n", __FUNCTION__);
3021                 goto exit;
3022         }
3023
3024 #ifdef CONFIG_PLATFORM_MSTAR_SCAN_BEFORE_CONNECT
3025         printk("MStar Android!\n");
3026         if (adapter_wdev_data(padapter)->bandroid_scan == _FALSE) {
3027 #ifdef CONFIG_P2P
3028                 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3029                 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3030 #endif /* CONFIG_P2P */
3031                 {
3032                         ret = -EBUSY;
3033                         printk("Android hasn't attached yet!\n");
3034                         goto exit;
3035                 }
3036         }
3037 #endif
3038
3039         if (!sme->ssid || !sme->ssid_len) {
3040                 ret = -EINVAL;
3041                 goto exit;
3042         }
3043
3044         if (sme->ssid_len > IW_ESSID_MAX_SIZE) {
3045                 ret = -E2BIG;
3046                 goto exit;
3047         }
3048
3049         rtw_ps_deny(padapter, PS_DENY_JOIN);
3050         if (_FAIL == rtw_pwr_wakeup(padapter)) {
3051                 ret = -EPERM;
3052                 goto cancel_ps_deny;
3053         }
3054
3055         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
3056                 ret = -EPERM;
3057                 goto cancel_ps_deny;
3058         }
3059
3060         if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
3061                 ret = -EBUSY;
3062                 RTW_INFO("%s, fw_state=0x%x, goto exit\n", __func__, pmlmepriv->fw_state);
3063                 goto cancel_ps_deny;
3064         }
3065
3066 #ifdef CONFIG_CONCURRENT_MODE
3067         if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING)) {
3068                 ret = -EINVAL;
3069                 goto cancel_ps_deny;
3070         }
3071 #endif
3072
3073         rtw_mi_scan_abort(padapter, _TRUE);
3074
3075         _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
3076         ndis_ssid.SsidLength = sme->ssid_len;
3077         _rtw_memcpy(ndis_ssid.Ssid, (u8 *)sme->ssid, sme->ssid_len);
3078
3079         RTW_INFO("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
3080
3081
3082         if (sme->bssid)
3083                 RTW_INFO("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
3084
3085
3086         psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
3087         psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
3088         psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
3089         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
3090         psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
3091
3092 #ifdef CONFIG_WAPI_SUPPORT
3093         padapter->wapiInfo.bWapiEnable = false;
3094 #endif
3095
3096         ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
3097         if (ret < 0)
3098                 goto cancel_ps_deny;
3099
3100 #ifdef CONFIG_WAPI_SUPPORT
3101         if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) {
3102                 padapter->wapiInfo.bWapiEnable = true;
3103                 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
3104                 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
3105         }
3106 #endif
3107
3108         ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
3109
3110 #ifdef CONFIG_WAPI_SUPPORT
3111         if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI)
3112                 padapter->mlmeextpriv.mlmext_info.auth_algo = psecuritypriv->dot11AuthAlgrthm;
3113 #endif
3114
3115
3116         if (ret < 0)
3117                 goto cancel_ps_deny;
3118
3119         RTW_INFO("%s, ie_len=%zu\n", __func__, sme->ie_len);
3120
3121         ret = rtw_cfg80211_set_wpa_ie(padapter, (u8 *)sme->ie, sme->ie_len);
3122         if (ret < 0)
3123                 goto cancel_ps_deny;
3124
3125         if (sme->crypto.n_ciphers_pairwise) {
3126                 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
3127                 if (ret < 0)
3128                         goto cancel_ps_deny;
3129         }
3130
3131         /* For WEP Shared auth */
3132         if (sme->key_len > 0 && sme->key) {
3133                 u32 wep_key_idx, wep_key_len, wep_total_len;
3134                 NDIS_802_11_WEP *pwep = NULL;
3135                 RTW_INFO("%s(): Shared/Auto WEP\n", __FUNCTION__);
3136
3137                 wep_key_idx = sme->key_idx;
3138                 wep_key_len = sme->key_len;
3139
3140                 if (sme->key_idx > WEP_KEYS) {
3141                         ret = -EINVAL;
3142                         goto cancel_ps_deny;
3143                 }
3144
3145                 if (wep_key_len > 0) {
3146                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
3147                         wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
3148                         pwep = (NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
3149                         if (pwep == NULL) {
3150                                 RTW_INFO(" wpa_set_encryption: pwep allocate fail !!!\n");
3151                                 ret = -ENOMEM;
3152                                 goto cancel_ps_deny;
3153                         }
3154
3155                         _rtw_memset(pwep, 0, wep_total_len);
3156
3157                         pwep->KeyLength = wep_key_len;
3158                         pwep->Length = wep_total_len;
3159
3160                         if (wep_key_len == 13) {
3161                                 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
3162                                 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
3163                         }
3164                 } else {
3165                         ret = -EINVAL;
3166                         goto cancel_ps_deny;
3167                 }
3168
3169                 pwep->KeyIndex = wep_key_idx;
3170                 pwep->KeyIndex |= 0x80000000;
3171
3172                 _rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
3173
3174                 if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
3175                         ret = -EOPNOTSUPP ;
3176
3177                 if (pwep)
3178                         rtw_mfree((u8 *)pwep, wep_total_len);
3179
3180                 if (ret < 0)
3181                         goto cancel_ps_deny;
3182         }
3183
3184         ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
3185         if (ret < 0)
3186                 return ret;
3187
3188         if (sme->crypto.n_akm_suites) {
3189                 ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
3190                 if (ret < 0)
3191                         goto cancel_ps_deny;
3192         }
3193 #ifdef CONFIG_8011R
3194         else {
3195                 /*It could be a connection without RSN IEs*/
3196                 psecuritypriv->rsn_akm_suite_type = 0;
3197         }
3198 #endif
3199
3200 #ifdef CONFIG_WAPI_SUPPORT
3201         if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_PSK)
3202                 padapter->wapiInfo.bWapiPSK = true;
3203         else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_CERT)
3204                 padapter->wapiInfo.bWapiPSK = false;
3205 #endif
3206
3207         authmode = psecuritypriv->ndisauthtype;
3208         rtw_set_802_11_authentication_mode(padapter, authmode);
3209
3210         /* rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
3211
3212         if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid) == _FALSE) {
3213                 ret = -1;
3214                 goto cancel_ps_deny;
3215         }
3216
3217         RTW_INFO("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
3218                 psecuritypriv->dot118021XGrpPrivacy);
3219
3220 cancel_ps_deny:
3221         rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
3222
3223 exit:
3224         RTW_INFO("<=%s, ret %d\n", __FUNCTION__, ret);
3225
3226 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
3227         padapter->mlmepriv.not_indic_disco = _FALSE;
3228 #endif
3229
3230         return ret;
3231 }
3232
3233 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
3234                                    u16 reason_code)
3235 {
3236         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3237
3238         RTW_INFO(FUNC_NDEV_FMT" - Start to Disconnect\n", FUNC_NDEV_ARG(ndev));
3239
3240 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
3241         padapter->mlmepriv.not_indic_disco = _TRUE;
3242 #endif
3243
3244         rtw_set_to_roam(padapter, 0);
3245
3246         /* if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) */
3247         {
3248                 rtw_scan_abort(padapter);
3249                 LeaveAllPowerSaveMode(padapter);
3250                 rtw_disassoc_cmd(padapter, 500, _FALSE);
3251                 rtw_sta_mstatus_report(padapter);
3252
3253                 RTW_INFO("%s...call rtw_indicate_disconnect\n", __func__);
3254
3255                 rtw_free_assoc_resources(padapter, 1);
3256                 rtw_indicate_disconnect(padapter, 0, _TRUE);
3257
3258                 rtw_pwr_wakeup(padapter);
3259         }
3260
3261 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
3262         padapter->mlmepriv.not_indic_disco = _FALSE;
3263 #endif
3264
3265         RTW_INFO(FUNC_NDEV_FMT" return 0\n", FUNC_NDEV_ARG(ndev));
3266         return 0;
3267 }
3268
3269 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
3270 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
3271         struct wireless_dev *wdev,
3272 #endif
3273 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) || defined(COMPAT_KERNEL_RELEASE)
3274         enum nl80211_tx_power_setting type, int mbm)
3275 #else
3276         enum tx_power_setting type, int dbm)
3277 #endif
3278 {
3279 #if 0
3280         struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
3281         int ret;
3282
3283         switch (type) {
3284         case NL80211_TX_POWER_AUTOMATIC:
3285                 return 0;
3286         case NL80211_TX_POWER_FIXED:
3287                 if (mbm < 0 || (mbm % 100))
3288                         return -EOPNOTSUPP;
3289
3290                 if (!test_bit(IWM_STATUS_READY, &iwm->status))
3291                         return 0;
3292
3293                 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
3294                                               CFG_TX_PWR_LIMIT_USR,
3295                                               MBM_TO_DBM(mbm) * 2);
3296                 if (ret < 0)
3297                         return ret;
3298
3299                 return iwm_tx_power_trigger(iwm);
3300         default:
3301                 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
3302                 return -EOPNOTSUPP;
3303         }
3304 #endif
3305         RTW_INFO("%s\n", __func__);
3306         return 0;
3307 }
3308
3309 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
3310 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
3311         struct wireless_dev *wdev,
3312 #endif
3313         int *dbm)
3314 {
3315         RTW_INFO("%s\n", __func__);
3316
3317         *dbm = (12);
3318
3319         return 0;
3320 }
3321
3322 inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
3323 {
3324         struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter);
3325         return rtw_wdev_priv->power_mgmt;
3326 }
3327
3328 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
3329                                        struct net_device *ndev,
3330                                        bool enabled, int timeout)
3331 {
3332         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3333         struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter);
3334
3335         RTW_INFO(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
3336                 enabled, timeout);
3337
3338         rtw_wdev_priv->power_mgmt = enabled;
3339
3340 #ifdef CONFIG_LPS
3341         if (!enabled)
3342                 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE_CFG80211_PWRMGMT, 1);
3343 #endif
3344
3345         return 0;
3346 }
3347
3348 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
3349                                   struct net_device *ndev,
3350                                   struct cfg80211_pmksa *pmksa)
3351 {
3352         u8      index, blInserted = _FALSE;
3353         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3354         struct mlme_priv *mlme = &padapter->mlmepriv;
3355         struct security_priv    *psecuritypriv = &padapter->securitypriv;
3356         u8      strZeroMacAddress[ETH_ALEN] = { 0x00 };
3357
3358         RTW_INFO(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
3359                 , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
3360
3361         if (_rtw_memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN) == _TRUE)
3362                 return -EINVAL;
3363
3364         if (check_fwstate(mlme, _FW_LINKED) == _FALSE) {
3365                 RTW_INFO(FUNC_NDEV_FMT" not set pmksa cause not in linked state\n", FUNC_NDEV_ARG(ndev));
3366                 return -EINVAL;
3367         }
3368
3369         blInserted = _FALSE;
3370
3371         /* overwrite PMKID */
3372         for (index = 0 ; index < NUM_PMKID_CACHE; index++) {
3373                 if (_rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) == _TRUE) {
3374                         /* BSSID is matched, the same AP => rewrite with new PMKID. */
3375                         RTW_INFO(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(ndev));
3376
3377                         _rtw_memcpy(psecuritypriv->PMKIDList[index].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
3378                         psecuritypriv->PMKIDList[index].bUsed = _TRUE;
3379                         psecuritypriv->PMKIDIndex = index + 1;
3380                         blInserted = _TRUE;
3381                         break;
3382                 }
3383         }
3384
3385         if (!blInserted) {
3386                 /* Find a new entry */
3387                 RTW_INFO(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
3388                         FUNC_NDEV_ARG(ndev), psecuritypriv->PMKIDIndex);
3389
3390                 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, (u8 *)pmksa->bssid, ETH_ALEN);
3391                 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
3392
3393                 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
3394                 psecuritypriv->PMKIDIndex++ ;
3395                 if (psecuritypriv->PMKIDIndex == 16)
3396                         psecuritypriv->PMKIDIndex = 0;
3397         }
3398
3399         return 0;
3400 }
3401
3402 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
3403                                   struct net_device *ndev,
3404                                   struct cfg80211_pmksa *pmksa)
3405 {
3406         u8      index, bMatched = _FALSE;
3407         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3408         struct security_priv    *psecuritypriv = &padapter->securitypriv;
3409
3410         RTW_INFO(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
3411                 , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
3412
3413         for (index = 0 ; index < NUM_PMKID_CACHE; index++) {
3414                 if (_rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) == _TRUE) {
3415                         /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
3416                         _rtw_memset(psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN);
3417                         _rtw_memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN);
3418                         psecuritypriv->PMKIDList[index].bUsed = _FALSE;
3419                         bMatched = _TRUE;
3420                         RTW_INFO(FUNC_NDEV_FMT" clear id:%hhu\n", FUNC_NDEV_ARG(ndev), index);
3421                         break;
3422                 }
3423         }
3424
3425         if (_FALSE == bMatched) {
3426                 RTW_INFO(FUNC_NDEV_FMT" do not have matched BSSID\n"
3427                         , FUNC_NDEV_ARG(ndev));
3428                 return -EINVAL;
3429         }
3430
3431         return 0;
3432 }
3433
3434 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
3435                                     struct net_device *ndev)
3436 {
3437         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3438         struct security_priv    *psecuritypriv = &padapter->securitypriv;
3439
3440         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3441
3442         _rtw_memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
3443         psecuritypriv->PMKIDIndex = 0;
3444
3445         return 0;
3446 }
3447
3448 #ifdef CONFIG_AP_MODE
3449 void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
3450 {
3451         s32 freq;
3452         int channel;
3453         struct wireless_dev *pwdev = padapter->rtw_wdev;
3454         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3455         struct net_device *ndev = padapter->pnetdev;
3456
3457         RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
3458
3459 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
3460         {
3461                 struct station_info sinfo;
3462                 u8 ie_offset;
3463                 if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
3464                         ie_offset = _ASOCREQ_IE_OFFSET_;
3465                 else /* WIFI_REASSOCREQ */
3466                         ie_offset = _REASOCREQ_IE_OFFSET_;
3467
3468                 memset(&sinfo, 0, sizeof(sinfo));
3469                 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
3470                 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
3471                 sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
3472                 cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
3473         }
3474 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
3475         channel = pmlmeext->cur_channel;
3476         freq = rtw_ch2freq(channel);
3477
3478         #ifdef COMPAT_KERNEL_RELEASE
3479         rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3480         #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3481         rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3482         #else /* COMPAT_KERNEL_RELEASE */
3483         {
3484                 /* to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)  when calling cfg80211_send_rx_assoc() */
3485                 #ifndef CONFIG_PLATFORM_MSTAR
3486                 pwdev->iftype = NL80211_IFTYPE_STATION;
3487                 #endif /* CONFIG_PLATFORM_MSTAR */
3488                 RTW_INFO("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
3489                 rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
3490                 RTW_INFO("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
3491                 pwdev->iftype = NL80211_IFTYPE_AP;
3492                 /* cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); */
3493         }
3494         #endif /* COMPAT_KERNEL_RELEASE */
3495 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
3496
3497 }
3498
3499 void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason)
3500 {
3501         s32 freq;
3502         int channel;
3503         u8 *pmgmt_frame;
3504         uint frame_len;
3505         struct rtw_ieee80211_hdr *pwlanhdr;
3506         unsigned short *fctrl;
3507         u8 mgmt_buf[128] = {0};
3508         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3509         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
3510         struct wireless_dev *wdev = padapter->rtw_wdev;
3511         struct net_device *ndev = padapter->pnetdev;
3512
3513         RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
3514
3515 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
3516         cfg80211_del_sta(ndev, da, GFP_ATOMIC);
3517 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
3518         channel = pmlmeext->cur_channel;
3519         freq = rtw_ch2freq(channel);
3520
3521         pmgmt_frame = mgmt_buf;
3522         pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
3523
3524         fctrl = &(pwlanhdr->frame_ctl);
3525         *(fctrl) = 0;
3526
3527         _rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN);
3528         _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN);
3529         _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3530
3531         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3532         pmlmeext->mgnt_seq++;
3533         SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
3534
3535         pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
3536         frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
3537
3538         reason = cpu_to_le16(reason);
3539         pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
3540
3541         #ifdef COMPAT_KERNEL_RELEASE
3542         rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
3543         #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3544         rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
3545         #else /* COMPAT_KERNEL_RELEASE */
3546         cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len);
3547         /* cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC); */
3548         #endif /* COMPAT_KERNEL_RELEASE */
3549 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
3550 }
3551
3552 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
3553 {
3554         int ret = 0;
3555
3556         RTW_INFO("%s\n", __func__);
3557
3558         return ret;
3559 }
3560
3561 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
3562 {
3563         int ret = 0;
3564
3565         RTW_INFO("%s\n", __func__);
3566
3567         return ret;
3568 }
3569
3570 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
3571 {
3572         int ret = 0;
3573         int rtap_len;
3574         int qos_len = 0;
3575         int dot11_hdr_len = 24;
3576         int snap_len = 6;
3577         unsigned char *pdata;
3578         u16 frame_ctl;
3579         unsigned char src_mac_addr[6];
3580         unsigned char dst_mac_addr[6];
3581         struct rtw_ieee80211_hdr *dot11_hdr;
3582         struct ieee80211_radiotap_header *rtap_hdr;
3583         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3584
3585         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3586
3587         if (skb)
3588                 rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
3589
3590         if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
3591                 goto fail;
3592
3593         rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
3594         if (unlikely(rtap_hdr->it_version))
3595                 goto fail;
3596
3597         rtap_len = ieee80211_get_radiotap_len(skb->data);
3598         if (unlikely(skb->len < rtap_len))
3599                 goto fail;
3600
3601         if (rtap_len != 14) {
3602                 RTW_INFO("radiotap len (should be 14): %d\n", rtap_len);
3603                 goto fail;
3604         }
3605
3606         /* Skip the ratio tap header */
3607         skb_pull(skb, rtap_len);
3608
3609         dot11_hdr = (struct rtw_ieee80211_hdr *)skb->data;
3610         frame_ctl = le16_to_cpu(dot11_hdr->frame_ctl);
3611         /* Check if the QoS bit is set */
3612         if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
3613                 /* Check if this ia a Wireless Distribution System (WDS) frame
3614                  * which has 4 MAC addresses
3615                  */
3616                 if (dot11_hdr->frame_ctl & 0x0080)
3617                         qos_len = 2;
3618                 if ((dot11_hdr->frame_ctl & 0x0300) == 0x0300)
3619                         dot11_hdr_len += 6;
3620
3621                 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
3622                 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
3623
3624                 /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
3625                  * for two MAC addresses
3626                  */
3627                 skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
3628                 pdata = (unsigned char *)skb->data;
3629                 memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
3630                 memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
3631
3632                 RTW_INFO("should be eapol packet\n");
3633
3634                 /* Use the real net device to transmit the packet */
3635                 ret = _rtw_xmit_entry(skb, padapter->pnetdev);
3636
3637                 return ret;
3638
3639         } else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE | RTW_IEEE80211_FCTL_STYPE))
3640                 == (RTW_IEEE80211_FTYPE_MGMT | RTW_IEEE80211_STYPE_ACTION)
3641         ) {
3642                 /* only for action frames */
3643                 struct xmit_frame               *pmgntframe;
3644                 struct pkt_attrib       *pattrib;
3645                 unsigned char   *pframe;
3646                 /* u8 category, action, OUI_Subtype, dialogToken=0; */
3647                 /* unsigned char        *frame_body; */
3648                 struct rtw_ieee80211_hdr *pwlanhdr;
3649                 struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
3650                 struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
3651                 u8 *buf = skb->data;
3652                 u32 len = skb->len;
3653                 u8 category, action;
3654                 int type = -1;
3655
3656                 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
3657                         RTW_INFO(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
3658                                 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
3659                         goto fail;
3660                 }
3661
3662                 RTW_INFO("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
3663                         MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
3664                 #ifdef CONFIG_P2P
3665                 type = rtw_p2p_check_frames(padapter, buf, len, _TRUE);
3666                 if (type >= 0)
3667                         goto dump;
3668                 #endif
3669                 if (category == RTW_WLAN_CATEGORY_PUBLIC)
3670                         RTW_INFO("RTW_Tx:%s\n", action_public_str(action));
3671                 else
3672                         RTW_INFO("RTW_Tx:category(%u), action(%u)\n", category, action);
3673
3674 dump:
3675                 /* starting alloc mgmt frame to dump it */
3676                 pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3677                 if (pmgntframe == NULL)
3678                         goto fail;
3679
3680                 /* update attribute */
3681                 pattrib = &pmgntframe->attrib;
3682                 update_mgntframe_attrib(padapter, pattrib);
3683                 pattrib->retry_ctrl = _FALSE;
3684
3685                 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3686
3687                 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3688
3689                 _rtw_memcpy(pframe, (void *)buf, len);
3690                 pattrib->pktlen = len;
3691
3692 #ifdef CONFIG_P2P
3693                 if (type >= 0)
3694                         rtw_xframe_chk_wfd_ie(pmgntframe);
3695 #endif /* CONFIG_P2P */
3696
3697                 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3698                 /* update seq number */
3699                 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
3700                 pattrib->seqnum = pmlmeext->mgnt_seq;
3701                 pmlmeext->mgnt_seq++;
3702
3703
3704                 pattrib->last_txcmdsz = pattrib->pktlen;
3705
3706                 dump_mgntframe(padapter, pmgntframe);
3707
3708         } else
3709                 RTW_INFO("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE | RTW_IEEE80211_FCTL_STYPE));
3710
3711
3712 fail:
3713
3714         rtw_skb_free(skb);
3715
3716         return 0;
3717
3718 }
3719
3720 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
3721 {
3722         RTW_INFO("%s\n", __func__);
3723 }
3724
3725 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
3726 {
3727         int ret = 0;
3728
3729         RTW_INFO("%s\n", __func__);
3730
3731         return ret;
3732 }
3733
3734 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
3735 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
3736         .ndo_open = rtw_cfg80211_monitor_if_open,
3737         .ndo_stop = rtw_cfg80211_monitor_if_close,
3738         .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
3739         #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
3740         .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
3741         #endif
3742         .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
3743 };
3744 #endif
3745
3746 static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
3747 {
3748         int ret = 0;
3749         struct net_device *mon_ndev = NULL;
3750         struct wireless_dev *mon_wdev = NULL;
3751         struct rtw_netdev_priv_indicator *pnpi;
3752         struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
3753
3754         if (!name) {
3755                 RTW_INFO(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
3756                 ret = -EINVAL;
3757                 goto out;
3758         }
3759
3760         if (pwdev_priv->pmon_ndev) {
3761                 RTW_INFO(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
3762                         FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
3763                 ret = -EBUSY;
3764                 goto out;
3765         }
3766
3767         mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
3768         if (!mon_ndev) {
3769                 RTW_INFO(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
3770                 ret = -ENOMEM;
3771                 goto out;
3772         }
3773
3774         mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
3775         strncpy(mon_ndev->name, name, IFNAMSIZ);
3776         mon_ndev->name[IFNAMSIZ - 1] = 0;
3777         mon_ndev->destructor = rtw_ndev_destructor;
3778
3779 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
3780         mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
3781 #else
3782         mon_ndev->open = rtw_cfg80211_monitor_if_open;
3783         mon_ndev->stop = rtw_cfg80211_monitor_if_close;
3784         mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry;
3785         mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address;
3786 #endif
3787
3788         pnpi = netdev_priv(mon_ndev);
3789         pnpi->priv = padapter;
3790         pnpi->sizeof_priv = sizeof(_adapter);
3791
3792         /*  wdev */
3793         mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
3794         if (!mon_wdev) {
3795                 RTW_INFO(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
3796                 ret = -ENOMEM;
3797                 goto out;
3798         }
3799
3800         mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
3801         mon_wdev->netdev = mon_ndev;
3802         mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
3803         mon_ndev->ieee80211_ptr = mon_wdev;
3804
3805         ret = register_netdevice(mon_ndev);
3806         if (ret)
3807                 goto out;
3808
3809         *ndev = pwdev_priv->pmon_ndev = mon_ndev;
3810         _rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ + 1);
3811
3812 out:
3813         if (ret && mon_wdev) {
3814                 rtw_mfree((u8 *)mon_wdev, sizeof(struct wireless_dev));
3815                 mon_wdev = NULL;
3816         }
3817
3818         if (ret && mon_ndev) {
3819                 free_netdev(mon_ndev);
3820                 *ndev = mon_ndev = NULL;
3821         }
3822
3823         return ret;
3824 }
3825
3826 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3827 static struct wireless_dev *
3828 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
3829 static struct net_device *
3830 #else
3831 static int
3832 #endif
3833         cfg80211_rtw_add_virtual_intf(
3834                 struct wiphy *wiphy,
3835                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
3836                 const char *name,
3837                 #else
3838                 char *name,
3839                 #endif
3840                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
3841                 unsigned char name_assign_type,
3842                 #endif
3843                 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
3844 {
3845         int ret = 0;
3846         struct wireless_dev *wdev = NULL;
3847         struct net_device *ndev = NULL;
3848         _adapter *padapter;
3849         struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy);
3850
3851         RTW_INFO(FUNC_WIPHY_FMT" name:%s, type:%d\n", FUNC_WIPHY_ARG(wiphy), name, type);
3852
3853         switch (type) {
3854         case NL80211_IFTYPE_MONITOR:
3855                 padapter = wiphy_to_adapter(wiphy); /* TODO: get ap iface ? */
3856                 ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
3857                 if (ret == 0)
3858                         wdev = ndev->ieee80211_ptr;
3859                 break;
3860
3861 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
3862         case NL80211_IFTYPE_P2P_CLIENT:
3863         case NL80211_IFTYPE_P2P_GO:
3864 #endif
3865         case NL80211_IFTYPE_STATION:
3866         case NL80211_IFTYPE_AP:
3867                 padapter = dvobj_get_unregisterd_adapter(dvobj);
3868                 if (!padapter) {
3869                         RTW_WARN("adapter pool empty!\n");
3870                         ret = -ENODEV;
3871                         break;
3872                 }
3873                 if (rtw_os_ndev_init(padapter, name) != _SUCCESS) {
3874                         RTW_WARN("ndev init fail!\n");
3875                         ret = -ENODEV;
3876                         break;
3877                 }
3878                 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
3879                 if (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)
3880                         rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
3881                 #endif
3882                 ndev = padapter->pnetdev;
3883                 wdev = ndev->ieee80211_ptr;
3884                 break;
3885
3886 #if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE)
3887         case NL80211_IFTYPE_P2P_DEVICE:
3888                 ret = rtw_pd_iface_alloc(wiphy, name, &wdev);
3889                 break;
3890 #endif
3891
3892         case NL80211_IFTYPE_ADHOC:
3893         case NL80211_IFTYPE_AP_VLAN:
3894         case NL80211_IFTYPE_WDS:
3895         case NL80211_IFTYPE_MESH_POINT:
3896         default:
3897                 ret = -ENODEV;
3898                 RTW_INFO("Unsupported interface type\n");
3899                 break;
3900         }
3901
3902         if (ndev)
3903                 RTW_INFO(FUNC_WIPHY_FMT" ndev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), ndev, ret);
3904         else
3905                 RTW_INFO(FUNC_WIPHY_FMT" wdev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), wdev, ret);
3906
3907 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3908         return wdev ? wdev : ERR_PTR(ret);
3909 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
3910         return ndev ? ndev : ERR_PTR(ret);
3911 #else
3912         return ret;
3913 #endif
3914 }
3915
3916 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
3917 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3918         struct wireless_dev *wdev
3919 #else
3920         struct net_device *ndev
3921 #endif
3922 )
3923 {
3924 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3925         struct net_device *ndev = wdev_to_ndev(wdev);
3926 #endif
3927         int ret = 0;
3928         _adapter *adapter;
3929         struct rtw_wdev_priv *pwdev_priv;
3930
3931         if (ndev) {
3932                 adapter = (_adapter *)rtw_netdev_priv(ndev);
3933                 pwdev_priv = adapter_wdev_data(adapter);
3934
3935                 if (ndev == pwdev_priv->pmon_ndev) {
3936                         unregister_netdevice(ndev);
3937                         pwdev_priv->pmon_ndev = NULL;
3938                         pwdev_priv->ifname_mon[0] = '\0';
3939                         RTW_INFO(FUNC_NDEV_FMT" remove monitor ndev\n", FUNC_NDEV_ARG(ndev));
3940                 } else {
3941                         RTW_INFO(FUNC_NDEV_FMT" unregister ndev\n", FUNC_NDEV_ARG(ndev));
3942                         rtw_os_ndev_unregister(adapter);
3943                 }
3944         } else
3945 #if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE)
3946         if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
3947                 if (wdev == wiphy_to_pd_wdev(wiphy))
3948                         rtw_pd_iface_free(wiphy);
3949                 else {
3950                         RTW_ERR(FUNC_WIPHY_FMT" unknown P2P Device wdev:%p\n", FUNC_WIPHY_ARG(wiphy), wdev);
3951                         rtw_warn_on(1);
3952                 }
3953         } else
3954 #endif
3955         {
3956                 ret = -EINVAL;
3957                 goto exit;
3958         }
3959
3960 exit:
3961         return ret;
3962 }
3963
3964 static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
3965 {
3966         int ret = 0;
3967         u8 *pbuf = NULL;
3968         uint len, wps_ielen = 0;
3969         uint p2p_ielen = 0;
3970         u8 *p2p_ie;
3971         u8 got_p2p_ie = _FALSE;
3972         struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
3973         /* struct sta_priv *pstapriv = &padapter->stapriv; */
3974
3975
3976         RTW_INFO("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
3977
3978
3979         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
3980                 return -EINVAL;
3981
3982         if (head_len < 24)
3983                 return -EINVAL;
3984
3985
3986         pbuf = rtw_zmalloc(head_len + tail_len);
3987         if (!pbuf)
3988                 return -ENOMEM;
3989
3990
3991         /* _rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2); */
3992
3993         /* if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0)) */
3994         /*      pstapriv->max_num_sta = NUM_STA; */
3995
3996
3997         _rtw_memcpy(pbuf, (void *)head + 24, head_len - 24); /* 24=beacon header len. */
3998         _rtw_memcpy(pbuf + head_len - 24, (void *)tail, tail_len);
3999
4000         len = head_len + tail_len - 24;
4001
4002         /* check wps ie if inclued */
4003         if (rtw_get_wps_ie(pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL, &wps_ielen))
4004                 RTW_INFO("add bcn, wps_ielen=%d\n", wps_ielen);
4005
4006 #ifdef CONFIG_P2P
4007         if (adapter->wdinfo.driver_interface == DRIVER_CFG80211) {
4008                 /* check p2p if enable */
4009                 if (rtw_get_p2p_ie(pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL, &p2p_ielen)) {
4010                         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4011                         struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
4012
4013                         RTW_INFO("got p2p_ie, len=%d\n", p2p_ielen);
4014
4015                         got_p2p_ie = _TRUE;
4016
4017                         if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
4018                                 RTW_INFO("Enable P2P function for the first time\n");
4019                                 rtw_p2p_enable(adapter, P2P_ROLE_GO);
4020
4021                                 adapter->stapriv.expire_to = 3; /* 3x2 = 6 sec in p2p mode */
4022                         } else {
4023                                 RTW_INFO("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);
4024
4025                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
4026                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
4027                                 pwdinfo->intent = 15;
4028                         }
4029                 }
4030         }
4031 #endif /* CONFIG_P2P */
4032
4033         /* pbss_network->IEs will not include p2p_ie, wfd ie */
4034         rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
4035         rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
4036
4037         if (rtw_check_beacon_data(adapter, pbuf,  len) == _SUCCESS) {
4038 #ifdef CONFIG_P2P
4039                 /* check p2p if enable */
4040                 if (got_p2p_ie == _TRUE) {
4041                         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
4042                         struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
4043                         pwdinfo->operating_channel = pmlmeext->cur_channel;
4044                 }
4045 #endif /* CONFIG_P2P */
4046                 ret = 0;
4047         } else
4048                 ret = -EINVAL;
4049
4050
4051         rtw_mfree(pbuf, head_len + tail_len);
4052
4053         return ret;
4054 }
4055
4056 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
4057 static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
4058                 struct beacon_parameters *info)
4059 {
4060         int ret = 0;
4061         _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
4062
4063         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4064         ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
4065
4066         return ret;
4067 }
4068
4069 static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
4070                 struct beacon_parameters *info)
4071 {
4072         _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
4073         struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
4074
4075         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4076
4077         pmlmeext->bstart_bss = _TRUE;
4078
4079         cfg80211_rtw_add_beacon(wiphy, ndev, info);
4080
4081         return 0;
4082 }
4083
4084 static int      cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
4085 {
4086         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4087
4088         return 0;
4089 }
4090 #else
4091 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4092                 struct cfg80211_ap_settings *settings)
4093 {
4094         int ret = 0;
4095         _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
4096
4097         RTW_INFO(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
4098                 settings->hidden_ssid, settings->auth_type);
4099
4100         ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
4101                 settings->beacon.tail, settings->beacon.tail_len);
4102
4103         adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
4104
4105         if (settings->ssid && settings->ssid_len) {
4106                 WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
4107                 WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
4108
4109                 if (0)
4110                         RTW_INFO(FUNC_ADPT_FMT" ssid:(%s,%zu), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
4111                                 settings->ssid, settings->ssid_len,
4112                                 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
4113
4114                 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
4115                 pbss_network->Ssid.SsidLength = settings->ssid_len;
4116                 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
4117                 pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
4118
4119                 if (0)
4120                         RTW_INFO(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
4121                                 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
4122                                 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
4123         }
4124
4125         return ret;
4126 }
4127
4128 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4129                 struct cfg80211_beacon_data *info)
4130 {
4131         int ret = 0;
4132         _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
4133
4134         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4135
4136         ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
4137
4138         return ret;
4139 }
4140
4141 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4142 {
4143         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4144         return 0;
4145 }
4146
4147 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) */
4148
4149 #if CONFIG_RTW_MACADDR_ACL && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
4150 static int cfg80211_rtw_set_mac_acl(struct wiphy *wiphy, struct net_device *ndev,
4151                 const struct cfg80211_acl_data *params)
4152 {
4153         _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
4154         u8 acl_mode = RTW_ACL_MODE_DISABLED;
4155         int ret = -1;
4156         int i;
4157
4158         if (!params) {
4159                 RTW_WARN(FUNC_ADPT_FMT" params NULL\n", FUNC_ADPT_ARG(adapter));
4160                 goto exit;
4161         }
4162
4163         RTW_INFO(FUNC_ADPT_FMT" acl_policy:%d, entry_num:%d\n"
4164                 , FUNC_ADPT_ARG(adapter), params->acl_policy, params->n_acl_entries);
4165
4166         if (params->acl_policy == NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED)
4167                 acl_mode = RTW_ACL_MODE_ACCEPT_UNLESS_LISTED;
4168         else if (params->acl_policy == NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
4169                 acl_mode = RTW_ACL_MODE_DENY_UNLESS_LISTED;
4170
4171         if (!params->n_acl_entries) {
4172                 if (acl_mode != RTW_ACL_MODE_DISABLED)
4173                         RTW_WARN(FUNC_ADPT_FMT" acl_policy:%d with no entry\n"
4174                                 , FUNC_ADPT_ARG(adapter), params->acl_policy);
4175                 acl_mode = RTW_ACL_MODE_DISABLED;
4176                 goto exit;
4177         }
4178
4179         for (i = 0; i < params->n_acl_entries; i++)
4180                 rtw_acl_add_sta(adapter, params->mac_addrs[i].addr);
4181
4182         ret = 0;
4183
4184 exit:
4185         rtw_set_macaddr_acl(adapter, acl_mode);
4186         return ret;
4187 }
4188 #endif /* CONFIG_RTW_MACADDR_ACL && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) */
4189
4190 static int      cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
4191 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
4192         u8 *mac,
4193 #else
4194         const u8 *mac,
4195 #endif
4196         struct station_parameters *params)
4197 {
4198         int ret = 0;
4199 #ifdef CONFIG_TDLS
4200         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4201         struct sta_priv *pstapriv = &padapter->stapriv;
4202         struct sta_info *psta;
4203 #endif /* CONFIG_TDLS */
4204         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4205
4206 #ifdef CONFIG_TDLS
4207         psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
4208         if (psta == NULL) {
4209                 psta = rtw_alloc_stainfo(pstapriv, (u8 *)mac);
4210                 if (psta == NULL) {
4211                         RTW_INFO("[%s] Alloc station for "MAC_FMT" fail\n", __FUNCTION__, MAC_ARG(mac));
4212                         ret = -EOPNOTSUPP;
4213                         goto exit;
4214                 }
4215         }
4216 #endif /* CONFIG_TDLS */
4217
4218 exit:
4219         return ret;
4220 }
4221
4222 static int      cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
4223 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
4224         u8 *mac
4225 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
4226         const u8 *mac
4227 #else
4228         struct station_del_parameters *params
4229 #endif
4230 )
4231 {
4232         int ret = 0;
4233         _irqL irqL;
4234         _list   *phead, *plist;
4235         u8 updated = _FALSE;
4236         const u8 *target_mac;
4237         struct sta_info *psta = NULL;
4238         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4239         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4240         struct sta_priv *pstapriv = &padapter->stapriv;
4241
4242         RTW_INFO("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4243
4244
4245 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
4246         target_mac = mac;
4247 #else
4248         target_mac = params->mac;
4249 #endif
4250
4251         if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE) {
4252                 RTW_INFO("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
4253                 return -EINVAL;
4254         }
4255
4256
4257         if (!target_mac) {
4258                 RTW_INFO("flush all sta, and cam_entry\n");
4259
4260                 flush_all_cam_entry(padapter);  /* clear CAM */
4261
4262                 ret = rtw_sta_flush(padapter, _TRUE);
4263
4264                 return ret;
4265         }
4266
4267
4268         RTW_INFO("free sta macaddr =" MAC_FMT "\n", MAC_ARG(target_mac));
4269
4270         if (target_mac[0] == 0xff && target_mac[1] == 0xff &&
4271             target_mac[2] == 0xff && target_mac[3] == 0xff &&
4272             target_mac[4] == 0xff && target_mac[5] == 0xff)
4273                 return -EINVAL;
4274
4275
4276         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
4277
4278         phead = &pstapriv->asoc_list;
4279         plist = get_next(phead);
4280
4281         /* check asoc_queue */
4282         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
4283                 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
4284
4285                 plist = get_next(plist);
4286
4287                 if (_rtw_memcmp((u8 *)target_mac, psta->hwaddr, ETH_ALEN)) {
4288                         if (psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE)
4289                                 RTW_INFO("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
4290                         else {
4291                                 RTW_INFO("free psta=%p, aid=%d\n", psta, psta->aid);
4292
4293                                 rtw_list_delete(&psta->asoc_list);
4294                                 pstapriv->asoc_list_cnt--;
4295
4296                                 /* _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); */
4297                                 if (check_fwstate(pmlmepriv, (WIFI_AP_STATE)) == _TRUE)
4298                                         updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID, _TRUE);
4299                                 else
4300                                         updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);
4301                                 /* _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); */
4302
4303                                 psta = NULL;
4304
4305                                 break;
4306                         }
4307
4308                 }
4309
4310         }
4311
4312         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
4313
4314         associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
4315
4316         RTW_INFO("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4317
4318         return ret;
4319
4320 }
4321
4322 static int      cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
4323 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
4324         u8 *mac,
4325 #else
4326         const u8 *mac,
4327 #endif
4328         struct station_parameters *params)
4329 {
4330         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4331
4332         return 0;
4333 }
4334
4335 struct sta_info *rtw_sta_info_get_by_idx(const int idx, struct sta_priv *pstapriv)
4336
4337 {
4338
4339         _list   *phead, *plist;
4340         struct sta_info *psta = NULL;
4341         int i = 0;
4342
4343         phead = &pstapriv->asoc_list;
4344         plist = get_next(phead);
4345
4346         /* check asoc_queue */
4347         while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
4348                 if (idx == i)
4349                         psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
4350                 plist = get_next(plist);
4351                 i++;
4352         }
4353         return psta;
4354 }
4355
4356 static int      cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
4357                 int idx, u8 *mac, struct station_info *sinfo)
4358 {
4359
4360         int ret = 0;
4361         _irqL irqL;
4362         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4363         struct sta_info *psta = NULL;
4364         struct sta_priv *pstapriv = &padapter->stapriv;
4365         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4366
4367         _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
4368         psta = rtw_sta_info_get_by_idx(idx, pstapriv);
4369         _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
4370         if (NULL == psta) {
4371                 RTW_INFO("Station is not found\n");
4372                 ret = -ENOENT;
4373                 goto exit;
4374         }
4375         _rtw_memcpy(mac, psta->hwaddr, ETH_ALEN);
4376         sinfo->filled = 0;
4377         sinfo->filled |= STATION_INFO_SIGNAL;
4378         sinfo->signal = psta->rssi;
4379
4380 exit:
4381         return ret;
4382 }
4383
4384 static int      cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
4385                 struct bss_parameters *params)
4386 {
4387         u8 i;
4388
4389         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4390 /*
4391         RTW_INFO("use_cts_prot=%d\n", params->use_cts_prot);
4392         RTW_INFO("use_short_preamble=%d\n", params->use_short_preamble);
4393         RTW_INFO("use_short_slot_time=%d\n", params->use_short_slot_time);
4394         RTW_INFO("ap_isolate=%d\n", params->ap_isolate);
4395
4396         RTW_INFO("basic_rates_len=%d\n", params->basic_rates_len);
4397         for(i = 0; i < params->basic_rates_len; i++)
4398                 RTW_INFO("basic_rates=%d\n", params->basic_rates[i]);
4399 */
4400         return 0;
4401
4402 }
4403
4404 static int      cfg80211_rtw_set_channel(struct wiphy *wiphy
4405         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
4406         , struct net_device *ndev
4407         #endif
4408         , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
4409 {
4410 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
4411         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4412 #else
4413         _adapter *padapter = wiphy_to_adapter(wiphy);
4414 #endif
4415         int chan_target = (u8) ieee80211_frequency_to_channel(chan->center_freq);
4416         int chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4417         int chan_width = CHANNEL_WIDTH_20;
4418
4419 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
4420         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4421 #endif
4422
4423         switch (channel_type) {
4424         case NL80211_CHAN_NO_HT:
4425         case NL80211_CHAN_HT20:
4426                 chan_width = CHANNEL_WIDTH_20;
4427                 chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4428                 break;
4429         case NL80211_CHAN_HT40MINUS:
4430                 chan_width = CHANNEL_WIDTH_40;
4431                 chan_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
4432                 break;
4433         case NL80211_CHAN_HT40PLUS:
4434                 chan_width = CHANNEL_WIDTH_40;
4435                 chan_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
4436                 break;
4437         default:
4438                 chan_width = CHANNEL_WIDTH_20;
4439                 chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4440                 break;
4441         }
4442
4443         set_channel_bwmode(padapter, chan_target, chan_offset, chan_width);
4444
4445         return 0;
4446 }
4447
4448 static int cfg80211_rtw_set_monitor_channel(struct wiphy *wiphy
4449 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
4450         , struct cfg80211_chan_def *chandef
4451 #else
4452         , struct ieee80211_channel *chan
4453         , enum nl80211_channel_type channel_type
4454 #endif
4455 )
4456 {
4457 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
4458         struct ieee80211_channel *chan = chandef->chan;
4459 #endif
4460
4461         _adapter *padapter = wiphy_to_adapter(wiphy);
4462         int target_channal = chan->hw_value;
4463         int target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4464         int target_width = CHANNEL_WIDTH_20;
4465
4466 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
4467 #ifdef CONFIG_DEBUG_CFG80211
4468         RTW_INFO("center_freq %u Mhz ch %u width %u freq1 %u freq2 %u\n"
4469                 , chan->center_freq
4470                 , chan->hw_value
4471                 , chandef->width
4472                 , chandef->center_freq1
4473                 , chandef->center_freq2);
4474 #endif /* CONFIG_DEBUG_CFG80211 */
4475
4476         switch (chandef->width) {
4477         case NL80211_CHAN_WIDTH_20_NOHT:
4478         case NL80211_CHAN_WIDTH_20:
4479                 target_width = CHANNEL_WIDTH_20;
4480                 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4481                 break;
4482         case NL80211_CHAN_WIDTH_40:
4483                 target_width = CHANNEL_WIDTH_40;
4484                 if (chandef->center_freq1 > chan->center_freq)
4485                         target_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
4486                 else
4487                         target_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
4488                 break;
4489         case NL80211_CHAN_WIDTH_80:
4490                 target_width = CHANNEL_WIDTH_80;
4491                 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4492                 break;
4493         case NL80211_CHAN_WIDTH_80P80:
4494                 target_width = CHANNEL_WIDTH_80_80;
4495                 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4496                 break;
4497         case NL80211_CHAN_WIDTH_160:
4498                 target_width = CHANNEL_WIDTH_160;
4499                 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4500                 break;
4501
4502 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
4503         case NL80211_CHAN_WIDTH_5:
4504         case NL80211_CHAN_WIDTH_10:
4505 #endif
4506         default:
4507                 target_width = CHANNEL_WIDTH_20;
4508                 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4509                 break;
4510         }
4511 #else
4512 #ifdef CONFIG_DEBUG_CFG80211
4513         RTW_INFO("center_freq %u Mhz ch %u channel_type %u\n"
4514                 , chan->center_freq
4515                 , chan->hw_value
4516                 , channel_type);
4517 #endif /* CONFIG_DEBUG_CFG80211 */
4518
4519         switch (channel_type) {
4520         case NL80211_CHAN_NO_HT:
4521         case NL80211_CHAN_HT20:
4522                 target_width = CHANNEL_WIDTH_20;
4523                 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4524                 break;
4525         case NL80211_CHAN_HT40MINUS:
4526                 target_width = CHANNEL_WIDTH_40;
4527                 target_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
4528                 break;
4529         case NL80211_CHAN_HT40PLUS:
4530                 target_width = CHANNEL_WIDTH_40;
4531                 target_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
4532                 break;
4533         default:
4534                 target_width = CHANNEL_WIDTH_20;
4535                 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
4536                 break;
4537         }
4538 #endif
4539
4540         set_channel_bwmode(padapter, target_channal, target_offset, target_width);
4541
4542         return 0;
4543 }
4544
4545 static int      cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
4546                 struct cfg80211_auth_request *req)
4547 {
4548         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4549
4550         return 0;
4551 }
4552
4553 static int      cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
4554                 struct cfg80211_assoc_request *req)
4555 {
4556         RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4557
4558         return 0;
4559 }
4560 #endif /* CONFIG_AP_MODE */
4561
4562 void rtw_cfg80211_rx_probe_request(_adapter *adapter, union recv_frame *rframe)
4563 {
4564         struct wireless_dev *wdev = adapter->rtw_wdev;
4565         struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
4566         u8 *frame = get_recvframe_data(rframe);
4567         uint frame_len = rframe->u.hdr.len;
4568         s32 freq;
4569         u8 ch, sch = rtw_get_oper_ch(adapter);
4570
4571         ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
4572         freq = rtw_ch2freq(ch);
4573
4574 #ifdef CONFIG_DEBUG_CFG80211
4575         RTW_INFO("RTW_Rx: probe request, ch=%d(%d)\n", ch, sch);
4576 #endif
4577
4578         rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
4579 }
4580
4581 void rtw_cfg80211_rx_action_p2p(_adapter *adapter, union recv_frame *rframe)
4582 {
4583         struct wireless_dev *wdev = adapter->rtw_wdev;
4584         u8 *frame = get_recvframe_data(rframe);
4585         uint frame_len = rframe->u.hdr.len;
4586         s32 freq;
4587         u8 ch, sch = rtw_get_oper_ch(adapter);
4588         u8 category, action;
4589         int type;
4590
4591         ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
4592         freq = rtw_ch2freq(ch);
4593
4594         RTW_INFO("RTW_Rx:ch=%d(%d)\n", ch, sch);
4595 #ifdef CONFIG_P2P
4596         type = rtw_p2p_check_frames(adapter, frame, frame_len, _FALSE);
4597         if (type >= 0)
4598                 goto indicate;
4599 #endif
4600         rtw_action_frame_parse(frame, frame_len, &category, &action);
4601         RTW_INFO("RTW_Rx:category(%u), action(%u)\n", category, action);
4602
4603 indicate:
4604
4605 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
4606         rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
4607 #else
4608         cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
4609 #endif
4610 }
4611
4612 void rtw_cfg80211_rx_p2p_action_public(_adapter *adapter, union recv_frame *rframe)
4613 {
4614         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
4615         struct wireless_dev *wdev = adapter->rtw_wdev;
4616         struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
4617         u8 *frame = get_recvframe_data(rframe);
4618         uint frame_len = rframe->u.hdr.len;
4619         s32 freq;
4620         u8 ch, sch = rtw_get_oper_ch(adapter);
4621         u8 category, action;
4622         int type;
4623
4624         ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
4625         freq = rtw_ch2freq(ch);
4626
4627         RTW_INFO("RTW_Rx:ch=%d(%d)\n", ch, sch);
4628         #ifdef CONFIG_P2P
4629         type = rtw_p2p_check_frames(adapter, frame, frame_len, _FALSE);
4630         if (type >= 0) {
4631                 switch (type) {
4632                 case P2P_GO_NEGO_CONF:
4633                         if (0) {
4634                                 RTW_INFO(FUNC_ADPT_FMT" Nego confirm. state=%u, status=%u, iaddr="MAC_FMT"\n"
4635                                         , FUNC_ADPT_ARG(adapter), pwdev_priv->nego_info.state, pwdev_priv->nego_info.status
4636                                         , MAC_ARG(pwdev_priv->nego_info.iface_addr));
4637                         }
4638                         if (pwdev_priv->nego_info.state == 2
4639                                 && pwdev_priv->nego_info.status == 0
4640                                 && rtw_check_invalid_mac_address(pwdev_priv->nego_info.iface_addr, _FALSE) == _FALSE
4641                         ) {
4642                                 _adapter *intended_iface = dvobj_get_adapter_by_addr(dvobj, pwdev_priv->nego_info.iface_addr);
4643
4644                                 if (intended_iface) {
4645                                         RTW_INFO(FUNC_ADPT_FMT" Nego confirm. Allow only "ADPT_FMT" to scan for 2000 ms\n"
4646                                                 , FUNC_ADPT_ARG(adapter), ADPT_ARG(intended_iface));
4647                                         /* allow only intended_iface to do scan for 2000 ms */
4648                                         rtw_mi_set_scan_deny(adapter, 2000);
4649                                         rtw_clear_scan_deny(intended_iface);
4650                                 }
4651                         }
4652                         break;
4653                 case P2P_PROVISION_DISC_RESP:
4654                 case P2P_INVIT_RESP:
4655                         #if !RTW_P2P_GROUP_INTERFACE
4656                         rtw_mi_buddy_set_scan_deny(adapter, 2000);
4657                         #endif
4658                         break;
4659                 }
4660                 goto indicate;
4661         }
4662         #endif
4663         rtw_action_frame_parse(frame, frame_len, &category, &action);
4664         RTW_INFO("RTW_Rx:category(%u), action(%u)\n", category, action);
4665
4666 indicate:
4667         #if defined(RTW_DEDICATED_P2P_DEVICE)
4668         if (rtw_cfg80211_redirect_pd_wdev(dvobj_to_wiphy(dvobj), get_ra(frame), &wdev))
4669                 if (0)
4670                         RTW_INFO("redirect to pd_wdev:%p\n", wdev);
4671         #endif
4672
4673 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
4674         rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
4675 #else
4676         cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
4677 #endif
4678 }
4679
4680 void rtw_cfg80211_rx_action(_adapter *adapter, union recv_frame *rframe, const char *msg)
4681 {
4682         struct wireless_dev *wdev = adapter->rtw_wdev;
4683         struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
4684         u8 *frame = get_recvframe_data(rframe);
4685         uint frame_len = rframe->u.hdr.len;
4686         s32 freq;
4687         u8 ch, sch = rtw_get_oper_ch(adapter);
4688         u8 category, action;
4689
4690         ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
4691         freq = rtw_ch2freq(ch);
4692
4693         rtw_action_frame_parse(frame, frame_len, &category, &action);
4694
4695         if (action == ACT_PUBLIC_GAS_INITIAL_REQ) {
4696                 rtw_mi_set_scan_deny(adapter, 200);
4697                 rtw_mi_scan_abort(adapter, _FALSE); /*rtw_scan_abort_no_wait*/
4698         }
4699
4700 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
4701         rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
4702 #else
4703         cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
4704 #endif
4705
4706         RTW_INFO("RTW_Rx:ch=%d(%d)\n", ch, sch);
4707         if (msg)
4708                 RTW_INFO("RTW_Rx:%s\n", msg);
4709         else
4710                 RTW_INFO("RTW_Rx:category(%u), action(%u)\n", category, action);
4711 }
4712
4713 #ifdef CONFIG_P2P
4714 void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
4715 {
4716         u16     wps_devicepassword_id = 0x0000;
4717         uint    wps_devicepassword_id_len = 0;
4718         u8                      wpsie[255] = { 0x00 }, p2p_ie[255] = { 0x00 };
4719         uint                    p2p_ielen = 0;
4720         uint                    wpsielen = 0;
4721         u32     devinfo_contentlen = 0;
4722         u8      devinfo_content[64] = { 0x00 };
4723         u16     capability = 0;
4724         uint capability_len = 0;
4725
4726         unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4727         u8                      action = P2P_PUB_ACTION_ACTION;
4728         u8                      dialogToken = 1;
4729         u32                     p2poui = cpu_to_be32(P2POUI);
4730         u8                      oui_subtype = P2P_PROVISION_DISC_REQ;
4731         u32                     p2pielen = 0;
4732 #ifdef CONFIG_WFD
4733         u32                                     wfdielen = 0;
4734 #endif
4735
4736         struct xmit_frame                       *pmgntframe;
4737         struct pkt_attrib                       *pattrib;
4738         unsigned char                                   *pframe;
4739         struct rtw_ieee80211_hdr        *pwlanhdr;
4740         unsigned short                          *fctrl;
4741         struct xmit_priv                        *pxmitpriv = &(padapter->xmitpriv);
4742         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
4743         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
4744
4745         struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4746         u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
4747         size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
4748
4749
4750         RTW_INFO("[%s] In\n", __FUNCTION__);
4751
4752         /* prepare for building provision_request frame  */
4753         _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
4754         _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
4755
4756         pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
4757
4758         rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
4759         rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8 *) &wps_devicepassword_id, &wps_devicepassword_id_len);
4760         wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
4761
4762         switch (wps_devicepassword_id) {
4763         case WPS_DPID_PIN:
4764                 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
4765                 break;
4766         case WPS_DPID_USER_SPEC:
4767                 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
4768                 break;
4769         case WPS_DPID_MACHINE_SPEC:
4770                 break;
4771         case WPS_DPID_REKEY:
4772                 break;
4773         case WPS_DPID_PBC:
4774                 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
4775                 break;
4776         case WPS_DPID_REGISTRAR_SPEC:
4777                 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
4778                 break;
4779         default:
4780                 break;
4781         }
4782
4783
4784         if (rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen)) {
4785
4786                 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);
4787                 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&capability, &capability_len);
4788
4789         }
4790
4791
4792         /* start to build provision_request frame        */
4793         _rtw_memset(wpsie, 0, sizeof(wpsie));
4794         _rtw_memset(p2p_ie, 0, sizeof(p2p_ie));
4795         p2p_ielen = 0;
4796
4797         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4798         if (pmgntframe == NULL)
4799                 return;
4800
4801
4802         /* update attribute */
4803         pattrib = &pmgntframe->attrib;
4804         update_mgntframe_attrib(padapter, pattrib);
4805
4806         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4807
4808         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4809         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4810
4811         fctrl = &(pwlanhdr->frame_ctl);
4812         *(fctrl) = 0;
4813
4814         _rtw_memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
4815         _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4816         _rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
4817
4818         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4819         pmlmeext->mgnt_seq++;
4820         SetFrameSubType(pframe, WIFI_ACTION);
4821
4822         pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4823         pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4824
4825         pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4826         pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4827         pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4828         pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4829         pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
4830
4831
4832         /* build_prov_disc_request_p2p_ie        */
4833         /*      P2P OUI */
4834         p2pielen = 0;
4835         p2p_ie[p2pielen++] = 0x50;
4836         p2p_ie[p2pielen++] = 0x6F;
4837         p2p_ie[p2pielen++] = 0x9A;
4838         p2p_ie[p2pielen++] = 0x09;      /*      WFA P2P v1.0 */
4839
4840         /*      Commented by Albert 20110301 */
4841         /*      According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes */
4842         /*      1. P2P Capability */
4843         /*      2. Device Info */
4844         /*      3. Group ID ( When joining an operating P2P Group ) */
4845
4846         /*      P2P Capability ATTR */
4847         /*      Type:    */
4848         p2p_ie[p2pielen++] = P2P_ATTR_CAPABILITY;
4849
4850         /*      Length: */
4851         /* *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); */
4852         RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
4853         p2pielen += 2;
4854
4855         /*      Value: */
4856         /*      Device Capability Bitmap, 1 byte */
4857         /*      Group Capability Bitmap, 1 byte */
4858         _rtw_memcpy(p2p_ie + p2pielen, &capability, 2);
4859         p2pielen += 2;
4860
4861
4862         /*      Device Info ATTR */
4863         /*      Type: */
4864         p2p_ie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
4865
4866         /*      Length: */
4867         /*      21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)  */
4868         /*      + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
4869         /* *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len ); */
4870         RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
4871         p2pielen += 2;
4872
4873         /*      Value: */
4874         _rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
4875         p2pielen += devinfo_contentlen;
4876
4877
4878         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);
4879         /* p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr); */
4880         /* pframe += p2pielen; */
4881         pattrib->pktlen += p2p_ielen;
4882
4883         wpsielen = 0;
4884         /*      WPS OUI */
4885         *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
4886         wpsielen += 4;
4887
4888         /*      WPS version */
4889         /*      Type: */
4890         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
4891         wpsielen += 2;
4892
4893         /*      Length: */
4894         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4895         wpsielen += 2;
4896
4897         /*      Value: */
4898         wpsie[wpsielen++] = WPS_VERSION_1;      /*      Version 1.0 */
4899
4900         /*      Config Method */
4901         /*      Type: */
4902         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
4903         wpsielen += 2;
4904
4905         /*      Length: */
4906         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
4907         wpsielen += 2;
4908
4909         /*      Value: */
4910         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
4911         wpsielen += 2;
4912
4913         pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
4914
4915
4916 #ifdef CONFIG_WFD
4917         wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
4918         pframe += wfdielen;
4919         pattrib->pktlen += wfdielen;
4920 #endif
4921
4922         pattrib->last_txcmdsz = pattrib->pktlen;
4923
4924         /* dump_mgntframe(padapter, pmgntframe); */
4925         if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
4926                 RTW_INFO("%s, ack to\n", __func__);
4927
4928         #if 0
4929         if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) {
4930                 RTW_INFO("waiting for p2p peer key-in PIN CODE\n");
4931                 rtw_msleep_os(15000); /* 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req. */
4932         }
4933         #endif
4934
4935 }
4936
4937 #ifdef CONFIG_RTW_80211R
4938 static s32 cfg80211_rtw_update_ft_ies(struct wiphy *wiphy,
4939         struct net_device *ndev,
4940         struct cfg80211_update_ft_ies_params *ftie)
4941 {
4942         _adapter *padapter = NULL;
4943         struct mlme_priv *pmlmepriv = NULL;
4944         ft_priv *pftpriv = NULL;
4945         _irqL irqL;
4946         u8 *p;
4947         u8 *pie = NULL;
4948         u32 ie_len = 0;
4949
4950         if (ndev == NULL)
4951                 return  -EINVAL;
4952
4953         padapter = (_adapter *)rtw_netdev_priv(ndev);
4954         pmlmepriv = &(padapter->mlmepriv);
4955         pftpriv = &pmlmepriv->ftpriv;
4956
4957         p = (u8 *)ftie->ie;
4958         if (ftie->ie_len <= sizeof(pftpriv->updated_ft_ies)) {
4959                 _enter_critical_bh(&pmlmepriv->lock, &irqL);
4960                 _rtw_memcpy(pftpriv->updated_ft_ies, ftie->ie, ftie->ie_len);
4961                 pftpriv->updated_ft_ies_len = ftie->ie_len;
4962                 _exit_critical_bh(&pmlmepriv->lock, &irqL);
4963         } else {
4964                 RTW_ERR("FTIEs parsing fail!\n");
4965                 return -EINVAL;
4966         }
4967
4968         if ((rtw_to_roam(padapter) > 0) && rtw_chk_ft_status(padapter, RTW_FT_AUTHENTICATED_STA)) {
4969                 RTW_PRINT("auth success, start reassoc\n");
4970                 _enter_critical_bh(&pmlmepriv->lock, &irqL);
4971                 rtw_set_ft_status(padapter, RTW_FT_ASSOCIATING_STA);
4972                 _exit_critical_bh(&pmlmepriv->lock, &irqL);
4973                 start_clnt_assoc(padapter);
4974         }
4975
4976         return 0;
4977 }
4978 #endif
4979
4980 inline void rtw_cfg80211_set_is_roch(_adapter *adapter, bool val)
4981 {
4982         adapter->cfg80211_wdinfo.is_ro_ch = val;
4983         rtw_mi_update_iface_status(&(adapter->mlmepriv), 0);
4984 }
4985
4986 inline bool rtw_cfg80211_get_is_roch(_adapter *adapter)
4987 {
4988         return adapter->cfg80211_wdinfo.is_ro_ch;
4989 }
4990
4991 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
4992 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
4993         struct wireless_dev *wdev,
4994 #else
4995         struct net_device *ndev,
4996 #endif
4997         struct ieee80211_channel *channel,
4998 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
4999         enum nl80211_channel_type channel_type,
5000 #endif
5001         unsigned int duration, u64 *cookie)
5002 {
5003         s32 err = 0;
5004         u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
5005         u8 union_ch = 0, union_bw = 0, union_offset = 0;
5006         u8 i;
5007         u8 ready_on_channel = _FALSE;
5008         _adapter *padapter = NULL;
5009         _adapter *iface;
5010         struct dvobj_priv *dvobj;
5011         struct rtw_wdev_priv *pwdev_priv;
5012         struct mlme_ext_priv *pmlmeext;
5013         struct wifidirect_info *pwdinfo;
5014         struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
5015         u8 is_p2p_find = _FALSE;
5016
5017 #ifndef CONFIG_RADIO_WORK
5018 #define RTW_ROCH_DURATION_ENLARGE
5019 #define RTW_ROCH_BACK_OP
5020 #endif
5021
5022 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5023         #if defined(RTW_DEDICATED_P2P_DEVICE)
5024         if (wdev == wiphy_to_pd_wdev(wiphy))
5025                 padapter = wiphy_to_adapter(wiphy);
5026         else
5027         #endif
5028         if (wdev_to_ndev(wdev))
5029                 padapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
5030         else {
5031                 err = -EINVAL;
5032                 goto exit;
5033         }
5034 #else
5035         struct wireless_dev *wdev;
5036
5037         if (ndev == NULL) {
5038                 err = -EINVAL;
5039                 goto exit;
5040         }
5041         padapter = (_adapter *)rtw_netdev_priv(ndev);
5042         wdev = ndev_to_wdev(ndev);
5043 #endif
5044
5045         dvobj = adapter_to_dvobj(padapter);
5046         pwdev_priv = adapter_wdev_data(padapter);
5047         pmlmeext = &padapter->mlmeextpriv;
5048         pwdinfo = &padapter->wdinfo;
5049         pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
5050 #ifdef CONFIG_CONCURRENT_MODE
5051         is_p2p_find = (duration < (pwdinfo->ext_listen_interval)) ? _TRUE : _FALSE;
5052 #endif
5053
5054         *cookie = ATOMIC_INC_RETURN(&pcfg80211_wdinfo->ro_ch_cookie_gen);
5055
5056         RTW_INFO(FUNC_ADPT_FMT"%s ch:%u duration:%d, cookie:0x%llx\n"
5057                 , FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : ""
5058                 , remain_ch, duration, *cookie);
5059
5060         if (rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) < 0) {
5061                 RTW_WARN(FUNC_ADPT_FMT" invalid ch:%u\n", FUNC_ADPT_ARG(padapter), remain_ch);
5062                 err = -EFAULT;
5063                 goto exit;
5064         }
5065
5066 #ifdef CONFIG_MP_INCLUDED
5067         if (rtw_mi_mp_mode_check(padapter)) {
5068                 RTW_INFO("MP mode block remain_on_channel request\n");
5069                 err = -EFAULT;
5070                 goto exit;
5071         }
5072 #endif
5073
5074         if (_FAIL == rtw_pwr_wakeup(padapter)) {
5075                 err = -EFAULT;
5076                 goto exit;
5077         }
5078
5079         rtw_scan_abort(padapter);
5080 #ifdef CONFIG_CONCURRENT_MODE
5081         /*don't scan_abort during p2p_listen.*/
5082         if (is_p2p_find)
5083                 rtw_mi_buddy_scan_abort(padapter, _TRUE);
5084 #endif /*CONFIG_CONCURRENT_MODE*/
5085
5086         if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) {
5087                 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
5088                 p2p_cancel_roch_cmd(padapter, 0, NULL, RTW_CMDF_WAIT_ACK);
5089         }
5090
5091         /* if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) */
5092         if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
5093                 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
5094                 padapter->wdinfo.listen_channel = remain_ch;
5095                 RTW_INFO(FUNC_ADPT_FMT" init listen_channel %u\n"
5096                         , FUNC_ADPT_ARG(padapter), padapter->wdinfo.listen_channel);
5097         } else if (rtw_p2p_chk_state(pwdinfo , P2P_STATE_LISTEN)
5098                 && (time_after_eq((unsigned long)rtw_get_current_time(), (unsigned long)pwdev_priv->probe_resp_ie_update_time)
5099                         && rtw_get_passing_time_ms(pwdev_priv->probe_resp_ie_update_time) < 50)
5100         ) {
5101                 if (padapter->wdinfo.listen_channel != remain_ch) {
5102                         padapter->wdinfo.listen_channel = remain_ch;
5103                         RTW_INFO(FUNC_ADPT_FMT" update listen_channel %u\n"
5104                                 , FUNC_ADPT_ARG(padapter), padapter->wdinfo.listen_channel);
5105                 }
5106         } else {
5107                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5108                 #ifdef CONFIG_DEBUG_CFG80211
5109                 RTW_INFO("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
5110                 #endif
5111         }
5112
5113         for (i = 0; i < dvobj->iface_nums; i++) {
5114                 iface = dvobj->padapters[i];
5115                 if (check_fwstate(&iface->mlmepriv, _FW_UNDER_LINKING | WIFI_UNDER_WPS) == _TRUE) {
5116                         RTW_INFO(ADPT_FMT"- _FW_UNDER_LINKING |WIFI_UNDER_WPS (mlme state:0x%x)\n", ADPT_ARG(iface), get_fwstate(&iface->mlmepriv));
5117                         remain_ch = iface->mlmeextpriv.cur_channel;
5118                 }
5119         }
5120
5121         rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
5122
5123         #ifdef RTW_ROCH_DURATION_ENLARGE
5124         if (duration < 400)
5125                 duration = duration * 3; /* extend from exper */
5126         #endif
5127
5128 #if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE)
5129         if (rtw_mi_check_status(padapter, MI_LINKED)) {
5130                 if (is_p2p_find) /* p2p_find , duration<1000 */
5131                         duration = duration + pwdinfo->ext_listen_interval;
5132                 else /* p2p_listen, duration=5000 */
5133                         duration = pwdinfo->ext_listen_interval + (pwdinfo->ext_listen_interval / 4);
5134         }
5135 #endif /*defined (RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) */
5136
5137         rtw_cfg80211_set_is_roch(padapter, _TRUE);
5138         pcfg80211_wdinfo->ro_ch_wdev = wdev;
5139         pcfg80211_wdinfo->remain_on_ch_cookie = *cookie;
5140         pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
5141         _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
5142         #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
5143         pcfg80211_wdinfo->remain_on_ch_type = channel_type;
5144         #endif
5145         pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter);
5146
5147 #ifdef CONFIG_CONCURRENT_MODE
5148         if (rtw_mi_check_status(padapter, MI_LINKED) && (0 != rtw_mi_get_union_chan(padapter))) {
5149                 if ((remain_ch != rtw_mi_get_union_chan(padapter)) && !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
5150                         if (ATOMIC_READ(&pwdev_priv->switch_ch_to) == 1 ||
5151                                 (remain_ch != pmlmeext->cur_channel)) {
5152
5153                                 rtw_mi_buddy_issue_nulldata(padapter, NULL, 1, 3, 500);
5154                                 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
5155
5156                                 #ifdef RTW_ROCH_BACK_OP
5157                                 RTW_INFO("%s, set switch ch timer, duration=%d\n", __func__, duration - pwdinfo->ext_listen_interval);
5158                                 _set_timer(&pwdinfo->ap_p2p_switch_timer, duration - pwdinfo->ext_listen_interval);
5159                                 #endif
5160                         }
5161                 }
5162                 ready_on_channel = _TRUE;
5163         } else
5164 #endif /* CONFIG_CONCURRENT_MODE */
5165         {
5166                 if (remain_ch != rtw_get_oper_ch(padapter))
5167                         ready_on_channel = _TRUE;
5168         }
5169
5170         if (ready_on_channel == _TRUE) {
5171                 #ifndef RTW_SINGLE_WIPHY
5172                 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
5173                 #endif
5174                 {
5175                         #ifdef CONFIG_CONCURRENT_MODE
5176                         if (rtw_get_oper_ch(padapter) != remain_ch)
5177                         #endif
5178                         {
5179                                 /* if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic) */
5180                                 set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5181                         }
5182                 }
5183         }
5184
5185 #ifdef CONFIG_BT_COEXIST
5186         rtw_btcoex_ScanNotify(padapter, _TRUE);
5187 #endif
5188
5189         RTW_INFO("%s, set ro ch timer, duration=%d\n", __func__, duration);
5190         _set_timer(&pcfg80211_wdinfo->remain_on_ch_timer, duration);
5191
5192         rtw_cfg80211_ready_on_channel(wdev, *cookie, channel, channel_type, duration, GFP_KERNEL);
5193
5194 exit:
5195         return err;
5196 }
5197
5198 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
5199 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5200         struct wireless_dev *wdev,
5201 #else
5202         struct net_device *ndev,
5203 #endif
5204         u64 cookie)
5205 {
5206         s32 err = 0;
5207         _adapter *padapter;
5208         struct rtw_wdev_priv *pwdev_priv;
5209         struct wifidirect_info *pwdinfo;
5210         struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
5211
5212 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5213         #if defined(RTW_DEDICATED_P2P_DEVICE)
5214         if (wdev == wiphy_to_pd_wdev(wiphy))
5215                 padapter = wiphy_to_adapter(wiphy);
5216         else
5217         #endif
5218         if (wdev_to_ndev(wdev))
5219                 padapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
5220         else {
5221                 err = -EINVAL;
5222                 goto exit;
5223         }
5224 #else
5225         struct wireless_dev *wdev;
5226
5227         if (ndev == NULL) {
5228                 err = -EINVAL;
5229                 goto exit;
5230         }
5231         padapter = (_adapter *)rtw_netdev_priv(ndev);
5232         wdev = ndev_to_wdev(ndev);
5233 #endif
5234
5235         pwdev_priv = adapter_wdev_data(padapter);
5236         pwdinfo = &padapter->wdinfo;
5237         pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
5238
5239         RTW_INFO(FUNC_ADPT_FMT"%s cookie:0x%llx\n"
5240                 , FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : ""
5241                 , cookie);
5242
5243         if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) {
5244                 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
5245                 p2p_cancel_roch_cmd(padapter, cookie, wdev, RTW_CMDF_WAIT_ACK);
5246         }
5247
5248 exit:
5249         return err;
5250 }
5251
5252 inline int rtw_cfg80211_iface_has_p2p_group_cap(_adapter *adapter)
5253 {
5254         struct wiphy *wiphy = adapter_to_wiphy(adapter);
5255         struct rtw_wdev_priv *wdev_data = adapter_wdev_data(adapter);
5256
5257 #if RTW_P2P_GROUP_INTERFACE
5258         if (is_primary_adapter(adapter))
5259                 return 0;
5260 #endif
5261         return 1;
5262 }
5263
5264 inline int rtw_cfg80211_is_p2p_scan(_adapter *adapter)
5265 {
5266 #if RTW_P2P_GROUP_INTERFACE
5267         if (rtw_cfg80211_iface_has_p2p_group_cap(adapter))
5268 #endif
5269         {
5270                 struct wifidirect_info *wdinfo = &adapter->wdinfo;
5271
5272                 return rtw_p2p_chk_state(wdinfo, P2P_STATE_SCAN)
5273                         || rtw_p2p_chk_state(wdinfo, P2P_STATE_FIND_PHASE_SEARCH);
5274         }
5275
5276 #if RTW_P2P_GROUP_INTERFACE
5277         #if defined(RTW_DEDICATED_P2P_DEVICE)
5278         if (wiphy_to_pd_wdev(adapter_to_wiphy(adapter))) /* pd_wdev exist */
5279                 return rtw_cfg80211_is_scan_by_pd_wdev(adapter);
5280         #endif
5281         {
5282                 /*
5283                 * For 2 RTW_P2P_GROUP_INTERFACE cases:
5284                 * 1. RTW_DEDICATED_P2P_DEVICE defined but upper layer don't use pd_wdev or
5285                 * 2. RTW_DEDICATED_P2P_DEVICE not defined
5286                 */
5287                 struct rtw_wdev_priv *wdev_data = adapter_wdev_data(adapter);
5288                 _irqL irqL;
5289                 int is_p2p_scan = 0;
5290
5291                 _enter_critical_bh(&wdev_data->scan_req_lock, &irqL);
5292                 if (wdev_data->scan_request
5293                         && wdev_data->scan_request->ssids
5294                         && wdev_data->scan_request->ie
5295                 ) {
5296                         if (_rtw_memcmp(wdev_data->scan_request->ssids->ssid, "DIRECT-", 7)
5297                                 && rtw_get_p2p_ie((u8 *)wdev_data->scan_request->ie, wdev_data->scan_request->ie_len, NULL, NULL))
5298                                 is_p2p_scan = 1;
5299                 }
5300                 _exit_critical_bh(&wdev_data->scan_req_lock, &irqL);
5301
5302                 return is_p2p_scan;
5303         }
5304 #endif
5305 }
5306
5307 #if defined(RTW_DEDICATED_P2P_DEVICE)
5308 int rtw_pd_iface_alloc(struct wiphy *wiphy, const char *name, struct wireless_dev **pd_wdev)
5309 {
5310         struct rtw_wiphy_data *wiphy_data = rtw_wiphy_priv(wiphy);
5311         struct wireless_dev *wdev = NULL;
5312         struct rtw_netdev_priv_indicator *npi;
5313         _adapter *primary_adpt = wiphy_to_adapter(wiphy);
5314         int ret = 0;
5315
5316         if (wiphy_data->pd_wdev) {
5317                 RTW_WARN(FUNC_WIPHY_FMT" pd_wdev already exists\n", FUNC_WIPHY_ARG(wiphy));
5318                 ret = -EBUSY;
5319                 goto exit;
5320         }
5321
5322         wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
5323         if (!wdev) {
5324                 RTW_WARN(FUNC_WIPHY_FMT" allocate wdev fail\n", FUNC_WIPHY_ARG(wiphy));
5325                 ret = -ENOMEM;
5326                 goto exit;
5327         }
5328
5329         wdev->wiphy = wiphy;
5330         wdev->iftype = NL80211_IFTYPE_P2P_DEVICE;
5331         _rtw_memcpy(wdev->address, adapter_mac_addr(primary_adpt), ETH_ALEN);
5332
5333         wiphy_data->pd_wdev = wdev;
5334         *pd_wdev = wdev;
5335
5336         RTW_INFO(FUNC_WIPHY_FMT" pd_wdev:%p, addr="MAC_FMT" added\n"
5337                 , FUNC_WIPHY_ARG(wiphy), wdev, MAC_ARG(wdev_address(wdev)));
5338
5339 exit:
5340         if (ret && wdev) {
5341                 rtw_mfree((u8 *)wdev, sizeof(struct wireless_dev));
5342                 wdev = NULL;
5343         }
5344
5345         return ret;
5346 }
5347
5348 void rtw_pd_iface_free(struct wiphy *wiphy)
5349 {
5350         struct rtw_wiphy_data *wiphy_data = rtw_wiphy_priv(wiphy);
5351         int rtnl_locked;
5352
5353         if (!wiphy_data->pd_wdev)
5354                 goto exit;
5355
5356         RTW_INFO(FUNC_WIPHY_FMT" pd_wdev:%p, addr="MAC_FMT"\n"
5357                 , FUNC_WIPHY_ARG(wiphy), wiphy_data->pd_wdev
5358                 , MAC_ARG(wdev_address(wiphy_data->pd_wdev)));
5359
5360         rtnl_locked = rtnl_is_locked();
5361         if (!rtnl_locked)
5362                 rtnl_lock();
5363         cfg80211_unregister_wdev(wiphy_data->pd_wdev);
5364         if (!rtnl_locked)
5365                 rtnl_unlock();
5366
5367         rtw_mfree((u8 *)wiphy_data->pd_wdev, sizeof(struct wireless_dev));
5368         wiphy_data->pd_wdev = NULL;
5369
5370 exit:
5371         return;
5372 }
5373
5374 static int cfg80211_rtw_start_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev)
5375 {
5376         _adapter *adapter = wiphy_to_adapter(wiphy);
5377
5378         RTW_INFO(FUNC_WIPHY_FMT" wdev=%p\n", FUNC_WIPHY_ARG(wiphy), wdev);
5379
5380         rtw_p2p_enable(adapter, P2P_ROLE_DEVICE);
5381         return 0;
5382 }
5383
5384 static void cfg80211_rtw_stop_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev)
5385 {
5386         _adapter *adapter = wiphy_to_adapter(wiphy);
5387
5388         RTW_INFO(FUNC_WIPHY_FMT" wdev=%p\n", FUNC_WIPHY_ARG(wiphy), wdev);
5389
5390         if (rtw_cfg80211_is_p2p_scan(adapter))
5391                 rtw_scan_abort(adapter);
5392
5393         rtw_p2p_enable(adapter, P2P_ROLE_DISABLE);
5394 }
5395
5396 inline int rtw_cfg80211_redirect_pd_wdev(struct wiphy *wiphy, u8 *ra, struct wireless_dev **wdev)
5397 {
5398         struct wireless_dev *pd_wdev = wiphy_to_pd_wdev(wiphy);
5399
5400         if (pd_wdev && pd_wdev != *wdev
5401                 && _rtw_memcmp(wdev_address(pd_wdev), ra, ETH_ALEN) == _TRUE
5402         ) {
5403                 *wdev = pd_wdev;
5404                 return 1;
5405         }
5406         return 0;
5407 }
5408
5409 inline int rtw_cfg80211_is_scan_by_pd_wdev(_adapter *adapter)
5410 {
5411         struct wiphy *wiphy = adapter_to_wiphy(adapter);
5412         struct rtw_wdev_priv *wdev_data = adapter_wdev_data(adapter);
5413         struct wireless_dev *wdev = NULL;
5414         _irqL irqL;
5415
5416         _enter_critical_bh(&wdev_data->scan_req_lock, &irqL);
5417         if (wdev_data->scan_request)
5418                 wdev = wdev_data->scan_request->wdev;
5419         _exit_critical_bh(&wdev_data->scan_req_lock, &irqL);
5420
5421         if (wdev && wdev == wiphy_to_pd_wdev(wiphy))
5422                 return 1;
5423
5424         return 0;
5425 }
5426 #endif /* RTW_DEDICATED_P2P_DEVICE */
5427 #endif /* CONFIG_P2P */
5428
5429 inline void rtw_cfg80211_set_is_mgmt_tx(_adapter *adapter, u8 val)
5430 {
5431         struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
5432
5433         wdev_priv->is_mgmt_tx = val;
5434         rtw_mi_update_iface_status(&(adapter->mlmepriv), 0);
5435 }
5436
5437 inline u8 rtw_cfg80211_get_is_mgmt_tx(_adapter *adapter)
5438 {
5439         struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
5440
5441         return wdev_priv->is_mgmt_tx;
5442 }
5443
5444 static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, u8 no_cck, const u8 *buf, size_t len, int wait_ack)
5445 {
5446         struct xmit_frame       *pmgntframe;
5447         struct pkt_attrib       *pattrib;
5448         unsigned char   *pframe;
5449         int ret = _FAIL;
5450         bool ack = _TRUE;
5451         struct rtw_ieee80211_hdr *pwlanhdr;
5452         struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
5453         struct xmit_priv        *pxmitpriv = &(padapter->xmitpriv);
5454         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5455         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
5456
5457 #ifdef CONFIG_P2P
5458         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
5459 #endif /* CONFIG_P2P */
5460         /* struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; */
5461
5462         rtw_mi_set_scan_deny(padapter, 1000);
5463         rtw_mi_scan_abort(padapter, _TRUE);
5464
5465         rtw_cfg80211_set_is_mgmt_tx(padapter, 1);
5466
5467 #ifdef CONFIG_BT_COEXIST
5468         rtw_btcoex_ScanNotify(padapter, _TRUE);
5469 #endif
5470
5471 #ifdef CONFIG_P2P
5472         if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) {
5473                 #ifdef CONFIG_CONCURRENT_MODE
5474                 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
5475                         RTW_INFO("%s, extend ro ch time\n", __func__);
5476                         _set_timer(&padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
5477                 }
5478                 #endif /* CONFIG_CONCURRENT_MODE */
5479         }
5480 #endif /* CONFIG_P2P */
5481 #ifdef CONFIG_CONCURRENT_MODE
5482         if (rtw_mi_check_status(padapter, MI_LINKED)) {
5483                 u8 union_ch = rtw_mi_get_union_chan(padapter);
5484                 u8 co_channel = 0xff;
5485                 co_channel = rtw_get_oper_ch(padapter);
5486
5487                 if (tx_ch != union_ch) {
5488                         u16 ext_listen_period;
5489
5490                         if (ATOMIC_READ(&pwdev_priv->switch_ch_to) == 1) {
5491                                 rtw_mi_buddy_issue_nulldata(padapter, NULL, 1, 3, 500);
5492                                 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
5493                                 /* RTW_INFO("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period); */
5494                                 /* _set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period); */
5495                         }
5496
5497                         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED))
5498                                 ext_listen_period = 500;/*500ms*/
5499 #ifdef CONFIG_P2P                               
5500                         else
5501                                 ext_listen_period = pwdinfo->ext_listen_period;
5502
5503                         _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period);
5504 #endif
5505                         RTW_INFO("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period);
5506                 }
5507
5508                 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
5509                         pmlmeext->cur_channel = tx_ch;
5510
5511                 if (tx_ch != co_channel)
5512                         set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5513         } else
5514 #endif /* CONFIG_CONCURRENT_MODE */
5515         /* if (tx_ch != pmlmeext->cur_channel) { */
5516         if (tx_ch != rtw_get_oper_ch(padapter)) {
5517                 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
5518                         pmlmeext->cur_channel = tx_ch;
5519                 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5520         }
5521
5522         /* starting alloc mgmt frame to dump it */
5523         pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5524         if (pmgntframe == NULL) {
5525                 /* ret = -ENOMEM; */
5526                 ret = _FAIL;
5527                 goto exit;
5528         }
5529
5530         /* update attribute */
5531         pattrib = &pmgntframe->attrib;
5532         update_mgntframe_attrib(padapter, pattrib);
5533
5534         if (no_cck && IS_CCK_RATE(pattrib->rate)) {
5535                 /* force OFDM 6M rate*/
5536                 pattrib->rate = MGN_6M;
5537                 pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11G);
5538         }
5539
5540         pattrib->retry_ctrl = _FALSE;
5541
5542         _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5543
5544         pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5545
5546         _rtw_memcpy(pframe, (void *)buf, len);
5547         pattrib->pktlen = len;
5548
5549         pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5550         /* update seq number */
5551         pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
5552         pattrib->seqnum = pmlmeext->mgnt_seq;
5553         pmlmeext->mgnt_seq++;
5554
5555 #ifdef CONFIG_P2P
5556         rtw_xframe_chk_wfd_ie(pmgntframe);
5557 #endif /* CONFIG_P2P */
5558
5559         pattrib->last_txcmdsz = pattrib->pktlen;
5560
5561         if (wait_ack) {
5562                 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS) {
5563                         ack = _FALSE;
5564                         ret = _FAIL;
5565
5566 #ifdef CONFIG_DEBUG_CFG80211
5567                         RTW_INFO("%s, ack == _FAIL\n", __func__);
5568 #endif
5569                 } else {
5570
5571 #ifdef CONFIG_XMIT_ACK
5572                         rtw_msleep_os(50);
5573 #endif
5574 #ifdef CONFIG_DEBUG_CFG80211
5575                         RTW_INFO("%s, ack=%d, ok!\n", __func__, ack);
5576 #endif
5577                         ret = _SUCCESS;
5578                 }
5579         } else {
5580                 dump_mgntframe(padapter, pmgntframe);
5581                 ret = _SUCCESS;
5582         }
5583 exit:
5584         rtw_cfg80211_set_is_mgmt_tx(padapter, 0);
5585
5586 #ifdef CONFIG_BT_COEXIST
5587         rtw_btcoex_ScanNotify(padapter, _FALSE);
5588 #endif
5589
5590 #ifdef CONFIG_DEBUG_CFG80211
5591         RTW_INFO("%s, ret=%d\n", __func__, ret);
5592 #endif
5593
5594         return ret;
5595
5596 }
5597
5598 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
5599 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5600         struct wireless_dev *wdev,
5601 #else
5602         struct net_device *ndev,
5603 #endif
5604 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) || defined(COMPAT_KERNEL_RELEASE)
5605         struct ieee80211_channel *chan,
5606         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
5607         bool offchan,
5608         #endif
5609         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
5610         enum nl80211_channel_type channel_type,
5611         #endif
5612         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
5613         bool channel_type_valid,
5614         #endif
5615         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
5616         unsigned int wait,
5617         #endif
5618         const u8 *buf, size_t len,
5619         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
5620         bool no_cck,
5621         #endif
5622         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
5623         bool dont_wait_for_ack,
5624         #endif
5625 #else
5626         struct cfg80211_mgmt_tx_params *params,
5627 #endif
5628         u64 *cookie)
5629 {
5630 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(COMPAT_KERNEL_RELEASE)
5631         struct ieee80211_channel *chan = params->chan;
5632         bool offchan = params->offchan;
5633         unsigned int wait = params->wait;
5634         const u8 *buf = params->buf;
5635         size_t len = params->len;
5636         bool no_cck = params->no_cck;
5637         bool dont_wait_for_ack = params->dont_wait_for_ack;
5638 #endif
5639 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
5640         bool no_cck = 0;
5641 #endif
5642         int ret = 0;
5643         int tx_ret;
5644         int wait_ack = 1;
5645         u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
5646         u32 dump_cnt = 0;
5647         bool ack = _TRUE;
5648         u8 tx_ch;
5649         u8 category, action;
5650         u8 frame_styp;
5651         int type = (-1);
5652         u32 start = rtw_get_current_time();
5653         _adapter *padapter;
5654         struct dvobj_priv *dvobj;
5655         struct rtw_wdev_priv *pwdev_priv;
5656
5657 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5658         #if defined(RTW_DEDICATED_P2P_DEVICE)
5659         if (wdev == wiphy_to_pd_wdev(wiphy))
5660                 padapter = wiphy_to_adapter(wiphy);
5661         else
5662         #endif
5663         if (wdev_to_ndev(wdev))
5664                 padapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
5665         else {
5666                 ret = -EINVAL;
5667                 goto exit;
5668         }
5669 #else
5670         struct wireless_dev *wdev;
5671
5672         if (ndev == NULL) {
5673                 ret = -EINVAL;
5674                 goto exit;
5675         }
5676         padapter = (_adapter *)rtw_netdev_priv(ndev);
5677         wdev = ndev_to_wdev(ndev);
5678 #endif
5679
5680         if (chan == NULL) {
5681                 ret = -EINVAL;
5682                 goto exit;
5683         }
5684
5685         tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
5686
5687         dvobj = adapter_to_dvobj(padapter);
5688         pwdev_priv = adapter_wdev_data(padapter);
5689
5690         /* cookie generation */
5691         *cookie = (unsigned long) buf;
5692
5693 #ifdef CONFIG_DEBUG_CFG80211
5694         RTW_INFO(FUNC_ADPT_FMT"%s len=%zu, ch=%d"
5695                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
5696                 ", ch_type=%d"
5697                 #endif
5698                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
5699                 ", channel_type_valid=%d"
5700                 #endif
5701                 "\n", FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : ""
5702                 , len, tx_ch
5703                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
5704                 , channel_type
5705                 #endif
5706                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
5707                 , channel_type_valid
5708                 #endif
5709         );
5710 #endif /* CONFIG_DEBUG_CFG80211 */
5711
5712         /* indicate ack before issue frame to avoid racing with rsp frame */
5713 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
5714         rtw_cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack, GFP_KERNEL);
5715 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 36))
5716         cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
5717 #endif
5718
5719         frame_styp = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl) & IEEE80211_FCTL_STYPE;
5720         if (IEEE80211_STYPE_PROBE_RESP == frame_styp) {
5721 #ifdef CONFIG_DEBUG_CFG80211
5722                 RTW_INFO("RTW_Tx: probe_resp tx_ch=%d, no_cck=%u, da="MAC_FMT"\n", tx_ch, no_cck, MAC_ARG(GetAddr1Ptr(buf)));
5723 #endif /* CONFIG_DEBUG_CFG80211 */
5724                 wait_ack = 0;
5725                 goto dump;
5726         }
5727
5728         if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
5729                 RTW_INFO(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
5730                         le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
5731                 goto exit;
5732         }
5733
5734         RTW_INFO("RTW_Tx:tx_ch=%d, no_cck=%u, da="MAC_FMT"\n", tx_ch, no_cck, MAC_ARG(GetAddr1Ptr(buf)));
5735 #ifdef CONFIG_P2P
5736         type = rtw_p2p_check_frames(padapter, buf, len, _TRUE);
5737         if (type >= 0) {
5738                 no_cck = 1; /* force no CCK for P2P frames */
5739                 goto dump;
5740         }
5741 #endif
5742         if (category == RTW_WLAN_CATEGORY_PUBLIC)
5743                 RTW_INFO("RTW_Tx:%s\n", action_public_str(action));
5744         else
5745                 RTW_INFO("RTW_Tx:category(%u), action(%u)\n", category, action);
5746
5747 dump:
5748
5749         rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
5750         if (_FAIL == rtw_pwr_wakeup(padapter)) {
5751                 ret = -EFAULT;
5752                 goto cancel_ps_deny;
5753         }
5754
5755         while (1) {
5756                 u32 sleep_ms = 0;
5757                 u32 retry_guarantee_ms = 0;
5758
5759                 dump_cnt++;
5760                 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, no_cck, buf, len, wait_ack);
5761
5762                 switch (action) {
5763                 case ACT_PUBLIC_GAS_INITIAL_REQ:
5764                 case ACT_PUBLIC_GAS_INITIAL_RSP:
5765                         sleep_ms = 50;
5766                         retry_guarantee_ms = RTW_MAX_MGMT_TX_MS_GAS;
5767                 }
5768
5769                 if (tx_ret == _SUCCESS
5770                         || (dump_cnt >= dump_limit && rtw_get_passing_time_ms(start) >= retry_guarantee_ms))
5771                         break;
5772
5773                 if (sleep_ms > 0)
5774                         rtw_msleep_os(sleep_ms);
5775         }
5776
5777         if (tx_ret != _SUCCESS || dump_cnt > 1) {
5778                 RTW_INFO(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
5779                         tx_ret == _SUCCESS ? "OK" : "FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
5780         }
5781
5782         switch (type) {
5783         case P2P_GO_NEGO_CONF:
5784                 if (0) {
5785                         RTW_INFO(FUNC_ADPT_FMT" Nego confirm. state=%u, status=%u, iaddr="MAC_FMT"\n"
5786                                 , FUNC_ADPT_ARG(padapter), pwdev_priv->nego_info.state, pwdev_priv->nego_info.status
5787                                 , MAC_ARG(pwdev_priv->nego_info.iface_addr));
5788                 }
5789                 if (pwdev_priv->nego_info.state == 2
5790                         && pwdev_priv->nego_info.status == 0
5791                         && rtw_check_invalid_mac_address(pwdev_priv->nego_info.iface_addr, _FALSE) == _FALSE
5792                 ) {
5793                         _adapter *intended_iface = dvobj_get_adapter_by_addr(dvobj, pwdev_priv->nego_info.iface_addr);
5794
5795                         if (intended_iface) {
5796                                 RTW_INFO(FUNC_ADPT_FMT" Nego confirm. Allow only "ADPT_FMT" to scan for 2000 ms\n"
5797                                         , FUNC_ADPT_ARG(padapter), ADPT_ARG(intended_iface));
5798                                 /* allow only intended_iface to do scan for 2000 ms */
5799                                 rtw_mi_set_scan_deny(padapter, 2000);
5800                                 rtw_clear_scan_deny(intended_iface);
5801                         }
5802                 }
5803                 break;
5804         case P2P_INVIT_RESP:
5805                 if (pwdev_priv->invit_info.flags & BIT(0)
5806                         && pwdev_priv->invit_info.status == 0
5807                 ) {
5808                         RTW_INFO(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
5809                                 FUNC_ADPT_ARG(padapter));
5810                         #if !RTW_P2P_GROUP_INTERFACE
5811                         rtw_mi_buddy_set_scan_deny(padapter, 5000);
5812                         #endif
5813                         rtw_pwr_wakeup_ex(padapter, 5000);
5814                 }
5815                 break;
5816         }
5817
5818 cancel_ps_deny:
5819         rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
5820 exit:
5821         return ret;
5822 }
5823
5824 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
5825 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5826         struct wireless_dev *wdev,
5827 #else
5828         struct net_device *ndev,
5829 #endif
5830         u16 frame_type, bool reg)
5831 {
5832 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
5833         struct net_device *ndev = wdev_to_ndev(wdev);
5834 #endif
5835         _adapter *adapter;
5836
5837         struct rtw_wdev_priv *pwdev_priv;
5838
5839         if (ndev == NULL)
5840                 goto exit;
5841
5842         adapter = (_adapter *)rtw_netdev_priv(ndev);
5843         pwdev_priv = adapter_wdev_data(adapter);
5844
5845 #ifdef CONFIG_DEBUG_CFG80211
5846         RTW_INFO(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
5847                 frame_type, reg);
5848 #endif
5849
5850         /* Wait QC Verify */
5851         return;
5852
5853         switch (frame_type) {
5854         case IEEE80211_STYPE_PROBE_REQ: /* 0x0040 */
5855                 SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ, reg);
5856                 break;
5857         case IEEE80211_STYPE_ACTION: /* 0x00D0 */
5858                 SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION, reg);
5859                 break;
5860         default:
5861                 break;
5862         }
5863
5864 exit:
5865         return;
5866 }
5867
5868 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
5869 static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy,
5870         struct net_device *ndev,
5871 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
5872         const u8 *peer,
5873 #else
5874         u8 *peer,
5875 #endif
5876         u8 action_code,
5877         u8 dialog_token,
5878         u16 status_code,
5879 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
5880         u32 peer_capability,
5881 #endif
5882 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
5883         bool initiator,
5884 #endif
5885         const u8 *buf,
5886         size_t len)
5887 {
5888         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
5889         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
5890         struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
5891         int ret = 0;
5892         struct tdls_txmgmt txmgmt;
5893
5894         if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
5895                 RTW_INFO("Discard tdls action:%d, since hal doesn't support tdls\n", action_code);
5896                 goto discard;
5897         }
5898
5899         if (rtw_tdls_is_driver_setup(padapter)) {
5900                 RTW_INFO("Discard tdls action:%d, let driver to set up direct link\n", action_code);
5901                 goto discard;
5902         }
5903
5904         _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
5905         _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
5906         txmgmt.action_code = action_code;
5907         txmgmt.dialog_token = dialog_token;
5908         txmgmt.status_code = status_code;
5909         txmgmt.len = len;
5910         txmgmt.buf = (u8 *)rtw_malloc(txmgmt.len);
5911         if (txmgmt.buf == NULL) {
5912                 ret = -ENOMEM;
5913                 goto bad;
5914         }
5915         _rtw_memcpy(txmgmt.buf, (void *)buf, txmgmt.len);
5916
5917         /* Debug purpose */
5918 #if 1
5919         RTW_INFO("%s %d\n", __FUNCTION__, __LINE__);
5920         RTW_INFO("peer:"MAC_FMT", action code:%d, dialog:%d, status code:%d\n",
5921                 MAC_ARG(txmgmt.peer), txmgmt.action_code,
5922                 txmgmt.dialog_token, txmgmt.status_code);
5923         if (txmgmt.len > 0) {
5924                 int i = 0;
5925                 for (; i < len; i++)
5926                         printk("%02x ", *(txmgmt.buf + i));
5927                 RTW_INFO("len:%d\n", (u32)txmgmt.len);
5928         }
5929 #endif
5930
5931         switch (txmgmt.action_code) {
5932         case TDLS_SETUP_REQUEST:
5933                 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
5934                 break;
5935         case TDLS_SETUP_RESPONSE:
5936                 issue_tdls_setup_rsp(padapter, &txmgmt);
5937                 break;
5938         case TDLS_SETUP_CONFIRM:
5939                 issue_tdls_setup_cfm(padapter, &txmgmt);
5940                 break;
5941         case TDLS_TEARDOWN:
5942                 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
5943                 break;
5944         case TDLS_DISCOVERY_REQUEST:
5945                 issue_tdls_dis_req(padapter, &txmgmt);
5946                 break;
5947         case TDLS_DISCOVERY_RESPONSE:
5948                 issue_tdls_dis_rsp(padapter, &txmgmt, pmlmeinfo->enc_algo ? _TRUE : _FALSE);
5949                 break;
5950         }
5951
5952 bad:
5953         if (txmgmt.buf)
5954                 rtw_mfree(txmgmt.buf, txmgmt.len);
5955
5956 discard:
5957         return ret;
5958 }
5959
5960 static int cfg80211_rtw_tdls_oper(struct wiphy *wiphy,
5961         struct net_device *ndev,
5962 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
5963         const u8 *peer,
5964 #else
5965         u8 *peer,
5966 #endif
5967         enum nl80211_tdls_operation oper)
5968 {
5969         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
5970         struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
5971         struct tdls_txmgmt      txmgmt;
5972         struct sta_info *ptdls_sta = NULL;
5973
5974         RTW_INFO(FUNC_NDEV_FMT", nl80211_tdls_operation:%d\n", FUNC_NDEV_ARG(ndev), oper);
5975
5976         if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
5977                 RTW_INFO("Discard tdls oper:%d, since hal doesn't support tdls\n", oper);
5978                 return 0;
5979         }
5980
5981 #ifdef CONFIG_LPS
5982         rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1);
5983 #endif /* CONFIG_LPS */
5984
5985         _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
5986         if (peer)
5987                 _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
5988
5989         if (rtw_tdls_is_driver_setup(padapter)) {
5990                 /* these two cases are done by driver itself */
5991                 if (oper == NL80211_TDLS_ENABLE_LINK || oper == NL80211_TDLS_DISABLE_LINK)
5992                         return 0;
5993         }
5994
5995         switch (oper) {
5996         case NL80211_TDLS_DISCOVERY_REQ:
5997                 issue_tdls_dis_req(padapter, &txmgmt);
5998                 break;
5999         case NL80211_TDLS_SETUP:
6000 #ifdef CONFIG_WFD
6001                 if (_AES_ != padapter->securitypriv.dot11PrivacyAlgrthm) {
6002                         if (padapter->wdinfo.wfd_tdls_weaksec == _TRUE)
6003                                 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
6004                         else
6005                                 RTW_INFO("[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__);
6006                 } else
6007 #endif /* CONFIG_WFD */
6008                 {
6009                         issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
6010                 }
6011                 break;
6012         case NL80211_TDLS_TEARDOWN:
6013                 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), txmgmt.peer);
6014                 if (ptdls_sta != NULL) {
6015                         txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
6016                         issue_tdls_teardown(padapter, &txmgmt, _TRUE);
6017                 } else
6018                         RTW_INFO("TDLS peer not found\n");
6019                 break;
6020         case NL80211_TDLS_ENABLE_LINK:
6021                 RTW_INFO(FUNC_NDEV_FMT", NL80211_TDLS_ENABLE_LINK;mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(peer));
6022                 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), (u8 *)peer);
6023                 if (ptdls_sta != NULL) {
6024                         ptdlsinfo->link_established = _TRUE;
6025                         ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE;
6026                         ptdls_sta->state |= _FW_LINKED;
6027                         rtw_tdls_cmd(padapter, txmgmt.peer, TDLS_ESTABLISHED);
6028                 }
6029                 break;
6030         case NL80211_TDLS_DISABLE_LINK:
6031                 RTW_INFO(FUNC_NDEV_FMT", NL80211_TDLS_DISABLE_LINK;mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(peer));
6032                 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), (u8 *)peer);
6033                 if (ptdls_sta != NULL)
6034                         rtw_tdls_cmd(padapter, (u8 *)peer, TDLS_TEARDOWN_STA_LOCALLY);
6035                 break;
6036         }
6037         return 0;
6038 }
6039 #endif /* CONFIG_TDLS */
6040
6041 #if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
6042 static int cfg80211_rtw_sched_scan_start(struct wiphy *wiphy,
6043                 struct net_device *dev,
6044                 struct cfg80211_sched_scan_request *request)
6045 {
6046
6047         _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6048         struct  mlme_priv       *pmlmepriv = &(padapter->mlmepriv);
6049         u8 ret;
6050
6051         if (padapter->bup == _FALSE) {
6052                 RTW_INFO("%s: net device is down.\n", __func__);
6053                 return -EIO;
6054         }
6055
6056         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE ||
6057                 check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE  ||
6058                 check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
6059                 RTW_INFO("%s: device is busy.\n", __func__);
6060                 rtw_scan_abort(padapter);
6061         }
6062
6063         if (request == NULL) {
6064                 RTW_INFO("%s: invalid cfg80211_requests parameters.\n", __func__);
6065                 return -EINVAL;
6066         }
6067
6068         ret = rtw_android_cfg80211_pno_setup(dev, request->ssids,
6069                         request->n_ssids, request->interval);
6070
6071         if (ret < 0) {
6072                 RTW_INFO("%s ret: %d\n", __func__, ret);
6073                 goto exit;
6074         }
6075
6076         ret = rtw_android_pno_enable(dev, _TRUE);
6077         if (ret < 0) {
6078                 RTW_INFO("%s ret: %d\n", __func__, ret);
6079                 goto exit;
6080         }
6081 exit:
6082         return ret;
6083 }
6084
6085 static int cfg80211_rtw_sched_scan_stop(struct wiphy *wiphy,
6086                 struct net_device *dev)
6087 {
6088         return rtw_android_pno_enable(dev, _FALSE);
6089 }
6090 #endif /* CONFIG_PNO_SUPPORT */
6091
6092 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
6093 {
6094         int ret = 0;
6095         uint wps_ielen = 0;
6096         u8 *wps_ie;
6097         u32     p2p_ielen = 0;
6098         u8 wps_oui[8] = {0x0, 0x50, 0xf2, 0x04};
6099         u8 *p2p_ie;
6100         u32     wfd_ielen = 0;
6101         u8 *wfd_ie;
6102         _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
6103         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6104         struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6105
6106         RTW_INFO(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
6107
6108         if (len > 0) {
6109                 wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen);
6110                 if (wps_ie) {
6111                         #ifdef CONFIG_DEBUG_CFG80211
6112                         RTW_INFO("bcn_wps_ielen=%d\n", wps_ielen);
6113                         #endif
6114
6115                         if (pmlmepriv->wps_beacon_ie) {
6116                                 u32 free_len = pmlmepriv->wps_beacon_ie_len;
6117                                 pmlmepriv->wps_beacon_ie_len = 0;
6118                                 rtw_mfree(pmlmepriv->wps_beacon_ie, free_len);
6119                                 pmlmepriv->wps_beacon_ie = NULL;
6120                         }
6121
6122                         pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen);
6123                         if (pmlmepriv->wps_beacon_ie == NULL) {
6124                                 RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6125                                 return -EINVAL;
6126
6127                         }
6128
6129                         _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
6130                         pmlmepriv->wps_beacon_ie_len = wps_ielen;
6131
6132                         update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
6133
6134                 }
6135
6136                 /* buf += wps_ielen; */
6137                 /* len -= wps_ielen; */
6138
6139                 #ifdef CONFIG_P2P
6140                 p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen);
6141                 if (p2p_ie) {
6142                         #ifdef CONFIG_DEBUG_CFG80211
6143                         RTW_INFO("bcn_p2p_ielen=%d\n", p2p_ielen);
6144                         #endif
6145
6146                         if (pmlmepriv->p2p_beacon_ie) {
6147                                 u32 free_len = pmlmepriv->p2p_beacon_ie_len;
6148                                 pmlmepriv->p2p_beacon_ie_len = 0;
6149                                 rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len);
6150                                 pmlmepriv->p2p_beacon_ie = NULL;
6151                         }
6152
6153                         pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen);
6154                         if (pmlmepriv->p2p_beacon_ie == NULL) {
6155                                 RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6156                                 return -EINVAL;
6157
6158                         }
6159
6160                         _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
6161                         pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
6162
6163                 }
6164                 #endif /* CONFIG_P2P */
6165
6166
6167                 #ifdef CONFIG_WFD
6168                 wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen);
6169                 if (wfd_ie) {
6170                         #ifdef CONFIG_DEBUG_CFG80211
6171                         RTW_INFO("bcn_wfd_ielen=%d\n", wfd_ielen);
6172                         #endif
6173
6174                         if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_BEACON_IE, wfd_ie, wfd_ielen) != _SUCCESS)
6175                                 return -EINVAL;
6176                 }
6177                 #endif /* CONFIG_WFD */
6178
6179                 pmlmeext->bstart_bss = _TRUE;
6180
6181         }
6182
6183         return ret;
6184
6185 }
6186
6187 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
6188 {
6189         int ret = 0;
6190         uint wps_ielen = 0;
6191         u8 *wps_ie;
6192         u32     p2p_ielen = 0;
6193         u8 *p2p_ie;
6194         u32     wfd_ielen = 0;
6195         u8 *wfd_ie;
6196         _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
6197         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6198
6199 #ifdef CONFIG_DEBUG_CFG80211
6200         RTW_INFO("%s, ielen=%d\n", __func__, len);
6201 #endif
6202
6203         if (len > 0) {
6204                 wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen);
6205                 if (wps_ie) {
6206                         uint    attr_contentlen = 0;
6207                         u16     uconfig_method, *puconfig_method = NULL;
6208
6209                         #ifdef CONFIG_DEBUG_CFG80211
6210                         RTW_INFO("probe_resp_wps_ielen=%d\n", wps_ielen);
6211                         #endif
6212
6213                         if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
6214                                 u8 sr = 0;
6215                                 rtw_get_wps_attr_content(wps_ie,  wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
6216
6217                                 if (sr != 0)
6218                                         RTW_INFO("%s, got sr\n", __func__);
6219                                 else {
6220                                         RTW_INFO("GO mode process WPS under site-survey,  sr no set\n");
6221                                         return ret;
6222                                 }
6223                         }
6224
6225                         if (pmlmepriv->wps_probe_resp_ie) {
6226                                 u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
6227                                 pmlmepriv->wps_probe_resp_ie_len = 0;
6228                                 rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len);
6229                                 pmlmepriv->wps_probe_resp_ie = NULL;
6230                         }
6231
6232                         pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen);
6233                         if (pmlmepriv->wps_probe_resp_ie == NULL) {
6234                                 RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6235                                 return -EINVAL;
6236
6237                         }
6238
6239                         /* add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode */
6240                         puconfig_method = (u16 *)rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen);
6241                         if (puconfig_method != NULL) {
6242                                 /* struct registry_priv *pregistrypriv = &padapter->registrypriv; */
6243                                 struct wireless_dev *wdev = padapter->rtw_wdev;
6244
6245                                 #ifdef CONFIG_DEBUG_CFG80211
6246                                 /* printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method)); */
6247                                 #endif
6248
6249                                 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
6250                                 /* for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags */
6251                                 if (wdev->iftype == NL80211_IFTYPE_P2P_GO) {
6252                                         uconfig_method = WPS_CM_PUSH_BUTTON;
6253                                         uconfig_method = cpu_to_be16(uconfig_method);
6254
6255                                         *puconfig_method &= ~uconfig_method;
6256                                 }
6257                                 #endif
6258                         }
6259
6260                         _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
6261                         pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
6262
6263                 }
6264
6265                 /* buf += wps_ielen; */
6266                 /* len -= wps_ielen; */
6267
6268                 #ifdef CONFIG_P2P
6269                 p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen);
6270                 if (p2p_ie) {
6271                         u8 is_GO = _FALSE;
6272                         u32 attr_contentlen = 0;
6273                         u16 cap_attr = 0;
6274
6275                         #ifdef CONFIG_DEBUG_CFG80211
6276                         RTW_INFO("probe_resp_p2p_ielen=%d\n", p2p_ielen);
6277                         #endif
6278
6279                         /* Check P2P Capability ATTR */
6280                         if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&cap_attr, (uint *) &attr_contentlen)) {
6281                                 u8 grp_cap = 0;
6282                                 /* RTW_INFO( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ ); */
6283                                 cap_attr = le16_to_cpu(cap_attr);
6284                                 grp_cap = (u8)((cap_attr >> 8) & 0xff);
6285
6286                                 is_GO = (grp_cap & BIT(0)) ? _TRUE : _FALSE;
6287
6288                                 if (is_GO)
6289                                         RTW_INFO("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
6290                         }
6291
6292
6293                         if (is_GO == _FALSE) {
6294                                 if (pmlmepriv->p2p_probe_resp_ie) {
6295                                         u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
6296                                         pmlmepriv->p2p_probe_resp_ie_len = 0;
6297                                         rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len);
6298                                         pmlmepriv->p2p_probe_resp_ie = NULL;
6299                                 }
6300
6301                                 pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen);
6302                                 if (pmlmepriv->p2p_probe_resp_ie == NULL) {
6303                                         RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6304                                         return -EINVAL;
6305
6306                                 }
6307                                 _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
6308                                 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
6309                         } else {
6310                                 if (pmlmepriv->p2p_go_probe_resp_ie) {
6311                                         u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
6312                                         pmlmepriv->p2p_go_probe_resp_ie_len = 0;
6313                                         rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len);
6314                                         pmlmepriv->p2p_go_probe_resp_ie = NULL;
6315                                 }
6316
6317                                 pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen);
6318                                 if (pmlmepriv->p2p_go_probe_resp_ie == NULL) {
6319                                         RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6320                                         return -EINVAL;
6321
6322                                 }
6323                                 _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
6324                                 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
6325                         }
6326
6327                 }
6328                 #endif /* CONFIG_P2P */
6329
6330
6331                 #ifdef CONFIG_WFD
6332                 wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen);
6333                 if (wfd_ie) {
6334                         #ifdef CONFIG_DEBUG_CFG80211
6335                         RTW_INFO("probe_resp_wfd_ielen=%d\n", wfd_ielen);
6336                         #endif
6337
6338                         if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_RESP_IE, wfd_ie, wfd_ielen) != _SUCCESS)
6339                                 return -EINVAL;
6340                 }
6341                 #endif /* CONFIG_WFD */
6342
6343         }
6344
6345         return ret;
6346
6347 }
6348
6349 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
6350 {
6351         int ret = 0;
6352         _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
6353         struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6354         u8 *ie;
6355         u32 ie_len;
6356
6357         RTW_INFO("%s, ielen=%d\n", __func__, len);
6358
6359         if (len <= 0)
6360                 goto exit;
6361
6362         ie = rtw_get_wps_ie(buf, len, NULL, &ie_len);
6363         if (ie && ie_len) {
6364                 if (pmlmepriv->wps_assoc_resp_ie) {
6365                         u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
6366
6367                         pmlmepriv->wps_assoc_resp_ie_len = 0;
6368                         rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len);
6369                         pmlmepriv->wps_assoc_resp_ie = NULL;
6370                 }
6371
6372                 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
6373                 if (pmlmepriv->wps_assoc_resp_ie == NULL) {
6374                         RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6375                         return -EINVAL;
6376                 }
6377                 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, ie, ie_len);
6378                 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
6379         }
6380
6381         ie = rtw_get_p2p_ie(buf, len, NULL, &ie_len);
6382         if (ie && ie_len) {
6383                 if (pmlmepriv->p2p_assoc_resp_ie) {
6384                         u32 free_len = pmlmepriv->p2p_assoc_resp_ie_len;
6385
6386                         pmlmepriv->p2p_assoc_resp_ie_len = 0;
6387                         rtw_mfree(pmlmepriv->p2p_assoc_resp_ie, free_len);
6388                         pmlmepriv->p2p_assoc_resp_ie = NULL;
6389                 }
6390
6391                 pmlmepriv->p2p_assoc_resp_ie = rtw_malloc(ie_len);
6392                 if (pmlmepriv->p2p_assoc_resp_ie == NULL) {
6393                         RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
6394                         return -EINVAL;
6395                 }
6396                 _rtw_memcpy(pmlmepriv->p2p_assoc_resp_ie, ie, ie_len);
6397                 pmlmepriv->p2p_assoc_resp_ie_len = ie_len;
6398         }
6399
6400 #ifdef CONFIG_WFD
6401         ie = rtw_get_wfd_ie(buf, len, NULL, &ie_len);
6402         if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_RESP_IE, ie, ie_len) != _SUCCESS)
6403                 return -EINVAL;
6404 #endif
6405
6406 exit:
6407         return ret;
6408 }
6409
6410 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
6411         int type)
6412 {
6413         int ret = 0;
6414         uint wps_ielen = 0;
6415         u32     p2p_ielen = 0;
6416
6417 #ifdef CONFIG_DEBUG_CFG80211
6418         RTW_INFO("%s, ielen=%d\n", __func__, len);
6419 #endif
6420
6421         if ((rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen > 0))
6422                 #ifdef CONFIG_P2P
6423                 || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen > 0))
6424                 #endif
6425         ) {
6426                 if (net != NULL) {
6427                         switch (type) {
6428                         case 0x1: /* BEACON */
6429                                 ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
6430                                 break;
6431                         case 0x2: /* PROBE_RESP */
6432                                 ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
6433                                 #ifdef CONFIG_P2P
6434                                 if (ret == 0)
6435                                         adapter_wdev_data((_adapter *)rtw_netdev_priv(net))->probe_resp_ie_update_time = rtw_get_current_time();
6436                                 #endif
6437                                 break;
6438                         case 0x4: /* ASSOC_RESP */
6439                                 ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
6440                                 break;
6441                         }
6442                 }
6443         }
6444
6445         return ret;
6446
6447 }
6448 #ifdef CONFIG_80211N_HT
6449 static void rtw_cfg80211_init_ht_capab_ex(_adapter *padapter, struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
6450 {
6451         struct registry_priv *pregistrypriv = &padapter->registrypriv;
6452         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
6453         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
6454         u8 stbc_rx_enable = _FALSE;
6455
6456         rtw_ht_use_default_setting(padapter);
6457
6458         /* RX LDPC */
6459         if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX))
6460                 ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING;
6461
6462         /* TX STBC */
6463         if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX))
6464                 ht_cap->cap |= IEEE80211_HT_CAP_TX_STBC;
6465
6466         /* RX STBC */
6467         if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) {
6468                 /*rtw_rx_stbc 0: disable, bit(0):enable 2.4g, bit(1):enable 5g*/
6469                 if (IEEE80211_BAND_2GHZ == band)
6470                         stbc_rx_enable = (pregistrypriv->rx_stbc & BIT(0)) ? _TRUE : _FALSE;
6471                 if (IEEE80211_BAND_5GHZ == band)
6472                         stbc_rx_enable = (pregistrypriv->rx_stbc & BIT(1)) ? _TRUE : _FALSE;
6473
6474                 if (stbc_rx_enable) {
6475                         switch (rf_type) {
6476                         case RF_1T1R:
6477                                 ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/*RX STBC One spatial stream*/
6478                                 break;
6479
6480                         case RF_2T2R:
6481                         case RF_1T2R:
6482                                 ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/* Only one spatial-stream STBC RX is supported */
6483                                 break;
6484                         case RF_3T3R:
6485                         case RF_3T4R:
6486                         case RF_4T4R:
6487                                 ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/* Only one spatial-stream STBC RX is supported */
6488                                 break;
6489                         default:
6490                                 RTW_INFO("[warning] rf_type %d is not expected\n", rf_type);
6491                                 break;
6492                         }
6493                 }
6494         }
6495 }
6496
6497 static void rtw_cfg80211_init_ht_capab(_adapter *padapter, struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
6498 {
6499 #define MAX_BIT_RATE_40MHZ_MCS23        450     /* Mbps */
6500 #define MAX_BIT_RATE_40MHZ_MCS15        300     /* Mbps */
6501 #define MAX_BIT_RATE_40MHZ_MCS7 150     /* Mbps */
6502
6503         ht_cap->ht_supported = _TRUE;
6504
6505         ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
6506                                 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
6507                                 IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
6508         rtw_cfg80211_init_ht_capab_ex(padapter, ht_cap, band, rf_type);
6509
6510         /*
6511          *Maximum length of AMPDU that the STA can receive.
6512          *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
6513          */
6514         ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
6515
6516         /*Minimum MPDU start spacing , */
6517         ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
6518
6519         ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
6520
6521         /*
6522          *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
6523          *base on ant_num
6524          *rx_mask: RX mask
6525          *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
6526          *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
6527          *if rx_ant >=3 rx_mask[2]=0xff;
6528          *if BW_40 rx_mask[4]=0x01;
6529          *highest supported RX rate
6530          */
6531         if (rf_type == RF_1T1R) {
6532                 ht_cap->mcs.rx_mask[0] = 0xFF;
6533
6534                 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
6535         } else if ((rf_type == RF_1T2R) || (rf_type == RF_2T2R) || (rf_type == RF_2T2R_GREEN)) {
6536                 ht_cap->mcs.rx_mask[0] = 0xFF;
6537                 ht_cap->mcs.rx_mask[1] = 0xFF;
6538
6539                 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
6540         } else if ((rf_type == RF_2T3R) || (rf_type == RF_3T3R)) {
6541                 ht_cap->mcs.rx_mask[0] = 0xFF;
6542                 ht_cap->mcs.rx_mask[1] = 0xFF;
6543                 ht_cap->mcs.rx_mask[2] = 0xFF;
6544
6545                 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS23;
6546         } else {
6547                 rtw_warn_on(1);
6548                 RTW_INFO("%s, error rf_type=%d\n", __func__, rf_type);
6549         }
6550
6551 }
6552 #endif /* CONFIG_80211N_HT */
6553
6554 void rtw_cfg80211_init_wdev_data(_adapter *padapter)
6555 {
6556 #ifdef CONFIG_CONCURRENT_MODE
6557         struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
6558
6559         ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
6560 #endif
6561 }
6562
6563 void rtw_cfg80211_init_wiphy(_adapter *padapter)
6564 {
6565         u8 rf_type;
6566         struct ieee80211_supported_band *bands;
6567         struct wireless_dev *pwdev = padapter->rtw_wdev;
6568         struct wiphy *wiphy = pwdev->wiphy;
6569
6570         rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
6571
6572         RTW_INFO("%s:rf_type=%d\n", __func__, rf_type);
6573
6574 #ifdef CONFIG_80211N_HT
6575         if (IsSupported24G(padapter->registrypriv.wireless_mode)) {
6576                 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
6577                 if (bands)
6578                         rtw_cfg80211_init_ht_capab(padapter, &bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type);
6579         }
6580 #endif /* CONFIG_80211N_HT */
6581
6582 #ifdef CONFIG_IEEE80211_BAND_5GHZ
6583         if (IsSupported5G(padapter->registrypriv.wireless_mode)) {
6584                 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
6585                 if (bands)
6586                         rtw_cfg80211_init_ht_capab(padapter, &bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type);
6587         }
6588 #endif
6589         /* init regulary domain */
6590         rtw_regd_init(padapter);
6591
6592         /* copy mac_addr to wiphy */
6593         _rtw_memcpy(wiphy->perm_addr, adapter_mac_addr(padapter), ETH_ALEN);
6594
6595 }
6596
6597 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
6598 struct ieee80211_iface_limit rtw_limits[] = {
6599         {
6600                 .max = 2,
6601                 .types = BIT(NL80211_IFTYPE_STATION)
6602                         #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
6603                         | BIT(NL80211_IFTYPE_P2P_CLIENT)
6604                         #endif
6605         },
6606         #ifdef CONFIG_AP_MODE
6607         {
6608                 .max = 1,
6609                 .types = BIT(NL80211_IFTYPE_AP)
6610                         #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
6611                         | BIT(NL80211_IFTYPE_P2P_GO)
6612                         #endif
6613         },
6614         #endif
6615         #if defined(RTW_DEDICATED_P2P_DEVICE)
6616         {
6617                 .max = 1,
6618                 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
6619         }
6620         #endif
6621 };
6622
6623 struct ieee80211_iface_combination rtw_combinations[] = {
6624         {
6625                 .limits = rtw_limits,
6626                 .n_limits = ARRAY_SIZE(rtw_limits),
6627                 #if defined(RTW_DEDICATED_P2P_DEVICE)
6628                 .max_interfaces = 3,
6629                 #else
6630                 .max_interfaces = 2,
6631                 #endif
6632                 .num_different_channels = 1,
6633         },
6634 };
6635 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) */
6636
6637 static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy)
6638 {
6639         struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
6640         struct registry_priv *regsty = dvobj_to_regsty(dvobj);
6641
6642         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6643
6644         wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
6645         wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
6646         wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
6647
6648 #if CONFIG_RTW_MACADDR_ACL && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
6649         wiphy->max_acl_mac_addrs = NUM_ACL;
6650 #endif
6651
6652 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
6653         wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
6654 #endif
6655
6656         wiphy->interface_modes =        BIT(NL80211_IFTYPE_STATION)
6657                                                                 | BIT(NL80211_IFTYPE_ADHOC)
6658 #ifdef CONFIG_AP_MODE
6659                                                                 | BIT(NL80211_IFTYPE_AP)
6660                                                                 #ifdef CONFIG_WIFI_MONITOR
6661                                                                 | BIT(NL80211_IFTYPE_MONITOR)
6662                                                                 #endif
6663 #endif
6664 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
6665                                                                 | BIT(NL80211_IFTYPE_P2P_CLIENT)
6666                                                                 | BIT(NL80211_IFTYPE_P2P_GO)
6667                                                                 #if defined(RTW_DEDICATED_P2P_DEVICE)
6668                                                                 | BIT(NL80211_IFTYPE_P2P_DEVICE)
6669                                                                 #endif
6670 #endif
6671                                                                 ;
6672
6673 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
6674 #ifdef CONFIG_AP_MODE
6675         wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
6676 #endif /* CONFIG_AP_MODE */
6677 #endif
6678
6679 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
6680         #ifdef CONFIG_WIFI_MONITOR
6681         wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
6682         #endif
6683 #endif
6684
6685 #if defined(RTW_SINGLE_WIPHY) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
6686         wiphy->iface_combinations = rtw_combinations;
6687         wiphy->n_iface_combinations = ARRAY_SIZE(rtw_combinations);
6688 #endif
6689
6690         wiphy->cipher_suites = rtw_cipher_suites;
6691         wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
6692
6693         if (IsSupported24G(adapter->registrypriv.wireless_mode))
6694                 wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
6695
6696 #ifdef CONFIG_IEEE80211_BAND_5GHZ
6697         if (IsSupported5G(adapter->registrypriv.wireless_mode))
6698                 wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
6699 #endif
6700
6701 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0))
6702         wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
6703 #endif
6704
6705 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
6706         wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
6707         wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
6708         /* remove WIPHY_FLAG_OFFCHAN_TX, because we not support this feature */
6709         /* wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME; */
6710 #endif
6711
6712 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
6713         wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6714 #ifdef CONFIG_PNO_SUPPORT
6715         wiphy->max_sched_scan_ssids = MAX_PNO_LIST_COUNT;
6716 #endif
6717 #endif
6718
6719 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
6720 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0))
6721         wiphy->wowlan = wowlan_stub;
6722 #else
6723         wiphy->wowlan = &wowlan_stub;
6724 #endif
6725 #endif
6726
6727 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
6728         wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
6729 #ifndef CONFIG_TDLS_DRIVER_SETUP
6730         wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; /* Driver handles key exchange */
6731         wiphy->flags |= NL80211_ATTR_HT_CAPABILITY;
6732 #endif /* CONFIG_TDLS_DRIVER_SETUP */
6733 #endif /* CONFIG_TDLS */
6734
6735         if (regsty->power_mgnt != PS_MODE_ACTIVE)
6736                 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
6737         else
6738                 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
6739
6740 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
6741         /* wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; */
6742 #endif
6743 }
6744
6745 static struct cfg80211_ops rtw_cfg80211_ops = {
6746         .change_virtual_intf = cfg80211_rtw_change_iface,
6747         .add_key = cfg80211_rtw_add_key,
6748         .get_key = cfg80211_rtw_get_key,
6749         .del_key = cfg80211_rtw_del_key,
6750         .set_default_key = cfg80211_rtw_set_default_key,
6751 #if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
6752         .set_rekey_data = cfg80211_rtw_set_rekey_data,
6753 #endif /*CONFIG_GTK_OL*/
6754         .get_station = cfg80211_rtw_get_station,
6755         .scan = cfg80211_rtw_scan,
6756         .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
6757         .connect = cfg80211_rtw_connect,
6758         .disconnect = cfg80211_rtw_disconnect,
6759         .join_ibss = cfg80211_rtw_join_ibss,
6760         .leave_ibss = cfg80211_rtw_leave_ibss,
6761         .set_tx_power = cfg80211_rtw_set_txpower,
6762         .get_tx_power = cfg80211_rtw_get_txpower,
6763         .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
6764         .set_pmksa = cfg80211_rtw_set_pmksa,
6765         .del_pmksa = cfg80211_rtw_del_pmksa,
6766         .flush_pmksa = cfg80211_rtw_flush_pmksa,
6767
6768 #ifdef CONFIG_AP_MODE
6769         .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
6770         .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
6771
6772 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
6773         .add_beacon = cfg80211_rtw_add_beacon,
6774         .set_beacon = cfg80211_rtw_set_beacon,
6775         .del_beacon = cfg80211_rtw_del_beacon,
6776 #else
6777         .start_ap = cfg80211_rtw_start_ap,
6778         .change_beacon = cfg80211_rtw_change_beacon,
6779         .stop_ap = cfg80211_rtw_stop_ap,
6780 #endif
6781
6782 #if CONFIG_RTW_MACADDR_ACL && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
6783         .set_mac_acl = cfg80211_rtw_set_mac_acl,
6784 #endif
6785
6786         .add_station = cfg80211_rtw_add_station,
6787         .del_station = cfg80211_rtw_del_station,
6788         .change_station = cfg80211_rtw_change_station,
6789         .dump_station = cfg80211_rtw_dump_station,
6790         .change_bss = cfg80211_rtw_change_bss,
6791 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
6792         .set_channel = cfg80211_rtw_set_channel,
6793 #endif
6794         /* .auth = cfg80211_rtw_auth, */
6795         /* .assoc = cfg80211_rtw_assoc,  */
6796 #endif /* CONFIG_AP_MODE */
6797
6798 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
6799         .set_monitor_channel = cfg80211_rtw_set_monitor_channel,
6800 #endif
6801
6802 #ifdef CONFIG_P2P
6803         .remain_on_channel = cfg80211_rtw_remain_on_channel,
6804         .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
6805         #if defined(RTW_DEDICATED_P2P_DEVICE)
6806         .start_p2p_device = cfg80211_rtw_start_p2p_device,
6807         .stop_p2p_device = cfg80211_rtw_stop_p2p_device,
6808         #endif
6809 #endif /* CONFIG_P2P */
6810
6811 #ifdef CONFIG_RTW_80211R
6812         .update_ft_ies = cfg80211_rtw_update_ft_ies,
6813 #endif
6814
6815 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
6816         .mgmt_tx = cfg80211_rtw_mgmt_tx,
6817         .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
6818 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
6819         .action = cfg80211_rtw_mgmt_tx,
6820 #endif
6821
6822 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
6823         .tdls_mgmt = cfg80211_rtw_tdls_mgmt,
6824         .tdls_oper = cfg80211_rtw_tdls_oper,
6825 #endif /* CONFIG_TDLS */
6826
6827 #if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
6828         .sched_scan_start = cfg80211_rtw_sched_scan_start,
6829         .sched_scan_stop = cfg80211_rtw_sched_scan_stop,
6830 #endif /* CONFIG_PNO_SUPPORT */
6831 };
6832
6833 struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev)
6834 {
6835         struct wiphy *wiphy;
6836         struct rtw_wiphy_data *wiphy_data;
6837
6838         /* wiphy */
6839         wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wiphy_data));
6840         if (!wiphy) {
6841                 RTW_INFO("Couldn't allocate wiphy device\n");
6842                 goto exit;
6843         }
6844         set_wiphy_dev(wiphy, dev);
6845
6846         /* wiphy_data */
6847         wiphy_data = rtw_wiphy_priv(wiphy);
6848         wiphy_data->dvobj = adapter_to_dvobj(padapter);
6849 #ifndef RTW_SINGLE_WIPHY
6850         wiphy_data->adapter = padapter;
6851 #endif
6852
6853         rtw_cfg80211_preinit_wiphy(padapter, wiphy);
6854
6855         RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
6856
6857 exit:
6858         return wiphy;
6859 }
6860
6861 void rtw_wiphy_free(struct wiphy *wiphy)
6862 {
6863         if (!wiphy)
6864                 return;
6865
6866         RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
6867
6868         if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6869                 rtw_spt_band_free(wiphy->bands[IEEE80211_BAND_2GHZ]);
6870                 wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
6871         }
6872         if (wiphy->bands[IEEE80211_BAND_5GHZ]) {
6873                 rtw_spt_band_free(wiphy->bands[IEEE80211_BAND_5GHZ]);
6874                 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
6875         }
6876
6877         wiphy_free(wiphy);
6878 }
6879
6880 int rtw_wiphy_register(struct wiphy *wiphy)
6881 {
6882         RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
6883
6884 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
6885         rtw_cfgvendor_attach(wiphy);
6886 #endif
6887
6888         return wiphy_register(wiphy);
6889 }
6890
6891 void rtw_wiphy_unregister(struct wiphy *wiphy)
6892 {
6893         RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
6894
6895 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
6896         rtw_cfgvendor_detach(wiphy);
6897 #endif
6898
6899         #if defined(RTW_DEDICATED_P2P_DEVICE)
6900         rtw_pd_iface_free(wiphy);
6901         #endif
6902
6903         return wiphy_unregister(wiphy);
6904 }
6905
6906 int rtw_wdev_alloc(_adapter *padapter, struct wiphy *wiphy)
6907 {
6908         int ret = 0;
6909         struct net_device *pnetdev = padapter->pnetdev;
6910         struct wireless_dev *wdev;
6911         struct rtw_wdev_priv *pwdev_priv;
6912
6913         RTW_INFO("%s(padapter=%p)\n", __func__, padapter);
6914
6915         /*  wdev */
6916         wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
6917         if (!wdev) {
6918                 RTW_INFO("Couldn't allocate wireless device\n");
6919                 ret = -ENOMEM;
6920                 goto exit;
6921         }
6922         wdev->wiphy = wiphy;
6923         wdev->netdev = pnetdev;
6924
6925         wdev->iftype = NL80211_IFTYPE_STATION;  /* will be init in rtw_hal_init() */
6926                                                                                         /* Must sync with _rtw_init_mlme_priv() */
6927                                                                                         /* pmlmepriv->fw_state = WIFI_STATION_STATE */
6928         /* wdev->iftype = NL80211_IFTYPE_MONITOR; */ /* for rtw_setopmode_cmd() in cfg80211_rtw_change_iface() */
6929         padapter->rtw_wdev = wdev;
6930         pnetdev->ieee80211_ptr = wdev;
6931
6932         /* init pwdev_priv */
6933         pwdev_priv = adapter_wdev_data(padapter);
6934         pwdev_priv->rtw_wdev = wdev;
6935         pwdev_priv->pmon_ndev = NULL;
6936         pwdev_priv->ifname_mon[0] = '\0';
6937         pwdev_priv->padapter = padapter;
6938         pwdev_priv->scan_request = NULL;
6939         _rtw_spinlock_init(&pwdev_priv->scan_req_lock);
6940
6941         pwdev_priv->p2p_enabled = _FALSE;
6942         pwdev_priv->probe_resp_ie_update_time = rtw_get_current_time();
6943         pwdev_priv->provdisc_req_issued = _FALSE;
6944         rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
6945         rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
6946
6947         pwdev_priv->bandroid_scan = _FALSE;
6948
6949         if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
6950                 pwdev_priv->power_mgmt = _TRUE;
6951         else
6952                 pwdev_priv->power_mgmt = _FALSE;
6953
6954         _rtw_mutex_init(&pwdev_priv->roch_mutex);
6955
6956 #ifdef CONFIG_CONCURRENT_MODE
6957         ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
6958 #endif
6959
6960 exit:
6961         return ret;
6962 }
6963
6964 void rtw_wdev_free(struct wireless_dev *wdev)
6965 {
6966         if (!wdev)
6967                 return;
6968
6969         RTW_INFO("%s(wdev=%p)\n", __func__, wdev);
6970
6971         if (wdev_to_ndev(wdev)) {
6972                 _adapter *adapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
6973                 struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
6974
6975                 _rtw_spinlock_free(&wdev_priv->scan_req_lock);
6976                 _rtw_mutex_free(&wdev_priv->roch_mutex);
6977         }
6978
6979         rtw_mfree((u8 *)wdev, sizeof(struct wireless_dev));
6980 }
6981
6982 void rtw_wdev_unregister(struct wireless_dev *wdev)
6983 {
6984         struct net_device *ndev;
6985         _adapter *adapter;
6986         struct rtw_wdev_priv *pwdev_priv;
6987
6988         if (!wdev)
6989                 return;
6990
6991         RTW_INFO("%s(wdev=%p)\n", __func__, wdev);
6992
6993         ndev = wdev_to_ndev(wdev);
6994         if (!ndev)
6995                 return;
6996
6997         adapter = (_adapter *)rtw_netdev_priv(ndev);
6998         pwdev_priv = adapter_wdev_data(adapter);
6999
7000         rtw_cfg80211_indicate_scan_done(adapter, _TRUE);
7001
7002 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
7003         if (wdev->current_bss) {
7004                 u8 locally_generated = 1;
7005                 RTW_INFO(FUNC_ADPT_FMT" clear current_bss by cfg80211_disconnected\n", FUNC_ADPT_ARG(adapter));
7006                 cfg80211_disconnected(adapter->pnetdev, 0, NULL, 0, locally_generated, GFP_ATOMIC);
7007         }
7008 #elif ((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0))) || defined(COMPAT_KERNEL_RELEASE)
7009         if (wdev->current_bss) {
7010                 RTW_INFO(FUNC_ADPT_FMT" clear current_bss by cfg80211_disconnected\n", FUNC_ADPT_ARG(adapter));
7011                 cfg80211_disconnected(adapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
7012         }
7013 #endif
7014
7015         if (pwdev_priv->pmon_ndev) {
7016                 RTW_INFO("%s, unregister monitor interface\n", __func__);
7017                 unregister_netdev(pwdev_priv->pmon_ndev);
7018         }
7019 }
7020
7021 int rtw_cfg80211_ndev_res_alloc(_adapter *adapter)
7022 {
7023         int ret = _FAIL;
7024
7025 #if !defined(RTW_SINGLE_WIPHY)
7026         struct wiphy *wiphy;
7027         struct device *dev = dvobj_to_dev(adapter_to_dvobj(adapter));
7028
7029         wiphy = rtw_wiphy_alloc(adapter, dev);
7030         if (wiphy == NULL)
7031                 goto exit;
7032
7033         adapter->wiphy = wiphy;
7034 #endif
7035
7036         if (rtw_wdev_alloc(adapter, adapter_to_wiphy(adapter)) == 0)
7037                 ret = _SUCCESS;
7038
7039 #if !defined(RTW_SINGLE_WIPHY)
7040         if (ret != _SUCCESS) {
7041                 rtw_wiphy_free(wiphy);
7042                 adapter->wiphy = NULL;
7043         }
7044 #endif
7045
7046 exit:
7047         return ret;
7048 }
7049
7050 void rtw_cfg80211_ndev_res_free(_adapter *adapter)
7051 {
7052         rtw_wdev_free(adapter->rtw_wdev);
7053 #if !defined(RTW_SINGLE_WIPHY)
7054         rtw_wiphy_free(adapter_to_wiphy(adapter));
7055         adapter->wiphy = NULL;
7056 #endif
7057 }
7058
7059 int rtw_cfg80211_ndev_res_register(_adapter *adapter)
7060 {
7061         int ret = _FAIL;
7062
7063 #if !defined(RTW_SINGLE_WIPHY)
7064         if (rtw_wiphy_register(adapter_to_wiphy(adapter)) < 0) {
7065                 RTW_INFO("%s rtw_wiphy_register fail for if%d\n", __func__, (adapter->iface_id + 1));
7066                 goto exit;
7067         }
7068 #endif
7069
7070         ret = _SUCCESS;
7071
7072 exit:
7073         return ret;
7074 }
7075
7076 void rtw_cfg80211_ndev_res_unregister(_adapter *adapter)
7077 {
7078         rtw_wdev_unregister(adapter->rtw_wdev);
7079 }
7080
7081 int rtw_cfg80211_dev_res_alloc(struct dvobj_priv *dvobj)
7082 {
7083         int ret = _FAIL;
7084
7085 #if defined(RTW_SINGLE_WIPHY)
7086         struct wiphy *wiphy;
7087         struct device *dev = dvobj_to_dev(dvobj);
7088
7089         wiphy = rtw_wiphy_alloc(dvobj->padapters[IFACE_ID0], dev);
7090         if (wiphy == NULL)
7091                 goto exit;
7092
7093         dvobj->wiphy = wiphy;
7094 #endif
7095
7096         ret = _SUCCESS;
7097
7098 exit:
7099         return ret;
7100 }
7101
7102 void rtw_cfg80211_dev_res_free(struct dvobj_priv *dvobj)
7103 {
7104 #if defined(RTW_SINGLE_WIPHY)
7105         rtw_wiphy_free(dvobj_to_wiphy(dvobj));
7106         dvobj->wiphy = NULL;
7107 #endif
7108 }
7109
7110 int rtw_cfg80211_dev_res_register(struct dvobj_priv *dvobj)
7111 {
7112         int ret = _FAIL;
7113
7114 #if defined(RTW_SINGLE_WIPHY)
7115         if (rtw_wiphy_register(dvobj_to_wiphy(dvobj)) != 0)
7116                 goto exit;
7117 #endif
7118
7119         ret = _SUCCESS;
7120
7121 exit:
7122         return ret;
7123 }
7124
7125 void rtw_cfg80211_dev_res_unregister(struct dvobj_priv *dvobj)
7126 {
7127 #if defined(RTW_SINGLE_WIPHY)
7128         rtw_wiphy_unregister(dvobj_to_wiphy(dvobj));
7129 #endif
7130 }
7131
7132 #endif /* CONFIG_IOCTL_CFG80211 */