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