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