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