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