1 /******************************************************************************
\r
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
\r
5 * This program is free software; you can redistribute it and/or modify it
\r
6 * under the terms of version 2 of the GNU General Public License as
\r
7 * published by the Free Software Foundation.
\r
9 * This program is distributed in the hope that it will be useful, but WITHOUT
\r
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
14 * You should have received a copy of the GNU General Public License along with
\r
15 * this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
\r
19 ******************************************************************************/
\r
20 #define _IOCTL_CFG80211_C_
\r
22 #include <drv_types.h>
\r
24 #ifdef CONFIG_IOCTL_CFG80211
\r
26 #include <rtw_wifi_regd.h>
\r
28 #define RTW_MAX_MGMT_TX_CNT (8)
\r
30 #define RTW_SCAN_IE_LEN_MAX 2304
\r
31 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 3000 //ms
\r
32 #define RTW_MAX_NUM_PMKIDS 4
\r
34 #define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
\r
36 #ifdef CONFIG_WAPI_SUPPORT
\r
38 #ifndef WLAN_CIPHER_SUITE_SMS4
\r
39 #define WLAN_CIPHER_SUITE_SMS4 0x00147201
\r
42 #ifndef WLAN_AKM_SUITE_WAPI_PSK
\r
43 #define WLAN_AKM_SUITE_WAPI_PSK 0x000FAC04
\r
46 #ifndef WLAN_AKM_SUITE_WAPI_CERT
\r
47 #define WLAN_AKM_SUITE_WAPI_CERT 0x000FAC12
\r
50 #ifndef NL80211_WAPI_VERSION_1
\r
51 #define NL80211_WAPI_VERSION_1 (1 << 2)
\r
56 #define BUSY_TRAFFIC_SCAN_DENY_PERIOD 8000
\r
58 static const u32 rtw_cipher_suites[] = {
\r
59 WLAN_CIPHER_SUITE_WEP40,
\r
60 WLAN_CIPHER_SUITE_WEP104,
\r
61 WLAN_CIPHER_SUITE_TKIP,
\r
62 WLAN_CIPHER_SUITE_CCMP,
\r
63 #ifdef CONFIG_WAPI_SUPPORT
\r
64 WLAN_CIPHER_SUITE_SMS4,
\r
65 #endif // CONFIG_WAPI_SUPPORT
\r
66 #ifdef CONFIG_IEEE80211W
\r
67 WLAN_CIPHER_SUITE_AES_CMAC,
\r
68 #endif //CONFIG_IEEE80211W
\r
71 #define RATETAB_ENT(_rate, _rateid, _flags) \
\r
73 .bitrate = (_rate), \
\r
74 .hw_value = (_rateid), \
\r
75 .flags = (_flags), \
\r
78 #define CHAN2G(_channel, _freq, _flags) { \
\r
79 .band = IEEE80211_BAND_2GHZ, \
\r
80 .center_freq = (_freq), \
\r
81 .hw_value = (_channel), \
\r
82 .flags = (_flags), \
\r
83 .max_antenna_gain = 0, \
\r
87 #define CHAN5G(_channel, _flags) { \
\r
88 .band = IEEE80211_BAND_5GHZ, \
\r
89 .center_freq = 5000 + (5 * (_channel)), \
\r
90 .hw_value = (_channel), \
\r
91 .flags = (_flags), \
\r
92 .max_antenna_gain = 0, \
\r
96 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
97 /* if wowlan is not supported, kernel generate a disconnect at each suspend
\r
98 * cf: /net/wireless/sysfs.c, so register a stub wowlan.
\r
99 * Moreover wowlan has to be enabled via a the nl80211_set_wowlan callback.
\r
100 * (from user space, e.g. iw phy0 wowlan enable)
\r
102 static const struct wiphy_wowlan_support wowlan_stub = {
\r
103 .flags = WIPHY_WOWLAN_ANY,
\r
105 .pattern_max_len = 0,
\r
106 .pattern_min_len = 0,
\r
107 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
\r
108 .max_pkt_offset = 0,
\r
113 static struct ieee80211_rate rtw_rates[] = {
\r
114 RATETAB_ENT(10, 0x1, 0),
\r
115 RATETAB_ENT(20, 0x2, 0),
\r
116 RATETAB_ENT(55, 0x4, 0),
\r
117 RATETAB_ENT(110, 0x8, 0),
\r
118 RATETAB_ENT(60, 0x10, 0),
\r
119 RATETAB_ENT(90, 0x20, 0),
\r
120 RATETAB_ENT(120, 0x40, 0),
\r
121 RATETAB_ENT(180, 0x80, 0),
\r
122 RATETAB_ENT(240, 0x100, 0),
\r
123 RATETAB_ENT(360, 0x200, 0),
\r
124 RATETAB_ENT(480, 0x400, 0),
\r
125 RATETAB_ENT(540, 0x800, 0),
\r
128 #define rtw_a_rates (rtw_rates + 4)
\r
129 #define RTW_A_RATES_NUM 8
\r
130 #define rtw_g_rates (rtw_rates + 0)
\r
131 #define RTW_G_RATES_NUM 12
\r
133 #define RTW_2G_CHANNELS_NUM 14
\r
134 #define RTW_5G_CHANNELS_NUM 37
\r
136 static struct ieee80211_channel rtw_2ghz_channels[] = {
\r
137 CHAN2G(1, 2412, 0),
\r
138 CHAN2G(2, 2417, 0),
\r
139 CHAN2G(3, 2422, 0),
\r
140 CHAN2G(4, 2427, 0),
\r
141 CHAN2G(5, 2432, 0),
\r
142 CHAN2G(6, 2437, 0),
\r
143 CHAN2G(7, 2442, 0),
\r
144 CHAN2G(8, 2447, 0),
\r
145 CHAN2G(9, 2452, 0),
\r
146 CHAN2G(10, 2457, 0),
\r
147 CHAN2G(11, 2462, 0),
\r
148 CHAN2G(12, 2467, 0),
\r
149 CHAN2G(13, 2472, 0),
\r
150 CHAN2G(14, 2484, 0),
\r
153 static struct ieee80211_channel rtw_5ghz_a_channels[] = {
\r
154 CHAN5G(34, 0), CHAN5G(36, 0),
\r
155 CHAN5G(38, 0), CHAN5G(40, 0),
\r
156 CHAN5G(42, 0), CHAN5G(44, 0),
\r
157 CHAN5G(46, 0), CHAN5G(48, 0),
\r
158 CHAN5G(52, 0), CHAN5G(56, 0),
\r
159 CHAN5G(60, 0), CHAN5G(64, 0),
\r
160 CHAN5G(100, 0), CHAN5G(104, 0),
\r
161 CHAN5G(108, 0), CHAN5G(112, 0),
\r
162 CHAN5G(116, 0), CHAN5G(120, 0),
\r
163 CHAN5G(124, 0), CHAN5G(128, 0),
\r
164 CHAN5G(132, 0), CHAN5G(136, 0),
\r
165 CHAN5G(140, 0), CHAN5G(149, 0),
\r
166 CHAN5G(153, 0), CHAN5G(157, 0),
\r
167 CHAN5G(161, 0), CHAN5G(165, 0),
\r
168 CHAN5G(184, 0), CHAN5G(188, 0),
\r
169 CHAN5G(192, 0), CHAN5G(196, 0),
\r
170 CHAN5G(200, 0), CHAN5G(204, 0),
\r
171 CHAN5G(208, 0), CHAN5G(212, 0),
\r
176 void rtw_2g_channels_init(struct ieee80211_channel *channels)
\r
178 _rtw_memcpy((void*)channels, (void*)rtw_2ghz_channels,
\r
179 sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
\r
183 void rtw_5g_channels_init(struct ieee80211_channel *channels)
\r
185 _rtw_memcpy((void*)channels, (void*)rtw_5ghz_a_channels,
\r
186 sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
\r
190 void rtw_2g_rates_init(struct ieee80211_rate *rates)
\r
192 _rtw_memcpy(rates, rtw_g_rates,
\r
193 sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
\r
197 void rtw_5g_rates_init(struct ieee80211_rate *rates)
\r
199 _rtw_memcpy(rates, rtw_a_rates,
\r
200 sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM
\r
204 struct ieee80211_supported_band *rtw_spt_band_alloc(
\r
205 enum ieee80211_band band
\r
208 struct ieee80211_supported_band *spt_band = NULL;
\r
209 int n_channels, n_bitrates;
\r
211 if(band == IEEE80211_BAND_2GHZ)
\r
213 n_channels = RTW_2G_CHANNELS_NUM;
\r
214 n_bitrates = RTW_G_RATES_NUM;
\r
216 else if(band == IEEE80211_BAND_5GHZ)
\r
218 n_channels = RTW_5G_CHANNELS_NUM;
\r
219 n_bitrates = RTW_A_RATES_NUM;
\r
226 spt_band = (struct ieee80211_supported_band *)rtw_zmalloc(
\r
227 sizeof(struct ieee80211_supported_band)
\r
228 + sizeof(struct ieee80211_channel)*n_channels
\r
229 + sizeof(struct ieee80211_rate)*n_bitrates
\r
234 spt_band->channels = (struct ieee80211_channel*)(((u8*)spt_band)+sizeof(struct ieee80211_supported_band));
\r
235 spt_band->bitrates= (struct ieee80211_rate*)(((u8*)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
\r
236 spt_band->band = band;
\r
237 spt_band->n_channels = n_channels;
\r
238 spt_band->n_bitrates = n_bitrates;
\r
240 if(band == IEEE80211_BAND_2GHZ)
\r
242 rtw_2g_channels_init(spt_band->channels);
\r
243 rtw_2g_rates_init(spt_band->bitrates);
\r
245 else if(band == IEEE80211_BAND_5GHZ)
\r
247 rtw_5g_channels_init(spt_band->channels);
\r
248 rtw_5g_rates_init(spt_band->bitrates);
\r
258 void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
\r
265 if(spt_band->band == IEEE80211_BAND_2GHZ)
\r
267 size = sizeof(struct ieee80211_supported_band)
\r
268 + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
\r
269 + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM;
\r
271 else if(spt_band->band == IEEE80211_BAND_5GHZ)
\r
273 size = sizeof(struct ieee80211_supported_band)
\r
274 + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
\r
275 + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM;
\r
281 rtw_mfree((u8*)spt_band, size);
\r
284 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
285 static const struct ieee80211_txrx_stypes
\r
286 rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
\r
287 [NL80211_IFTYPE_ADHOC] = {
\r
289 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
\r
291 [NL80211_IFTYPE_STATION] = {
\r
293 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
\r
294 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
\r
296 [NL80211_IFTYPE_AP] = {
\r
298 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
299 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
300 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
301 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
302 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
303 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
304 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
306 [NL80211_IFTYPE_AP_VLAN] = {
\r
309 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
310 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
311 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
312 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
313 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
314 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
315 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
317 [NL80211_IFTYPE_P2P_CLIENT] = {
\r
319 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
\r
320 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
\r
322 [NL80211_IFTYPE_P2P_GO] = {
\r
324 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
325 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
326 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
327 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
328 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
329 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
330 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
335 static int rtw_ieee80211_channel_to_frequency(int chan, int band)
\r
337 /* see 802.11 17.3.8.3.2 and Annex J
\r
338 * there are overlapping channel numbers in 5GHz and 2GHz bands */
\r
340 if (band == IEEE80211_BAND_5GHZ) {
\r
341 if (chan >= 182 && chan <= 196)
\r
342 return 4000 + chan * 5;
\r
344 return 5000 + chan * 5;
\r
345 } else { /* IEEE80211_BAND_2GHZ */
\r
348 else if (chan < 14)
\r
349 return 2407 + chan * 5;
\r
351 return 0; /* not supported */
\r
355 static u64 rtw_get_systime_us(void)
\r
357 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
\r
358 struct timespec ts;
\r
359 get_monotonic_boottime(&ts);
\r
360 return ((u64)ts.tv_sec*1000000) + ts.tv_nsec / 1000;
\r
363 do_gettimeofday(&tv);
\r
364 return ((u64)tv.tv_sec*1000000) + tv.tv_usec;
\r
368 #define MAX_BSSINFO_LEN 1000
\r
369 struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork)
\r
371 struct ieee80211_channel *notify_channel;
\r
372 struct cfg80211_bss *bss = NULL;
\r
373 //struct ieee80211_supported_band *band;
\r
376 u64 notify_timestamp;
\r
377 u16 notify_capability;
\r
378 u16 notify_interval;
\r
380 size_t notify_ielen;
\r
382 u8 buf[MAX_BSSINFO_LEN], *pbuf;
\r
383 size_t len,bssinf_len=0;
\r
384 struct rtw_ieee80211_hdr *pwlanhdr;
\r
385 unsigned short *fctrl;
\r
386 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
\r
388 struct wireless_dev *wdev = padapter->rtw_wdev;
\r
389 struct wiphy *wiphy = wdev->wiphy;
\r
390 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
393 //DBG_8192C("%s\n", __func__);
\r
395 bssinf_len = pnetwork->network.IELength+sizeof (struct rtw_ieee80211_hdr_3addr);
\r
396 if(bssinf_len > MAX_BSSINFO_LEN){
\r
397 DBG_871X("%s IE Length too long > %d byte \n",__FUNCTION__,MAX_BSSINFO_LEN);
\r
401 #ifndef CONFIG_WAPI_SUPPORT
\r
405 if(rtw_get_wapi_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &wapi_len)>0)
\r
409 DBG_871X("%s, no support wapi!\n",__FUNCTION__);
\r
414 #endif //!CONFIG_WAPI_SUPPORT
\r
416 //To reduce PBC Overlap rate
\r
417 //_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
418 if(adapter_wdev_data(padapter)->scan_request != NULL)
\r
420 u8 *psr=NULL, sr = 0;
\r
421 NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid;
\r
422 struct cfg80211_scan_request *request = adapter_wdev_data(padapter)->scan_request;
\r
423 struct cfg80211_ssid *ssids = request->ssids;
\r
427 wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
\r
429 if(wpsie && wpsielen>0)
\r
430 psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
\r
434 if(request->n_ssids == 1 && request->n_channels == 1) // it means under processing WPS
\r
436 DBG_8192C("ssid=%s, len=%d\n", pssid->Ssid, pssid->SsidLength);
\r
438 if (ssids[0].ssid_len == 0) {
\r
440 else if(pssid->SsidLength == ssids[0].ssid_len &&
\r
441 _rtw_memcmp(pssid->Ssid, ssids[0].ssid, ssids[0].ssid_len))
\r
443 DBG_871X("%s, got sr and ssid match!\n", __func__);
\r
448 *psr = 0; //clear sr
\r
451 WLAN_BSSID_EX *pselect_network = &pnetwork->network;
\r
452 struct cfg80211_bss *pselect_bss = NULL;
\r
453 struct ieee80211_channel *notify_channel = NULL;
\r
456 DBG_871X("%s, got sr, but ssid mismatch, to remove this bss\n", __func__);
\r
458 if (pselect_network->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
\r
459 freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
\r
461 freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
\r
463 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
464 pselect_bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
\r
465 pselect_network->MacAddress, pselect_network->Ssid.Ssid,
\r
466 pselect_network->Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
\r
467 0/*WLAN_CAPABILITY_ESS*/);
\r
471 DBG_871X("%s, got bss for cfg80211 for unlinking bss\n", __func__);
\r
473 cfg80211_unlink_bss(wiphy, pselect_bss);
\r
474 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
475 cfg80211_put_bss(wiphy, pselect_bss);
\r
477 cfg80211_put_bss(pselect_bss);
\r
488 //_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
491 channel = pnetwork->network.Configuration.DSConfig;
\r
492 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
493 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
495 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
498 notify_timestamp = le64_to_cpu(*(u64*)rtw_get_timestampe_from_ie(pnetwork->network.IEs));
\r
500 notify_timestamp = rtw_get_systime_us();
\r
502 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
504 //rtw_get_timestampe_from_ie()
\r
505 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
\r
507 notify_interval = le16_to_cpu(*(u16*)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
\r
508 notify_capability = le16_to_cpu(*(u16*)rtw_get_capability_from_ie(pnetwork->network.IEs));
\r
511 notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_;
\r
512 notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_;
\r
514 //We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm)
\r
515 if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
\r
516 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
\r
517 notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);//dbm
\r
519 notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);//dbm
\r
523 DBG_8192C("bssid: "MAC_FMT"\n", MAC_ARG(pnetwork->network.MacAddress));
\r
524 DBG_8192C("Channel: %d(%d)\n", channel, freq);
\r
525 DBG_8192C("Capability: %X\n", notify_capability);
\r
526 DBG_8192C("Beacon interval: %d\n", notify_interval);
\r
527 DBG_8192C("Signal: %d\n", notify_signal);
\r
528 DBG_8192C("notify_timestamp: %llu\n", notify_timestamp);
\r
533 pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;
\r
534 fctrl = &(pwlanhdr->frame_ctl);
\r
537 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
\r
538 //pmlmeext->mgnt_seq++;
\r
540 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
\r
541 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
\r
542 SetFrameSubType(pbuf, WIFI_BEACON);
\r
544 _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
545 SetFrameSubType(pbuf, WIFI_PROBERSP);
\r
548 _rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
\r
549 _rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
\r
552 pbuf += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
553 len = sizeof (struct rtw_ieee80211_hdr_3addr);
\r
555 _rtw_memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength);
\r
556 len += pnetwork->network.IELength;
\r
558 *((u64*)pbuf) = cpu_to_le64(notify_timestamp);
\r
560 //#ifdef CONFIG_P2P
\r
561 //if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
\r
563 // DBG_8192C("%s, got p2p_ie\n", __func__);
\r
568 bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)buf,
\r
569 len, notify_signal, GFP_ATOMIC);
\r
572 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress,
\r
573 notify_timestamp, notify_capability, notify_interval, notify_ie,
\r
574 notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/);
\r
577 if (unlikely(!bss)) {
\r
578 DBG_8192C(FUNC_ADPT_FMT" bss NULL\n", FUNC_ADPT_ARG(padapter));
\r
582 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
\r
583 #ifndef COMPAT_KERNEL_RELEASE
\r
584 //patch for cfg80211, update beacon ies to information_elements
\r
585 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
\r
587 if(bss->len_information_elements != bss->len_beacon_ies)
\r
589 bss->information_elements = bss->beacon_ies;
\r
590 bss->len_information_elements = bss->len_beacon_ies;
\r
593 #endif //COMPAT_KERNEL_RELEASE
\r
594 #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
\r
598 if( bss->information_elements == bss->proberesp_ies)
\r
600 if( bss->len_information_elements != bss->len_proberesp_ies)
\r
602 DBG_8192C("error!, len_information_elements != bss->len_proberesp_ies\n");
\r
606 else if(bss->len_information_elements < bss->len_beacon_ies)
\r
608 bss->information_elements = bss->beacon_ies;
\r
609 bss->len_information_elements = bss->len_beacon_ies;
\r
613 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
614 cfg80211_put_bss(wiphy, bss);
\r
616 cfg80211_put_bss(bss);
\r
625 Check the given bss is valid by kernel API cfg80211_get_bss()
\r
626 @padapter : the given adapter
\r
628 return _TRUE if bss is valid, _FALSE for not found.
\r
630 int rtw_cfg80211_check_bss(_adapter *padapter)
\r
632 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
633 struct cfg80211_bss *bss = NULL;
\r
634 struct ieee80211_channel *notify_channel = NULL;
\r
637 if (!(pnetwork) || !(padapter->rtw_wdev))
\r
640 if (pnetwork->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
\r
641 freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
\r
643 freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
\r
645 notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
\r
646 bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
\r
647 pnetwork->MacAddress, pnetwork->Ssid.Ssid,
\r
648 pnetwork->Ssid.SsidLength,
\r
649 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
\r
651 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
652 cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
\r
654 cfg80211_put_bss(bss);
\r
657 return (bss!=NULL);
\r
660 void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter)
\r
662 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
663 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
664 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
665 struct cfg80211_bss *bss = NULL;
\r
667 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
668 if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
\r
673 if (!rtw_cfg80211_check_bss(padapter)) {
\r
674 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
675 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
\r
677 if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE)
\r
680 _rtw_memcpy(&cur_network->network, pnetwork, sizeof(WLAN_BSSID_EX));
\r
683 if (!rtw_cfg80211_inform_bss(padapter,cur_network))
\r
684 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
686 DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
690 DBG_871X("cur_network is not exist!!!\n");
\r
696 if(scanned == NULL)
\r
699 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
\r
700 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
\r
702 if (!rtw_cfg80211_inform_bss(padapter,scanned)) {
\r
703 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
705 //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
708 DBG_871X("scanned & pnetwork compare fail\n");
\r
713 if (!rtw_cfg80211_check_bss(padapter))
\r
714 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
\r
716 //notify cfg80211 that device joined an IBSS
\r
717 cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, GFP_ATOMIC);
\r
720 void rtw_cfg80211_indicate_connect(_adapter *padapter)
\r
722 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
723 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
724 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
726 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
728 struct cfg80211_bss *bss = NULL;
\r
730 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
731 if (pwdev->iftype != NL80211_IFTYPE_STATION
\r
732 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
733 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
\r
739 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
743 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
745 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
747 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
748 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
\r
749 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
\r
750 DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
\r
753 #endif //CONFIG_P2P
\r
756 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
757 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
\r
759 //DBG_871X(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter));
\r
761 if(scanned == NULL) {
\r
766 if (_rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
\r
767 && _rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
\r
769 if (!rtw_cfg80211_inform_bss(padapter,scanned)) {
\r
770 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
772 //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
775 DBG_871X("scanned: %s("MAC_FMT"), cur: %s("MAC_FMT")\n",
\r
776 scanned->network.Ssid.Ssid, MAC_ARG(scanned->network.MacAddress),
\r
777 pnetwork->Ssid.Ssid, MAC_ARG(pnetwork->MacAddress)
\r
784 if (!rtw_cfg80211_check_bss(padapter))
\r
785 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
\r
787 if (rtw_to_roam(padapter) > 0) {
\r
788 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
\r
789 struct wiphy *wiphy = pwdev->wiphy;
\r
790 struct ieee80211_channel *notify_channel;
\r
792 u16 channel = cur_network->network.Configuration.DSConfig;
\r
794 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
795 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
797 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
799 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
802 DBG_871X(FUNC_ADPT_FMT" call cfg80211_roamed\n", FUNC_ADPT_ARG(padapter));
\r
803 cfg80211_roamed(padapter->pnetdev
\r
804 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
\r
807 , cur_network->network.MacAddress
\r
808 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
\r
809 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
\r
810 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
\r
811 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
\r
816 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
\r
817 cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
\r
818 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
\r
819 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
\r
820 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
\r
821 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
\r
822 , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
\r
823 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
\r
827 void rtw_cfg80211_indicate_disconnect(_adapter *padapter)
\r
829 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
830 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
832 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
835 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
837 if (pwdev->iftype != NL80211_IFTYPE_STATION
\r
838 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
839 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
\r
845 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
849 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
851 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
853 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
854 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
856 DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
\r
859 #endif //CONFIG_P2P
\r
861 if (!padapter->mlmepriv.not_indic_disco) {
\r
862 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
\r
864 if(pwdev->sme_state==CFG80211_SME_CONNECTING)
\r
865 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
\r
866 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
\r
867 else if(pwdev->sme_state==CFG80211_SME_CONNECTED)
\r
868 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
\r
870 //DBG_8192C("pwdev->sme_state=%d\n", pwdev->sme_state);
\r
872 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
\r
877 #ifdef CONFIG_AP_MODE
\r
878 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
\r
881 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
882 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
\r
883 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
884 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
885 struct security_priv* psecuritypriv=&(padapter->securitypriv);
\r
886 struct sta_priv *pstapriv = &padapter->stapriv;
\r
888 DBG_8192C("%s\n", __FUNCTION__);
\r
890 param->u.crypt.err = 0;
\r
891 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
\r
893 //sizeof(struct ieee_param) = 64 bytes;
\r
894 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
\r
895 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
\r
901 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
\r
902 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
\r
903 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
\r
905 if (param->u.crypt.idx >= WEP_KEYS)
\r
913 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
\r
917 DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n");
\r
922 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
\r
924 //todo:clear default encryption keys
\r
926 DBG_8192C("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
\r
932 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
\r
934 DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
\r
936 wep_key_idx = param->u.crypt.idx;
\r
937 wep_key_len = param->u.crypt.key_len;
\r
939 DBG_8192C("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
\r
941 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
\r
947 if (wep_key_len > 0)
\r
949 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
952 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
\r
954 //wep default key has not been set, so use this key index as default key.
\r
956 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
\r
957 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
958 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
\r
959 psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
\r
961 if(wep_key_len == 13)
\r
963 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
\r
964 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
\r
967 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
\r
970 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
\r
972 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
\r
974 rtw_ap_set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx, 1);
\r
981 if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
\r
983 if(param->u.crypt.set_tx == 0) //group key
\r
985 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
987 DBG_8192C("%s, set group_key, WEP\n", __FUNCTION__);
\r
989 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
991 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
992 if(param->u.crypt.key_len==13)
\r
994 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
998 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1000 DBG_8192C("%s, set group_key, TKIP\n", __FUNCTION__);
\r
1002 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
\r
1004 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1006 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1008 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
\r
1009 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
\r
1011 psecuritypriv->busetkipkey = _TRUE;
\r
1014 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1016 DBG_8192C("%s, set group_key, CCMP\n", __FUNCTION__);
\r
1018 psecuritypriv->dot118021XGrpPrivacy = _AES_;
\r
1020 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1024 DBG_8192C("%s, set group_key, none\n", __FUNCTION__);
\r
1026 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
1029 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
\r
1031 psecuritypriv->binstallGrpkey = _TRUE;
\r
1033 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
\r
1035 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
\r
1037 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1040 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1041 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
\r
1050 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
\r
1052 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
1054 if(param->u.crypt.set_tx ==1) //pairwise key
\r
1056 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1058 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1060 DBG_8192C("%s, set pairwise key, WEP\n", __FUNCTION__);
\r
1062 psta->dot118021XPrivacy = _WEP40_;
\r
1063 if(param->u.crypt.key_len==13)
\r
1065 psta->dot118021XPrivacy = _WEP104_;
\r
1068 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1070 DBG_8192C("%s, set pairwise key, TKIP\n", __FUNCTION__);
\r
1072 psta->dot118021XPrivacy = _TKIP_;
\r
1074 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1076 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
\r
1077 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
\r
1079 psecuritypriv->busetkipkey = _TRUE;
\r
1082 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1085 DBG_8192C("%s, set pairwise key, CCMP\n", __FUNCTION__);
\r
1087 psta->dot118021XPrivacy = _AES_;
\r
1091 DBG_8192C("%s, set pairwise key, none\n", __FUNCTION__);
\r
1093 psta->dot118021XPrivacy = _NO_PRIVACY_;
\r
1096 rtw_ap_set_pairwise_key(padapter, psta);
\r
1098 psta->ieee8021x_blocked = _FALSE;
\r
1100 psta->bpairwise_key_installed = _TRUE;
\r
1103 else//group key???
\r
1105 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
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));
\r
1109 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1110 if(param->u.crypt.key_len==13)
\r
1112 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1115 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1117 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
\r
1119 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1121 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1123 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
\r
1124 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
\r
1126 psecuritypriv->busetkipkey = _TRUE;
\r
1129 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1131 psecuritypriv->dot118021XGrpPrivacy = _AES_;
\r
1133 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1137 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
1140 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
\r
1142 psecuritypriv->binstallGrpkey = _TRUE;
\r
1144 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
\r
1146 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
\r
1148 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1151 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1152 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
\r
1168 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
\r
1171 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
1172 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
1173 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1174 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1176 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
\r
1177 #endif //CONFIG_P2P
\r
1181 DBG_8192C("%s\n", __func__);
\r
1183 param->u.crypt.err = 0;
\r
1184 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
\r
1186 if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
\r
1192 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
\r
1193 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
\r
1194 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
\r
1196 if (param->u.crypt.idx >= WEP_KEYS
\r
1197 #ifdef CONFIG_IEEE80211W
\r
1198 && param->u.crypt.idx > BIP_MAX_KEYID
\r
1199 #endif //CONFIG_IEEE80211W
\r
1206 #ifdef CONFIG_WAPI_SUPPORT
\r
1207 if (strcmp(param->u.crypt.alg, "SMS4"))
\r
1215 if (strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1217 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
\r
1218 DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n");
\r
1220 wep_key_idx = param->u.crypt.idx;
\r
1221 wep_key_len = param->u.crypt.key_len;
\r
1223 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0))
\r
1229 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
\r
1231 //wep default key has not been set, so use this key index as default key.
\r
1233 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
1235 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1236 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
\r
1237 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1239 if(wep_key_len==13)
\r
1241 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
\r
1242 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1245 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
\r
1248 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
\r
1250 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
\r
1252 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, _TRUE);
\r
1257 if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
\r
1259 struct sta_info * psta,*pbcmc_sta;
\r
1260 struct sta_priv * pstapriv = &padapter->stapriv;
\r
1262 //DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__);
\r
1264 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
\r
1266 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
\r
1267 if (psta == NULL) {
\r
1268 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
\r
1269 DBG_8192C("%s, : Obtain Sta_info fail \n", __func__);
\r
1273 //Jeff: don't disable ieee8021x_blocked while clearing key
\r
1274 if (strcmp(param->u.crypt.alg, "none") != 0)
\r
1275 psta->ieee8021x_blocked = _FALSE;
\r
1278 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
\r
1279 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
\r
1281 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
\r
1284 if(param->u.crypt.set_tx ==1)//pairwise key
\r
1287 DBG_8192C("%s, : param->u.crypt.set_tx ==1 \n", __func__);
\r
1289 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1291 if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
\r
1293 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
\r
1294 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
\r
1295 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
\r
1297 padapter->securitypriv.busetkipkey=_FALSE;
\r
1298 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
\r
1301 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
\r
1302 DBG_871X(" ~~~~set sta key:unicastkey\n");
\r
1304 rtw_setstakey_cmd(padapter, psta, _TRUE, _TRUE);
\r
1308 if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1310 _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1311 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
\r
1312 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
\r
1313 padapter->securitypriv.binstallGrpkey = _TRUE;
\r
1314 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
\r
1315 DBG_871X(" ~~~~set sta key:groupkey\n");
\r
1317 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
\r
1319 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1, _TRUE);
\r
1321 #ifdef CONFIG_IEEE80211W
\r
1322 else if(strcmp(param->u.crypt.alg, "BIP") == 0)
\r
1325 //DBG_871X("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx);
\r
1326 //save the IGTK key, length 16 bytes
\r
1327 _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1328 /*DBG_871X("IGTK key below:\n");
\r
1329 for(no=0;no<16;no++)
\r
1330 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
\r
1332 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
\r
1333 padapter->securitypriv.binstallBIPkey = _TRUE;
\r
1334 DBG_871X(" ~~~~set sta key:IGKT\n");
\r
1336 #endif //CONFIG_IEEE80211W
\r
1339 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1341 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
\r
1343 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
\r
1346 #endif //CONFIG_P2P
\r
1351 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1352 if(pbcmc_sta==NULL)
\r
1354 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
\r
1358 //Jeff: don't disable ieee8021x_blocked while clearing key
\r
1359 if (strcmp(param->u.crypt.alg, "none") != 0)
\r
1360 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1362 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
\r
1363 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
\r
1365 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
\r
1369 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
\r
1374 #ifdef CONFIG_WAPI_SUPPORT
\r
1375 if (strcmp(param->u.crypt.alg, "SMS4") == 0)
\r
1377 PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
\r
1378 PRT_WAPI_STA_INFO pWapiSta;
\r
1379 u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1380 u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1381 u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1383 if(param->u.crypt.set_tx == 1)
\r
1385 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
\r
1386 if(_rtw_memcmp(pWapiSta->PeerMacAddr,param->sta_addr,6))
\r
1388 _rtw_memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
\r
1390 pWapiSta->wapiUsk.bSet = true;
\r
1391 _rtw_memcpy(pWapiSta->wapiUsk.dataKey,param->u.crypt.key,16);
\r
1392 _rtw_memcpy(pWapiSta->wapiUsk.micKey,param->u.crypt.key+16,16);
\r
1393 pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
\r
1394 pWapiSta->wapiUsk.bTxEnable = true;
\r
1396 _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16);
\r
1397 _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16);
\r
1398 _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16);
\r
1399 _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16);
\r
1400 _rtw_memcpy(pWapiSta->lastRxUnicastPN,WapiAEPNInitialValueSrc,16);
\r
1401 pWapiSta->wapiUskUpdate.bTxEnable = false;
\r
1402 pWapiSta->wapiUskUpdate.bSet = false;
\r
1404 if (psecuritypriv->sw_encrypt== false || psecuritypriv->sw_decrypt == false)
\r
1406 //set unicast key for ASUE
\r
1407 rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
\r
1414 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
\r
1415 if(_rtw_memcmp(pWapiSta->PeerMacAddr,get_bssid(pmlmepriv),6))
\r
1417 pWapiSta->wapiMsk.bSet = true;
\r
1418 _rtw_memcpy(pWapiSta->wapiMsk.dataKey,param->u.crypt.key,16);
\r
1419 _rtw_memcpy(pWapiSta->wapiMsk.micKey,param->u.crypt.key+16,16);
\r
1420 pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
\r
1421 pWapiSta->wapiMsk.bTxEnable = false;
\r
1422 if(!pWapiSta->bSetkeyOk)
\r
1423 pWapiSta->bSetkeyOk = true;
\r
1424 pWapiSta->bAuthenticateInProgress = false;
\r
1426 _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
\r
1428 if (psecuritypriv->sw_decrypt == false)
\r
1430 //set rx broadcast key for ASUE
\r
1431 rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
\r
1443 DBG_8192C("%s, ret=%d\n", __func__, ret);
\r
1450 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1451 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1452 u8 key_index, bool pairwise, const u8 *mac_addr,
\r
1453 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1454 u8 key_index, const u8 *mac_addr,
\r
1455 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1456 struct key_params *params)
\r
1460 struct ieee_param *param = NULL;
\r
1462 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1463 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
1464 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1466 DBG_871X(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
\r
1467 DBG_871X("cipher=0x%x\n", params->cipher);
\r
1468 DBG_871X("key_len=0x%x\n", params->key_len);
\r
1469 DBG_871X("seq_len=0x%x\n", params->seq_len);
\r
1470 DBG_871X("key_index=%d\n", key_index);
\r
1471 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1472 DBG_871X("pairwise=%d\n", pairwise);
\r
1473 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1475 param_len = sizeof(struct ieee_param) + params->key_len;
\r
1476 param = (struct ieee_param *)rtw_malloc(param_len);
\r
1477 if (param == NULL)
\r
1480 _rtw_memset(param, 0, param_len);
\r
1482 param->cmd = IEEE_CMD_SET_ENCRYPTION;
\r
1483 _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
\r
1485 switch (params->cipher) {
\r
1486 case IW_AUTH_CIPHER_NONE:
\r
1487 //todo: remove key
\r
1489 alg_name = "none";
\r
1491 case WLAN_CIPHER_SUITE_WEP40:
\r
1492 case WLAN_CIPHER_SUITE_WEP104:
\r
1495 case WLAN_CIPHER_SUITE_TKIP:
\r
1496 alg_name = "TKIP";
\r
1498 case WLAN_CIPHER_SUITE_CCMP:
\r
1499 alg_name = "CCMP";
\r
1501 #ifdef CONFIG_IEEE80211W
\r
1502 case WLAN_CIPHER_SUITE_AES_CMAC:
\r
1505 #endif //CONFIG_IEEE80211W
\r
1506 #ifdef CONFIG_WAPI_SUPPORT
\r
1507 case WLAN_CIPHER_SUITE_SMS4:
\r
1509 if(pairwise == NL80211_KEYTYPE_PAIRWISE) {
\r
1510 if (key_index != 0 && key_index != 1) {
\r
1514 _rtw_memcpy((void*)param->sta_addr, (void*)mac_addr, ETH_ALEN);
\r
1516 DBG_871X("mac_addr is null \n");
\r
1518 DBG_871X("rtw_wx_set_enc_ext: SMS4 case \n");
\r
1527 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
\r
1530 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
\r
1532 param->u.crypt.set_tx = 0; //for wpa/wpa2 group key
\r
1534 param->u.crypt.set_tx = 1; //for wpa/wpa2 pairwise key
\r
1538 //param->u.crypt.idx = key_index - 1;
\r
1539 param->u.crypt.idx = key_index;
\r
1541 if (params->seq_len && params->seq)
\r
1543 _rtw_memcpy(param->u.crypt.seq, params->seq, params->seq_len);
\r
1546 if(params->key_len && params->key)
\r
1548 param->u.crypt.key_len = params->key_len;
\r
1549 _rtw_memcpy(param->u.crypt.key, params->key, params->key_len);
\r
1552 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
\r
1554 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
\r
1556 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
1558 #ifdef CONFIG_AP_MODE
\r
1560 _rtw_memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN);
\r
1562 ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
\r
1567 DBG_8192C("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
\r
1574 rtw_mfree((u8*)param, param_len);
\r
1581 static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1582 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1583 u8 key_index, bool pairwise, const u8 *mac_addr,
\r
1584 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1585 u8 key_index, const u8 *mac_addr,
\r
1586 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1588 void (*callback)(void *cookie,
\r
1589 struct key_params*))
\r
1592 struct iwm_priv *iwm = ndev_to_iwm(ndev);
\r
1593 struct iwm_key *key = &iwm->keys[key_index];
\r
1594 struct key_params params;
\r
1596 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
\r
1598 memset(¶ms, 0, sizeof(params));
\r
1600 params.cipher = key->cipher;
\r
1601 params.key_len = key->key_len;
\r
1602 params.seq_len = key->seq_len;
\r
1603 params.seq = key->seq;
\r
1604 params.key = key->key;
\r
1606 callback(cookie, ¶ms);
\r
1608 return key->key_len ? 0 : -ENOENT;
\r
1610 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
1614 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1615 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1616 u8 key_index, bool pairwise, const u8 *mac_addr)
\r
1617 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1618 u8 key_index, const u8 *mac_addr)
\r
1619 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1621 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1622 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1624 DBG_871X(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index);
\r
1626 if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
\r
1628 //clear the flag of wep default key set.
\r
1629 psecuritypriv->bWepDefaultKeyIdxSet = 0;
\r
1635 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
\r
1636 struct net_device *ndev, u8 key_index
\r
1637 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1638 , bool unicast, bool multicast
\r
1642 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1643 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1645 DBG_871X(FUNC_NDEV_FMT" key_index=%d"
\r
1646 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1647 ", unicast=%d, multicast=%d"
\r
1649 ".\n", FUNC_NDEV_ARG(ndev), key_index
\r
1650 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1651 , unicast, multicast
\r
1655 if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) //set wep default key
\r
1657 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1659 psecuritypriv->dot11PrivacyKeyIndex = key_index;
\r
1661 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
\r
1662 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1663 if (psecuritypriv->dot11DefKeylen[key_index] == 13)
\r
1665 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
\r
1666 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1669 psecuritypriv->bWepDefaultKeyIdxSet = 1; //set the flag to represent that wep default key has been set
\r
1676 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
\r
1677 struct net_device *ndev,
\r
1678 u8 *mac, struct station_info *sinfo)
\r
1681 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1682 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1683 struct sta_info *psta = NULL;
\r
1684 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1686 sinfo->filled = 0;
\r
1689 DBG_871X(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
\r
1694 psta = rtw_get_stainfo(pstapriv, mac);
\r
1695 if (psta == NULL) {
\r
1696 DBG_8192C("%s, sta_info is null\n", __func__);
\r
1701 #ifdef CONFIG_DEBUG_CFG80211
\r
1702 DBG_871X(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
\r
1705 //for infra./P2PClient mode
\r
1706 if( check_fwstate(pmlmepriv, WIFI_STATION_STATE)
\r
1707 && check_fwstate(pmlmepriv, _FW_LINKED)
\r
1710 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
1712 if (_rtw_memcmp(mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) {
\r
1713 DBG_871X("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
\r
1718 sinfo->filled |= STATION_INFO_SIGNAL;
\r
1719 sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
\r
1721 sinfo->filled |= STATION_INFO_TX_BITRATE;
\r
1722 sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
\r
1724 sinfo->filled |= STATION_INFO_RX_PACKETS;
\r
1725 sinfo->rx_packets = sta_rx_data_pkts(psta);
\r
1727 sinfo->filled |= STATION_INFO_TX_PACKETS;
\r
1728 sinfo->tx_packets = psta->sta_stats.tx_pkts;
\r
1732 //for Ad-Hoc/AP mode
\r
1733 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
\r
1734 ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
\r
1735 ||check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
1736 && check_fwstate(pmlmepriv, _FW_LINKED)
\r
1739 //TODO: should acquire station info...
\r
1746 extern int netdev_open(struct net_device *pnetdev);
\r
1747 #ifdef CONFIG_CONCURRENT_MODE
\r
1748 extern int netdev_if2_open(struct net_device *pnetdev);
\r
1752 enum nl80211_iftype {
\r
1753 NL80211_IFTYPE_UNSPECIFIED,
\r
1754 NL80211_IFTYPE_ADHOC, //1
\r
1755 NL80211_IFTYPE_STATION, //2
\r
1756 NL80211_IFTYPE_AP, //3
\r
1757 NL80211_IFTYPE_AP_VLAN,
\r
1758 NL80211_IFTYPE_WDS,
\r
1759 NL80211_IFTYPE_MONITOR, //6
\r
1760 NL80211_IFTYPE_MESH_POINT,
\r
1761 NL80211_IFTYPE_P2P_CLIENT, //8
\r
1762 NL80211_IFTYPE_P2P_GO, //9
\r
1764 NUM_NL80211_IFTYPES,
\r
1765 NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
\r
1768 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
\r
1769 struct net_device *ndev,
\r
1770 enum nl80211_iftype type, u32 *flags,
\r
1771 struct vif_params *params)
\r
1773 enum nl80211_iftype old_type;
\r
1774 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
\r
1775 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1776 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
1777 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
1779 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
1782 u8 change = _FALSE;
\r
1784 DBG_871X(FUNC_NDEV_FMT" type=%d\n", FUNC_NDEV_ARG(ndev), type);
\r
1786 if(adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE)
\r
1792 #ifdef CONFIG_CONCURRENT_MODE
\r
1793 if(padapter->adapter_type == SECONDARY_ADAPTER)
\r
1795 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev));
\r
1796 if(netdev_if2_open(ndev) != 0) {
\r
1797 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open fail\n", FUNC_NDEV_ARG(ndev));
\r
1802 else if(padapter->adapter_type == PRIMARY_ADAPTER)
\r
1803 #endif //CONFIG_CONCURRENT_MODE
\r
1805 DBG_871X(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
\r
1806 if(netdev_open(ndev) != 0) {
\r
1807 DBG_871X(FUNC_NDEV_FMT" call netdev_open fail\n", FUNC_NDEV_ARG(ndev));
\r
1813 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
1814 DBG_871X(FUNC_NDEV_FMT" call rtw_pwr_wakeup fail\n", FUNC_NDEV_ARG(ndev));
\r
1819 old_type = rtw_wdev->iftype;
\r
1820 DBG_871X(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
\r
1821 FUNC_NDEV_ARG(ndev), old_type, type);
\r
1823 if(old_type != type)
\r
1826 pmlmeext->action_public_rxseq = 0xffff;
\r
1827 pmlmeext->action_public_dialog_token = 0xff;
\r
1831 case NL80211_IFTYPE_ADHOC:
\r
1832 networkType = Ndis802_11IBSS;
\r
1834 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1835 case NL80211_IFTYPE_P2P_CLIENT:
\r
1837 case NL80211_IFTYPE_STATION:
\r
1838 networkType = Ndis802_11Infrastructure;
\r
1840 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1842 if(change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
1844 //it means remove GO and change mode from AP(GO) to station(P2P DEVICE)
\r
1845 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
1846 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
1848 DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
\r
1851 #endif //CONFIG_P2P
\r
1853 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1854 case NL80211_IFTYPE_P2P_GO:
\r
1856 case NL80211_IFTYPE_AP:
\r
1857 networkType = Ndis802_11APMode;
\r
1859 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1861 if(change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
1863 //it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO)
\r
1864 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
\r
1867 #endif //CONFIG_P2P
\r
1870 ret = -EOPNOTSUPP;
\r
1874 rtw_wdev->iftype = type;
\r
1876 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE)
\r
1878 rtw_wdev->iftype = old_type;
\r
1883 rtw_setopmode_cmd(padapter, networkType,_TRUE);
\r
1887 DBG_871X(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret);
\r
1891 void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted)
\r
1893 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
1896 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
1897 if (pwdev_priv->scan_request != NULL) {
\r
1898 #ifdef CONFIG_DEBUG_CFG80211
\r
1899 DBG_871X("%s with scan req\n", __FUNCTION__);
\r
1902 /* avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); */
\r
1903 if(pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
\r
1905 DBG_8192C("error wiphy compare\n");
\r
1909 cfg80211_scan_done(pwdev_priv->scan_request, aborted);
\r
1912 pwdev_priv->scan_request = NULL;
\r
1914 #ifdef CONFIG_DEBUG_CFG80211
\r
1915 DBG_871X("%s without scan req\n", __FUNCTION__);
\r
1918 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
1921 void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork)
\r
1923 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
1924 struct wiphy *wiphy = pwdev->wiphy;
\r
1925 struct cfg80211_bss *bss = NULL;
\r
1926 WLAN_BSSID_EX select_network = pnetwork->network;
\r
1928 bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
\r
1929 select_network.MacAddress, select_network.Ssid.Ssid,
\r
1930 select_network.Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
\r
1931 0/*WLAN_CAPABILITY_ESS*/);
\r
1934 cfg80211_unlink_bss(wiphy, bss);
\r
1935 DBG_8192C("%s(): cfg80211_unlink %s!! () ",__func__,select_network.Ssid.Ssid );
\r
1936 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
1937 cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
\r
1939 cfg80211_put_bss(bss);
\r
1945 void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
\r
1948 _list *plist, *phead;
\r
1949 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
1950 _queue *queue = &(pmlmepriv->scanned_queue);
\r
1951 struct wlan_network *pnetwork = NULL;
\r
1953 u32 wait_for_surveydone;
\r
1956 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
\r
1957 #endif //CONFIG_P2P
\r
1958 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
1960 #ifdef CONFIG_DEBUG_CFG80211
\r
1961 DBG_8192C("%s\n", __func__);
\r
1964 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
1966 phead = get_list_head(queue);
\r
1967 plist = get_next(phead);
\r
1971 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
\r
1974 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
\r
1976 //report network only if the current channel set contains the channel to which this network belongs
\r
1977 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
\r
1978 && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
\r
1979 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
\r
1982 //ev=translate_scan(padapter, a, pnetwork, ev, stop);
\r
1983 rtw_cfg80211_inform_bss(padapter, pnetwork);
\r
1986 plist = get_next(plist);
\r
1990 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
1993 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
\r
1996 uint wps_ielen = 0;
\r
1998 u32 p2p_ielen = 0;
\r
2000 u32 wfd_ielen = 0;
\r
2002 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2004 #ifdef CONFIG_DEBUG_CFG80211
\r
2005 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
2010 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
2012 #ifdef CONFIG_DEBUG_CFG80211
\r
2013 DBG_8192C("probe_req_wps_ielen=%d\n", wps_ielen);
\r
2016 if(pmlmepriv->wps_probe_req_ie)
\r
2018 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
\r
2019 pmlmepriv->wps_probe_req_ie_len = 0;
\r
2020 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
\r
2021 pmlmepriv->wps_probe_req_ie = NULL;
\r
2024 pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
\r
2025 if ( pmlmepriv->wps_probe_req_ie == NULL) {
\r
2026 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2030 _rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
\r
2031 pmlmepriv->wps_probe_req_ie_len = wps_ielen;
\r
2034 //buf += wps_ielen;
\r
2035 //len -= wps_ielen;
\r
2038 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
2040 struct wifidirect_info *wdinfo = &padapter->wdinfo;
\r
2041 u32 attr_contentlen = 0;
\r
2042 u8 listen_ch_attr[5];
\r
2044 #ifdef CONFIG_DEBUG_CFG80211
\r
2045 DBG_8192C("probe_req_p2p_ielen=%d\n", p2p_ielen);
\r
2048 if(pmlmepriv->p2p_probe_req_ie)
\r
2050 u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
\r
2051 pmlmepriv->p2p_probe_req_ie_len = 0;
\r
2052 rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len);
\r
2053 pmlmepriv->p2p_probe_req_ie = NULL;
\r
2056 pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen);
\r
2057 if ( pmlmepriv->p2p_probe_req_ie == NULL) {
\r
2058 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2062 _rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
\r
2063 pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
\r
2065 if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8*)listen_ch_attr, (uint*) &attr_contentlen)
\r
2066 && attr_contentlen == 5)
\r
2068 if (wdinfo->listen_channel != listen_ch_attr[4]) {
\r
2069 DBG_871X(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n",
\r
2070 FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2],
\r
2071 listen_ch_attr[3], listen_ch_attr[4]);
\r
2072 wdinfo->listen_channel = listen_ch_attr[4];
\r
2076 #endif //CONFIG_P2P
\r
2078 //buf += p2p_ielen;
\r
2079 //len -= p2p_ielen;
\r
2082 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
2084 #ifdef CONFIG_DEBUG_CFG80211
\r
2085 DBG_8192C("probe_req_wfd_ielen=%d\n", wfd_ielen);
\r
2088 if(pmlmepriv->wfd_probe_req_ie)
\r
2090 u32 free_len = pmlmepriv->wfd_probe_req_ie_len;
\r
2091 pmlmepriv->wfd_probe_req_ie_len = 0;
\r
2092 rtw_mfree(pmlmepriv->wfd_probe_req_ie, free_len);
\r
2093 pmlmepriv->wfd_probe_req_ie = NULL;
\r
2096 pmlmepriv->wfd_probe_req_ie = rtw_malloc(wfd_ielen);
\r
2097 if ( pmlmepriv->wfd_probe_req_ie == NULL) {
\r
2098 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2102 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
\r
2104 #endif //CONFIG_WFD
\r
2112 static int cfg80211_rtw_scan(struct wiphy *wiphy
\r
2113 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
\r
2114 , struct net_device *ndev
\r
2116 , struct cfg80211_scan_request *request)
\r
2118 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
2119 struct net_device *ndev = wdev_to_ndev(request->wdev);
\r
2122 u8 _status = _FALSE;
\r
2124 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
\r
2125 struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
\r
2128 uint wps_ielen=0;
\r
2131 u8 survey_times=3;
\r
2132 u8 survey_times_for_one_ch=6;
\r
2133 struct cfg80211_ssid *ssids = request->ssids;
\r
2134 int social_channel = 0, j = 0;
\r
2135 bool need_indicate_scan_done = _FALSE;
\r
2137 _adapter *padapter;
\r
2138 struct rtw_wdev_priv *pwdev_priv;
\r
2139 struct mlme_priv *pmlmepriv;
\r
2141 struct wifidirect_info *pwdinfo;
\r
2142 #endif //CONFIG_P2P
\r
2143 #ifdef CONFIG_CONCURRENT_MODE
\r
2144 PADAPTER pbuddy_adapter = NULL;
\r
2145 struct mlme_priv *pbuddy_mlmepriv = NULL;
\r
2146 #endif //CONFIG_CONCURRENT_MODE
\r
2148 if (ndev == NULL) {
\r
2153 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2154 pwdev_priv = adapter_wdev_data(padapter);
\r
2155 pmlmepriv= &padapter->mlmepriv;
\r
2157 pwdinfo= &(padapter->wdinfo);
\r
2158 #endif //CONFIG_P2P
\r
2160 //#ifdef CONFIG_DEBUG_CFG80211
\r
2161 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
2164 #ifdef CONFIG_CONCURRENT_MODE
\r
2165 if (padapter->pbuddy_adapter) {
\r
2166 pbuddy_adapter = padapter->pbuddy_adapter;
\r
2167 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
\r
2169 #endif //CONFIG_CONCURRENT_MODE
\r
2171 #ifdef CONFIG_MP_INCLUDED
\r
2172 if (padapter->registrypriv.mp_mode == 1)
\r
2174 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter));
\r
2178 #ifdef CONFIG_CONCURRENT_MODE
\r
2179 if (padapter->pbuddy_adapter) {
\r
2180 if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1)
\r
2182 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter));
\r
2187 #endif //CONFIG_CONCURRENT_MODE
\r
2190 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2191 pwdev_priv->scan_request = request;
\r
2192 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2194 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
2196 #ifdef CONFIG_DEBUG_CFG80211
\r
2197 DBG_871X("%s under WIFI_AP_STATE\n", __FUNCTION__);
\r
2200 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
\r
2202 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2204 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
\r
2206 DBG_8192C("AP mode process WPS \n");
\r
2209 need_indicate_scan_done = _TRUE;
\r
2210 goto check_need_indicate_scan_done;
\r
2214 rtw_ps_deny(padapter, PS_DENY_SCAN);
\r
2215 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
2216 need_indicate_scan_done = _TRUE;
\r
2217 goto check_need_indicate_scan_done;
\r
2221 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
2223 if(ssids->ssid != NULL
\r
2224 && _rtw_memcmp(ssids->ssid, "DIRECT-", 7)
\r
2225 && rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
\r
2228 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2230 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
\r
2231 adapter_wdev_data(padapter)->p2p_enabled = _TRUE;
\r
2235 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
2236 #ifdef CONFIG_DEBUG_CFG80211
\r
2237 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
2240 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
\r
2242 if(request->n_channels == 3 &&
\r
2243 request->channels[0]->hw_value == 1 &&
\r
2244 request->channels[1]->hw_value == 6 &&
\r
2245 request->channels[2]->hw_value == 11
\r
2248 social_channel = 1;
\r
2252 #endif //CONFIG_P2P
\r
2254 if(request->ie && request->ie_len>0)
\r
2256 rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len );
\r
2259 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
\r
2260 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2261 need_indicate_scan_done = _TRUE;
\r
2262 goto check_need_indicate_scan_done;
\r
2263 } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
2264 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2266 goto check_need_indicate_scan_done;
\r
2269 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)
\r
2271 #if 1 // Miracast can't do AP scan
\r
2272 static u32 lastscantime = 0;
\r
2275 passtime = rtw_get_passing_time_ms(lastscantime);
\r
2276 lastscantime = rtw_get_current_time();
\r
2277 if (passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD)
\r
2280 DBG_871X("%s: bBusyTraffic == _TRUE\n", __FUNCTION__);
\r
2281 need_indicate_scan_done = _TRUE;
\r
2282 goto check_need_indicate_scan_done;
\r
2286 if (rtw_is_scan_deny(padapter)){
\r
2287 DBG_871X(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter));
\r
2288 need_indicate_scan_done = _TRUE;
\r
2289 goto check_need_indicate_scan_done;
\r
2292 #ifdef CONFIG_CONCURRENT_MODE
\r
2293 if(pbuddy_mlmepriv && (pbuddy_mlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))
\r
2295 #if 1 // Miracast can't do AP scan
\r
2296 static u32 buddylastscantime = 0;
\r
2299 passtime = rtw_get_passing_time_ms(buddylastscantime);
\r
2300 buddylastscantime = rtw_get_current_time();
\r
2301 if ((passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD)
\r
2302 //#ifdef CONFIG_P2P
\r
2303 // ||(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
\r
2304 //#endif //CONFIG_P2P
\r
2308 DBG_871X("%s: bBusyTraffic == _TRUE at buddy_intf\n", __FUNCTION__);
\r
2309 need_indicate_scan_done = _TRUE;
\r
2310 goto check_need_indicate_scan_done;
\r
2314 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE) {
\r
2315 DBG_871X("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv->fw_state);
\r
2316 need_indicate_scan_done = _TRUE;
\r
2317 goto check_need_indicate_scan_done;
\r
2319 } else if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY)) {
\r
2320 bool scan_via_buddy = _FALSE;
\r
2321 struct rtw_wdev_priv *buddy_wdev_priv = adapter_wdev_data(pbuddy_adapter);
\r
2323 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2324 _enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
\r
2325 if (buddy_wdev_priv->scan_request) {
\r
2326 DBG_871X("scan via buddy\n");
\r
2327 pmlmepriv->scanning_via_buddy_intf = _TRUE;
\r
2328 _enter_critical_bh(&pmlmepriv->lock, &irqL);
\r
2329 set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
\r
2330 _exit_critical_bh(&pmlmepriv->lock, &irqL);
\r
2331 scan_via_buddy = _TRUE;
\r
2333 _exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
\r
2334 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2336 if (scan_via_buddy == _FALSE)
\r
2337 need_indicate_scan_done = _TRUE;
\r
2339 goto check_need_indicate_scan_done;
\r
2341 #endif /* CONFIG_CONCURRENT_MODE */
\r
2344 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
2346 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
\r
2348 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
\r
2349 rtw_free_network_queue(padapter, _TRUE);
\r
2351 if(social_channel == 0)
\r
2352 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
\r
2354 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
\r
2357 #endif //CONFIG_P2P
\r
2360 _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
\r
2361 //parsing request ssids, n_ssids
\r
2362 for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
\r
2363 #ifdef CONFIG_DEBUG_CFG80211
\r
2364 DBG_8192C("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
\r
2366 _rtw_memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
\r
2367 ssid[i].SsidLength = ssids[i].ssid_len;
\r
2370 /* parsing channels, n_channels */
\r
2371 _rtw_memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
\r
2372 for (i=0;i<request->n_channels && i<RTW_CHANNEL_SCAN_AMOUNT;i++) {
\r
2373 #ifdef CONFIG_DEBUG_CFG80211
\r
2374 DBG_871X(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
\r
2376 ch[i].hw_value = request->channels[i]->hw_value;
\r
2377 ch[i].flags = request->channels[i]->flags;
\r
2380 _enter_critical_bh(&pmlmepriv->lock, &irqL);
\r
2381 if (request->n_channels == 1) {
\r
2382 for(i=1;i<survey_times_for_one_ch;i++)
\r
2383 _rtw_memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
\r
2384 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times_for_one_ch);
\r
2385 } else if (request->n_channels <= 4) {
\r
2386 for(j=request->n_channels-1;j>=0;j--)
\r
2387 for(i=0;i<survey_times;i++)
\r
2389 _rtw_memcpy(&ch[j*survey_times+i], &ch[j], sizeof(struct rtw_ieee80211_channel));
\r
2391 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * request->n_channels);
\r
2393 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
\r
2395 _exit_critical_bh(&pmlmepriv->lock, &irqL);
\r
2398 if(_status == _FALSE)
\r
2403 check_need_indicate_scan_done:
\r
2404 if (_TRUE == need_indicate_scan_done)
\r
2406 rtw_cfg80211_surveydone_event_callback(padapter);
\r
2407 rtw_cfg80211_indicate_scan_done(padapter, _FALSE);
\r
2411 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
\r
2418 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
\r
2421 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
\r
2423 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
\r
2424 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
\r
2427 iwm->conf.rts_threshold = wiphy->rts_threshold;
\r
2429 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
\r
2430 CFG_RTS_THRESHOLD,
\r
2431 iwm->conf.rts_threshold);
\r
2436 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
\r
2437 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
\r
2440 iwm->conf.frag_threshold = wiphy->frag_threshold;
\r
2442 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
\r
2443 CFG_FRAG_THRESHOLD,
\r
2444 iwm->conf.frag_threshold);
\r
2449 DBG_8192C("%s\n", __func__);
\r
2455 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
\r
2457 DBG_8192C("%s, wpa_version=%d\n", __func__, wpa_version);
\r
2459 if (!wpa_version) {
\r
2460 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
2465 if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
\r
2467 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
\r
2471 if (wpa_version & NL80211_WPA_VERSION_2)
\r
2473 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
\r
2477 #ifdef CONFIG_WAPI_SUPPORT
\r
2478 if (wpa_version & NL80211_WAPI_VERSION_1)
\r
2480 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWAPI;
\r
2488 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
\r
2489 enum nl80211_auth_type sme_auth_type)
\r
2491 DBG_8192C("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
\r
2494 switch (sme_auth_type) {
\r
2495 case NL80211_AUTHTYPE_AUTOMATIC:
\r
2497 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
\r
2500 case NL80211_AUTHTYPE_OPEN_SYSTEM:
\r
2502 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
\r
2504 if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
\r
2505 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2507 #ifdef CONFIG_WAPI_SUPPORT
\r
2508 if(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI)
\r
2509 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2513 case NL80211_AUTHTYPE_SHARED_KEY:
\r
2515 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
\r
2517 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2522 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
\r
2523 //return -ENOTSUPP;
\r
2530 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
\r
2532 u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2534 u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
\r
2535 &psecuritypriv->dot118021XGrpPrivacy;
\r
2537 DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
\r
2541 *profile_cipher = _NO_PRIVACY_;
\r
2542 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
\r
2547 case IW_AUTH_CIPHER_NONE:
\r
2548 *profile_cipher = _NO_PRIVACY_;
\r
2549 ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2550 #ifdef CONFIG_WAPI_SUPPORT
\r
2551 if(psecuritypriv->dot11PrivacyAlgrthm ==_SMS4_ )
\r
2553 *profile_cipher = _SMS4_;
\r
2557 case WLAN_CIPHER_SUITE_WEP40:
\r
2558 *profile_cipher = _WEP40_;
\r
2559 ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2561 case WLAN_CIPHER_SUITE_WEP104:
\r
2562 *profile_cipher = _WEP104_;
\r
2563 ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2565 case WLAN_CIPHER_SUITE_TKIP:
\r
2566 *profile_cipher = _TKIP_;
\r
2567 ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2569 case WLAN_CIPHER_SUITE_CCMP:
\r
2570 *profile_cipher = _AES_;
\r
2571 ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2573 #ifdef CONFIG_WAPI_SUPPORT
\r
2574 case WLAN_CIPHER_SUITE_SMS4:
\r
2575 *profile_cipher = _SMS4_;
\r
2576 ndisencryptstatus = Ndis802_11_EncrypteionWAPI;
\r
2580 DBG_8192C("Unsupported cipher: 0x%x\n", cipher);
\r
2586 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
\r
2588 //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
\r
2589 // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
\r
2595 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
\r
2597 DBG_8192C("%s, key_mgt=0x%x\n", __func__, key_mgt);
\r
2599 if (key_mgt == WLAN_AKM_SUITE_8021X)
\r
2600 //*auth_type = UMAC_AUTH_TYPE_8021X;
\r
2601 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2602 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
\r
2603 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2605 #ifdef CONFIG_WAPI_SUPPORT
\r
2606 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_PSK){
\r
2607 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2609 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_CERT){
\r
2610 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2616 DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt);
\r
2623 static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
\r
2625 u8 *buf=NULL, *pos=NULL;
\r
2627 int group_cipher = 0, pairwise_cipher = 0;
\r
2632 u8 null_addr[]= {0,0,0,0,0,0};
\r
2634 if (pie == NULL || !ielen) {
\r
2635 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
\r
2636 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2640 if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
\r
2645 buf = rtw_zmalloc(ielen);
\r
2651 _rtw_memcpy(buf, pie , ielen);
\r
2656 DBG_8192C("set wpa_ie(length:%zu):\n", ielen);
\r
2657 for(i=0;i<ielen;i=i+8)
\r
2658 DBG_8192C("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n",buf[i],buf[i+1],buf[i+2],buf[i+3],buf[i+4],buf[i+5],buf[i+6],buf[i+7]);
\r
2662 if(ielen < RSN_HEADER_LEN){
\r
2663 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
\r
2668 pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
\r
2669 if(pwpa && wpa_ielen>0)
\r
2671 if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
2673 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
2674 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
\r
2675 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
\r
2677 DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
\r
2681 pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
\r
2682 if(pwpa2 && wpa2_ielen>0)
\r
2684 if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
2686 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
2687 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
\r
2688 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
\r
2690 DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
\r
2694 if (group_cipher == 0)
\r
2696 group_cipher = WPA_CIPHER_NONE;
\r
2698 if (pairwise_cipher == 0)
\r
2700 pairwise_cipher = WPA_CIPHER_NONE;
\r
2703 switch(group_cipher)
\r
2705 case WPA_CIPHER_NONE:
\r
2706 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
\r
2707 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
\r
2709 case WPA_CIPHER_WEP40:
\r
2710 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
\r
2711 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2713 case WPA_CIPHER_TKIP:
\r
2714 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
\r
2715 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2717 case WPA_CIPHER_CCMP:
\r
2718 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
\r
2719 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2721 case WPA_CIPHER_WEP104:
\r
2722 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
\r
2723 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2727 switch(pairwise_cipher)
\r
2729 case WPA_CIPHER_NONE:
\r
2730 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
\r
2731 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
\r
2733 case WPA_CIPHER_WEP40:
\r
2734 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
\r
2735 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2737 case WPA_CIPHER_TKIP:
\r
2738 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
\r
2739 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2741 case WPA_CIPHER_CCMP:
\r
2742 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
\r
2743 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2745 case WPA_CIPHER_WEP104:
\r
2746 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
\r
2747 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2751 {/* handle wps_ie */
\r
2755 wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
\r
2756 if (wps_ie && wps_ielen > 0) {
\r
2757 DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen);
\r
2758 padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
\r
2759 _rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
\r
2760 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2762 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2767 {//check p2p_ie for assoc req;
\r
2770 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2772 if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen)))
\r
2774 #ifdef CONFIG_DEBUG_CFG80211
\r
2775 DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
\r
2778 if(pmlmepriv->p2p_assoc_req_ie)
\r
2780 u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
\r
2781 pmlmepriv->p2p_assoc_req_ie_len = 0;
\r
2782 rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
\r
2783 pmlmepriv->p2p_assoc_req_ie = NULL;
\r
2786 pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
\r
2787 if ( pmlmepriv->p2p_assoc_req_ie == NULL) {
\r
2788 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2791 _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
\r
2792 pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
\r
2795 #endif //CONFIG_P2P
\r
2798 {//check wfd_ie for assoc req;
\r
2801 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2803 if(rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen))
\r
2805 #ifdef CONFIG_DEBUG_CFG80211
\r
2806 DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
\r
2809 if(pmlmepriv->wfd_assoc_req_ie)
\r
2811 u32 free_len = pmlmepriv->wfd_assoc_req_ie_len;
\r
2812 pmlmepriv->wfd_assoc_req_ie_len = 0;
\r
2813 rtw_mfree(pmlmepriv->wfd_assoc_req_ie, free_len);
\r
2814 pmlmepriv->wfd_assoc_req_ie = NULL;
\r
2817 pmlmepriv->wfd_assoc_req_ie = rtw_malloc(wfd_ielen);
\r
2818 if ( pmlmepriv->wfd_assoc_req_ie == NULL) {
\r
2819 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2822 rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
\r
2825 #endif //CONFIG_WFD
\r
2827 //TKIP and AES disallow multicast packets until installing group key
\r
2828 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
\r
2829 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
\r
2830 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
\r
2831 //WPS open need to enable multicast
\r
2832 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
\r
2833 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
\r
2835 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
\r
2836 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
\r
2837 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
\r
2841 rtw_mfree(buf, ielen);
\r
2843 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2847 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
\r
2848 struct cfg80211_ibss_params *params)
\r
2850 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2851 NDIS_802_11_SSID ndis_ssid;
\r
2852 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
2853 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2856 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
2861 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
\r
2866 #ifdef CONFIG_CONCURRENT_MODE
\r
2867 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
\r
2868 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
\r
2872 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
\r
2873 rtw_scan_abort(padapter->pbuddy_adapter);
\r
2875 #endif //CONFIG_CONCURRENT_MODE
\r
2877 if (!params->ssid || !params->ssid_len)
\r
2883 if (params->ssid_len > IW_ESSID_MAX_SIZE){
\r
2889 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
\r
2890 ndis_ssid.SsidLength = params->ssid_len;
\r
2891 _rtw_memcpy(ndis_ssid.Ssid, params->ssid, params->ssid_len);
\r
2893 //DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, params->ssid_len);
\r
2895 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2896 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
\r
2897 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
2898 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
\r
2899 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
2901 ret = rtw_cfg80211_set_auth_type(psecuritypriv, NL80211_AUTHTYPE_OPEN_SYSTEM);
\r
2902 rtw_set_802_11_authentication_mode(padapter, psecuritypriv->ndisauthtype);
\r
2904 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE)
\r
2914 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
\r
2916 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2917 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
2918 enum nl80211_iftype old_type;
\r
2921 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
2923 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
2925 old_type = rtw_wdev->iftype;
\r
2927 rtw_set_to_roam(padapter, 0);
\r
2929 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
2931 rtw_scan_abort(padapter);
\r
2932 LeaveAllPowerSaveMode(padapter);
\r
2934 rtw_wdev->iftype = NL80211_IFTYPE_STATION;
\r
2936 if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) ==_FALSE)
\r
2938 rtw_wdev->iftype = old_type;
\r
2942 rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure,_TRUE);
\r
2946 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
2951 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
\r
2952 struct cfg80211_connect_params *sme)
\r
2957 struct wlan_network *pnetwork = NULL;
\r
2958 NDIS_802_11_AUTHENTICATION_MODE authmode;
\r
2959 NDIS_802_11_SSID ndis_ssid;
\r
2960 u8 *dst_ssid, *src_ssid;
\r
2961 u8 *dst_bssid, *src_bssid;
\r
2962 //u8 matched_by_bssid=_FALSE;
\r
2963 //u8 matched_by_ssid=_FALSE;
\r
2964 u8 matched=_FALSE;
\r
2965 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2966 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2967 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
2968 _queue *queue = &pmlmepriv->scanned_queue;
\r
2970 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
2972 DBG_871X("=>"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
2973 DBG_871X("privacy=%d, key=%p, key_len=%d, key_idx=%d\n",
\r
2974 sme->privacy, sme->key, sme->key_len, sme->key_idx);
\r
2977 if(adapter_wdev_data(padapter)->block == _TRUE)
\r
2980 DBG_871X("%s wdev_priv.block is set\n", __FUNCTION__);
\r
2984 #ifdef CONFIG_PLATFORM_MSTAR_SCAN_BEFORE_CONNECT
\r
2985 printk("MStar Android!\n");
\r
2986 if(adapter_wdev_data(padapter)->bandroid_scan == _FALSE)
\r
2989 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
2990 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2991 #endif //CONFIG_P2P
\r
2994 printk("Android hasn't attached yet!\n");
\r
3000 rtw_ps_deny(padapter, PS_DENY_JOIN);
\r
3001 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
3006 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
\r
3011 #ifdef CONFIG_CONCURRENT_MODE
\r
3012 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
\r
3013 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
\r
3017 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
\r
3018 rtw_scan_abort(padapter->pbuddy_adapter);
\r
3022 if (!sme->ssid || !sme->ssid_len)
\r
3028 if (sme->ssid_len > IW_ESSID_MAX_SIZE){
\r
3034 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
\r
3035 ndis_ssid.SsidLength = sme->ssid_len;
\r
3036 _rtw_memcpy(ndis_ssid.Ssid, sme->ssid, sme->ssid_len);
\r
3038 DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
\r
3042 DBG_8192C("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
\r
3045 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
3047 DBG_8192C("%s, fw_state=0x%x, goto exit\n", __FUNCTION__, pmlmepriv->fw_state);
\r
3050 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
\r
3051 rtw_scan_abort(padapter);
\r
3054 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
3055 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
\r
3056 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
3057 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
\r
3058 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
3060 #ifdef CONFIG_WAPI_SUPPORT
\r
3061 padapter->wapiInfo.bWapiEnable = false;
\r
3064 ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
\r
3068 #ifdef CONFIG_WAPI_SUPPORT
\r
3069 if(sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1)
\r
3071 padapter->wapiInfo.bWapiEnable = true;
\r
3072 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
\r
3073 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
\r
3077 ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
\r
3079 #ifdef CONFIG_WAPI_SUPPORT
\r
3080 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI)
\r
3081 padapter->mlmeextpriv.mlmext_info.auth_algo = psecuritypriv->dot11AuthAlgrthm;
\r
3088 DBG_8192C("%s, ie_len=%zu\n", __func__, sme->ie_len);
\r
3090 ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len);
\r
3094 if (sme->crypto.n_ciphers_pairwise) {
\r
3095 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
\r
3100 //For WEP Shared auth
\r
3101 if((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared
\r
3102 || psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && sme->key
\r
3105 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
3106 NDIS_802_11_WEP *pwep = NULL;
\r
3107 DBG_871X("%s(): Shared/Auto WEP\n",__FUNCTION__);
\r
3109 wep_key_idx = sme->key_idx;
\r
3110 wep_key_len = sme->key_len;
\r
3112 if (sme->key_idx > WEP_KEYS) {
\r
3117 if (wep_key_len > 0)
\r
3119 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
3120 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
\r
3121 pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
\r
3123 DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
\r
3128 _rtw_memset(pwep, 0, wep_total_len);
\r
3130 pwep->KeyLength = wep_key_len;
\r
3131 pwep->Length = wep_total_len;
\r
3133 if(wep_key_len==13)
\r
3135 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
\r
3136 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
\r
3144 pwep->KeyIndex = wep_key_idx;
\r
3145 pwep->KeyIndex |= 0x80000000;
\r
3147 _rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
\r
3149 if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
\r
3151 ret = -EOPNOTSUPP ;
\r
3155 rtw_mfree((u8 *)pwep,wep_total_len);
\r
3162 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
\r
3166 if (sme->crypto.n_akm_suites) {
\r
3167 ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
\r
3172 #ifdef CONFIG_WAPI_SUPPORT
\r
3173 if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_PSK){
\r
3174 padapter->wapiInfo.bWapiPSK = true;
\r
3176 else if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_CERT){
\r
3177 padapter->wapiInfo.bWapiPSK = false;
\r
3181 authmode = psecuritypriv->ndisauthtype;
\r
3182 rtw_set_802_11_authentication_mode(padapter, authmode);
\r
3184 //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
\r
3186 if (rtw_set_802_11_connect(padapter, sme->bssid, &ndis_ssid) == _FALSE) {
\r
3191 DBG_8192C("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy);
\r
3195 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
\r
3197 DBG_8192C("<=%s, ret %d\n",__FUNCTION__, ret);
\r
3199 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3204 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
\r
3207 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3209 struct wlan_network *pwlan = NULL;
\r
3210 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
3211 struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
\r
3214 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3216 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
3218 rtw_set_to_roam(padapter, 0);
\r
3220 //if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
3222 rtw_scan_abort(padapter);
\r
3223 LeaveAllPowerSaveMode(padapter);
\r
3224 rtw_disassoc_cmd(padapter, 500, _FALSE);
\r
3226 DBG_871X("%s...call rtw_indicate_disconnect\n", __FUNCTION__);
\r
3228 rtw_indicate_disconnect(padapter);
\r
3230 rtw_free_assoc_resources(padapter, 1);
\r
3232 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
3233 // remove the network entry in scanned_queue
\r
3235 pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.MacAddress);
\r
3237 DBG_871X("find target AP in scanned queue(%d)\n", cnt);
\r
3239 pwlan->fixed = _FALSE;
\r
3240 rtw_free_network_nolock(padapter, pwlan);
\r
3242 DBG_871X("target AP is not found\n");
\r
3244 }while(pwlan != NULL);
\r
3246 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
3248 rtw_pwr_wakeup(padapter);
\r
3251 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3253 DBG_871X(FUNC_NDEV_FMT" return 0\n", FUNC_NDEV_ARG(ndev));
\r
3258 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
\r
3259 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
\r
3260 struct wireless_dev *wdev,
\r
3262 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE)
\r
3263 enum nl80211_tx_power_setting type, int mbm)
\r
3265 enum tx_power_setting type, int dbm)
\r
3269 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
\r
3273 case NL80211_TX_POWER_AUTOMATIC:
\r
3275 case NL80211_TX_POWER_FIXED:
\r
3276 if (mbm < 0 || (mbm % 100))
\r
3277 return -EOPNOTSUPP;
\r
3279 if (!test_bit(IWM_STATUS_READY, &iwm->status))
\r
3282 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
\r
3283 CFG_TX_PWR_LIMIT_USR,
\r
3284 MBM_TO_DBM(mbm) * 2);
\r
3288 return iwm_tx_power_trigger(iwm);
\r
3290 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
\r
3291 return -EOPNOTSUPP;
\r
3294 DBG_8192C("%s\n", __func__);
\r
3298 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
\r
3299 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
\r
3300 struct wireless_dev *wdev,
\r
3304 DBG_8192C("%s\n", __func__);
\r
3311 inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
\r
3313 struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter);
\r
3314 return rtw_wdev_priv->power_mgmt;
\r
3317 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
\r
3318 struct net_device *ndev,
\r
3319 bool enabled, int timeout)
\r
3321 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3322 struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter);
\r
3324 DBG_871X(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
\r
3325 enabled, timeout);
\r
3327 rtw_wdev_priv->power_mgmt = enabled;
\r
3331 LPS_Leave(padapter, "CFG80211_PWRMGMT");
\r
3337 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
\r
3338 struct net_device *ndev,
\r
3339 struct cfg80211_pmksa *pmksa)
\r
3341 u8 index,blInserted = _FALSE;
\r
3342 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3343 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3344 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
\r
3346 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3348 if ( _rtw_memcmp( pmksa->bssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
\r
3353 blInserted = _FALSE;
\r
3356 for(index=0 ; index<NUM_PMKID_CACHE; index++)
\r
3358 if( _rtw_memcmp( psecuritypriv->PMKIDList[index].Bssid, pmksa->bssid, ETH_ALEN) ==_TRUE )
\r
3359 { // BSSID is matched, the same AP => rewrite with new PMKID.
\r
3360 DBG_871X(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(ndev));
\r
3362 _rtw_memcpy( psecuritypriv->PMKIDList[index].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
\r
3363 psecuritypriv->PMKIDList[index].bUsed = _TRUE;
\r
3364 psecuritypriv->PMKIDIndex = index+1;
\r
3365 blInserted = _TRUE;
\r
3372 // Find a new entry
\r
3373 DBG_871X(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
\r
3374 FUNC_NDEV_ARG(ndev), psecuritypriv->PMKIDIndex );
\r
3376 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, pmksa->bssid, ETH_ALEN);
\r
3377 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
\r
3379 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
\r
3380 psecuritypriv->PMKIDIndex++ ;
\r
3381 if(psecuritypriv->PMKIDIndex==16)
\r
3383 psecuritypriv->PMKIDIndex =0;
\r
3390 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
\r
3391 struct net_device *ndev,
\r
3392 struct cfg80211_pmksa *pmksa)
\r
3394 u8 index, bMatched = _FALSE;
\r
3395 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3396 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3398 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3400 for(index=0 ; index<NUM_PMKID_CACHE; index++)
\r
3402 if( _rtw_memcmp( psecuritypriv->PMKIDList[index].Bssid, pmksa->bssid, ETH_ALEN) ==_TRUE )
\r
3403 { // BSSID is matched, the same AP => Remove this PMKID information and reset it.
\r
3404 _rtw_memset( psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN );
\r
3405 _rtw_memset( psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN );
\r
3406 psecuritypriv->PMKIDList[index].bUsed = _FALSE;
\r
3412 if(_FALSE == bMatched)
\r
3414 DBG_871X(FUNC_NDEV_FMT" do not have matched BSSID\n"
\r
3415 , FUNC_NDEV_ARG(ndev));
\r
3422 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
\r
3423 struct net_device *ndev)
\r
3425 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3426 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3428 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3430 _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
\r
3431 psecuritypriv->PMKIDIndex = 0;
\r
3436 #ifdef CONFIG_AP_MODE
\r
3437 void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
3441 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
3442 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3443 struct net_device *ndev = padapter->pnetdev;
\r
3445 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
3447 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
\r
3449 struct station_info sinfo;
\r
3451 if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
\r
3452 ie_offset = _ASOCREQ_IE_OFFSET_;
\r
3453 else // WIFI_REASSOCREQ
\r
3454 ie_offset = _REASOCREQ_IE_OFFSET_;
\r
3457 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
\r
3458 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
\r
3459 sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
\r
3460 cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
\r
3462 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3463 channel = pmlmeext->cur_channel;
\r
3464 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
3465 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
3467 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
3469 #ifdef COMPAT_KERNEL_RELEASE
\r
3470 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3471 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
3472 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3473 #else //COMPAT_KERNEL_RELEASE
\r
3475 //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc()
\r
3476 #ifndef CONFIG_PLATFORM_MSTAR
\r
3477 pwdev->iftype = NL80211_IFTYPE_STATION;
\r
3478 #endif //CONFIG_PLATFORM_MSTAR
\r
3479 DBG_8192C("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
\r
3480 rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
\r
3481 DBG_8192C("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
\r
3482 pwdev->iftype = NL80211_IFTYPE_AP;
\r
3483 //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3485 #endif //COMPAT_KERNEL_RELEASE
\r
3486 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3490 void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason)
\r
3496 struct rtw_ieee80211_hdr *pwlanhdr;
\r
3497 unsigned short *fctrl;
\r
3498 u8 mgmt_buf[128] = {0};
\r
3499 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3500 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
3501 struct net_device *ndev = padapter->pnetdev;
\r
3503 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
3505 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
\r
3506 cfg80211_del_sta(ndev, da, GFP_ATOMIC);
\r
3507 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3508 channel = pmlmeext->cur_channel;
\r
3509 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
3510 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
3512 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
3514 pmgmt_frame = mgmt_buf;
\r
3515 pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
\r
3517 fctrl = &(pwlanhdr->frame_ctl);
\r
3520 //_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
\r
3521 //_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
3522 _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
3523 _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN);
\r
3524 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
3526 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
3527 pmlmeext->mgnt_seq++;
\r
3528 SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
\r
3530 pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
3531 frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
3533 reason = cpu_to_le16(reason);
\r
3534 pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
\r
3536 #ifdef COMPAT_KERNEL_RELEASE
\r
3537 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3538 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
3539 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3540 #else //COMPAT_KERNEL_RELEASE
\r
3541 cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len);
\r
3542 //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3543 #endif //COMPAT_KERNEL_RELEASE
\r
3544 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3547 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
\r
3551 DBG_8192C("%s\n", __func__);
\r
3556 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
\r
3560 DBG_8192C("%s\n", __func__);
\r
3565 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
\r
3570 int dot11_hdr_len = 24;
\r
3572 unsigned char *pdata;
\r
3574 unsigned char src_mac_addr[6];
\r
3575 unsigned char dst_mac_addr[6];
\r
3576 struct ieee80211_hdr *dot11_hdr;
\r
3577 struct ieee80211_radiotap_header *rtap_hdr;
\r
3578 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3580 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3583 rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
\r
3585 if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
\r
3588 rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
\r
3589 if (unlikely(rtap_hdr->it_version))
\r
3592 rtap_len = ieee80211_get_radiotap_len(skb->data);
\r
3593 if (unlikely(skb->len < rtap_len))
\r
3596 if(rtap_len != 14)
\r
3598 DBG_8192C("radiotap len (should be 14): %d\n", rtap_len);
\r
3602 /* Skip the ratio tap header */
\r
3603 skb_pull(skb, rtap_len);
\r
3605 dot11_hdr = (struct ieee80211_hdr *)skb->data;
\r
3606 frame_ctl = le16_to_cpu(dot11_hdr->frame_control);
\r
3607 /* Check if the QoS bit is set */
\r
3608 if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
\r
3609 /* Check if this ia a Wireless Distribution System (WDS) frame
\r
3610 * which has 4 MAC addresses
\r
3612 if (dot11_hdr->frame_control & 0x0080)
\r
3614 if ((dot11_hdr->frame_control & 0x0300) == 0x0300)
\r
3615 dot11_hdr_len += 6;
\r
3617 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
\r
3618 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
\r
3620 /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
\r
3621 * for two MAC addresses
\r
3623 skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
\r
3624 pdata = (unsigned char*)skb->data;
\r
3625 memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
\r
3626 memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
\r
3628 DBG_8192C("should be eapol packet\n");
\r
3630 /* Use the real net device to transmit the packet */
\r
3631 ret = _rtw_xmit_entry(skb, padapter->pnetdev);
\r
3636 else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE))
\r
3637 == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION)
\r
3640 //only for action frames
\r
3641 struct xmit_frame *pmgntframe;
\r
3642 struct pkt_attrib *pattrib;
\r
3643 unsigned char *pframe;
\r
3644 //u8 category, action, OUI_Subtype, dialogToken=0;
\r
3645 //unsigned char *frame_body;
\r
3646 struct rtw_ieee80211_hdr *pwlanhdr;
\r
3647 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
3648 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3649 u8 *buf = skb->data;
\r
3650 u32 len = skb->len;
\r
3651 u8 category, action;
\r
3654 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
\r
3655 DBG_8192C(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
\r
3656 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
\r
3660 DBG_8192C("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
\r
3661 MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
\r
3663 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0)
\r
3666 if (category == RTW_WLAN_CATEGORY_PUBLIC)
\r
3667 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
\r
3669 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
\r
3672 //starting alloc mgmt frame to dump it
\r
3673 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
3678 //update attribute
\r
3679 pattrib = &pmgntframe->attrib;
\r
3680 update_mgntframe_attrib(padapter, pattrib);
\r
3681 pattrib->retry_ctrl = _FALSE;
\r
3683 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
3685 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
3687 _rtw_memcpy(pframe, (void*)buf, len);
\r
3691 struct wifi_display_info *pwfd_info;
\r
3693 pwfd_info = padapter->wdinfo.wfd_info;
\r
3695 if ( _TRUE == pwfd_info->wfd_enable )
\r
3697 rtw_append_wfd_ie( padapter, pframe, &len );
\r
3700 #endif // CONFIG_WFD
\r
3701 pattrib->pktlen = len;
\r
3703 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
3704 //update seq number
\r
3705 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
\r
3706 pattrib->seqnum = pmlmeext->mgnt_seq;
\r
3707 pmlmeext->mgnt_seq++;
\r
3710 pattrib->last_txcmdsz = pattrib->pktlen;
\r
3712 dump_mgntframe(padapter, pmgntframe);
\r
3717 DBG_8192C("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE));
\r
3723 rtw_skb_free(skb);
\r
3729 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
\r
3731 DBG_8192C("%s\n", __func__);
\r
3734 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
\r
3738 DBG_8192C("%s\n", __func__);
\r
3743 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
\r
3744 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
\r
3745 .ndo_open = rtw_cfg80211_monitor_if_open,
\r
3746 .ndo_stop = rtw_cfg80211_monitor_if_close,
\r
3747 .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
\r
3748 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
\r
3749 .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
\r
3751 .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
\r
3755 static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
\r
3758 struct net_device* mon_ndev = NULL;
\r
3759 struct wireless_dev* mon_wdev = NULL;
\r
3760 struct rtw_netdev_priv_indicator *pnpi;
\r
3761 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
3764 DBG_871X(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
\r
3769 if (pwdev_priv->pmon_ndev) {
\r
3770 DBG_871X(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
\r
3771 FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
\r
3776 mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
\r
3778 DBG_871X(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
\r
3783 mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
\r
3784 strncpy(mon_ndev->name, name, IFNAMSIZ);
\r
3785 mon_ndev->name[IFNAMSIZ - 1] = 0;
\r
3786 mon_ndev->destructor = rtw_ndev_destructor;
\r
3788 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
\r
3789 mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
\r
3791 mon_ndev->open = rtw_cfg80211_monitor_if_open;
\r
3792 mon_ndev->stop = rtw_cfg80211_monitor_if_close;
\r
3793 mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry;
\r
3794 mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address;
\r
3797 pnpi = netdev_priv(mon_ndev);
\r
3798 pnpi->priv = padapter;
\r
3799 pnpi->sizeof_priv = sizeof(_adapter);
\r
3802 mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
\r
3804 DBG_871X(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
\r
3809 mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
\r
3810 mon_wdev->netdev = mon_ndev;
\r
3811 mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
\r
3812 mon_ndev->ieee80211_ptr = mon_wdev;
\r
3814 ret = register_netdevice(mon_ndev);
\r
3819 *ndev = pwdev_priv->pmon_ndev = mon_ndev;
\r
3820 _rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
\r
3823 if (ret && mon_wdev) {
\r
3824 rtw_mfree((u8*)mon_wdev, sizeof(struct wireless_dev));
\r
3828 if (ret && mon_ndev) {
\r
3829 free_netdev(mon_ndev);
\r
3830 *ndev = mon_ndev = NULL;
\r
3836 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3837 static struct wireless_dev *
\r
3838 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
3839 static struct net_device *
\r
3843 cfg80211_rtw_add_virtual_intf(
\r
3844 struct wiphy *wiphy,
\r
3845 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
\r
3850 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
\r
3853 struct net_device* ndev = NULL;
\r
3854 _adapter *padapter = wiphy_to_adapter(wiphy);
\r
3856 DBG_871X(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
\r
3857 FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
\r
3860 case NL80211_IFTYPE_ADHOC:
\r
3861 case NL80211_IFTYPE_AP_VLAN:
\r
3862 case NL80211_IFTYPE_WDS:
\r
3863 case NL80211_IFTYPE_MESH_POINT:
\r
3866 case NL80211_IFTYPE_MONITOR:
\r
3867 ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
\r
3870 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
3871 case NL80211_IFTYPE_P2P_CLIENT:
\r
3873 case NL80211_IFTYPE_STATION:
\r
3877 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
3878 case NL80211_IFTYPE_P2P_GO:
\r
3880 case NL80211_IFTYPE_AP:
\r
3885 DBG_871X("Unsupported interface type\n");
\r
3889 DBG_871X(FUNC_ADPT_FMT" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter), ndev, ret);
\r
3891 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3892 return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
\r
3893 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
3894 return ndev ? ndev : ERR_PTR(ret);
\r
3900 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
\r
3901 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3902 struct wireless_dev *wdev
\r
3904 struct net_device *ndev
\r
3908 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3909 struct net_device *ndev = wdev_to_ndev(wdev);
\r
3912 _adapter *adapter;
\r
3913 struct rtw_wdev_priv *pwdev_priv;
\r
3920 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3921 pwdev_priv = adapter_wdev_data(adapter);
\r
3923 unregister_netdevice(ndev);
\r
3925 if (ndev == pwdev_priv->pmon_ndev) {
\r
3926 pwdev_priv->pmon_ndev = NULL;
\r
3927 pwdev_priv->ifname_mon[0] = '\0';
\r
3928 DBG_871X(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev));
\r
3935 static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
\r
3939 uint len, wps_ielen=0;
\r
3942 u8 got_p2p_ie = _FALSE;
\r
3943 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
3944 //struct sta_priv *pstapriv = &padapter->stapriv;
\r
3947 DBG_8192C("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
\r
3950 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
\r
3957 pbuf = rtw_zmalloc(head_len+tail_len);
\r
3962 //_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
\r
3964 //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
\r
3965 // pstapriv->max_num_sta = NUM_STA;
\r
3968 _rtw_memcpy(pbuf, (void *)head+24, head_len-24);// 24=beacon header len.
\r
3969 _rtw_memcpy(pbuf+head_len-24, (void *)tail, tail_len);
\r
3971 len = head_len+tail_len-24;
\r
3973 //check wps ie if inclued
\r
3974 if(rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
\r
3975 DBG_8192C("add bcn, wps_ielen=%d\n", wps_ielen);
\r
3978 if( adapter->wdinfo.driver_interface == DRIVER_CFG80211 )
\r
3980 //check p2p if enable
\r
3981 if(rtw_get_p2p_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &p2p_ielen))
\r
3983 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
\r
3984 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
\r
3986 DBG_8192C("got p2p_ie, len=%d\n", p2p_ielen);
\r
3988 got_p2p_ie = _TRUE;
\r
3990 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
3992 DBG_8192C("Enable P2P function for the first time\n");
\r
3993 rtw_p2p_enable(adapter, P2P_ROLE_GO);
\r
3994 adapter_wdev_data(adapter)->p2p_enabled = _TRUE;
\r
3996 adapter->stapriv.expire_to = 3; // 3x2 = 6 sec in p2p mode
\r
4000 DBG_8192C("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);
\r
4002 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
\r
4003 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
\r
4004 pwdinfo->intent = 15;
\r
4008 #endif // CONFIG_P2P
\r
4010 /* pbss_network->IEs will not include p2p_ie, wfd ie */
\r
4011 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
\r
4012 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
\r
4014 if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS)
\r
4016 #ifdef CONFIG_P2P
\r
4017 //check p2p if enable
\r
4018 if(got_p2p_ie == _TRUE)
\r
4020 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
\r
4021 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
\r
4022 pwdinfo->operating_channel = pmlmeext->cur_channel;
\r
4024 #endif //CONFIG_P2P
\r
4033 rtw_mfree(pbuf, head_len+tail_len);
\r
4038 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE)
\r
4039 static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4040 struct beacon_parameters *info)
\r
4043 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4045 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4046 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
\r
4051 static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4052 struct beacon_parameters *info)
\r
4054 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4055 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
4057 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4059 pmlmeext->bstart_bss = _TRUE;
\r
4061 cfg80211_rtw_add_beacon(wiphy, ndev, info);
\r
4066 static int cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
\r
4068 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4073 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
\r
4074 struct cfg80211_ap_settings *settings)
\r
4077 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4079 DBG_871X(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
\r
4080 settings->hidden_ssid, settings->auth_type);
\r
4082 ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
\r
4083 settings->beacon.tail, settings->beacon.tail_len);
\r
4085 adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
\r
4087 if (settings->ssid && settings->ssid_len) {
\r
4088 WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
\r
4089 WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
\r
4092 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
\r
4093 settings->ssid, settings->ssid_len,
\r
4094 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
\r
4096 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
\r
4097 pbss_network->Ssid.SsidLength = settings->ssid_len;
\r
4098 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
\r
4099 pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
\r
4102 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
\r
4103 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
\r
4104 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
\r
4110 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4111 struct cfg80211_beacon_data *info)
\r
4114 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4116 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4118 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
\r
4123 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
\r
4125 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4129 #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
\r
4131 static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4132 u8 *mac, struct station_parameters *params)
\r
4134 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4139 static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4144 _list *phead, *plist;
\r
4145 u8 updated = _FALSE;
\r
4146 struct sta_info *psta = NULL;
\r
4147 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4148 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
4149 struct sta_priv *pstapriv = &padapter->stapriv;
\r
4151 DBG_871X("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4153 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
\r
4155 DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
\r
4162 DBG_8192C("flush all sta, and cam_entry\n");
\r
4164 flush_all_cam_entry(padapter); //clear CAM
\r
4166 ret = rtw_sta_flush(padapter);
\r
4172 DBG_8192C("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
\r
4174 if (mac[0] == 0xff && mac[1] == 0xff &&
\r
4175 mac[2] == 0xff && mac[3] == 0xff &&
\r
4176 mac[4] == 0xff && mac[5] == 0xff)
\r
4182 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4184 phead = &pstapriv->asoc_list;
\r
4185 plist = get_next(phead);
\r
4187 //check asoc_queue
\r
4188 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
4190 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
4192 plist = get_next(plist);
\r
4194 if(_rtw_memcmp(mac, psta->hwaddr, ETH_ALEN))
\r
4196 if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE)
\r
4198 DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
\r
4202 DBG_8192C("free psta=%p, aid=%d\n", psta, psta->aid);
\r
4204 rtw_list_delete(&psta->asoc_list);
\r
4205 pstapriv->asoc_list_cnt--;
\r
4207 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4208 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
\r
4209 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4220 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4222 associated_clients_update(padapter, updated);
\r
4224 DBG_871X("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4230 static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4231 u8 *mac, struct station_parameters *params)
\r
4233 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4238 static int cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4239 int idx, u8 *mac, struct station_info *sinfo)
\r
4241 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4243 //TODO: dump scanned queue
\r
4248 static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
\r
4249 struct bss_parameters *params)
\r
4253 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4255 DBG_8192C("use_cts_prot=%d\n", params->use_cts_prot);
\r
4256 DBG_8192C("use_short_preamble=%d\n", params->use_short_preamble);
\r
4257 DBG_8192C("use_short_slot_time=%d\n", params->use_short_slot_time);
\r
4258 DBG_8192C("ap_isolate=%d\n", params->ap_isolate);
\r
4260 DBG_8192C("basic_rates_len=%d\n", params->basic_rates_len);
\r
4261 for(i=0; i<params->basic_rates_len; i++)
\r
4263 DBG_8192C("basic_rates=%d\n", params->basic_rates[i]);
\r
4271 static int cfg80211_rtw_set_channel(struct wiphy *wiphy
\r
4272 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
\r
4273 , struct net_device *ndev
\r
4275 , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
\r
4277 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
\r
4278 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4284 static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
\r
4285 struct cfg80211_auth_request *req)
\r
4287 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4292 static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
\r
4293 struct cfg80211_assoc_request *req)
\r
4295 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4299 #endif //CONFIG_AP_MODE
\r
4301 void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
4306 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4307 u8 category, action;
\r
4309 channel = rtw_get_oper_ch(padapter);
\r
4311 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4313 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
\r
4317 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
\r
4318 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4321 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4322 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4324 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4326 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4327 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4329 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4333 void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
4338 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4339 u8 category, action;
\r
4341 channel = rtw_get_oper_ch(padapter);
\r
4343 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4345 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
\r
4348 case P2P_GO_NEGO_CONF:
\r
4349 case P2P_PROVISION_DISC_RESP:
\r
4350 case P2P_INVIT_RESP:
\r
4351 rtw_set_scan_deny(padapter, 2000);
\r
4352 rtw_clear_scan_deny(padapter);
\r
4357 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
\r
4358 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4361 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4362 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4364 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4366 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4367 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4369 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4373 void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg)
\r
4377 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
4378 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
4379 u8 category, action;
\r
4381 channel = rtw_get_oper_ch(adapter);
\r
4383 rtw_action_frame_parse(frame, frame_len, &category, &action);
\r
4385 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4387 DBG_871X("RTW_Rx:%s\n", msg);
\r
4389 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4391 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4392 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4394 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4396 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4397 rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
\r
4399 cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
\r
4405 void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
\r
4407 u16 wps_devicepassword_id = 0x0000;
\r
4408 uint wps_devicepassword_id_len = 0;
\r
4409 u8 wpsie[ 255 ] = { 0x00 }, p2p_ie[ 255 ] = { 0x00 };
\r
4410 uint p2p_ielen = 0;
\r
4411 uint wpsielen = 0;
\r
4412 u32 devinfo_contentlen = 0;
\r
4413 u8 devinfo_content[64] = { 0x00 };
\r
4414 u16 capability = 0;
\r
4415 uint capability_len = 0;
\r
4417 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
\r
4418 u8 action = P2P_PUB_ACTION_ACTION;
\r
4419 u8 dialogToken = 1;
\r
4420 u32 p2poui = cpu_to_be32(P2POUI);
\r
4421 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
\r
4425 #endif //CONFIG_WFD
\r
4427 struct xmit_frame *pmgntframe;
\r
4428 struct pkt_attrib *pattrib;
\r
4429 unsigned char *pframe;
\r
4430 struct rtw_ieee80211_hdr *pwlanhdr;
\r
4431 unsigned short *fctrl;
\r
4432 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
4433 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4434 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
4436 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
\r
4437 u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
\r
4438 size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4441 DBG_871X( "[%s] In\n", __FUNCTION__ );
\r
4443 //prepare for building provision_request frame
\r
4444 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
\r
4445 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
\r
4447 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
\r
4449 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
\r
4450 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
\r
4451 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
\r
4453 switch(wps_devicepassword_id)
\r
4455 case WPS_DPID_PIN:
\r
4456 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
\r
4458 case WPS_DPID_USER_SPEC:
\r
4459 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
\r
4461 case WPS_DPID_MACHINE_SPEC:
\r
4463 case WPS_DPID_REKEY:
\r
4465 case WPS_DPID_PBC:
\r
4466 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
\r
4468 case WPS_DPID_REGISTRAR_SPEC:
\r
4469 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
\r
4476 if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) )
\r
4479 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);
\r
4480 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&capability, &capability_len);
\r
4485 //start to build provision_request frame
\r
4486 _rtw_memset(wpsie, 0, sizeof(wpsie));
\r
4487 _rtw_memset(p2p_ie, 0, sizeof(p2p_ie));
\r
4490 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
4496 //update attribute
\r
4497 pattrib = &pmgntframe->attrib;
\r
4498 update_mgntframe_attrib(padapter, pattrib);
\r
4500 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
4502 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
4503 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
4505 fctrl = &(pwlanhdr->frame_ctl);
\r
4508 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
\r
4509 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
4510 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
\r
4512 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
4513 pmlmeext->mgnt_seq++;
\r
4514 SetFrameSubType(pframe, WIFI_ACTION);
\r
4516 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4517 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4519 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
4520 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
4521 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
\r
4522 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
\r
4523 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
\r
4526 //build_prov_disc_request_p2p_ie
\r
4529 p2p_ie[ p2pielen++ ] = 0x50;
\r
4530 p2p_ie[ p2pielen++ ] = 0x6F;
\r
4531 p2p_ie[ p2pielen++ ] = 0x9A;
\r
4532 p2p_ie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
\r
4534 // Commented by Albert 20110301
\r
4535 // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
\r
4536 // 1. P2P Capability
\r
4538 // 3. Group ID ( When joining an operating P2P Group )
\r
4540 // P2P Capability ATTR
\r
4542 p2p_ie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
\r
4545 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
\r
4546 RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
\r
4550 // Device Capability Bitmap, 1 byte
\r
4551 // Group Capability Bitmap, 1 byte
\r
4552 _rtw_memcpy(p2p_ie + p2pielen, &capability, 2);
\r
4556 // Device Info ATTR
\r
4558 p2p_ie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
\r
4561 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
\r
4562 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
\r
4563 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
\r
4564 RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
\r
4568 _rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
\r
4569 p2pielen += devinfo_contentlen;
\r
4572 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);
\r
4573 //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr);
\r
4574 //pframe += p2pielen;
\r
4575 pattrib->pktlen += p2p_ielen;
\r
4579 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
\r
4584 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
\r
4588 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
\r
4592 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
\r
4596 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
\r
4600 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
\r
4604 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
\r
4607 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
\r
4611 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
\r
4612 pframe += wfdielen;
\r
4613 pattrib->pktlen += wfdielen;
\r
4614 #endif //CONFIG_WFD
\r
4616 pattrib->last_txcmdsz = pattrib->pktlen;
\r
4618 //dump_mgntframe(padapter, pmgntframe);
\r
4619 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
\r
4620 DBG_8192C("%s, ack to\n", __func__);
\r
4622 //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
\r
4624 // DBG_8192C("waiting for p2p peer key-in PIN CODE\n");
\r
4625 // rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req.
\r
4630 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
\r
4631 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4632 struct wireless_dev *wdev,
\r
4634 struct net_device *ndev,
\r
4636 struct ieee80211_channel * channel,
\r
4637 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
4638 enum nl80211_channel_type channel_type,
\r
4640 unsigned int duration, u64 *cookie)
\r
4642 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4643 struct net_device *ndev = wdev_to_ndev(wdev);
\r
4646 u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
\r
4647 u8 ready_on_channel = _FALSE;
\r
4648 _adapter *padapter;
\r
4649 struct rtw_wdev_priv *pwdev_priv;
\r
4650 struct mlme_ext_priv *pmlmeext;
\r
4651 struct wifidirect_info *pwdinfo;
\r
4652 struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
\r
4654 if (ndev == NULL) {
\r
4658 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4659 pwdev_priv = adapter_wdev_data(padapter);
\r
4660 pmlmeext = &padapter->mlmeextpriv;
\r
4661 pwdinfo = &padapter->wdinfo;
\r
4662 pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
4664 DBG_871X(FUNC_ADPT_FMT" ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter), remain_ch, duration);
\r
4666 if(pcfg80211_wdinfo->is_ro_ch == _TRUE)
\r
4668 DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
4670 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
4672 #ifdef CONFIG_CONCURRENT_MODE
\r
4673 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
4674 #endif //CONFIG_CONCURRENT_MODE
\r
4676 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
\r
4679 pcfg80211_wdinfo->is_ro_ch = _TRUE;
\r
4680 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
4682 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
4687 _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
\r
4688 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
4689 pcfg80211_wdinfo->remain_on_ch_type= channel_type;
\r
4691 pcfg80211_wdinfo->remain_on_ch_cookie= *cookie;
\r
4693 rtw_scan_abort(padapter);
\r
4694 #ifdef CONFIG_CONCURRENT_MODE
\r
4695 if(rtw_buddy_adapter_up(padapter))
\r
4696 rtw_scan_abort(padapter->pbuddy_adapter);
\r
4697 #endif //CONFIG_CONCURRENT_MODE
\r
4699 if (check_fwstate(&padapter->mlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
\r
4701 DBG_871X("mlme state:0x%x\n", get_fwstate(&padapter->mlmepriv));
\r
4702 remain_ch = padapter->mlmeextpriv.cur_channel;
\r
4704 #ifdef CONFIG_CONCURRENT_MODE
\r
4705 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
\r
4707 DBG_871X("buddy_intf's mlme state:0x%x\n", get_fwstate(&(padapter->pbuddy_adapter->mlmepriv)));
\r
4708 remain_ch = padapter->pbuddy_adapter->mlmeextpriv.cur_channel;
\r
4710 #endif /* CONFIG_CONCURRENT_MODE */
\r
4712 //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
4713 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4715 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
\r
4716 adapter_wdev_data(padapter)->p2p_enabled = _TRUE;
\r
4717 padapter->wdinfo.listen_channel = remain_ch;
\r
4721 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
4722 #ifdef CONFIG_DEBUG_CFG80211
\r
4723 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
4728 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
\r
4731 if(duration < 400)
\r
4732 duration = duration*3;//extend from exper.
\r
4735 #ifdef CONFIG_CONCURRENT_MODE
\r
4736 if(check_buddy_fwstate(padapter, _FW_LINKED) &&
\r
4737 (duration<pwdinfo->ext_listen_interval))
\r
4739 duration = duration + pwdinfo->ext_listen_interval;
\r
4743 pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter);
\r
4745 if(rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) >= 0) {
\r
4746 #ifdef CONFIG_CONCURRENT_MODE
\r
4747 if ( check_buddy_fwstate(padapter, _FW_LINKED) )
\r
4749 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
\r
4750 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
4752 if((remain_ch != pbuddy_mlmeext->cur_channel) && !check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
4754 if(ATOMIC_READ(&pwdev_priv->switch_ch_to)==1 ||
\r
4755 (remain_ch != pmlmeext->cur_channel))
\r
4757 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
\r
4758 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
\r
4760 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
\r
4762 DBG_8192C("%s, set switch ch timer, duration=%d\n", __func__, duration-pwdinfo->ext_listen_interval);
\r
4763 _set_timer(&pwdinfo->ap_p2p_switch_timer, duration-pwdinfo->ext_listen_interval);
\r
4767 ready_on_channel = _TRUE;
\r
4768 //pmlmeext->cur_channel = remain_ch;
\r
4769 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4771 #endif //CONFIG_CONCURRENT_MODE
\r
4772 if(remain_ch != rtw_get_oper_ch(padapter) )
\r
4774 ready_on_channel = _TRUE;
\r
4775 //pmlmeext->cur_channel = remain_ch;
\r
4776 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4779 DBG_871X("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__, remain_ch);
\r
4783 //call this after other things have been done
\r
4784 #ifdef CONFIG_CONCURRENT_MODE
\r
4785 if(ATOMIC_READ(&pwdev_priv->ro_ch_to)==1 ||
\r
4786 (remain_ch != rtw_get_oper_ch(padapter)))
\r
4788 u8 co_channel = 0xff;
\r
4789 ATOMIC_SET(&pwdev_priv->ro_ch_to, 0);
\r
4792 if(ready_on_channel == _TRUE)
\r
4794 if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) )
\r
4796 pmlmeext->cur_channel = remain_ch;
\r
4798 #ifdef CONFIG_CONCURRENT_MODE
\r
4799 co_channel = rtw_get_oper_ch(padapter);
\r
4801 if(co_channel !=remain_ch)
\r
4804 //if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic)
\r
4805 set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4809 DBG_8192C("%s, set ro ch timer, duration=%d\n", __func__, duration);
\r
4810 _set_timer( &pcfg80211_wdinfo->remain_on_ch_timer, duration);
\r
4812 #ifdef CONFIG_CONCURRENT_MODE
\r
4816 rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type, duration, GFP_KERNEL);
\r
4820 pcfg80211_wdinfo->is_ro_ch = _FALSE;
\r
4821 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
4827 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
\r
4828 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4829 struct wireless_dev *wdev,
\r
4831 struct net_device *ndev,
\r
4835 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4836 struct net_device *ndev = wdev_to_ndev(wdev);
\r
4839 _adapter *padapter;
\r
4840 struct rtw_wdev_priv *pwdev_priv;
\r
4841 struct wifidirect_info *pwdinfo;
\r
4842 struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
\r
4844 if (ndev == NULL) {
\r
4849 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4850 pwdev_priv = adapter_wdev_data(padapter);
\r
4851 pwdinfo = &padapter->wdinfo;
\r
4852 pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
4854 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
4856 if (pcfg80211_wdinfo->is_ro_ch == _TRUE) {
\r
4857 DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
4858 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
4859 #ifdef CONFIG_CONCURRENT_MODE
\r
4860 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
4862 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
\r
4866 // Disable P2P Listen State
\r
4867 if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
4869 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4871 rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
\r
4872 _rtw_memset(pwdinfo, 0x00, sizeof(struct wifidirect_info));
\r
4878 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
4879 #ifdef CONFIG_DEBUG_CFG80211
\r
4880 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
4884 pcfg80211_wdinfo->is_ro_ch = _FALSE;
\r
4885 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
4891 #endif //CONFIG_P2P
\r
4893 static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, const u8 *buf, size_t len)
\r
4895 struct xmit_frame *pmgntframe;
\r
4896 struct pkt_attrib *pattrib;
\r
4897 unsigned char *pframe;
\r
4900 struct rtw_ieee80211_hdr *pwlanhdr;
\r
4901 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
4902 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
4903 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
4904 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4906 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
\r
4907 #endif //CONFIG_P2P
\r
4908 //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
4910 rtw_set_scan_deny(padapter, 1000);
\r
4912 rtw_scan_abort(padapter);
\r
4913 #ifdef CONFIG_CONCURRENT_MODE
\r
4914 if(rtw_buddy_adapter_up(padapter))
\r
4915 rtw_scan_abort(padapter->pbuddy_adapter);
\r
4916 #endif /* CONFIG_CONCURRENT_MODE */
\r
4918 if (padapter->cfg80211_wdinfo.is_ro_ch == _TRUE) {
\r
4919 //DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
4920 //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
4921 //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE;
\r
4922 #ifdef CONFIG_CONCURRENT_MODE
\r
4923 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
4925 DBG_8192C("%s, extend ro ch time\n", __func__);
\r
4926 _set_timer( &padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
\r
4928 #endif //CONFIG_CONCURRENT_MODE
\r
4930 #endif //CONFIG_P2P
\r
4931 #ifdef CONFIG_CONCURRENT_MODE
\r
4932 if (check_buddy_fwstate(padapter, _FW_LINKED )) {
\r
4933 u8 co_channel=0xff;
\r
4934 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
\r
4935 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
4937 co_channel = rtw_get_oper_ch(padapter);
\r
4939 if (tx_ch != pbuddy_mlmeext->cur_channel) {
\r
4941 u16 ext_listen_period;
\r
4943 if (ATOMIC_READ(&pwdev_priv->switch_ch_to)==1) {
\r
4944 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
\r
4945 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
\r
4947 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
\r
4949 //DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
\r
4950 //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
\r
4953 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
4955 ext_listen_period = 500;// 500ms
\r
4959 ext_listen_period = pwdinfo->ext_listen_period;
\r
4962 DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period);
\r
4963 _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period);
\r
4967 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
4968 pmlmeext->cur_channel = tx_ch;
\r
4970 if (tx_ch != co_channel)
\r
4971 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4973 #endif //CONFIG_CONCURRENT_MODE
\r
4974 //if (tx_ch != pmlmeext->cur_channel) {
\r
4975 if(tx_ch != rtw_get_oper_ch(padapter)) {
\r
4976 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
4977 pmlmeext->cur_channel = tx_ch;
\r
4978 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4981 //starting alloc mgmt frame to dump it
\r
4982 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
4989 //update attribute
\r
4990 pattrib = &pmgntframe->attrib;
\r
4991 update_mgntframe_attrib(padapter, pattrib);
\r
4992 pattrib->retry_ctrl = _FALSE;
\r
4994 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
4996 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
4998 _rtw_memcpy(pframe, (void*)buf, len);
\r
4999 pattrib->pktlen = len;
\r
5001 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
5002 //update seq number
\r
5003 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
\r
5004 pattrib->seqnum = pmlmeext->mgnt_seq;
\r
5005 pmlmeext->mgnt_seq++;
\r
5009 struct wifi_display_info *pwfd_info;
\r
5011 pwfd_info = padapter->wdinfo.wfd_info;
\r
5013 if ( _TRUE == pwfd_info->wfd_enable )
\r
5015 rtw_append_wfd_ie( padapter, pframe, &pattrib->pktlen );
\r
5018 #endif // CONFIG_WFD
\r
5020 pattrib->last_txcmdsz = pattrib->pktlen;
\r
5022 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
\r
5027 #ifdef CONFIG_DEBUG_CFG80211
\r
5028 DBG_8192C("%s, ack == _FAIL\n", __func__);
\r
5034 #ifdef CONFIG_XMIT_ACK
\r
5035 rtw_msleep_os(50);
\r
5037 #ifdef CONFIG_DEBUG_CFG80211
\r
5038 DBG_8192C("%s, ack=%d, ok!\n", __func__, ack);
\r
5045 #ifdef CONFIG_DEBUG_CFG80211
\r
5046 DBG_8192C("%s, ret=%d\n", __func__, ret);
\r
5053 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
\r
5054 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5055 struct wireless_dev *wdev,
\r
5057 struct net_device *ndev,
\r
5059 struct ieee80211_channel *chan,
\r
5060 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
5063 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5064 enum nl80211_channel_type channel_type,
\r
5065 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5066 bool channel_type_valid,
\r
5069 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
5070 unsigned int wait,
\r
5072 const u8 *buf, size_t len,
\r
5073 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5076 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
\r
5077 bool dont_wait_for_ack,
\r
5081 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5082 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5086 u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
\r
5089 u8 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
\r
5090 u8 category, action;
\r
5092 u32 start = rtw_get_current_time();
\r
5093 _adapter *padapter;
\r
5094 struct rtw_wdev_priv *pwdev_priv;
\r
5096 if (ndev == NULL) {
\r
5101 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5102 pwdev_priv = adapter_wdev_data(padapter);
\r
5104 /* cookie generation */
\r
5105 *cookie = (unsigned long) buf;
\r
5107 #ifdef CONFIG_DEBUG_CFG80211
\r
5108 DBG_871X(FUNC_ADPT_FMT" len=%zu, ch=%d"
\r
5109 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5111 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5112 ", channel_type_valid=%d"
\r
5115 "\n", FUNC_ADPT_ARG(padapter),
\r
5117 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5119 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5120 , channel_type_valid
\r
5124 #endif /* CONFIG_DEBUG_CFG80211 */
\r
5126 /* indicate ack before issue frame to avoid racing with rsp frame */
\r
5127 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5128 rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL);
\r
5129 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
\r
5130 cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
\r
5133 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
\r
5134 DBG_8192C(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
\r
5135 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
\r
5139 DBG_8192C("RTW_Tx:tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
\r
5141 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0) {
\r
5145 if (category == RTW_WLAN_CATEGORY_PUBLIC)
\r
5146 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
\r
5148 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
\r
5152 rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
\r
5153 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
5155 goto cancel_ps_deny;
\r
5160 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
\r
5161 } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
\r
5163 if (tx_ret != _SUCCESS || dump_cnt > 1) {
\r
5164 DBG_871X(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
\r
5165 tx_ret==_SUCCESS?"OK":"FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
\r
5169 case P2P_GO_NEGO_CONF:
\r
5170 rtw_clear_scan_deny(padapter);
\r
5172 case P2P_INVIT_RESP:
\r
5173 if (pwdev_priv->invit_info.flags & BIT(0)
\r
5174 && pwdev_priv->invit_info.status == 0)
\r
5176 DBG_871X(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
\r
5177 FUNC_ADPT_ARG(padapter));
\r
5178 rtw_set_scan_deny(padapter, 5000);
\r
5179 rtw_pwr_wakeup_ex(padapter, 5000);
\r
5180 rtw_clear_scan_deny(padapter);
\r
5186 rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
\r
5191 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
\r
5192 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
\r
5193 struct wireless_dev *wdev,
\r
5195 struct net_device *ndev,
\r
5197 u16 frame_type, bool reg)
\r
5199 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5200 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5202 _adapter *adapter;
\r
5207 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5209 #ifdef CONFIG_DEBUG_CFG80211
\r
5210 DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
\r
5214 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
\r
5220 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5221 static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy,
\r
5222 struct net_device *ndev,
\r
5230 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5232 struct tdls_txmgmt txmgmt;
\r
5234 //TDLS: discard wpa_supplicant's frame mgmt
\r
5235 DBG_871X("%s %d\n", __FUNCTION__, __LINE__);
\r
5238 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
5239 _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
\r
5240 txmgmt.action_code = action_code;
\r
5241 txmgmt.dialog_token= dialog_token;
\r
5242 txmgmt.status_code = status_code;
\r
5244 txmgmt.buf = (u8 *)rtw_malloc(txmgmt.len);
\r
5245 if (txmgmt.buf == NULL)
\r
5250 _rtw_memcpy(txmgmt.buf, (void*)buf, txmgmt.len);
\r
5251 txmgmt.external_support = _TRUE;
\r
5253 //TDLS: Debug purpose
\r
5255 DBG_871X("%s %d\n", __FUNCTION__, __LINE__);
\r
5256 DBG_871X("peer:"MAC_FMT" ", MAC_ARG(txmgmt.peer));
\r
5257 DBG_871X("action code:%d ", txmgmt.action_code);
\r
5258 DBG_871X("dialog:%d ", txmgmt.dialog_token);
\r
5259 DBG_871X("status code:%d\n", txmgmt.status_code);
\r
5260 if( txmgmt.len > 0 )
\r
5263 for(;i < len; i++)
\r
5264 DBG_871X("%02x ", *(txmgmt.buf+i));
\r
5265 DBG_871X("\n len:%d\n", txmgmt.len);
\r
5269 switch(txmgmt.action_code) {
\r
5270 case TDLS_SETUP_REQUEST:
\r
5271 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5273 case TDLS_SETUP_RESPONSE:
\r
5274 issue_tdls_setup_rsp(padapter, &txmgmt);
\r
5276 case TDLS_SETUP_CONFIRM:
\r
5277 issue_tdls_setup_cfm(padapter, &txmgmt);
\r
5279 case TDLS_TEARDOWN:
\r
5281 case TDLS_DISCOVERY_REQUEST:
\r
5282 issue_tdls_dis_req(padapter, &txmgmt);
\r
5289 rtw_mfree(txmgmt.buf, txmgmt.len);
\r
5295 static int cfg80211_rtw_tdls_oper(struct wiphy *wiphy,
\r
5296 struct net_device *ndev,
\r
5298 enum nl80211_tdls_operation oper)
\r
5300 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5301 struct tdls_txmgmt txmgmt;
\r
5302 struct sta_info *ptdls_sta = NULL;
\r
5304 DBG_871X(FUNC_NDEV_FMT", nl80211_tdls_operation:%d\n", FUNC_NDEV_ARG(ndev), oper);
\r
5307 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1);
\r
5308 #endif //CONFIG_LPS
\r
5310 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
5312 _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
\r
5314 CFG80211_TDLS_DISCOVERY_REQ,
\r
5315 CFG80211_TDLS_SETUP,
\r
5316 CFG80211_TDLS_TEARDOWN,
\r
5317 CFG80211_TDLS_ENABLE_LINK,
\r
5318 CFG80211_TDLS_DISABLE_LINK,
\r
5319 CFG80211_TDLS_ENABLE,
\r
5320 CFG80211_TDLS_DISABLE
\r
5323 case NL80211_TDLS_DISCOVERY_REQ:
\r
5324 issue_tdls_dis_req(padapter, &txmgmt);
\r
5326 case NL80211_TDLS_SETUP:
\r
5328 if ( _AES_ != padapter->securitypriv.dot11PrivacyAlgrthm )
\r
5330 if ( padapter->wdinfo.wfd_tdls_weaksec == _TRUE)
\r
5331 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5333 DBG_871X( "[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__ );
\r
5336 #endif // CONFIG_WFD
\r
5338 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5341 case NL80211_TDLS_TEARDOWN:
\r
5342 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), txmgmt.peer);
\r
5343 if(ptdls_sta != NULL)
\r
5345 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
\r
5346 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
\r
5349 DBG_871X( "TDLS peer not found\n");
\r
5351 case NL80211_TDLS_ENABLE_LINK:
\r
5353 case NL80211_TDLS_DISABLE_LINK:
\r
5358 #endif /* CONFIG_TDLS */
\r
5360 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
\r
5363 uint wps_ielen = 0;
\r
5365 u32 p2p_ielen = 0;
\r
5366 u8 wps_oui[8]={0x0,0x50,0xf2,0x04};
\r
5368 u32 wfd_ielen = 0;
\r
5370 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5371 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5372 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
5374 DBG_871X(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
\r
5378 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
5380 #ifdef CONFIG_DEBUG_CFG80211
\r
5381 DBG_8192C("bcn_wps_ielen=%d\n", wps_ielen);
\r
5384 if(pmlmepriv->wps_beacon_ie)
\r
5386 u32 free_len = pmlmepriv->wps_beacon_ie_len;
\r
5387 pmlmepriv->wps_beacon_ie_len = 0;
\r
5388 rtw_mfree(pmlmepriv->wps_beacon_ie, free_len);
\r
5389 pmlmepriv->wps_beacon_ie = NULL;
\r
5392 pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen);
\r
5393 if ( pmlmepriv->wps_beacon_ie == NULL) {
\r
5394 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5399 _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
\r
5400 pmlmepriv->wps_beacon_ie_len = wps_ielen;
\r
5402 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
\r
5406 //buf += wps_ielen;
\r
5407 //len -= wps_ielen;
\r
5410 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
5412 #ifdef CONFIG_DEBUG_CFG80211
\r
5413 DBG_8192C("bcn_p2p_ielen=%d\n", p2p_ielen);
\r
5416 if(pmlmepriv->p2p_beacon_ie)
\r
5418 u32 free_len = pmlmepriv->p2p_beacon_ie_len;
\r
5419 pmlmepriv->p2p_beacon_ie_len = 0;
\r
5420 rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len);
\r
5421 pmlmepriv->p2p_beacon_ie = NULL;
\r
5424 pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen);
\r
5425 if ( pmlmepriv->p2p_beacon_ie == NULL) {
\r
5426 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5431 _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
\r
5432 pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
\r
5435 #endif //CONFIG_P2P
\r
5437 //buf += p2p_ielen;
\r
5438 //len -= p2p_ielen;
\r
5441 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
5443 #ifdef CONFIG_DEBUG_CFG80211
\r
5444 DBG_8192C("bcn_wfd_ielen=%d\n", wfd_ielen);
\r
5447 if(pmlmepriv->wfd_beacon_ie)
\r
5449 u32 free_len = pmlmepriv->wfd_beacon_ie_len;
\r
5450 pmlmepriv->wfd_beacon_ie_len = 0;
\r
5451 rtw_mfree(pmlmepriv->wfd_beacon_ie, free_len);
\r
5452 pmlmepriv->wfd_beacon_ie = NULL;
\r
5455 pmlmepriv->wfd_beacon_ie = rtw_malloc(wfd_ielen);
\r
5456 if ( pmlmepriv->wfd_beacon_ie == NULL) {
\r
5457 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5461 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
\r
5463 #endif //CONFIG_WFD
\r
5465 pmlmeext->bstart_bss = _TRUE;
\r
5473 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
\r
5476 uint wps_ielen = 0;
\r
5478 u32 p2p_ielen = 0;
\r
5480 u32 wfd_ielen = 0;
\r
5482 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
\r
5483 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5485 #ifdef CONFIG_DEBUG_CFG80211
\r
5486 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5491 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
5493 uint attr_contentlen = 0;
\r
5494 u16 uconfig_method, *puconfig_method = NULL;
\r
5496 #ifdef CONFIG_DEBUG_CFG80211
\r
5497 DBG_8192C("probe_resp_wps_ielen=%d\n", wps_ielen);
\r
5500 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
\r
5503 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
\r
5507 DBG_871X("%s, got sr\n", __func__);
\r
5511 DBG_8192C("GO mode process WPS under site-survey, sr no set\n");
\r
5516 if(pmlmepriv->wps_probe_resp_ie)
\r
5518 u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
\r
5519 pmlmepriv->wps_probe_resp_ie_len = 0;
\r
5520 rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len);
\r
5521 pmlmepriv->wps_probe_resp_ie = NULL;
\r
5524 pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen);
\r
5525 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
\r
5526 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5531 //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode
\r
5532 if ( (puconfig_method = (u16*)rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen)) != NULL )
\r
5534 //struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
5535 struct wireless_dev *wdev = padapter->rtw_wdev;
\r
5537 #ifdef CONFIG_DEBUG_CFG80211
\r
5538 //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method));
\r
5541 //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
\r
5542 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5543 if(wdev->iftype != NL80211_IFTYPE_P2P_GO) //for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags
\r
5545 uconfig_method = WPS_CM_PUSH_BUTTON;
\r
5546 uconfig_method = cpu_to_be16( uconfig_method );
\r
5548 *puconfig_method |= uconfig_method;
\r
5553 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
\r
5554 pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
\r
5558 //buf += wps_ielen;
\r
5559 //len -= wps_ielen;
\r
5562 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
5564 u8 is_GO = _FALSE;
\r
5565 u32 attr_contentlen = 0;
\r
5568 #ifdef CONFIG_DEBUG_CFG80211
\r
5569 DBG_8192C("probe_resp_p2p_ielen=%d\n", p2p_ielen);
\r
5572 //Check P2P Capability ATTR
\r
5573 if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) )
\r
5576 //DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
\r
5577 cap_attr = le16_to_cpu(cap_attr);
\r
5578 grp_cap = (u8)((cap_attr >> 8)&0xff);
\r
5580 is_GO = (grp_cap&BIT(0)) ? _TRUE:_FALSE;
\r
5583 DBG_8192C("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
\r
5587 if(is_GO == _FALSE)
\r
5589 if(pmlmepriv->p2p_probe_resp_ie)
\r
5591 u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
\r
5592 pmlmepriv->p2p_probe_resp_ie_len = 0;
\r
5593 rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len);
\r
5594 pmlmepriv->p2p_probe_resp_ie = NULL;
\r
5597 pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen);
\r
5598 if ( pmlmepriv->p2p_probe_resp_ie == NULL) {
\r
5599 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5603 _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
\r
5604 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
\r
5608 if(pmlmepriv->p2p_go_probe_resp_ie)
\r
5610 u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
\r
5611 pmlmepriv->p2p_go_probe_resp_ie_len = 0;
\r
5612 rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len);
\r
5613 pmlmepriv->p2p_go_probe_resp_ie = NULL;
\r
5616 pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen);
\r
5617 if ( pmlmepriv->p2p_go_probe_resp_ie == NULL) {
\r
5618 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5622 _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
\r
5623 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
\r
5627 #endif //CONFIG_P2P
\r
5629 //buf += p2p_ielen;
\r
5630 //len -= p2p_ielen;
\r
5633 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
5635 #ifdef CONFIG_DEBUG_CFG80211
\r
5636 DBG_8192C("probe_resp_wfd_ielen=%d\n", wfd_ielen);
\r
5639 if(pmlmepriv->wfd_probe_resp_ie)
\r
5641 u32 free_len = pmlmepriv->wfd_probe_resp_ie_len;
\r
5642 pmlmepriv->wfd_probe_resp_ie_len = 0;
\r
5643 rtw_mfree(pmlmepriv->wfd_probe_resp_ie, free_len);
\r
5644 pmlmepriv->wfd_probe_resp_ie = NULL;
\r
5647 pmlmepriv->wfd_probe_resp_ie = rtw_malloc(wfd_ielen);
\r
5648 if ( pmlmepriv->wfd_probe_resp_ie == NULL) {
\r
5649 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5653 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
\r
5655 #endif //CONFIG_WFD
\r
5663 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
\r
5666 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
\r
5667 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5669 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5673 if(pmlmepriv->wps_assoc_resp_ie)
\r
5675 u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
\r
5676 pmlmepriv->wps_assoc_resp_ie_len = 0;
\r
5677 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len);
\r
5678 pmlmepriv->wps_assoc_resp_ie = NULL;
\r
5681 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(len);
\r
5682 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
\r
5683 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5687 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len);
\r
5688 pmlmepriv->wps_assoc_resp_ie_len = len;
\r
5695 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
\r
5699 uint wps_ielen = 0;
\r
5700 u32 p2p_ielen = 0;
\r
5702 #ifdef CONFIG_DEBUG_CFG80211
\r
5703 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5706 if( (rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen>0))
\r
5708 || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen>0))
\r
5716 case 0x1: //BEACON
\r
5717 ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
\r
5719 case 0x2: //PROBE_RESP
\r
5720 ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
\r
5722 case 0x4: //ASSOC_RESP
\r
5723 ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
\r
5733 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
\r
5736 #define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
\r
5737 #define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
\r
5739 ht_cap->ht_supported = _TRUE;
\r
5741 ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
\r
5742 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
\r
5743 IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
\r
5746 *Maximum length of AMPDU that the STA can receive.
\r
5747 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
\r
5749 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
\r
5751 /*Minimum MPDU start spacing , */
\r
5752 ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
\r
5754 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
\r
5757 *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
\r
5760 *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
\r
5761 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
\r
5762 *if rx_ant >=3 rx_mask[2]=0xff;
\r
5763 *if BW_40 rx_mask[4]=0x01;
\r
5764 *highest supported RX rate
\r
5766 if(rf_type == RF_1T1R)
\r
5768 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
5769 ht_cap->mcs.rx_mask[1] = 0x00;
\r
5770 ht_cap->mcs.rx_mask[4] = 0x01;
\r
5772 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
\r
5774 else if((rf_type == RF_1T2R) || (rf_type==RF_2T2R))
\r
5776 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
5777 ht_cap->mcs.rx_mask[1] = 0xFF;
\r
5778 ht_cap->mcs.rx_mask[4] = 0x01;
\r
5780 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
\r
5784 DBG_8192C("%s, error rf_type=%d\n", __func__, rf_type);
\r
5789 void rtw_cfg80211_init_wiphy(_adapter *padapter)
\r
5792 struct ieee80211_supported_band *bands;
\r
5793 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
5794 struct wiphy *wiphy = pwdev->wiphy;
\r
5796 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
\r
5798 DBG_8192C("%s:rf_type=%d\n", __func__, rf_type);
\r
5800 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
\r
5802 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
\r
5804 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type);
\r
5807 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
\r
5809 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
\r
5811 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type);
\r
5814 /* init regulary domain */
\r
5815 rtw_regd_init(padapter, rtw_reg_notifier);
\r
5817 /* copy mac_addr to wiphy */
\r
5818 _rtw_memcpy(wiphy->perm_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
\r
5823 struct ieee80211_iface_limit rtw_limits[] = {
\r
5824 { .max = 1, .types = BIT(NL80211_IFTYPE_STATION)
\r
5825 | BIT(NL80211_IFTYPE_ADHOC)
\r
5826 #ifdef CONFIG_AP_MODE
\r
5827 | BIT(NL80211_IFTYPE_AP)
\r
5829 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
5830 | BIT(NL80211_IFTYPE_P2P_CLIENT)
\r
5831 | BIT(NL80211_IFTYPE_P2P_GO)
\r
5834 {.max = 1, .types = BIT(NL80211_IFTYPE_MONITOR)},
\r
5837 struct ieee80211_iface_combination rtw_combinations = {
\r
5838 .limits = rtw_limits,
\r
5839 .n_limits = ARRAY_SIZE(rtw_limits),
\r
5840 .max_interfaces = 2,
\r
5841 .num_different_channels = 1,
\r
5845 static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy)
\r
5848 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
\r
5850 wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
\r
5851 wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
\r
5852 wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
\r
5854 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
5855 wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
\r
5858 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
\r
5859 | BIT(NL80211_IFTYPE_ADHOC)
\r
5860 #ifdef CONFIG_AP_MODE
\r
5861 | BIT(NL80211_IFTYPE_AP)
\r
5862 | BIT(NL80211_IFTYPE_MONITOR)
\r
5864 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
5865 | BIT(NL80211_IFTYPE_P2P_CLIENT)
\r
5866 | BIT(NL80211_IFTYPE_P2P_GO)
\r
5870 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5871 #ifdef CONFIG_AP_MODE
\r
5872 wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
\r
5873 #endif //CONFIG_AP_MODE
\r
5876 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
5877 wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
\r
5881 wiphy->iface_combinations = &rtw_combinations;
\r
5882 wiphy->n_iface_combinations = 1;
\r
5885 wiphy->cipher_suites = rtw_cipher_suites;
\r
5886 wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
\r
5888 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
\r
5889 wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
\r
5890 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
\r
5891 wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
\r
5893 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
\r
5894 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
\r
5897 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
\r
5898 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
\r
5899 wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
\r
5902 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
5903 wiphy->wowlan = wowlan_stub;
\r
5906 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5907 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
\r
5908 //wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
\r
5909 #endif /* CONFIG_TDLS */
\r
5911 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
\r
5912 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
\r
5914 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
\r
5916 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5917 //wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
\r
5921 static struct cfg80211_ops rtw_cfg80211_ops = {
\r
5922 .change_virtual_intf = cfg80211_rtw_change_iface,
\r
5923 .add_key = cfg80211_rtw_add_key,
\r
5924 .get_key = cfg80211_rtw_get_key,
\r
5925 .del_key = cfg80211_rtw_del_key,
\r
5926 .set_default_key = cfg80211_rtw_set_default_key,
\r
5927 .get_station = cfg80211_rtw_get_station,
\r
5928 .scan = cfg80211_rtw_scan,
\r
5929 .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
\r
5930 .connect = cfg80211_rtw_connect,
\r
5931 .disconnect = cfg80211_rtw_disconnect,
\r
5932 .join_ibss = cfg80211_rtw_join_ibss,
\r
5933 .leave_ibss = cfg80211_rtw_leave_ibss,
\r
5934 .set_tx_power = cfg80211_rtw_set_txpower,
\r
5935 .get_tx_power = cfg80211_rtw_get_txpower,
\r
5936 .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
\r
5937 .set_pmksa = cfg80211_rtw_set_pmksa,
\r
5938 .del_pmksa = cfg80211_rtw_del_pmksa,
\r
5939 .flush_pmksa = cfg80211_rtw_flush_pmksa,
\r
5941 #ifdef CONFIG_AP_MODE
\r
5942 .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
\r
5943 .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
\r
5945 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
\r
5946 .add_beacon = cfg80211_rtw_add_beacon,
\r
5947 .set_beacon = cfg80211_rtw_set_beacon,
\r
5948 .del_beacon = cfg80211_rtw_del_beacon,
\r
5950 .start_ap = cfg80211_rtw_start_ap,
\r
5951 .change_beacon = cfg80211_rtw_change_beacon,
\r
5952 .stop_ap = cfg80211_rtw_stop_ap,
\r
5955 .add_station = cfg80211_rtw_add_station,
\r
5956 .del_station = cfg80211_rtw_del_station,
\r
5957 .change_station = cfg80211_rtw_change_station,
\r
5958 .dump_station = cfg80211_rtw_dump_station,
\r
5959 .change_bss = cfg80211_rtw_change_bss,
\r
5960 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
\r
5961 .set_channel = cfg80211_rtw_set_channel,
\r
5963 //.auth = cfg80211_rtw_auth,
\r
5964 //.assoc = cfg80211_rtw_assoc,
\r
5965 #endif //CONFIG_AP_MODE
\r
5968 .remain_on_channel = cfg80211_rtw_remain_on_channel,
\r
5969 .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
\r
5972 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5973 .mgmt_tx = cfg80211_rtw_mgmt_tx,
\r
5974 .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
\r
5975 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
\r
5976 .action = cfg80211_rtw_mgmt_tx,
\r
5979 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5980 .tdls_mgmt = cfg80211_rtw_tdls_mgmt,
\r
5981 .tdls_oper = cfg80211_rtw_tdls_oper,
\r
5982 #endif /* CONFIG_TDLS */
\r
5985 int rtw_wdev_alloc(_adapter *padapter, struct device *dev)
\r
5988 struct wiphy *wiphy;
\r
5989 struct wireless_dev *wdev;
\r
5990 struct rtw_wdev_priv *pwdev_priv;
\r
5991 struct net_device *pnetdev = padapter->pnetdev;
\r
5993 DBG_8192C("%s(padapter=%p)\n", __func__, padapter);
\r
5996 wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(_adapter*));
\r
5998 DBG_8192C("Couldn't allocate wiphy device\n");
\r
6002 set_wiphy_dev(wiphy, dev);
\r
6003 *((_adapter**)wiphy_priv(wiphy)) = padapter;
\r
6004 rtw_cfg80211_preinit_wiphy(padapter, wiphy);
\r
6006 ret = wiphy_register(wiphy);
\r
6008 DBG_8192C("Couldn't register wiphy device\n");
\r
6013 wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
\r
6015 DBG_8192C("Couldn't allocate wireless device\n");
\r
6017 goto unregister_wiphy;
\r
6019 wdev->wiphy = wiphy;
\r
6020 wdev->netdev = pnetdev;
\r
6022 wdev->iftype = NL80211_IFTYPE_STATION; // will be init in rtw_hal_init()
\r
6023 // Must sync with _rtw_init_mlme_priv()
\r
6024 // pmlmepriv->fw_state = WIFI_STATION_STATE
\r
6025 //wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
\r
6026 padapter->rtw_wdev = wdev;
\r
6027 pnetdev->ieee80211_ptr = wdev;
\r
6030 pwdev_priv = adapter_wdev_data(padapter);
\r
6031 pwdev_priv->rtw_wdev = wdev;
\r
6032 pwdev_priv->pmon_ndev = NULL;
\r
6033 pwdev_priv->ifname_mon[0] = '\0';
\r
6034 pwdev_priv->padapter = padapter;
\r
6035 pwdev_priv->scan_request = NULL;
\r
6036 _rtw_spinlock_init(&pwdev_priv->scan_req_lock);
\r
6038 pwdev_priv->p2p_enabled = _FALSE;
\r
6039 pwdev_priv->provdisc_req_issued = _FALSE;
\r
6040 rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
\r
6041 rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
\r
6043 pwdev_priv->bandroid_scan = _FALSE;
\r
6045 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
\r
6046 pwdev_priv->power_mgmt = _TRUE;
\r
6048 pwdev_priv->power_mgmt = _FALSE;
\r
6050 #ifdef CONFIG_CONCURRENT_MODE
\r
6051 ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
\r
6052 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
6057 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
\r
6059 wiphy_unregister(wiphy);
\r
6061 wiphy_free(wiphy);
\r
6067 void rtw_wdev_free(struct wireless_dev *wdev)
\r
6069 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
\r
6074 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
\r
6075 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
\r
6077 wiphy_free(wdev->wiphy);
\r
6079 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
\r
6082 void rtw_wdev_unregister(struct wireless_dev *wdev)
\r
6084 struct net_device *ndev;
\r
6085 _adapter *adapter;
\r
6086 struct rtw_wdev_priv *pwdev_priv;
\r
6088 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
\r
6093 if(!(ndev = wdev_to_ndev(wdev)))
\r
6096 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
6097 pwdev_priv = adapter_wdev_data(adapter);
\r
6099 rtw_cfg80211_indicate_scan_done(adapter, _TRUE);
\r
6101 if (pwdev_priv->pmon_ndev) {
\r
6102 DBG_8192C("%s, unregister monitor interface\n", __func__);
\r
6103 unregister_netdev(pwdev_priv->pmon_ndev);
\r
6106 wiphy_unregister(wdev->wiphy);
\r
6109 #endif //CONFIG_IOCTL_CFG80211
\r