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
29 #define RTW_MAX_MGMT_TX_MS_GAS (500)
\r
31 #define RTW_SCAN_IE_LEN_MAX 2304
\r
32 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 5000 //ms
\r
33 #define RTW_MAX_NUM_PMKIDS 4
\r
35 #define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
\r
37 #ifdef CONFIG_WAPI_SUPPORT
\r
39 #ifndef WLAN_CIPHER_SUITE_SMS4
\r
40 #define WLAN_CIPHER_SUITE_SMS4 0x00147201
\r
43 #ifndef WLAN_AKM_SUITE_WAPI_PSK
\r
44 #define WLAN_AKM_SUITE_WAPI_PSK 0x000FAC04
\r
47 #ifndef WLAN_AKM_SUITE_WAPI_CERT
\r
48 #define WLAN_AKM_SUITE_WAPI_CERT 0x000FAC12
\r
51 #ifndef NL80211_WAPI_VERSION_1
\r
52 #define NL80211_WAPI_VERSION_1 (1 << 2)
\r
57 #ifdef CONFIG_PLATFORM_ARM_SUN8I
\r
58 #define BUSY_TRAFFIC_SCAN_DENY_PERIOD 8000
\r
60 #define BUSY_TRAFFIC_SCAN_DENY_PERIOD 12000
\r
63 static const u32 rtw_cipher_suites[] = {
\r
64 WLAN_CIPHER_SUITE_WEP40,
\r
65 WLAN_CIPHER_SUITE_WEP104,
\r
66 WLAN_CIPHER_SUITE_TKIP,
\r
67 WLAN_CIPHER_SUITE_CCMP,
\r
68 #ifdef CONFIG_WAPI_SUPPORT
\r
69 WLAN_CIPHER_SUITE_SMS4,
\r
70 #endif // CONFIG_WAPI_SUPPORT
\r
71 #ifdef CONFIG_IEEE80211W
\r
72 WLAN_CIPHER_SUITE_AES_CMAC,
\r
73 #endif //CONFIG_IEEE80211W
\r
76 #define RATETAB_ENT(_rate, _rateid, _flags) \
\r
78 .bitrate = (_rate), \
\r
79 .hw_value = (_rateid), \
\r
80 .flags = (_flags), \
\r
83 #define CHAN2G(_channel, _freq, _flags) { \
\r
84 .band = IEEE80211_BAND_2GHZ, \
\r
85 .center_freq = (_freq), \
\r
86 .hw_value = (_channel), \
\r
87 .flags = (_flags), \
\r
88 .max_antenna_gain = 0, \
\r
92 #define CHAN5G(_channel, _flags) { \
\r
93 .band = IEEE80211_BAND_5GHZ, \
\r
94 .center_freq = 5000 + (5 * (_channel)), \
\r
95 .hw_value = (_channel), \
\r
96 .flags = (_flags), \
\r
97 .max_antenna_gain = 0, \
\r
101 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
102 /* if wowlan is not supported, kernel generate a disconnect at each suspend
\r
103 * cf: /net/wireless/sysfs.c, so register a stub wowlan.
\r
104 * Moreover wowlan has to be enabled via a the nl80211_set_wowlan callback.
\r
105 * (from user space, e.g. iw phy0 wowlan enable)
\r
107 static const struct wiphy_wowlan_support wowlan_stub = {
\r
108 .flags = WIPHY_WOWLAN_ANY,
\r
110 .pattern_max_len = 0,
\r
111 .pattern_min_len = 0,
\r
112 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
\r
113 .max_pkt_offset = 0,
\r
118 static struct ieee80211_rate rtw_rates[] = {
\r
119 RATETAB_ENT(10, 0x1, 0),
\r
120 RATETAB_ENT(20, 0x2, 0),
\r
121 RATETAB_ENT(55, 0x4, 0),
\r
122 RATETAB_ENT(110, 0x8, 0),
\r
123 RATETAB_ENT(60, 0x10, 0),
\r
124 RATETAB_ENT(90, 0x20, 0),
\r
125 RATETAB_ENT(120, 0x40, 0),
\r
126 RATETAB_ENT(180, 0x80, 0),
\r
127 RATETAB_ENT(240, 0x100, 0),
\r
128 RATETAB_ENT(360, 0x200, 0),
\r
129 RATETAB_ENT(480, 0x400, 0),
\r
130 RATETAB_ENT(540, 0x800, 0),
\r
133 #define rtw_a_rates (rtw_rates + 4)
\r
134 #define RTW_A_RATES_NUM 8
\r
135 #define rtw_g_rates (rtw_rates + 0)
\r
136 #define RTW_G_RATES_NUM 12
\r
138 #define RTW_2G_CHANNELS_NUM 14
\r
139 #define RTW_5G_CHANNELS_NUM 37
\r
141 static struct ieee80211_channel rtw_2ghz_channels[] = {
\r
142 CHAN2G(1, 2412, 0),
\r
143 CHAN2G(2, 2417, 0),
\r
144 CHAN2G(3, 2422, 0),
\r
145 CHAN2G(4, 2427, 0),
\r
146 CHAN2G(5, 2432, 0),
\r
147 CHAN2G(6, 2437, 0),
\r
148 CHAN2G(7, 2442, 0),
\r
149 CHAN2G(8, 2447, 0),
\r
150 CHAN2G(9, 2452, 0),
\r
151 CHAN2G(10, 2457, 0),
\r
152 CHAN2G(11, 2462, 0),
\r
153 CHAN2G(12, 2467, 0),
\r
154 CHAN2G(13, 2472, 0),
\r
155 CHAN2G(14, 2484, 0),
\r
158 static struct ieee80211_channel rtw_5ghz_a_channels[] = {
\r
159 CHAN5G(34, 0), CHAN5G(36, 0),
\r
160 CHAN5G(38, 0), CHAN5G(40, 0),
\r
161 CHAN5G(42, 0), CHAN5G(44, 0),
\r
162 CHAN5G(46, 0), CHAN5G(48, 0),
\r
163 CHAN5G(52, 0), CHAN5G(56, 0),
\r
164 CHAN5G(60, 0), CHAN5G(64, 0),
\r
165 CHAN5G(100, 0), CHAN5G(104, 0),
\r
166 CHAN5G(108, 0), CHAN5G(112, 0),
\r
167 CHAN5G(116, 0), CHAN5G(120, 0),
\r
168 CHAN5G(124, 0), CHAN5G(128, 0),
\r
169 CHAN5G(132, 0), CHAN5G(136, 0),
\r
170 CHAN5G(140, 0), CHAN5G(149, 0),
\r
171 CHAN5G(153, 0), CHAN5G(157, 0),
\r
172 CHAN5G(161, 0), CHAN5G(165, 0),
\r
173 CHAN5G(184, 0), CHAN5G(188, 0),
\r
174 CHAN5G(192, 0), CHAN5G(196, 0),
\r
175 CHAN5G(200, 0), CHAN5G(204, 0),
\r
176 CHAN5G(208, 0), CHAN5G(212, 0),
\r
181 void rtw_2g_channels_init(struct ieee80211_channel *channels)
\r
183 _rtw_memcpy((void*)channels, (void*)rtw_2ghz_channels,
\r
184 sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
\r
188 void rtw_5g_channels_init(struct ieee80211_channel *channels)
\r
190 _rtw_memcpy((void*)channels, (void*)rtw_5ghz_a_channels,
\r
191 sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
\r
195 void rtw_2g_rates_init(struct ieee80211_rate *rates)
\r
197 _rtw_memcpy(rates, rtw_g_rates,
\r
198 sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
\r
202 void rtw_5g_rates_init(struct ieee80211_rate *rates)
\r
204 _rtw_memcpy(rates, rtw_a_rates,
\r
205 sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM
\r
209 struct ieee80211_supported_band *rtw_spt_band_alloc(
\r
210 enum ieee80211_band band
\r
213 struct ieee80211_supported_band *spt_band = NULL;
\r
214 int n_channels, n_bitrates;
\r
216 if(band == IEEE80211_BAND_2GHZ)
\r
218 n_channels = RTW_2G_CHANNELS_NUM;
\r
219 n_bitrates = RTW_G_RATES_NUM;
\r
221 else if(band == IEEE80211_BAND_5GHZ)
\r
223 n_channels = RTW_5G_CHANNELS_NUM;
\r
224 n_bitrates = RTW_A_RATES_NUM;
\r
231 spt_band = (struct ieee80211_supported_band *)rtw_zmalloc(
\r
232 sizeof(struct ieee80211_supported_band)
\r
233 + sizeof(struct ieee80211_channel)*n_channels
\r
234 + sizeof(struct ieee80211_rate)*n_bitrates
\r
239 spt_band->channels = (struct ieee80211_channel*)(((u8*)spt_band)+sizeof(struct ieee80211_supported_band));
\r
240 spt_band->bitrates= (struct ieee80211_rate*)(((u8*)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
\r
241 spt_band->band = band;
\r
242 spt_band->n_channels = n_channels;
\r
243 spt_band->n_bitrates = n_bitrates;
\r
245 if(band == IEEE80211_BAND_2GHZ)
\r
247 rtw_2g_channels_init(spt_band->channels);
\r
248 rtw_2g_rates_init(spt_band->bitrates);
\r
250 else if(band == IEEE80211_BAND_5GHZ)
\r
252 rtw_5g_channels_init(spt_band->channels);
\r
253 rtw_5g_rates_init(spt_band->bitrates);
\r
263 void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
\r
270 if(spt_band->band == IEEE80211_BAND_2GHZ)
\r
272 size = sizeof(struct ieee80211_supported_band)
\r
273 + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
\r
274 + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM;
\r
276 else if(spt_band->band == IEEE80211_BAND_5GHZ)
\r
278 size = sizeof(struct ieee80211_supported_band)
\r
279 + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
\r
280 + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM;
\r
286 rtw_mfree((u8*)spt_band, size);
\r
289 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
290 static const struct ieee80211_txrx_stypes
\r
291 rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
\r
292 [NL80211_IFTYPE_ADHOC] = {
\r
294 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
\r
296 [NL80211_IFTYPE_STATION] = {
\r
298 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
\r
299 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
\r
301 [NL80211_IFTYPE_AP] = {
\r
303 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
304 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
305 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
306 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
307 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
308 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
309 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
311 [NL80211_IFTYPE_AP_VLAN] = {
\r
314 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
315 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
316 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
317 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
318 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
319 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
320 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
322 [NL80211_IFTYPE_P2P_CLIENT] = {
\r
324 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
\r
325 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
\r
327 [NL80211_IFTYPE_P2P_GO] = {
\r
329 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
330 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
331 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
332 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
333 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
334 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
335 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
340 static int rtw_ieee80211_channel_to_frequency(int chan, int band)
\r
342 /* see 802.11 17.3.8.3.2 and Annex J
\r
343 * there are overlapping channel numbers in 5GHz and 2GHz bands */
\r
345 if (band == IEEE80211_BAND_5GHZ) {
\r
346 if (chan >= 182 && chan <= 196)
\r
347 return 4000 + chan * 5;
\r
349 return 5000 + chan * 5;
\r
350 } else { /* IEEE80211_BAND_2GHZ */
\r
353 else if (chan < 14)
\r
354 return 2407 + chan * 5;
\r
356 return 0; /* not supported */
\r
360 static u64 rtw_get_systime_us(void)
\r
362 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
\r
363 struct timespec ts;
\r
364 get_monotonic_boottime(&ts);
\r
365 return ((u64)ts.tv_sec*1000000) + ts.tv_nsec / 1000;
\r
368 do_gettimeofday(&tv);
\r
369 return ((u64)tv.tv_sec*1000000) + tv.tv_usec;
\r
373 #define MAX_BSSINFO_LEN 1000
\r
374 struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork)
\r
376 struct ieee80211_channel *notify_channel;
\r
377 struct cfg80211_bss *bss = NULL;
\r
378 //struct ieee80211_supported_band *band;
\r
381 u64 notify_timestamp;
\r
382 u16 notify_capability;
\r
383 u16 notify_interval;
\r
385 size_t notify_ielen;
\r
387 //u8 buf[MAX_BSSINFO_LEN];
\r
390 size_t buf_size = MAX_BSSINFO_LEN;
\r
391 size_t len,bssinf_len=0;
\r
392 struct rtw_ieee80211_hdr *pwlanhdr;
\r
393 unsigned short *fctrl;
\r
394 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
\r
396 struct wireless_dev *wdev = padapter->rtw_wdev;
\r
397 struct wiphy *wiphy = wdev->wiphy;
\r
398 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
400 pbuf = rtw_zmalloc(buf_size);
\r
402 DBG_871X("%s pbuf allocate failed !! \n",__FUNCTION__);
\r
406 //DBG_8192C("%s\n", __func__);
\r
408 bssinf_len = pnetwork->network.IELength+sizeof (struct rtw_ieee80211_hdr_3addr);
\r
409 if(bssinf_len > buf_size){
\r
410 DBG_871X("%s IE Length too long > %zu byte \n",__FUNCTION__,buf_size);
\r
414 #ifndef CONFIG_WAPI_SUPPORT
\r
418 if(rtw_get_wapi_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &wapi_len)>0)
\r
422 DBG_871X("%s, no support wapi!\n",__FUNCTION__);
\r
427 #endif //!CONFIG_WAPI_SUPPORT
\r
429 //To reduce PBC Overlap rate
\r
430 //_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
431 if(adapter_wdev_data(padapter)->scan_request != NULL)
\r
433 u8 *psr=NULL, sr = 0;
\r
434 NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid;
\r
435 struct cfg80211_scan_request *request = adapter_wdev_data(padapter)->scan_request;
\r
436 struct cfg80211_ssid *ssids = request->ssids;
\r
440 wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
\r
442 if(wpsie && wpsielen>0)
\r
443 psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
\r
447 if(request->n_ssids == 1 && request->n_channels == 1) // it means under processing WPS
\r
449 DBG_8192C("ssid=%s, len=%d\n", pssid->Ssid, pssid->SsidLength);
\r
451 if (ssids[0].ssid_len == 0) {
\r
453 else if(pssid->SsidLength == ssids[0].ssid_len &&
\r
454 _rtw_memcmp(pssid->Ssid, ssids[0].ssid, ssids[0].ssid_len))
\r
456 DBG_871X("%s, got sr and ssid match!\n", __func__);
\r
461 *psr = 0; //clear sr
\r
464 WLAN_BSSID_EX *pselect_network = &pnetwork->network;
\r
465 struct cfg80211_bss *pselect_bss = NULL;
\r
466 struct ieee80211_channel *notify_channel = NULL;
\r
469 DBG_871X("%s, got sr, but ssid mismatch, to remove this bss\n", __func__);
\r
471 if (pselect_network->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
\r
472 freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
\r
474 freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
\r
476 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
477 pselect_bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
\r
478 pselect_network->MacAddress, pselect_network->Ssid.Ssid,
\r
479 pselect_network->Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
\r
480 0/*WLAN_CAPABILITY_ESS*/);
\r
484 DBG_871X("%s, got bss for cfg80211 for unlinking bss\n", __func__);
\r
486 cfg80211_unlink_bss(wiphy, pselect_bss);
\r
487 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
488 cfg80211_put_bss(wiphy, pselect_bss);
\r
490 cfg80211_put_bss(pselect_bss);
\r
501 //_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
504 channel = pnetwork->network.Configuration.DSConfig;
\r
505 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
506 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
508 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
510 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
513 notify_timestamp = le64_to_cpu(*(u64*)rtw_get_timestampe_from_ie(pnetwork->network.IEs));
\r
515 notify_timestamp = rtw_get_systime_us();
\r
517 notify_interval = le16_to_cpu(*(u16*)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
\r
518 notify_capability = le16_to_cpu(*(u16*)rtw_get_capability_from_ie(pnetwork->network.IEs));
\r
520 notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_;
\r
521 notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_;
\r
523 //We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm)
\r
524 if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
\r
525 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
\r
526 notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);//dbm
\r
528 notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);//dbm
\r
532 DBG_8192C("bssid: "MAC_FMT"\n", MAC_ARG(pnetwork->network.MacAddress));
\r
533 DBG_8192C("Channel: %d(%d)\n", channel, freq);
\r
534 DBG_8192C("Capability: %X\n", notify_capability);
\r
535 DBG_8192C("Beacon interval: %d\n", notify_interval);
\r
536 DBG_8192C("Signal: %d\n", notify_signal);
\r
537 DBG_8192C("notify_timestamp: %llu\n", notify_timestamp);
\r
542 pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;
\r
543 fctrl = &(pwlanhdr->frame_ctl);
\r
546 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
\r
547 //pmlmeext->mgnt_seq++;
\r
549 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
\r
550 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
\r
551 SetFrameSubType(pbuf, WIFI_BEACON);
\r
553 _rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN);
\r
554 SetFrameSubType(pbuf, WIFI_PROBERSP);
\r
557 _rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
\r
558 _rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
\r
561 //pbuf += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
562 len = sizeof (struct rtw_ieee80211_hdr_3addr);
\r
563 _rtw_memcpy((pbuf+len), pnetwork->network.IEs, pnetwork->network.IELength);
\r
564 *((u64*)(pbuf+len)) = cpu_to_le64(notify_timestamp);
\r
566 len += pnetwork->network.IELength;
\r
568 //#ifdef CONFIG_P2P
\r
569 //if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
\r
571 // DBG_8192C("%s, got p2p_ie\n", __func__);
\r
576 bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)pbuf,
\r
577 len, notify_signal, GFP_ATOMIC);
\r
580 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress,
\r
581 notify_timestamp, notify_capability, notify_interval, notify_ie,
\r
582 notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/);
\r
585 if (unlikely(!bss)) {
\r
586 DBG_8192C(FUNC_ADPT_FMT" bss NULL\n", FUNC_ADPT_ARG(padapter));
\r
590 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
\r
591 #ifndef COMPAT_KERNEL_RELEASE
\r
592 //patch for cfg80211, update beacon ies to information_elements
\r
593 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
\r
595 if(bss->len_information_elements != bss->len_beacon_ies)
\r
597 bss->information_elements = bss->beacon_ies;
\r
598 bss->len_information_elements = bss->len_beacon_ies;
\r
601 #endif //COMPAT_KERNEL_RELEASE
\r
602 #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
\r
606 if( bss->information_elements == bss->proberesp_ies)
\r
608 if( bss->len_information_elements != bss->len_proberesp_ies)
\r
610 DBG_8192C("error!, len_information_elements != bss->len_proberesp_ies\n");
\r
614 else if(bss->len_information_elements < bss->len_beacon_ies)
\r
616 bss->information_elements = bss->beacon_ies;
\r
617 bss->len_information_elements = bss->len_beacon_ies;
\r
621 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
622 cfg80211_put_bss(wiphy, bss);
\r
624 cfg80211_put_bss(bss);
\r
629 rtw_mfree(pbuf, buf_size);
\r
635 Check the given bss is valid by kernel API cfg80211_get_bss()
\r
636 @padapter : the given adapter
\r
638 return _TRUE if bss is valid, _FALSE for not found.
\r
640 int rtw_cfg80211_check_bss(_adapter *padapter)
\r
642 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
643 struct cfg80211_bss *bss = NULL;
\r
644 struct ieee80211_channel *notify_channel = NULL;
\r
647 if (!(pnetwork) || !(padapter->rtw_wdev))
\r
650 if (pnetwork->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
\r
651 freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
\r
653 freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
\r
655 notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
\r
656 bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
\r
657 pnetwork->MacAddress, pnetwork->Ssid.Ssid,
\r
658 pnetwork->Ssid.SsidLength,
\r
659 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
\r
661 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
662 cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
\r
664 cfg80211_put_bss(bss);
\r
667 return (bss!=NULL);
\r
670 void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter)
\r
672 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
673 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
674 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
675 struct cfg80211_bss *bss = NULL;
\r
676 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
\r
677 struct wiphy *wiphy = pwdev->wiphy;
\r
679 struct ieee80211_channel *notify_channel;
\r
682 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
684 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
\r
685 if (cur_network->network.Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
\r
686 freq = rtw_ieee80211_channel_to_frequency(cur_network->network.Configuration.DSConfig, IEEE80211_BAND_2GHZ);
\r
688 freq = rtw_ieee80211_channel_to_frequency(cur_network->network.Configuration.DSConfig, IEEE80211_BAND_5GHZ);
\r
691 DBG_871X("chan: %d, freq: %d\n", cur_network->network.Configuration.DSConfig, freq);
\r
694 if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
\r
699 if (!rtw_cfg80211_check_bss(padapter)) {
\r
700 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
701 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
\r
703 if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE)
\r
706 _rtw_memcpy(&cur_network->network, pnetwork, sizeof(WLAN_BSSID_EX));
\r
709 if (!rtw_cfg80211_inform_bss(padapter,cur_network))
\r
710 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
712 DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
716 DBG_871X("cur_network is not exist!!!\n");
\r
722 if(scanned == NULL)
\r
725 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
\r
726 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
\r
728 if (!rtw_cfg80211_inform_bss(padapter,scanned)) {
\r
729 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
731 //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
734 DBG_871X("scanned & pnetwork compare fail\n");
\r
739 if (!rtw_cfg80211_check_bss(padapter))
\r
740 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
\r
742 //notify cfg80211 that device joined an IBSS
\r
743 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
\r
744 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
745 cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, notify_channel, GFP_ATOMIC);
\r
747 cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, GFP_ATOMIC);
\r
751 void rtw_cfg80211_indicate_connect(_adapter *padapter)
\r
753 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
754 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
755 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
757 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
759 struct cfg80211_bss *bss = NULL;
\r
761 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
762 if (pwdev->iftype != NL80211_IFTYPE_STATION
\r
763 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
764 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
\r
770 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
774 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
776 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
778 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
779 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
\r
780 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
\r
781 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
784 #endif //CONFIG_P2P
\r
787 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
788 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
\r
790 //DBG_871X(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter));
\r
792 if(scanned == NULL) {
\r
797 if (_rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
\r
798 && _rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
\r
800 if (!rtw_cfg80211_inform_bss(padapter,scanned)) {
\r
801 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
803 //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
806 DBG_871X("scanned: %s("MAC_FMT"), cur: %s("MAC_FMT")\n",
\r
807 scanned->network.Ssid.Ssid, MAC_ARG(scanned->network.MacAddress),
\r
808 pnetwork->Ssid.Ssid, MAC_ARG(pnetwork->MacAddress)
\r
815 if (!rtw_cfg80211_check_bss(padapter))
\r
816 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
\r
818 if (rtw_to_roam(padapter) > 0) {
\r
819 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
\r
820 struct wiphy *wiphy = pwdev->wiphy;
\r
821 struct ieee80211_channel *notify_channel;
\r
823 u16 channel = cur_network->network.Configuration.DSConfig;
\r
825 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
826 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
828 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
830 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
833 DBG_871X(FUNC_ADPT_FMT" call cfg80211_roamed\n", FUNC_ADPT_ARG(padapter));
\r
834 cfg80211_roamed(padapter->pnetdev
\r
835 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
\r
838 , cur_network->network.MacAddress
\r
839 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
\r
840 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
\r
841 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
\r
842 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
\r
847 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
\r
848 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
\r
850 cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
\r
851 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
\r
852 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
\r
853 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
\r
854 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
\r
855 , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
\r
856 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
\r
857 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
\r
862 void rtw_cfg80211_indicate_disconnect(_adapter *padapter)
\r
864 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
865 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
867 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
870 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
872 if (pwdev->iftype != NL80211_IFTYPE_STATION
\r
873 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
874 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
\r
880 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
884 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
886 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
888 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
889 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
891 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
894 #endif //CONFIG_P2P
\r
896 if (!padapter->mlmepriv.not_indic_disco) {
\r
897 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
\r
898 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
\r
900 if(pwdev->sme_state==CFG80211_SME_CONNECTING)
\r
901 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
\r
902 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
\r
903 else if(pwdev->sme_state==CFG80211_SME_CONNECTED)
\r
904 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
\r
906 //DBG_8192C("pwdev->sme_state=%d\n", pwdev->sme_state);
\r
908 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
\r
911 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
912 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
\r
914 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
\r
915 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
\r
921 #ifdef CONFIG_AP_MODE
\r
922 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
\r
925 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
926 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
\r
927 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
928 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
929 struct security_priv* psecuritypriv=&(padapter->securitypriv);
\r
930 struct sta_priv *pstapriv = &padapter->stapriv;
\r
932 DBG_8192C("%s\n", __FUNCTION__);
\r
934 param->u.crypt.err = 0;
\r
935 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
\r
937 //sizeof(struct ieee_param) = 64 bytes;
\r
938 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
\r
939 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
\r
945 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
\r
946 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
\r
947 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
\r
949 if (param->u.crypt.idx >= WEP_KEYS)
\r
957 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
\r
961 DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n");
\r
966 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
\r
968 //todo:clear default encryption keys
\r
970 DBG_8192C("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
\r
976 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
\r
978 DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
\r
980 wep_key_idx = param->u.crypt.idx;
\r
981 wep_key_len = param->u.crypt.key_len;
\r
983 DBG_8192C("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
\r
985 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
\r
991 if (wep_key_len > 0)
\r
993 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
996 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
\r
998 //wep default key has not been set, so use this key index as default key.
\r
1000 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
\r
1001 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1002 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
\r
1003 psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
\r
1005 if(wep_key_len == 13)
\r
1007 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
\r
1008 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
\r
1011 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
\r
1014 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
\r
1016 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
\r
1018 rtw_ap_set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx, 1);
\r
1025 if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
\r
1027 if(param->u.crypt.set_tx == 0) //group key
\r
1029 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1031 DBG_8192C("%s, set group_key, WEP\n", __FUNCTION__);
\r
1033 _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
1035 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1036 if(param->u.crypt.key_len==13)
\r
1038 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1042 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1044 DBG_8192C("%s, set group_key, TKIP\n", __FUNCTION__);
\r
1046 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
\r
1048 _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
1050 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1052 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
\r
1053 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
\r
1055 psecuritypriv->busetkipkey = _TRUE;
\r
1058 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1060 DBG_8192C("%s, set group_key, CCMP\n", __FUNCTION__);
\r
1062 psecuritypriv->dot118021XGrpPrivacy = _AES_;
\r
1064 _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
1068 DBG_8192C("%s, set group_key, none\n", __FUNCTION__);
\r
1070 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
1073 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
\r
1075 psecuritypriv->binstallGrpkey = _TRUE;
\r
1077 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
\r
1079 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
\r
1081 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1084 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1085 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
\r
1094 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
\r
1096 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
1098 if(param->u.crypt.set_tx ==1) //pairwise key
\r
1100 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1102 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1104 DBG_8192C("%s, set pairwise key, WEP\n", __FUNCTION__);
\r
1106 psta->dot118021XPrivacy = _WEP40_;
\r
1107 if(param->u.crypt.key_len==13)
\r
1109 psta->dot118021XPrivacy = _WEP104_;
\r
1112 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1114 DBG_8192C("%s, set pairwise key, TKIP\n", __FUNCTION__);
\r
1116 psta->dot118021XPrivacy = _TKIP_;
\r
1118 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1120 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
\r
1121 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
\r
1123 psecuritypriv->busetkipkey = _TRUE;
\r
1126 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1129 DBG_8192C("%s, set pairwise key, CCMP\n", __FUNCTION__);
\r
1131 psta->dot118021XPrivacy = _AES_;
\r
1135 DBG_8192C("%s, set pairwise key, none\n", __FUNCTION__);
\r
1137 psta->dot118021XPrivacy = _NO_PRIVACY_;
\r
1140 rtw_ap_set_pairwise_key(padapter, psta);
\r
1142 psta->ieee8021x_blocked = _FALSE;
\r
1144 psta->bpairwise_key_installed = _TRUE;
\r
1147 else//group key???
\r
1149 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1151 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1153 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1154 if(param->u.crypt.key_len==13)
\r
1156 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1159 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1161 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
\r
1163 _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
1165 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1167 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
\r
1168 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
\r
1170 psecuritypriv->busetkipkey = _TRUE;
\r
1173 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1175 psecuritypriv->dot118021XGrpPrivacy = _AES_;
\r
1177 _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
1181 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
1184 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
\r
1186 psecuritypriv->binstallGrpkey = _TRUE;
\r
1188 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
\r
1190 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
\r
1192 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1195 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1196 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
\r
1212 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
\r
1215 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
1216 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
1217 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1218 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1220 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
\r
1221 #endif //CONFIG_P2P
\r
1225 DBG_8192C("%s\n", __func__);
\r
1227 param->u.crypt.err = 0;
\r
1228 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
\r
1230 if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
\r
1236 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
\r
1237 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
\r
1238 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
\r
1240 if (param->u.crypt.idx >= WEP_KEYS
\r
1241 #ifdef CONFIG_IEEE80211W
\r
1242 && param->u.crypt.idx > BIP_MAX_KEYID
\r
1243 #endif //CONFIG_IEEE80211W
\r
1250 #ifdef CONFIG_WAPI_SUPPORT
\r
1251 if (strcmp(param->u.crypt.alg, "SMS4"))
\r
1259 if (strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1261 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
\r
1262 DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n");
\r
1264 wep_key_idx = param->u.crypt.idx;
\r
1265 wep_key_len = param->u.crypt.key_len;
\r
1267 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0))
\r
1273 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
\r
1275 //wep default key has not been set, so use this key index as default key.
\r
1277 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
1279 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1280 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
\r
1281 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1283 if(wep_key_len==13)
\r
1285 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
\r
1286 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1289 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
\r
1292 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
\r
1294 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
\r
1296 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, _TRUE);
\r
1301 if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
\r
1303 struct sta_info * psta,*pbcmc_sta;
\r
1304 struct sta_priv * pstapriv = &padapter->stapriv;
\r
1306 //DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__);
\r
1308 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
\r
1310 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
\r
1311 if (psta == NULL) {
\r
1312 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
\r
1313 DBG_8192C("%s, : Obtain Sta_info fail \n", __func__);
\r
1317 //Jeff: don't disable ieee8021x_blocked while clearing key
\r
1318 if (strcmp(param->u.crypt.alg, "none") != 0)
\r
1319 psta->ieee8021x_blocked = _FALSE;
\r
1322 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
\r
1323 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
\r
1325 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
\r
1328 if(param->u.crypt.set_tx ==1)//pairwise key
\r
1331 DBG_8192C("%s, : param->u.crypt.set_tx ==1 \n", __func__);
\r
1333 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1335 if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
\r
1337 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
\r
1338 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
\r
1339 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
\r
1341 padapter->securitypriv.busetkipkey=_FALSE;
\r
1342 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
\r
1345 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
\r
1346 DBG_871X(" ~~~~set sta key:unicastkey\n");
\r
1348 rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE);
\r
1352 if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1354 _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
1355 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
\r
1356 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
\r
1357 padapter->securitypriv.binstallGrpkey = _TRUE;
\r
1358 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
\r
1359 DBG_871X(" ~~~~set sta key:groupkey\n");
\r
1361 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
\r
1362 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1, _TRUE);
\r
1364 #ifdef CONFIG_IEEE80211W
\r
1365 else if(strcmp(param->u.crypt.alg, "BIP") == 0)
\r
1368 //DBG_871X("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx);
\r
1369 //save the IGTK key, length 16 bytes
\r
1370 _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
1371 /*DBG_871X("IGTK key below:\n");
\r
1372 for(no=0;no<16;no++)
\r
1373 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
\r
1375 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
\r
1376 padapter->securitypriv.binstallBIPkey = _TRUE;
\r
1377 DBG_871X(" ~~~~set sta key:IGKT\n");
\r
1379 #endif //CONFIG_IEEE80211W
\r
1382 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1384 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
\r
1386 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
\r
1389 #endif //CONFIG_P2P
\r
1394 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1395 if(pbcmc_sta==NULL)
\r
1397 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
\r
1401 //Jeff: don't disable ieee8021x_blocked while clearing key
\r
1402 if (strcmp(param->u.crypt.alg, "none") != 0)
\r
1403 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1405 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
\r
1406 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
\r
1408 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
\r
1412 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
\r
1417 #ifdef CONFIG_WAPI_SUPPORT
\r
1418 if (strcmp(param->u.crypt.alg, "SMS4") == 0)
\r
1420 PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
\r
1421 PRT_WAPI_STA_INFO pWapiSta;
\r
1422 u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1423 u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1424 u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1426 if(param->u.crypt.set_tx == 1)
\r
1428 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
\r
1429 if(_rtw_memcmp(pWapiSta->PeerMacAddr,param->sta_addr,6))
\r
1431 _rtw_memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
\r
1433 pWapiSta->wapiUsk.bSet = true;
\r
1434 _rtw_memcpy(pWapiSta->wapiUsk.dataKey,param->u.crypt.key,16);
\r
1435 _rtw_memcpy(pWapiSta->wapiUsk.micKey,param->u.crypt.key+16,16);
\r
1436 pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
\r
1437 pWapiSta->wapiUsk.bTxEnable = true;
\r
1439 _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16);
\r
1440 _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16);
\r
1441 _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16);
\r
1442 _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16);
\r
1443 _rtw_memcpy(pWapiSta->lastRxUnicastPN,WapiAEPNInitialValueSrc,16);
\r
1444 pWapiSta->wapiUskUpdate.bTxEnable = false;
\r
1445 pWapiSta->wapiUskUpdate.bSet = false;
\r
1447 if (psecuritypriv->sw_encrypt== false || psecuritypriv->sw_decrypt == false)
\r
1449 //set unicast key for ASUE
\r
1450 rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
\r
1457 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
\r
1458 if(_rtw_memcmp(pWapiSta->PeerMacAddr,get_bssid(pmlmepriv),6))
\r
1460 pWapiSta->wapiMsk.bSet = true;
\r
1461 _rtw_memcpy(pWapiSta->wapiMsk.dataKey,param->u.crypt.key,16);
\r
1462 _rtw_memcpy(pWapiSta->wapiMsk.micKey,param->u.crypt.key+16,16);
\r
1463 pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
\r
1464 pWapiSta->wapiMsk.bTxEnable = false;
\r
1465 if(!pWapiSta->bSetkeyOk)
\r
1466 pWapiSta->bSetkeyOk = true;
\r
1467 pWapiSta->bAuthenticateInProgress = false;
\r
1469 _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
\r
1471 if (psecuritypriv->sw_decrypt == false)
\r
1473 //set rx broadcast key for ASUE
\r
1474 rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
\r
1486 DBG_8192C("%s, ret=%d\n", __func__, ret);
\r
1493 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1494 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1495 u8 key_index, bool pairwise, const u8 *mac_addr,
\r
1496 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1497 u8 key_index, const u8 *mac_addr,
\r
1498 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1499 struct key_params *params)
\r
1503 struct ieee_param *param = NULL;
\r
1505 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1506 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
1507 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1508 #ifdef CONFIG_TDLS
\r
1509 struct sta_info *ptdls_sta;
\r
1510 #endif /* CONFIG_TDLS */
\r
1512 DBG_871X(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
\r
1513 DBG_871X("cipher=0x%x\n", params->cipher);
\r
1514 DBG_871X("key_len=0x%x\n", params->key_len);
\r
1515 DBG_871X("seq_len=0x%x\n", params->seq_len);
\r
1516 DBG_871X("key_index=%d\n", key_index);
\r
1517 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1518 DBG_871X("pairwise=%d\n", pairwise);
\r
1519 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1521 param_len = sizeof(struct ieee_param) + params->key_len;
\r
1522 param = (struct ieee_param *)rtw_malloc(param_len);
\r
1523 if (param == NULL)
\r
1526 _rtw_memset(param, 0, param_len);
\r
1528 param->cmd = IEEE_CMD_SET_ENCRYPTION;
\r
1529 _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
\r
1531 switch (params->cipher) {
\r
1532 case IW_AUTH_CIPHER_NONE:
\r
1533 //todo: remove key
\r
1535 alg_name = "none";
\r
1537 case WLAN_CIPHER_SUITE_WEP40:
\r
1538 case WLAN_CIPHER_SUITE_WEP104:
\r
1541 case WLAN_CIPHER_SUITE_TKIP:
\r
1542 alg_name = "TKIP";
\r
1544 case WLAN_CIPHER_SUITE_CCMP:
\r
1545 alg_name = "CCMP";
\r
1547 #ifdef CONFIG_IEEE80211W
\r
1548 case WLAN_CIPHER_SUITE_AES_CMAC:
\r
1551 #endif //CONFIG_IEEE80211W
\r
1552 #ifdef CONFIG_WAPI_SUPPORT
\r
1553 case WLAN_CIPHER_SUITE_SMS4:
\r
1555 if(pairwise == NL80211_KEYTYPE_PAIRWISE) {
\r
1556 if (key_index != 0 && key_index != 1) {
\r
1560 _rtw_memcpy((void*)param->sta_addr, (void*)mac_addr, ETH_ALEN);
\r
1562 DBG_871X("mac_addr is null \n");
\r
1564 DBG_871X("rtw_wx_set_enc_ext: SMS4 case \n");
\r
1573 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
\r
1576 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
\r
1578 param->u.crypt.set_tx = 0; //for wpa/wpa2 group key
\r
1580 param->u.crypt.set_tx = 1; //for wpa/wpa2 pairwise key
\r
1584 //param->u.crypt.idx = key_index - 1;
\r
1585 param->u.crypt.idx = key_index;
\r
1587 if (params->seq_len && params->seq)
\r
1589 _rtw_memcpy(param->u.crypt.seq, (u8 *)params->seq, params->seq_len);
\r
1592 if(params->key_len && params->key)
\r
1594 param->u.crypt.key_len = params->key_len;
\r
1595 _rtw_memcpy(param->u.crypt.key, (u8 *)params->key, params->key_len);
\r
1598 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
\r
1600 #ifdef CONFIG_TDLS
\r
1601 if (rtw_tdls_is_driver_setup(padapter) == _FALSE && mac_addr) {
\r
1602 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, (void *)mac_addr);
\r
1603 if (ptdls_sta != NULL && ptdls_sta->tdls_sta_state) {
\r
1604 _rtw_memcpy(ptdls_sta->tpk.tk, params->key, params->key_len);
\r
1605 rtw_tdls_set_key(padapter, ptdls_sta);
\r
1609 #endif /* CONFIG_TDLS */
\r
1611 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
\r
1613 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
1615 #ifdef CONFIG_AP_MODE
\r
1617 _rtw_memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN);
\r
1619 ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
\r
1622 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE
\r
1623 || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)
\r
1625 //DBG_8192C("@@@@@@@@@@ fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
\r
1626 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
\r
1630 DBG_8192C("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
\r
1637 rtw_mfree((u8*)param, param_len);
\r
1644 static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1645 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1646 u8 key_index, bool pairwise, const u8 *mac_addr,
\r
1647 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1648 u8 key_index, const u8 *mac_addr,
\r
1649 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1651 void (*callback)(void *cookie,
\r
1652 struct key_params*))
\r
1655 struct iwm_priv *iwm = ndev_to_iwm(ndev);
\r
1656 struct iwm_key *key = &iwm->keys[key_index];
\r
1657 struct key_params params;
\r
1659 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
\r
1661 memset(¶ms, 0, sizeof(params));
\r
1663 params.cipher = key->cipher;
\r
1664 params.key_len = key->key_len;
\r
1665 params.seq_len = key->seq_len;
\r
1666 params.seq = key->seq;
\r
1667 params.key = key->key;
\r
1669 callback(cookie, ¶ms);
\r
1671 return key->key_len ? 0 : -ENOENT;
\r
1673 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
1677 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1678 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1679 u8 key_index, bool pairwise, const u8 *mac_addr)
\r
1680 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1681 u8 key_index, const u8 *mac_addr)
\r
1682 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1684 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1685 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1687 DBG_871X(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index);
\r
1689 if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
\r
1691 //clear the flag of wep default key set.
\r
1692 psecuritypriv->bWepDefaultKeyIdxSet = 0;
\r
1698 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
\r
1699 struct net_device *ndev, u8 key_index
\r
1700 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1701 , bool unicast, bool multicast
\r
1705 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1706 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1708 #define SET_DEF_KEY_PARAM_FMT " key_index=%d"
\r
1709 #define SET_DEF_KEY_PARAM_ARG , key_index
\r
1710 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1711 #define SET_DEF_KEY_PARAM_FMT_2_6_38 ", unicast=%d, multicast=%d"
\r
1712 #define SET_DEF_KEY_PARAM_ARG_2_6_38 , unicast, multicast
\r
1714 #define SET_DEF_KEY_PARAM_FMT_2_6_38 ""
\r
1715 #define SET_DEF_KEY_PARAM_ARG_2_6_38
\r
1718 DBG_871X(FUNC_NDEV_FMT
\r
1719 SET_DEF_KEY_PARAM_FMT
\r
1720 SET_DEF_KEY_PARAM_FMT_2_6_38
\r
1721 "\n", FUNC_NDEV_ARG(ndev)
\r
1722 SET_DEF_KEY_PARAM_ARG
\r
1723 SET_DEF_KEY_PARAM_ARG_2_6_38
\r
1726 if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) //set wep default key
\r
1728 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1730 psecuritypriv->dot11PrivacyKeyIndex = key_index;
\r
1732 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
\r
1733 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1734 if (psecuritypriv->dot11DefKeylen[key_index] == 13)
\r
1736 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
\r
1737 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1740 psecuritypriv->bWepDefaultKeyIdxSet = 1; //set the flag to represent that wep default key has been set
\r
1746 #if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
\r
1747 static int cfg80211_rtw_set_rekey_data(struct wiphy *wiphy,
\r
1748 struct net_device *ndev,
\r
1749 struct cfg80211_gtk_rekey_data *data)
\r
1752 struct sta_info *psta;
\r
1753 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1754 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1755 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1756 struct security_priv *psecuritypriv = &(padapter->securitypriv);
\r
1758 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
\r
1759 if (psta == NULL) {
\r
1760 DBG_871X("%s, : Obtain Sta_info fail\n", __func__);
\r
1764 _rtw_memcpy(psta->kek, data->kek, NL80211_KEK_LEN);
\r
1765 /*printk("\ncfg80211_rtw_set_rekey_data KEK:");
\r
1766 for(i=0;i<NL80211_KEK_LEN; i++)
\r
1767 printk(" %02x ", psta->kek[i]);*/
\r
1768 _rtw_memcpy(psta->kck, data->kck, NL80211_KCK_LEN);
\r
1769 /*printk("\ncfg80211_rtw_set_rekey_data KCK:");
\r
1770 for(i=0;i<NL80211_KCK_LEN; i++)
\r
1771 printk(" %02x ", psta->kck[i]);*/
\r
1772 _rtw_memcpy(psta->replay_ctr, data->replay_ctr, NL80211_REPLAY_CTR_LEN);
\r
1773 psecuritypriv->binstallKCK_KEK = _TRUE;
\r
1774 /*printk("\nREPLAY_CTR: ");
\r
1775 for(i=0;i<RTW_REPLAY_CTR_LEN; i++)
\r
1776 printk(" %02x ", psta->replay_ctr[i]);*/
\r
1780 #endif /*CONFIG_GTK_OL*/
\r
1781 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
\r
1782 struct net_device *ndev,
\r
1783 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
1788 struct station_info *sinfo)
\r
1791 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1792 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1793 struct sta_info *psta = NULL;
\r
1794 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1796 sinfo->filled = 0;
\r
1799 DBG_871X(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
\r
1804 psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
\r
1805 if (psta == NULL) {
\r
1806 DBG_8192C("%s, sta_info is null\n", __func__);
\r
1811 #ifdef CONFIG_DEBUG_CFG80211
\r
1812 DBG_871X(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
\r
1815 //for infra./P2PClient mode
\r
1816 if( check_fwstate(pmlmepriv, WIFI_STATION_STATE)
\r
1817 && check_fwstate(pmlmepriv, _FW_LINKED)
\r
1820 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
1822 if (_rtw_memcmp((u8 *)mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) {
\r
1823 DBG_871X("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
\r
1828 sinfo->filled |= STATION_INFO_SIGNAL;
\r
1829 sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
\r
1831 sinfo->filled |= STATION_INFO_TX_BITRATE;
\r
1832 sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
\r
1834 sinfo->filled |= STATION_INFO_RX_PACKETS;
\r
1835 sinfo->rx_packets = sta_rx_data_pkts(psta);
\r
1837 sinfo->filled |= STATION_INFO_TX_PACKETS;
\r
1838 sinfo->tx_packets = psta->sta_stats.tx_pkts;
\r
1842 //for Ad-Hoc/AP mode
\r
1843 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
\r
1844 ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
\r
1845 ||check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
1846 && check_fwstate(pmlmepriv, _FW_LINKED)
\r
1849 //TODO: should acquire station info...
\r
1856 extern int netdev_open(struct net_device *pnetdev);
\r
1857 #ifdef CONFIG_CONCURRENT_MODE
\r
1858 extern int netdev_if2_open(struct net_device *pnetdev);
\r
1862 enum nl80211_iftype {
\r
1863 NL80211_IFTYPE_UNSPECIFIED,
\r
1864 NL80211_IFTYPE_ADHOC, //1
\r
1865 NL80211_IFTYPE_STATION, //2
\r
1866 NL80211_IFTYPE_AP, //3
\r
1867 NL80211_IFTYPE_AP_VLAN,
\r
1868 NL80211_IFTYPE_WDS,
\r
1869 NL80211_IFTYPE_MONITOR, //6
\r
1870 NL80211_IFTYPE_MESH_POINT,
\r
1871 NL80211_IFTYPE_P2P_CLIENT, //8
\r
1872 NL80211_IFTYPE_P2P_GO, //9
\r
1874 NUM_NL80211_IFTYPES,
\r
1875 NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
\r
1878 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
\r
1879 struct net_device *ndev,
\r
1880 enum nl80211_iftype type, u32 *flags,
\r
1881 struct vif_params *params)
\r
1883 enum nl80211_iftype old_type;
\r
1884 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
\r
1885 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1886 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
1887 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
1889 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
1892 u8 change = _FALSE;
\r
1894 DBG_871X(FUNC_NDEV_FMT" type=%d\n", FUNC_NDEV_ARG(ndev), type);
\r
1896 if(adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE)
\r
1902 #ifdef CONFIG_CONCURRENT_MODE
\r
1903 if(padapter->adapter_type == SECONDARY_ADAPTER)
\r
1905 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev));
\r
1906 if(netdev_if2_open(ndev) != 0) {
\r
1907 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open fail\n", FUNC_NDEV_ARG(ndev));
\r
1912 else if(padapter->adapter_type == PRIMARY_ADAPTER)
\r
1913 #endif //CONFIG_CONCURRENT_MODE
\r
1915 DBG_871X(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
\r
1916 if(netdev_open(ndev) != 0) {
\r
1917 DBG_871X(FUNC_NDEV_FMT" call netdev_open fail\n", FUNC_NDEV_ARG(ndev));
\r
1923 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
1924 DBG_871X(FUNC_NDEV_FMT" call rtw_pwr_wakeup fail\n", FUNC_NDEV_ARG(ndev));
\r
1929 old_type = rtw_wdev->iftype;
\r
1930 DBG_871X(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
\r
1931 FUNC_NDEV_ARG(ndev), old_type, type);
\r
1933 if(old_type != type)
\r
1936 pmlmeext->action_public_rxseq = 0xffff;
\r
1937 pmlmeext->action_public_dialog_token = 0xff;
\r
1940 /* initial default type */
\r
1941 ndev->type = ARPHRD_ETHER;
\r
1944 case NL80211_IFTYPE_ADHOC:
\r
1945 networkType = Ndis802_11IBSS;
\r
1947 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1948 case NL80211_IFTYPE_P2P_CLIENT:
\r
1950 case NL80211_IFTYPE_STATION:
\r
1951 networkType = Ndis802_11Infrastructure;
\r
1953 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1955 if(change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
1957 //it means remove GO and change mode from AP(GO) to station(P2P DEVICE)
\r
1958 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
1959 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
1961 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
1964 #endif //CONFIG_P2P
\r
1966 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1967 case NL80211_IFTYPE_P2P_GO:
\r
1969 case NL80211_IFTYPE_AP:
\r
1970 networkType = Ndis802_11APMode;
\r
1972 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1974 if(change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
1976 //it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO)
\r
1977 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
\r
1980 #endif //CONFIG_P2P
\r
1982 case NL80211_IFTYPE_MONITOR:
\r
1983 networkType = Ndis802_11Monitor;
\r
1985 ndev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */
\r
1987 ndev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */
\r
1990 ret = -EOPNOTSUPP;
\r
1994 rtw_wdev->iftype = type;
\r
1996 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE)
\r
1998 rtw_wdev->iftype = old_type;
\r
2003 rtw_setopmode_cmd(padapter, networkType, _TRUE);
\r
2007 DBG_871X(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret);
\r
2011 void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted)
\r
2013 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
2016 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2017 if (pwdev_priv->scan_request != NULL) {
\r
2018 #ifdef CONFIG_DEBUG_CFG80211
\r
2019 DBG_871X("%s with scan req\n", __FUNCTION__);
\r
2022 /* avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); */
\r
2023 if(pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
\r
2025 DBG_8192C("error wiphy compare\n");
\r
2029 cfg80211_scan_done(pwdev_priv->scan_request, aborted);
\r
2032 pwdev_priv->scan_request = NULL;
\r
2034 #ifdef CONFIG_DEBUG_CFG80211
\r
2035 DBG_871X("%s without scan req\n", __FUNCTION__);
\r
2038 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2041 void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork)
\r
2043 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
2044 struct wiphy *wiphy = pwdev->wiphy;
\r
2045 struct cfg80211_bss *bss = NULL;
\r
2046 WLAN_BSSID_EX select_network = pnetwork->network;
\r
2048 bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
\r
2049 select_network.MacAddress, select_network.Ssid.Ssid,
\r
2050 select_network.Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
\r
2051 0/*WLAN_CAPABILITY_ESS*/);
\r
2054 cfg80211_unlink_bss(wiphy, bss);
\r
2055 DBG_8192C("%s(): cfg80211_unlink %s!! () ",__func__,select_network.Ssid.Ssid );
\r
2056 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
2057 cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
\r
2059 cfg80211_put_bss(bss);
\r
2065 void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
\r
2068 _list *plist, *phead;
\r
2069 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2070 _queue *queue = &(pmlmepriv->scanned_queue);
\r
2071 struct wlan_network *pnetwork = NULL;
\r
2073 u32 wait_for_surveydone;
\r
2076 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
\r
2077 #endif //CONFIG_P2P
\r
2078 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
2080 #ifdef CONFIG_DEBUG_CFG80211
\r
2081 DBG_8192C("%s\n", __func__);
\r
2084 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
2086 phead = get_list_head(queue);
\r
2087 plist = get_next(phead);
\r
2091 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
\r
2094 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
\r
2096 //report network only if the current channel set contains the channel to which this network belongs
\r
2097 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
\r
2098 && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
\r
2099 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
\r
2102 //ev=translate_scan(padapter, a, pnetwork, ev, stop);
\r
2103 rtw_cfg80211_inform_bss(padapter, pnetwork);
\r
2105 /* //check ralink testbed RSN IE length
\r
2107 if(_rtw_memcmp(pnetwork->network.Ssid.Ssid, "Ralink_11n_AP",13))
\r
2111 p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
\r
2112 DBG_871X("ie_len=%d\n", ie_len);
\r
2115 plist = get_next(plist);
\r
2119 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
2122 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
\r
2125 uint wps_ielen = 0;
\r
2127 u32 p2p_ielen = 0;
\r
2129 u32 wfd_ielen = 0;
\r
2131 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2133 #ifdef CONFIG_DEBUG_CFG80211
\r
2134 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
2139 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
2141 #ifdef CONFIG_DEBUG_CFG80211
\r
2142 DBG_8192C("probe_req_wps_ielen=%d\n", wps_ielen);
\r
2145 if(pmlmepriv->wps_probe_req_ie)
\r
2147 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
\r
2148 pmlmepriv->wps_probe_req_ie_len = 0;
\r
2149 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
\r
2150 pmlmepriv->wps_probe_req_ie = NULL;
\r
2153 pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
\r
2154 if ( pmlmepriv->wps_probe_req_ie == NULL) {
\r
2155 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2159 _rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
\r
2160 pmlmepriv->wps_probe_req_ie_len = wps_ielen;
\r
2163 //buf += wps_ielen;
\r
2164 //len -= wps_ielen;
\r
2167 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
2169 struct wifidirect_info *wdinfo = &padapter->wdinfo;
\r
2170 u32 attr_contentlen = 0;
\r
2171 u8 listen_ch_attr[5];
\r
2173 #ifdef CONFIG_DEBUG_CFG80211
\r
2174 DBG_8192C("probe_req_p2p_ielen=%d\n", p2p_ielen);
\r
2177 if(pmlmepriv->p2p_probe_req_ie)
\r
2179 u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
\r
2180 pmlmepriv->p2p_probe_req_ie_len = 0;
\r
2181 rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len);
\r
2182 pmlmepriv->p2p_probe_req_ie = NULL;
\r
2185 pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen);
\r
2186 if ( pmlmepriv->p2p_probe_req_ie == NULL) {
\r
2187 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2191 _rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
\r
2192 pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
\r
2194 if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8*)listen_ch_attr, (uint*) &attr_contentlen)
\r
2195 && attr_contentlen == 5)
\r
2197 if (wdinfo->listen_channel != listen_ch_attr[4]) {
\r
2198 DBG_871X(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n",
\r
2199 FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2],
\r
2200 listen_ch_attr[3], listen_ch_attr[4]);
\r
2201 wdinfo->listen_channel = listen_ch_attr[4];
\r
2205 #endif //CONFIG_P2P
\r
2207 //buf += p2p_ielen;
\r
2208 //len -= p2p_ielen;
\r
2211 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
2213 #ifdef CONFIG_DEBUG_CFG80211
\r
2214 DBG_8192C("probe_req_wfd_ielen=%d\n", wfd_ielen);
\r
2217 if(pmlmepriv->wfd_probe_req_ie)
\r
2219 u32 free_len = pmlmepriv->wfd_probe_req_ie_len;
\r
2220 pmlmepriv->wfd_probe_req_ie_len = 0;
\r
2221 rtw_mfree(pmlmepriv->wfd_probe_req_ie, free_len);
\r
2222 pmlmepriv->wfd_probe_req_ie = NULL;
\r
2225 pmlmepriv->wfd_probe_req_ie = rtw_malloc(wfd_ielen);
\r
2226 if ( pmlmepriv->wfd_probe_req_ie == NULL) {
\r
2227 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2231 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
\r
2233 #endif //CONFIG_WFD
\r
2241 static int cfg80211_rtw_scan(struct wiphy *wiphy
\r
2242 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
\r
2243 , struct net_device *ndev
\r
2245 , struct cfg80211_scan_request *request)
\r
2247 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
2248 struct net_device *ndev = wdev_to_ndev(request->wdev);
\r
2251 u8 _status = _FALSE;
\r
2253 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
\r
2254 struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
\r
2257 uint wps_ielen=0;
\r
2260 u8 survey_times=3;
\r
2261 u8 survey_times_for_one_ch=6;
\r
2262 struct cfg80211_ssid *ssids = request->ssids;
\r
2263 int social_channel = 0, j = 0;
\r
2264 bool need_indicate_scan_done = _FALSE;
\r
2265 bool ps_denied = _FALSE;
\r
2267 _adapter *padapter;
\r
2268 struct rtw_wdev_priv *pwdev_priv;
\r
2269 struct mlme_priv *pmlmepriv;
\r
2271 struct wifidirect_info *pwdinfo;
\r
2272 #endif //CONFIG_P2P
\r
2273 #ifdef CONFIG_CONCURRENT_MODE
\r
2274 PADAPTER pbuddy_adapter = NULL;
\r
2275 struct mlme_priv *pbuddy_mlmepriv = NULL;
\r
2276 #endif //CONFIG_CONCURRENT_MODE
\r
2278 if (ndev == NULL) {
\r
2283 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2284 pwdev_priv = adapter_wdev_data(padapter);
\r
2285 pmlmepriv= &padapter->mlmepriv;
\r
2287 pwdinfo= &(padapter->wdinfo);
\r
2288 #endif //CONFIG_P2P
\r
2290 //#ifdef CONFIG_DEBUG_CFG80211
\r
2291 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
2294 #ifdef CONFIG_CONCURRENT_MODE
\r
2295 if (padapter->pbuddy_adapter) {
\r
2296 pbuddy_adapter = padapter->pbuddy_adapter;
\r
2297 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
\r
2299 #endif //CONFIG_CONCURRENT_MODE
\r
2301 #ifdef CONFIG_MP_INCLUDED
\r
2302 if (padapter->registrypriv.mp_mode == 1)
\r
2304 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter));
\r
2308 #ifdef CONFIG_CONCURRENT_MODE
\r
2309 if (padapter->pbuddy_adapter) {
\r
2310 if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1)
\r
2312 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter));
\r
2317 #endif //CONFIG_CONCURRENT_MODE
\r
2320 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2321 pwdev_priv->scan_request = request;
\r
2322 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2324 if (adapter_wdev_data(padapter)->block_scan == _TRUE) {
\r
2325 DBG_871X(FUNC_ADPT_FMT" wdev_priv.block_scan is set\n", FUNC_ADPT_ARG(padapter));
\r
2326 need_indicate_scan_done = _TRUE;
\r
2327 goto check_need_indicate_scan_done;
\r
2330 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
2332 #ifdef CONFIG_DEBUG_CFG80211
\r
2333 DBG_871X("%s under WIFI_AP_STATE\n", __FUNCTION__);
\r
2336 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
\r
2338 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2340 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
\r
2342 DBG_8192C("AP mode process WPS \n");
\r
2345 need_indicate_scan_done = _TRUE;
\r
2346 goto check_need_indicate_scan_done;
\r
2350 rtw_ps_deny(padapter, PS_DENY_SCAN);
\r
2351 ps_denied = _TRUE;
\r
2352 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
2353 need_indicate_scan_done = _TRUE;
\r
2354 goto check_need_indicate_scan_done;
\r
2358 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
2360 if(ssids->ssid != NULL
\r
2361 && _rtw_memcmp(ssids->ssid, "DIRECT-", 7)
\r
2362 && rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
\r
2365 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2367 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
\r
2368 adapter_wdev_data(padapter)->p2p_enabled = _TRUE;
\r
2372 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
2373 #ifdef CONFIG_DEBUG_CFG80211
\r
2374 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
2377 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
\r
2379 if(request->n_channels == 3 &&
\r
2380 request->channels[0]->hw_value == 1 &&
\r
2381 request->channels[1]->hw_value == 6 &&
\r
2382 request->channels[2]->hw_value == 11
\r
2385 social_channel = 1;
\r
2389 #endif //CONFIG_P2P
\r
2391 if(request->ie && request->ie_len>0)
\r
2393 rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len );
\r
2396 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
\r
2397 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2398 need_indicate_scan_done = _TRUE;
\r
2399 goto check_need_indicate_scan_done;
\r
2400 } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
2401 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2403 goto check_need_indicate_scan_done;
\r
2406 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)
\r
2408 #if 1 // Miracast can't do AP scan
\r
2409 static u32 lastscantime = 0;
\r
2412 passtime = rtw_get_passing_time_ms(lastscantime);
\r
2413 lastscantime = rtw_get_current_time();
\r
2414 if (passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD)
\r
2417 DBG_871X("%s: bBusyTraffic == _TRUE\n", __FUNCTION__);
\r
2418 need_indicate_scan_done = _TRUE;
\r
2419 goto check_need_indicate_scan_done;
\r
2423 if (rtw_is_scan_deny(padapter)){
\r
2424 DBG_871X(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter));
\r
2425 need_indicate_scan_done = _TRUE;
\r
2426 goto check_need_indicate_scan_done;
\r
2429 #ifdef CONFIG_CONCURRENT_MODE
\r
2430 if(pbuddy_mlmepriv && (pbuddy_mlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))
\r
2432 #if 1 // Miracast can't do AP scan
\r
2433 static u32 buddylastscantime = 0;
\r
2436 passtime = rtw_get_passing_time_ms(buddylastscantime);
\r
2437 buddylastscantime = rtw_get_current_time();
\r
2438 if ((passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD)
\r
2439 //#ifdef CONFIG_P2P
\r
2440 // ||(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
\r
2441 //#endif //CONFIG_P2P
\r
2445 DBG_871X("%s: bBusyTraffic == _TRUE at buddy_intf\n", __FUNCTION__);
\r
2446 need_indicate_scan_done = _TRUE;
\r
2447 goto check_need_indicate_scan_done;
\r
2451 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE) {
\r
2452 DBG_871X("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv->fw_state);
\r
2453 need_indicate_scan_done = _TRUE;
\r
2454 goto check_need_indicate_scan_done;
\r
2456 } else if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY)) {
\r
2457 bool scan_via_buddy = _FALSE;
\r
2458 struct rtw_wdev_priv *buddy_wdev_priv = adapter_wdev_data(pbuddy_adapter);
\r
2460 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2461 _enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
\r
2462 if (buddy_wdev_priv->scan_request) {
\r
2463 DBG_871X("scan via buddy\n");
\r
2464 pmlmepriv->scanning_via_buddy_intf = _TRUE;
\r
2465 _enter_critical_bh(&pmlmepriv->lock, &irqL);
\r
2466 set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
\r
2467 _exit_critical_bh(&pmlmepriv->lock, &irqL);
\r
2468 scan_via_buddy = _TRUE;
\r
2470 _exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
\r
2471 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2473 if (scan_via_buddy == _FALSE)
\r
2474 need_indicate_scan_done = _TRUE;
\r
2476 goto check_need_indicate_scan_done;
\r
2478 #endif /* CONFIG_CONCURRENT_MODE */
\r
2481 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
\r
2483 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
\r
2484 rtw_free_network_queue(padapter, _TRUE);
\r
2486 if(social_channel == 0)
\r
2487 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
\r
2489 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
\r
2491 #endif //CONFIG_P2P
\r
2494 _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
\r
2495 //parsing request ssids, n_ssids
\r
2496 for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
\r
2497 #ifdef CONFIG_DEBUG_CFG80211
\r
2498 DBG_8192C("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
\r
2500 _rtw_memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
\r
2501 ssid[i].SsidLength = ssids[i].ssid_len;
\r
2504 /* parsing channels, n_channels */
\r
2505 _rtw_memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
\r
2506 for (i=0;i<request->n_channels && i<RTW_CHANNEL_SCAN_AMOUNT;i++) {
\r
2507 #ifdef CONFIG_DEBUG_CFG80211
\r
2508 DBG_871X(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
\r
2510 ch[i].hw_value = request->channels[i]->hw_value;
\r
2511 ch[i].flags = request->channels[i]->flags;
\r
2514 _enter_critical_bh(&pmlmepriv->lock, &irqL);
\r
2515 if (request->n_channels == 1) {
\r
2516 for(i=1;i<survey_times_for_one_ch;i++)
\r
2517 _rtw_memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
\r
2518 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times_for_one_ch);
\r
2519 } else if (request->n_channels <= 4) {
\r
2520 for(j=request->n_channels-1;j>=0;j--)
\r
2521 for(i=0;i<survey_times;i++)
\r
2523 _rtw_memcpy(&ch[j*survey_times+i], &ch[j], sizeof(struct rtw_ieee80211_channel));
\r
2525 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * request->n_channels);
\r
2527 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
\r
2529 _exit_critical_bh(&pmlmepriv->lock, &irqL);
\r
2532 if(_status == _FALSE)
\r
2537 check_need_indicate_scan_done:
\r
2538 if (_TRUE == need_indicate_scan_done)
\r
2540 rtw_cfg80211_surveydone_event_callback(padapter);
\r
2541 rtw_cfg80211_indicate_scan_done(padapter, _FALSE);
\r
2545 if (ps_denied == _TRUE)
\r
2546 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
\r
2553 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
\r
2556 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
\r
2558 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
\r
2559 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
\r
2562 iwm->conf.rts_threshold = wiphy->rts_threshold;
\r
2564 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
\r
2565 CFG_RTS_THRESHOLD,
\r
2566 iwm->conf.rts_threshold);
\r
2571 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
\r
2572 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
\r
2575 iwm->conf.frag_threshold = wiphy->frag_threshold;
\r
2577 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
\r
2578 CFG_FRAG_THRESHOLD,
\r
2579 iwm->conf.frag_threshold);
\r
2584 DBG_8192C("%s\n", __func__);
\r
2590 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
\r
2592 DBG_8192C("%s, wpa_version=%d\n", __func__, wpa_version);
\r
2594 if (!wpa_version) {
\r
2595 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
2600 if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
\r
2602 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
\r
2606 if (wpa_version & NL80211_WPA_VERSION_2)
\r
2608 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
\r
2612 #ifdef CONFIG_WAPI_SUPPORT
\r
2613 if (wpa_version & NL80211_WAPI_VERSION_1)
\r
2615 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWAPI;
\r
2623 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
\r
2624 enum nl80211_auth_type sme_auth_type)
\r
2626 DBG_8192C("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
\r
2629 switch (sme_auth_type) {
\r
2630 case NL80211_AUTHTYPE_AUTOMATIC:
\r
2632 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
\r
2635 case NL80211_AUTHTYPE_OPEN_SYSTEM:
\r
2637 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
\r
2639 if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
\r
2640 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2642 #ifdef CONFIG_WAPI_SUPPORT
\r
2643 if(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI)
\r
2644 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2648 case NL80211_AUTHTYPE_SHARED_KEY:
\r
2650 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
\r
2652 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2657 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
\r
2658 //return -ENOTSUPP;
\r
2665 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
\r
2667 u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2669 u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
\r
2670 &psecuritypriv->dot118021XGrpPrivacy;
\r
2672 DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
\r
2676 *profile_cipher = _NO_PRIVACY_;
\r
2677 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
\r
2682 case IW_AUTH_CIPHER_NONE:
\r
2683 *profile_cipher = _NO_PRIVACY_;
\r
2684 ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2685 #ifdef CONFIG_WAPI_SUPPORT
\r
2686 if(psecuritypriv->dot11PrivacyAlgrthm ==_SMS4_ )
\r
2688 *profile_cipher = _SMS4_;
\r
2692 case WLAN_CIPHER_SUITE_WEP40:
\r
2693 *profile_cipher = _WEP40_;
\r
2694 ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2696 case WLAN_CIPHER_SUITE_WEP104:
\r
2697 *profile_cipher = _WEP104_;
\r
2698 ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2700 case WLAN_CIPHER_SUITE_TKIP:
\r
2701 *profile_cipher = _TKIP_;
\r
2702 ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2704 case WLAN_CIPHER_SUITE_CCMP:
\r
2705 *profile_cipher = _AES_;
\r
2706 ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2708 #ifdef CONFIG_WAPI_SUPPORT
\r
2709 case WLAN_CIPHER_SUITE_SMS4:
\r
2710 *profile_cipher = _SMS4_;
\r
2711 ndisencryptstatus = Ndis802_11_EncrypteionWAPI;
\r
2715 DBG_8192C("Unsupported cipher: 0x%x\n", cipher);
\r
2721 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
\r
2723 //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
\r
2724 // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
\r
2730 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
\r
2732 DBG_8192C("%s, key_mgt=0x%x\n", __func__, key_mgt);
\r
2734 if (key_mgt == WLAN_AKM_SUITE_8021X)
\r
2735 //*auth_type = UMAC_AUTH_TYPE_8021X;
\r
2736 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2737 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
\r
2738 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2740 #ifdef CONFIG_WAPI_SUPPORT
\r
2741 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_PSK){
\r
2742 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2744 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_CERT){
\r
2745 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2751 DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt);
\r
2758 static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
\r
2760 u8 *buf=NULL, *pos=NULL;
\r
2762 int group_cipher = 0, pairwise_cipher = 0;
\r
2767 u8 null_addr[]= {0,0,0,0,0,0};
\r
2769 if (pie == NULL || !ielen) {
\r
2770 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
\r
2771 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2775 if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
\r
2780 buf = rtw_zmalloc(ielen);
\r
2786 _rtw_memcpy(buf, pie , ielen);
\r
2791 DBG_8192C("set wpa_ie(length:%zu):\n", ielen);
\r
2792 for(i=0;i<ielen;i=i+8)
\r
2793 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
2797 if(ielen < RSN_HEADER_LEN){
\r
2798 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
\r
2803 pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
\r
2804 if(pwpa && wpa_ielen>0)
\r
2806 if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
2808 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
2809 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
\r
2810 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
\r
2812 DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
\r
2816 pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
\r
2817 if(pwpa2 && wpa2_ielen>0)
\r
2819 if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
2821 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
2822 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
\r
2823 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
\r
2825 DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
\r
2829 if (group_cipher == 0)
\r
2831 group_cipher = WPA_CIPHER_NONE;
\r
2833 if (pairwise_cipher == 0)
\r
2835 pairwise_cipher = WPA_CIPHER_NONE;
\r
2838 switch(group_cipher)
\r
2840 case WPA_CIPHER_NONE:
\r
2841 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
\r
2842 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
\r
2844 case WPA_CIPHER_WEP40:
\r
2845 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
\r
2846 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2848 case WPA_CIPHER_TKIP:
\r
2849 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
\r
2850 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2852 case WPA_CIPHER_CCMP:
\r
2853 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
\r
2854 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2856 case WPA_CIPHER_WEP104:
\r
2857 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
\r
2858 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2862 switch(pairwise_cipher)
\r
2864 case WPA_CIPHER_NONE:
\r
2865 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
\r
2866 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
\r
2868 case WPA_CIPHER_WEP40:
\r
2869 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
\r
2870 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2872 case WPA_CIPHER_TKIP:
\r
2873 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
\r
2874 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2876 case WPA_CIPHER_CCMP:
\r
2877 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
\r
2878 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2880 case WPA_CIPHER_WEP104:
\r
2881 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
\r
2882 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2886 {/* handle wps_ie */
\r
2890 wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
\r
2891 if (wps_ie && wps_ielen > 0) {
\r
2892 DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen);
\r
2893 padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
\r
2894 _rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
\r
2895 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2897 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2902 {//check p2p_ie for assoc req;
\r
2905 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2907 if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen)))
\r
2909 #ifdef CONFIG_DEBUG_CFG80211
\r
2910 DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
\r
2913 if(pmlmepriv->p2p_assoc_req_ie)
\r
2915 u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
\r
2916 pmlmepriv->p2p_assoc_req_ie_len = 0;
\r
2917 rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
\r
2918 pmlmepriv->p2p_assoc_req_ie = NULL;
\r
2921 pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
\r
2922 if ( pmlmepriv->p2p_assoc_req_ie == NULL) {
\r
2923 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2926 _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
\r
2927 pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
\r
2930 #endif //CONFIG_P2P
\r
2933 {//check wfd_ie for assoc req;
\r
2936 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2938 if(rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen))
\r
2940 #ifdef CONFIG_DEBUG_CFG80211
\r
2941 DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
\r
2944 if(pmlmepriv->wfd_assoc_req_ie)
\r
2946 u32 free_len = pmlmepriv->wfd_assoc_req_ie_len;
\r
2947 pmlmepriv->wfd_assoc_req_ie_len = 0;
\r
2948 rtw_mfree(pmlmepriv->wfd_assoc_req_ie, free_len);
\r
2949 pmlmepriv->wfd_assoc_req_ie = NULL;
\r
2952 pmlmepriv->wfd_assoc_req_ie = rtw_malloc(wfd_ielen);
\r
2953 if ( pmlmepriv->wfd_assoc_req_ie == NULL) {
\r
2954 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2957 rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
\r
2960 #endif //CONFIG_WFD
\r
2962 //TKIP and AES disallow multicast packets until installing group key
\r
2963 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
\r
2964 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
\r
2965 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
\r
2966 //WPS open need to enable multicast
\r
2967 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
\r
2968 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
\r
2970 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
\r
2971 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
\r
2972 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
\r
2976 rtw_mfree(buf, ielen);
\r
2978 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2982 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
\r
2983 struct cfg80211_ibss_params *params)
\r
2985 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2986 NDIS_802_11_SSID ndis_ssid;
\r
2987 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
2988 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2989 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
2990 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
2991 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
\r
2992 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
\r
2993 struct cfg80211_chan_def *pch_def;
\r
2995 struct ieee80211_channel *pch;
\r
2998 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
\r
2999 pch_def = (struct cfg80211_chan_def *)(¶ms->chandef);
\r
3000 pch = (struct ieee80211_channel *) pch_def->chan;
\r
3001 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
\r
3002 pch = (struct ieee80211_channel *)(params->channel);
\r
3005 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
3010 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
\r
3015 #ifdef CONFIG_CONCURRENT_MODE
\r
3016 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
\r
3017 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
\r
3021 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
\r
3022 rtw_scan_abort(padapter->pbuddy_adapter);
\r
3024 #endif //CONFIG_CONCURRENT_MODE
\r
3026 if (!params->ssid || !params->ssid_len)
\r
3032 if (params->ssid_len > IW_ESSID_MAX_SIZE){
\r
3038 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
\r
3039 ndis_ssid.SsidLength = params->ssid_len;
\r
3040 _rtw_memcpy(ndis_ssid.Ssid, (u8 *)params->ssid, params->ssid_len);
\r
3042 //DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, params->ssid_len);
\r
3044 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
3045 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
\r
3046 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
3047 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
\r
3048 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
3050 ret = rtw_cfg80211_set_auth_type(psecuritypriv, NL80211_AUTHTYPE_OPEN_SYSTEM);
\r
3051 rtw_set_802_11_authentication_mode(padapter, psecuritypriv->ndisauthtype);
\r
3053 DBG_871X("%s: center_freq = %d\n", __func__, pch->center_freq);
\r
3054 pmlmeext->cur_channel = rtw_freq2ch(pch->center_freq);
\r
3056 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE)
\r
3066 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
\r
3068 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3069 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
3070 enum nl80211_iftype old_type;
\r
3073 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3075 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
3077 old_type = rtw_wdev->iftype;
\r
3079 rtw_set_to_roam(padapter, 0);
\r
3081 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
3083 rtw_scan_abort(padapter);
\r
3084 LeaveAllPowerSaveMode(padapter);
\r
3086 rtw_wdev->iftype = NL80211_IFTYPE_STATION;
\r
3088 if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) ==_FALSE)
\r
3090 rtw_wdev->iftype = old_type;
\r
3094 rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure,_TRUE);
\r
3098 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3103 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
\r
3104 struct cfg80211_connect_params *sme)
\r
3109 struct wlan_network *pnetwork = NULL;
\r
3110 NDIS_802_11_AUTHENTICATION_MODE authmode;
\r
3111 NDIS_802_11_SSID ndis_ssid;
\r
3112 u8 *dst_ssid, *src_ssid;
\r
3113 u8 *dst_bssid, *src_bssid;
\r
3114 //u8 matched_by_bssid=_FALSE;
\r
3115 //u8 matched_by_ssid=_FALSE;
\r
3116 u8 matched=_FALSE;
\r
3117 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3118 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
3119 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3120 _queue *queue = &pmlmepriv->scanned_queue;
\r
3122 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
3124 DBG_871X("=>"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3125 DBG_871X("privacy=%d, key=%p, key_len=%d, key_idx=%d\n",
\r
3126 sme->privacy, sme->key, sme->key_len, sme->key_idx);
\r
3129 if(adapter_wdev_data(padapter)->block == _TRUE)
\r
3132 DBG_871X("%s wdev_priv.block is set\n", __FUNCTION__);
\r
3136 #ifdef CONFIG_PLATFORM_MSTAR_SCAN_BEFORE_CONNECT
\r
3137 printk("MStar Android!\n");
\r
3138 if(adapter_wdev_data(padapter)->bandroid_scan == _FALSE)
\r
3141 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
3142 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
3143 #endif //CONFIG_P2P
\r
3146 printk("Android hasn't attached yet!\n");
\r
3152 rtw_ps_deny(padapter, PS_DENY_JOIN);
\r
3153 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
3158 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
\r
3163 #ifdef CONFIG_CONCURRENT_MODE
\r
3164 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
\r
3165 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
\r
3169 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
\r
3170 rtw_scan_abort(padapter->pbuddy_adapter);
\r
3174 if (!sme->ssid || !sme->ssid_len)
\r
3180 if (sme->ssid_len > IW_ESSID_MAX_SIZE){
\r
3186 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
\r
3187 ndis_ssid.SsidLength = sme->ssid_len;
\r
3188 _rtw_memcpy(ndis_ssid.Ssid, (u8 *)sme->ssid, sme->ssid_len);
\r
3190 DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
\r
3194 DBG_8192C("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
\r
3197 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
3199 DBG_8192C("%s, fw_state=0x%x, goto exit\n", __FUNCTION__, pmlmepriv->fw_state);
\r
3202 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
\r
3203 rtw_scan_abort(padapter);
\r
3206 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
3207 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
\r
3208 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
3209 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
\r
3210 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
3212 #ifdef CONFIG_WAPI_SUPPORT
\r
3213 padapter->wapiInfo.bWapiEnable = false;
\r
3216 ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
\r
3220 #ifdef CONFIG_WAPI_SUPPORT
\r
3221 if(sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1)
\r
3223 padapter->wapiInfo.bWapiEnable = true;
\r
3224 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
\r
3225 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
\r
3229 ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
\r
3231 #ifdef CONFIG_WAPI_SUPPORT
\r
3232 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI)
\r
3233 padapter->mlmeextpriv.mlmext_info.auth_algo = psecuritypriv->dot11AuthAlgrthm;
\r
3240 DBG_8192C("%s, ie_len=%zu\n", __func__, sme->ie_len);
\r
3242 ret = rtw_cfg80211_set_wpa_ie(padapter, (u8 *)sme->ie, sme->ie_len);
\r
3246 if (sme->crypto.n_ciphers_pairwise) {
\r
3247 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
\r
3252 //For WEP Shared auth
\r
3253 if((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared
\r
3254 || psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && sme->key
\r
3257 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
3258 NDIS_802_11_WEP *pwep = NULL;
\r
3259 DBG_871X("%s(): Shared/Auto WEP\n",__FUNCTION__);
\r
3261 wep_key_idx = sme->key_idx;
\r
3262 wep_key_len = sme->key_len;
\r
3264 if (sme->key_idx > WEP_KEYS) {
\r
3269 if (wep_key_len > 0)
\r
3271 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
3272 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
\r
3273 pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
\r
3275 DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
\r
3280 _rtw_memset(pwep, 0, wep_total_len);
\r
3282 pwep->KeyLength = wep_key_len;
\r
3283 pwep->Length = wep_total_len;
\r
3285 if(wep_key_len==13)
\r
3287 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
\r
3288 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
\r
3296 pwep->KeyIndex = wep_key_idx;
\r
3297 pwep->KeyIndex |= 0x80000000;
\r
3299 _rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
\r
3301 if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
\r
3303 ret = -EOPNOTSUPP ;
\r
3307 rtw_mfree((u8 *)pwep,wep_total_len);
\r
3314 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
\r
3318 if (sme->crypto.n_akm_suites) {
\r
3319 ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
\r
3324 #ifdef CONFIG_WAPI_SUPPORT
\r
3325 if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_PSK){
\r
3326 padapter->wapiInfo.bWapiPSK = true;
\r
3328 else if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_CERT){
\r
3329 padapter->wapiInfo.bWapiPSK = false;
\r
3333 authmode = psecuritypriv->ndisauthtype;
\r
3334 rtw_set_802_11_authentication_mode(padapter, authmode);
\r
3336 //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
\r
3338 if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid) == _FALSE) {
\r
3343 DBG_8192C("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy);
\r
3347 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
\r
3349 DBG_8192C("<=%s, ret %d\n",__FUNCTION__, ret);
\r
3351 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3356 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
\r
3359 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3361 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3363 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
3365 rtw_set_to_roam(padapter, 0);
\r
3367 //if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
3369 rtw_scan_abort(padapter);
\r
3370 LeaveAllPowerSaveMode(padapter);
\r
3371 rtw_disassoc_cmd(padapter, 500, _FALSE);
\r
3373 DBG_871X("%s...call rtw_indicate_disconnect\n", __FUNCTION__);
\r
3375 rtw_indicate_disconnect(padapter);
\r
3377 rtw_free_assoc_resources(padapter, 1);
\r
3378 rtw_pwr_wakeup(padapter);
\r
3381 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3383 DBG_871X(FUNC_NDEV_FMT" return 0\n", FUNC_NDEV_ARG(ndev));
\r
3387 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
\r
3388 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
\r
3389 struct wireless_dev *wdev,
\r
3391 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE)
\r
3392 enum nl80211_tx_power_setting type, int mbm)
\r
3394 enum tx_power_setting type, int dbm)
\r
3398 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
\r
3402 case NL80211_TX_POWER_AUTOMATIC:
\r
3404 case NL80211_TX_POWER_FIXED:
\r
3405 if (mbm < 0 || (mbm % 100))
\r
3406 return -EOPNOTSUPP;
\r
3408 if (!test_bit(IWM_STATUS_READY, &iwm->status))
\r
3411 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
\r
3412 CFG_TX_PWR_LIMIT_USR,
\r
3413 MBM_TO_DBM(mbm) * 2);
\r
3417 return iwm_tx_power_trigger(iwm);
\r
3419 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
\r
3420 return -EOPNOTSUPP;
\r
3423 DBG_8192C("%s\n", __func__);
\r
3427 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
\r
3428 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
\r
3429 struct wireless_dev *wdev,
\r
3433 DBG_8192C("%s\n", __func__);
\r
3440 inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
\r
3442 struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter);
\r
3443 return rtw_wdev_priv->power_mgmt;
\r
3446 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
\r
3447 struct net_device *ndev,
\r
3448 bool enabled, int timeout)
\r
3450 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3451 struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter);
\r
3453 DBG_871X(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
\r
3454 enabled, timeout);
\r
3456 rtw_wdev_priv->power_mgmt = enabled;
\r
3460 LPS_Leave(padapter, "CFG80211_PWRMGMT");
\r
3466 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
\r
3467 struct net_device *ndev,
\r
3468 struct cfg80211_pmksa *pmksa)
\r
3470 u8 index,blInserted = _FALSE;
\r
3471 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3472 struct mlme_priv *mlme = &padapter->mlmepriv;
\r
3473 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3474 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
\r
3476 DBG_871X(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
\r
3477 , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
\r
3479 if ( _rtw_memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
\r
3484 if (check_fwstate(mlme, _FW_LINKED) == _FALSE) {
\r
3485 DBG_871X(FUNC_NDEV_FMT" not set pmksa cause not in linked state\n", FUNC_NDEV_ARG(ndev));
\r
3489 blInserted = _FALSE;
\r
3492 for(index=0 ; index<NUM_PMKID_CACHE; index++)
\r
3494 if( _rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) ==_TRUE )
\r
3495 { // BSSID is matched, the same AP => rewrite with new PMKID.
\r
3496 DBG_871X(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(ndev));
\r
3498 _rtw_memcpy( psecuritypriv->PMKIDList[index].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
\r
3499 psecuritypriv->PMKIDList[index].bUsed = _TRUE;
\r
3500 psecuritypriv->PMKIDIndex = index+1;
\r
3501 blInserted = _TRUE;
\r
3508 // Find a new entry
\r
3509 DBG_871X(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
\r
3510 FUNC_NDEV_ARG(ndev), psecuritypriv->PMKIDIndex );
\r
3512 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, (u8 *)pmksa->bssid, ETH_ALEN);
\r
3513 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
\r
3515 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
\r
3516 psecuritypriv->PMKIDIndex++ ;
\r
3517 if(psecuritypriv->PMKIDIndex==16)
\r
3519 psecuritypriv->PMKIDIndex =0;
\r
3526 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
\r
3527 struct net_device *ndev,
\r
3528 struct cfg80211_pmksa *pmksa)
\r
3530 u8 index, bMatched = _FALSE;
\r
3531 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3532 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3534 DBG_871X(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
\r
3535 , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
\r
3537 for(index=0 ; index<NUM_PMKID_CACHE; index++)
\r
3539 if( _rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) ==_TRUE )
\r
3540 { // BSSID is matched, the same AP => Remove this PMKID information and reset it.
\r
3541 _rtw_memset(psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN );
\r
3542 _rtw_memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN );
\r
3543 psecuritypriv->PMKIDList[index].bUsed = _FALSE;
\r
3545 DBG_871X(FUNC_NDEV_FMT" clear id:%hhu\n", FUNC_NDEV_ARG(ndev), index);
\r
3550 if(_FALSE == bMatched)
\r
3552 DBG_871X(FUNC_NDEV_FMT" do not have matched BSSID\n"
\r
3553 , FUNC_NDEV_ARG(ndev));
\r
3560 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
\r
3561 struct net_device *ndev)
\r
3563 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3564 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3566 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3568 _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
\r
3569 psecuritypriv->PMKIDIndex = 0;
\r
3574 #ifdef CONFIG_AP_MODE
\r
3575 void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
3579 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
3580 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3581 struct net_device *ndev = padapter->pnetdev;
\r
3583 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
3585 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
\r
3587 struct station_info sinfo;
\r
3589 if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
\r
3590 ie_offset = _ASOCREQ_IE_OFFSET_;
\r
3591 else // WIFI_REASSOCREQ
\r
3592 ie_offset = _REASOCREQ_IE_OFFSET_;
\r
3595 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
\r
3596 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
\r
3597 sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
\r
3598 cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
\r
3600 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3601 channel = pmlmeext->cur_channel;
\r
3602 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
3603 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
3605 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
3607 #ifdef COMPAT_KERNEL_RELEASE
\r
3608 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3609 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
3610 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3611 #else //COMPAT_KERNEL_RELEASE
\r
3613 //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc()
\r
3614 #ifndef CONFIG_PLATFORM_MSTAR
\r
3615 pwdev->iftype = NL80211_IFTYPE_STATION;
\r
3616 #endif //CONFIG_PLATFORM_MSTAR
\r
3617 DBG_8192C("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
\r
3618 rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
\r
3619 DBG_8192C("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
\r
3620 pwdev->iftype = NL80211_IFTYPE_AP;
\r
3621 //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3623 #endif //COMPAT_KERNEL_RELEASE
\r
3624 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3628 void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason)
\r
3634 struct rtw_ieee80211_hdr *pwlanhdr;
\r
3635 unsigned short *fctrl;
\r
3636 u8 mgmt_buf[128] = {0};
\r
3637 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3638 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
3639 struct net_device *ndev = padapter->pnetdev;
\r
3641 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
3643 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
\r
3644 cfg80211_del_sta(ndev, da, GFP_ATOMIC);
\r
3645 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3646 channel = pmlmeext->cur_channel;
\r
3647 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
3648 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
3650 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
3652 pmgmt_frame = mgmt_buf;
\r
3653 pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
\r
3655 fctrl = &(pwlanhdr->frame_ctl);
\r
3658 _rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN);
\r
3659 _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN);
\r
3660 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
3662 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
3663 pmlmeext->mgnt_seq++;
\r
3664 SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
\r
3666 pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
3667 frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
3669 reason = cpu_to_le16(reason);
\r
3670 pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
\r
3672 #ifdef COMPAT_KERNEL_RELEASE
\r
3673 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3674 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
3675 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3676 #else //COMPAT_KERNEL_RELEASE
\r
3677 cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len);
\r
3678 //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3679 #endif //COMPAT_KERNEL_RELEASE
\r
3680 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3683 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
\r
3687 DBG_8192C("%s\n", __func__);
\r
3692 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
\r
3696 DBG_8192C("%s\n", __func__);
\r
3701 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
\r
3706 int dot11_hdr_len = 24;
\r
3708 unsigned char *pdata;
\r
3710 unsigned char src_mac_addr[6];
\r
3711 unsigned char dst_mac_addr[6];
\r
3712 struct ieee80211_hdr *dot11_hdr;
\r
3713 struct ieee80211_radiotap_header *rtap_hdr;
\r
3714 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3716 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3719 rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
\r
3721 if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
\r
3724 rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
\r
3725 if (unlikely(rtap_hdr->it_version))
\r
3728 rtap_len = ieee80211_get_radiotap_len(skb->data);
\r
3729 if (unlikely(skb->len < rtap_len))
\r
3732 if(rtap_len != 14)
\r
3734 DBG_8192C("radiotap len (should be 14): %d\n", rtap_len);
\r
3738 /* Skip the ratio tap header */
\r
3739 skb_pull(skb, rtap_len);
\r
3741 dot11_hdr = (struct ieee80211_hdr *)skb->data;
\r
3742 frame_ctl = le16_to_cpu(dot11_hdr->frame_control);
\r
3743 /* Check if the QoS bit is set */
\r
3744 if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
\r
3745 /* Check if this ia a Wireless Distribution System (WDS) frame
\r
3746 * which has 4 MAC addresses
\r
3748 if (dot11_hdr->frame_control & 0x0080)
\r
3750 if ((dot11_hdr->frame_control & 0x0300) == 0x0300)
\r
3751 dot11_hdr_len += 6;
\r
3753 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
\r
3754 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
\r
3756 /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
\r
3757 * for two MAC addresses
\r
3759 skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
\r
3760 pdata = (unsigned char*)skb->data;
\r
3761 memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
\r
3762 memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
\r
3764 DBG_8192C("should be eapol packet\n");
\r
3766 /* Use the real net device to transmit the packet */
\r
3767 ret = _rtw_xmit_entry(skb, padapter->pnetdev);
\r
3772 else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE))
\r
3773 == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION)
\r
3776 //only for action frames
\r
3777 struct xmit_frame *pmgntframe;
\r
3778 struct pkt_attrib *pattrib;
\r
3779 unsigned char *pframe;
\r
3780 //u8 category, action, OUI_Subtype, dialogToken=0;
\r
3781 //unsigned char *frame_body;
\r
3782 struct rtw_ieee80211_hdr *pwlanhdr;
\r
3783 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
3784 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3785 u8 *buf = skb->data;
\r
3786 u32 len = skb->len;
\r
3787 u8 category, action;
\r
3790 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
\r
3791 DBG_8192C(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
\r
3792 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
\r
3796 DBG_8192C("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
\r
3797 MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
\r
3799 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0)
\r
3802 if (category == RTW_WLAN_CATEGORY_PUBLIC)
\r
3803 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
\r
3805 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
\r
3808 //starting alloc mgmt frame to dump it
\r
3809 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
3814 //update attribute
\r
3815 pattrib = &pmgntframe->attrib;
\r
3816 update_mgntframe_attrib(padapter, pattrib);
\r
3817 pattrib->retry_ctrl = _FALSE;
\r
3819 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
3821 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
3823 _rtw_memcpy(pframe, (void*)buf, len);
\r
3827 struct wifi_display_info *pwfd_info;
\r
3829 pwfd_info = padapter->wdinfo.wfd_info;
\r
3831 if ( _TRUE == pwfd_info->wfd_enable )
\r
3833 rtw_append_wfd_ie( padapter, pframe, &len );
\r
3836 #endif // CONFIG_WFD
\r
3837 pattrib->pktlen = len;
\r
3839 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
3840 //update seq number
\r
3841 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
\r
3842 pattrib->seqnum = pmlmeext->mgnt_seq;
\r
3843 pmlmeext->mgnt_seq++;
\r
3846 pattrib->last_txcmdsz = pattrib->pktlen;
\r
3848 dump_mgntframe(padapter, pmgntframe);
\r
3853 DBG_8192C("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE));
\r
3859 rtw_skb_free(skb);
\r
3865 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
\r
3867 DBG_8192C("%s\n", __func__);
\r
3870 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
\r
3874 DBG_8192C("%s\n", __func__);
\r
3879 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
\r
3880 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
\r
3881 .ndo_open = rtw_cfg80211_monitor_if_open,
\r
3882 .ndo_stop = rtw_cfg80211_monitor_if_close,
\r
3883 .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
\r
3884 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
\r
3885 .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
\r
3887 .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
\r
3891 static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
\r
3894 struct net_device* mon_ndev = NULL;
\r
3895 struct wireless_dev* mon_wdev = NULL;
\r
3896 struct rtw_netdev_priv_indicator *pnpi;
\r
3897 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
3900 DBG_871X(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
\r
3905 if (pwdev_priv->pmon_ndev) {
\r
3906 DBG_871X(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
\r
3907 FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
\r
3912 mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
\r
3914 DBG_871X(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
\r
3919 mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
\r
3920 strncpy(mon_ndev->name, name, IFNAMSIZ);
\r
3921 mon_ndev->name[IFNAMSIZ - 1] = 0;
\r
3922 mon_ndev->destructor = rtw_ndev_destructor;
\r
3924 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
\r
3925 mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
\r
3927 mon_ndev->open = rtw_cfg80211_monitor_if_open;
\r
3928 mon_ndev->stop = rtw_cfg80211_monitor_if_close;
\r
3929 mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry;
\r
3930 mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address;
\r
3933 pnpi = netdev_priv(mon_ndev);
\r
3934 pnpi->priv = padapter;
\r
3935 pnpi->sizeof_priv = sizeof(_adapter);
\r
3938 mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
\r
3940 DBG_871X(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
\r
3945 mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
\r
3946 mon_wdev->netdev = mon_ndev;
\r
3947 mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
\r
3948 mon_ndev->ieee80211_ptr = mon_wdev;
\r
3950 ret = register_netdevice(mon_ndev);
\r
3955 *ndev = pwdev_priv->pmon_ndev = mon_ndev;
\r
3956 _rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
\r
3959 if (ret && mon_wdev) {
\r
3960 rtw_mfree((u8*)mon_wdev, sizeof(struct wireless_dev));
\r
3964 if (ret && mon_ndev) {
\r
3965 free_netdev(mon_ndev);
\r
3966 *ndev = mon_ndev = NULL;
\r
3972 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3973 static struct wireless_dev *
\r
3974 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
3975 static struct net_device *
\r
3979 cfg80211_rtw_add_virtual_intf(
\r
3980 struct wiphy *wiphy,
\r
3981 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
\r
3986 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
\r
3989 struct net_device* ndev = NULL;
\r
3990 _adapter *padapter = wiphy_to_adapter(wiphy);
\r
3992 DBG_871X(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
\r
3993 FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
\r
3996 case NL80211_IFTYPE_ADHOC:
\r
3997 case NL80211_IFTYPE_AP_VLAN:
\r
3998 case NL80211_IFTYPE_WDS:
\r
3999 case NL80211_IFTYPE_MESH_POINT:
\r
4002 case NL80211_IFTYPE_MONITOR:
\r
4003 ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
\r
4006 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4007 case NL80211_IFTYPE_P2P_CLIENT:
\r
4009 case NL80211_IFTYPE_STATION:
\r
4013 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4014 case NL80211_IFTYPE_P2P_GO:
\r
4016 case NL80211_IFTYPE_AP:
\r
4021 DBG_871X("Unsupported interface type\n");
\r
4025 DBG_871X(FUNC_ADPT_FMT" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter), ndev, ret);
\r
4027 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4028 return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
\r
4029 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
4030 return ndev ? ndev : ERR_PTR(ret);
\r
4036 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
\r
4037 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4038 struct wireless_dev *wdev
\r
4040 struct net_device *ndev
\r
4044 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4045 struct net_device *ndev = wdev_to_ndev(wdev);
\r
4048 _adapter *adapter;
\r
4049 struct rtw_wdev_priv *pwdev_priv;
\r
4056 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4057 pwdev_priv = adapter_wdev_data(adapter);
\r
4059 unregister_netdevice(ndev);
\r
4061 if (ndev == pwdev_priv->pmon_ndev) {
\r
4062 pwdev_priv->pmon_ndev = NULL;
\r
4063 pwdev_priv->ifname_mon[0] = '\0';
\r
4064 DBG_871X(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev));
\r
4071 static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
\r
4075 uint len, wps_ielen=0;
\r
4078 u8 got_p2p_ie = _FALSE;
\r
4079 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
4080 //struct sta_priv *pstapriv = &padapter->stapriv;
\r
4083 DBG_8192C("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
\r
4086 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
\r
4093 pbuf = rtw_zmalloc(head_len+tail_len);
\r
4098 //_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
\r
4100 //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
\r
4101 // pstapriv->max_num_sta = NUM_STA;
\r
4104 _rtw_memcpy(pbuf, (void *)head+24, head_len-24);// 24=beacon header len.
\r
4105 _rtw_memcpy(pbuf+head_len-24, (void *)tail, tail_len);
\r
4107 len = head_len+tail_len-24;
\r
4109 //check wps ie if inclued
\r
4110 if(rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
\r
4111 DBG_8192C("add bcn, wps_ielen=%d\n", wps_ielen);
\r
4114 if( adapter->wdinfo.driver_interface == DRIVER_CFG80211 )
\r
4116 //check p2p if enable
\r
4117 if(rtw_get_p2p_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &p2p_ielen))
\r
4119 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
\r
4120 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
\r
4122 DBG_8192C("got p2p_ie, len=%d\n", p2p_ielen);
\r
4124 got_p2p_ie = _TRUE;
\r
4126 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4128 DBG_8192C("Enable P2P function for the first time\n");
\r
4129 rtw_p2p_enable(adapter, P2P_ROLE_GO);
\r
4130 adapter_wdev_data(adapter)->p2p_enabled = _TRUE;
\r
4132 adapter->stapriv.expire_to = 3; // 3x2 = 6 sec in p2p mode
\r
4136 DBG_8192C("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);
\r
4138 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
\r
4139 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
\r
4140 pwdinfo->intent = 15;
\r
4144 #endif // CONFIG_P2P
\r
4146 /* pbss_network->IEs will not include p2p_ie, wfd ie */
\r
4147 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
\r
4148 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
\r
4150 if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS)
\r
4152 #ifdef CONFIG_P2P
\r
4153 //check p2p if enable
\r
4154 if(got_p2p_ie == _TRUE)
\r
4156 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
\r
4157 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
\r
4158 pwdinfo->operating_channel = pmlmeext->cur_channel;
\r
4160 #endif //CONFIG_P2P
\r
4169 rtw_mfree(pbuf, head_len+tail_len);
\r
4174 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE)
\r
4175 static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4176 struct beacon_parameters *info)
\r
4179 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4181 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4182 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
\r
4187 static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4188 struct beacon_parameters *info)
\r
4190 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4191 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
4193 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4195 pmlmeext->bstart_bss = _TRUE;
\r
4197 cfg80211_rtw_add_beacon(wiphy, ndev, info);
\r
4202 static int cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
\r
4204 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4209 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
\r
4210 struct cfg80211_ap_settings *settings)
\r
4213 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4215 DBG_871X(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
\r
4216 settings->hidden_ssid, settings->auth_type);
\r
4218 ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
\r
4219 settings->beacon.tail, settings->beacon.tail_len);
\r
4221 adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
\r
4223 if (settings->ssid && settings->ssid_len) {
\r
4224 WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
\r
4225 WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
\r
4228 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%zu), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
\r
4229 settings->ssid, settings->ssid_len,
\r
4230 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
\r
4232 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
\r
4233 pbss_network->Ssid.SsidLength = settings->ssid_len;
\r
4234 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
\r
4235 pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
\r
4238 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
\r
4239 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
\r
4240 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
\r
4246 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4247 struct cfg80211_beacon_data *info)
\r
4250 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4252 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4254 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
\r
4259 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
\r
4261 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4265 #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
\r
4267 static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4268 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
4273 struct station_parameters *params)
\r
4276 #ifdef CONFIG_TDLS
\r
4277 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4278 struct sta_priv *pstapriv = &padapter->stapriv;
\r
4279 struct sta_info *psta;
\r
4280 #endif /* CONFIG_TDLS */
\r
4281 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4283 #ifdef CONFIG_TDLS
\r
4284 psta = rtw_get_stainfo(pstapriv, mac);
\r
4285 if (psta == NULL) {
\r
4286 psta = rtw_alloc_stainfo(pstapriv, mac);
\r
4287 if (psta ==NULL) {
\r
4288 DBG_871X("[%s] Alloc station for "MAC_FMT" fail\n", __FUNCTION__, MAC_ARG(mac));
\r
4293 #endif /* CONFIG_TDLS */
\r
4299 static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4300 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
4309 _list *phead, *plist;
\r
4310 u8 updated = _FALSE;
\r
4311 struct sta_info *psta = NULL;
\r
4312 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4313 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
4314 struct sta_priv *pstapriv = &padapter->stapriv;
\r
4316 DBG_871X("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4318 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
\r
4320 DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
\r
4327 DBG_8192C("flush all sta, and cam_entry\n");
\r
4329 flush_all_cam_entry(padapter); //clear CAM
\r
4331 ret = rtw_sta_flush(padapter);
\r
4337 DBG_8192C("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
\r
4339 if (mac[0] == 0xff && mac[1] == 0xff &&
\r
4340 mac[2] == 0xff && mac[3] == 0xff &&
\r
4341 mac[4] == 0xff && mac[5] == 0xff)
\r
4347 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4349 phead = &pstapriv->asoc_list;
\r
4350 plist = get_next(phead);
\r
4352 //check asoc_queue
\r
4353 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
4355 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
4357 plist = get_next(plist);
\r
4359 if(_rtw_memcmp((u8 *)mac, psta->hwaddr, ETH_ALEN))
\r
4361 if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE)
\r
4363 DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
\r
4367 DBG_8192C("free psta=%p, aid=%d\n", psta, psta->aid);
\r
4369 rtw_list_delete(&psta->asoc_list);
\r
4370 pstapriv->asoc_list_cnt--;
\r
4372 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4373 if (check_fwstate(pmlmepriv, (WIFI_AP_STATE)) == _TRUE)
\r
4374 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID);
\r
4376 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
\r
4377 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4388 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4390 associated_clients_update(padapter, updated);
\r
4392 DBG_871X("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4398 static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4399 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
4404 struct station_parameters *params)
\r
4406 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4411 struct sta_info *rtw_sta_info_get_by_idx(const int idx, struct sta_priv *pstapriv)
\r
4414 _list *phead, *plist;
\r
4415 struct sta_info *psta = NULL;
\r
4418 phead = &pstapriv->asoc_list;
\r
4419 plist = get_next(phead);
\r
4421 //check asoc_queue
\r
4422 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
4424 if(idx == i) psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
4425 plist = get_next(plist);
\r
4431 static int cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4432 int idx, u8 *mac, struct station_info *sinfo)
\r
4437 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4438 struct sta_info *psta = NULL;
\r
4439 struct sta_priv *pstapriv = &padapter->stapriv;
\r
4440 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4442 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4443 psta = rtw_sta_info_get_by_idx(idx, pstapriv);
\r
4444 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4447 DBG_871X("Station is not found\n");
\r
4451 _rtw_memcpy(mac, psta->hwaddr, ETH_ALEN);
\r
4452 sinfo->filled = 0;
\r
4453 sinfo->filled |= STATION_INFO_SIGNAL;
\r
4454 sinfo->signal = psta->rssi;
\r
4460 static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
\r
4461 struct bss_parameters *params)
\r
4465 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4467 DBG_8192C("use_cts_prot=%d\n", params->use_cts_prot);
\r
4468 DBG_8192C("use_short_preamble=%d\n", params->use_short_preamble);
\r
4469 DBG_8192C("use_short_slot_time=%d\n", params->use_short_slot_time);
\r
4470 DBG_8192C("ap_isolate=%d\n", params->ap_isolate);
\r
4472 DBG_8192C("basic_rates_len=%d\n", params->basic_rates_len);
\r
4473 for(i=0; i<params->basic_rates_len; i++)
\r
4475 DBG_8192C("basic_rates=%d\n", params->basic_rates[i]);
\r
4483 static int cfg80211_rtw_set_channel(struct wiphy *wiphy
\r
4484 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
\r
4485 , struct net_device *ndev
\r
4487 , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
\r
4489 int chan_target = (u8) ieee80211_frequency_to_channel(chan->center_freq);
\r
4490 int chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4491 int chan_width = CHANNEL_WIDTH_20;
\r
4492 _adapter *padapter = wiphy_to_adapter(wiphy);
\r
4494 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
\r
4495 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4498 switch (channel_type) {
\r
4499 case NL80211_CHAN_NO_HT:
\r
4500 case NL80211_CHAN_HT20:
\r
4501 chan_width = CHANNEL_WIDTH_20;
\r
4502 chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4504 case NL80211_CHAN_HT40MINUS:
\r
4505 chan_width = CHANNEL_WIDTH_40;
\r
4506 chan_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
\r
4508 case NL80211_CHAN_HT40PLUS:
\r
4509 chan_width = CHANNEL_WIDTH_40;
\r
4510 chan_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
\r
4513 chan_width = CHANNEL_WIDTH_20;
\r
4514 chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4518 set_channel_bwmode(padapter, chan_target, chan_offset, chan_width);
\r
4523 static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
\r
4524 struct cfg80211_auth_request *req)
\r
4526 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4531 static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
\r
4532 struct cfg80211_assoc_request *req)
\r
4534 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4538 #endif //CONFIG_AP_MODE
\r
4540 void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
4545 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4546 u8 category, action;
\r
4548 channel = rtw_get_oper_ch(padapter);
\r
4550 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4552 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
\r
4556 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
\r
4557 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4560 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4561 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4563 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4565 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4566 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4568 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4572 void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
4577 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4578 u8 category, action;
\r
4580 channel = rtw_get_oper_ch(padapter);
\r
4582 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4584 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
\r
4587 case P2P_GO_NEGO_CONF:
\r
4588 case P2P_PROVISION_DISC_RESP:
\r
4589 case P2P_INVIT_RESP:
\r
4590 rtw_set_scan_deny(padapter, 2000);
\r
4591 rtw_clear_scan_deny(padapter);
\r
4596 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
\r
4597 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4600 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4601 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4603 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4605 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4606 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4608 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4612 void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg)
\r
4616 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
4617 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
4618 u8 category, action;
\r
4620 channel = rtw_get_oper_ch(adapter);
\r
4622 rtw_action_frame_parse(frame, frame_len, &category, &action);
\r
4624 if (action == ACT_PUBLIC_GAS_INITIAL_REQ) {
\r
4625 rtw_set_scan_deny(adapter, 200);
\r
4626 rtw_scan_abort_no_wait(adapter);
\r
4627 #ifdef CONFIG_CONCURRENT_MODE
\r
4628 if (rtw_buddy_adapter_up(adapter))
\r
4629 rtw_scan_abort_no_wait(adapter->pbuddy_adapter);
\r
4633 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4634 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4636 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4638 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4639 rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
\r
4641 cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
\r
4644 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4646 DBG_871X("RTW_Rx:%s\n", msg);
\r
4648 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4652 void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
\r
4654 u16 wps_devicepassword_id = 0x0000;
\r
4655 uint wps_devicepassword_id_len = 0;
\r
4656 u8 wpsie[ 255 ] = { 0x00 }, p2p_ie[ 255 ] = { 0x00 };
\r
4657 uint p2p_ielen = 0;
\r
4658 uint wpsielen = 0;
\r
4659 u32 devinfo_contentlen = 0;
\r
4660 u8 devinfo_content[64] = { 0x00 };
\r
4661 u16 capability = 0;
\r
4662 uint capability_len = 0;
\r
4664 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
\r
4665 u8 action = P2P_PUB_ACTION_ACTION;
\r
4666 u8 dialogToken = 1;
\r
4667 u32 p2poui = cpu_to_be32(P2POUI);
\r
4668 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
\r
4672 #endif //CONFIG_WFD
\r
4674 struct xmit_frame *pmgntframe;
\r
4675 struct pkt_attrib *pattrib;
\r
4676 unsigned char *pframe;
\r
4677 struct rtw_ieee80211_hdr *pwlanhdr;
\r
4678 unsigned short *fctrl;
\r
4679 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
4680 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4681 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
4683 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
\r
4684 u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
\r
4685 size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4688 DBG_871X( "[%s] In\n", __FUNCTION__ );
\r
4690 //prepare for building provision_request frame
\r
4691 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
\r
4692 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
\r
4694 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
\r
4696 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
\r
4697 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
\r
4698 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
\r
4700 switch(wps_devicepassword_id)
\r
4702 case WPS_DPID_PIN:
\r
4703 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
\r
4705 case WPS_DPID_USER_SPEC:
\r
4706 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
\r
4708 case WPS_DPID_MACHINE_SPEC:
\r
4710 case WPS_DPID_REKEY:
\r
4712 case WPS_DPID_PBC:
\r
4713 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
\r
4715 case WPS_DPID_REGISTRAR_SPEC:
\r
4716 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
\r
4723 if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) )
\r
4726 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);
\r
4727 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&capability, &capability_len);
\r
4732 //start to build provision_request frame
\r
4733 _rtw_memset(wpsie, 0, sizeof(wpsie));
\r
4734 _rtw_memset(p2p_ie, 0, sizeof(p2p_ie));
\r
4737 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
4743 //update attribute
\r
4744 pattrib = &pmgntframe->attrib;
\r
4745 update_mgntframe_attrib(padapter, pattrib);
\r
4747 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
4749 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
4750 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
4752 fctrl = &(pwlanhdr->frame_ctl);
\r
4755 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
\r
4756 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
\r
4757 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
\r
4759 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
4760 pmlmeext->mgnt_seq++;
\r
4761 SetFrameSubType(pframe, WIFI_ACTION);
\r
4763 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4764 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4766 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
4767 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
4768 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
\r
4769 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
\r
4770 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
\r
4773 //build_prov_disc_request_p2p_ie
\r
4776 p2p_ie[ p2pielen++ ] = 0x50;
\r
4777 p2p_ie[ p2pielen++ ] = 0x6F;
\r
4778 p2p_ie[ p2pielen++ ] = 0x9A;
\r
4779 p2p_ie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
\r
4781 // Commented by Albert 20110301
\r
4782 // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
\r
4783 // 1. P2P Capability
\r
4785 // 3. Group ID ( When joining an operating P2P Group )
\r
4787 // P2P Capability ATTR
\r
4789 p2p_ie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
\r
4792 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
\r
4793 RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
\r
4797 // Device Capability Bitmap, 1 byte
\r
4798 // Group Capability Bitmap, 1 byte
\r
4799 _rtw_memcpy(p2p_ie + p2pielen, &capability, 2);
\r
4803 // Device Info ATTR
\r
4805 p2p_ie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
\r
4808 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
\r
4809 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
\r
4810 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
\r
4811 RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
\r
4815 _rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
\r
4816 p2pielen += devinfo_contentlen;
\r
4819 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);
\r
4820 //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr);
\r
4821 //pframe += p2pielen;
\r
4822 pattrib->pktlen += p2p_ielen;
\r
4826 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
\r
4831 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
\r
4835 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
\r
4839 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
\r
4843 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
\r
4847 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
\r
4851 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
\r
4854 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
\r
4858 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
\r
4859 pframe += wfdielen;
\r
4860 pattrib->pktlen += wfdielen;
\r
4861 #endif //CONFIG_WFD
\r
4863 pattrib->last_txcmdsz = pattrib->pktlen;
\r
4865 //dump_mgntframe(padapter, pmgntframe);
\r
4866 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
\r
4867 DBG_8192C("%s, ack to\n", __func__);
\r
4869 //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
\r
4871 // DBG_8192C("waiting for p2p peer key-in PIN CODE\n");
\r
4872 // rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req.
\r
4877 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
\r
4878 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4879 struct wireless_dev *wdev,
\r
4881 struct net_device *ndev,
\r
4883 struct ieee80211_channel * channel,
\r
4884 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
4885 enum nl80211_channel_type channel_type,
\r
4887 unsigned int duration, u64 *cookie)
\r
4889 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4890 struct net_device *ndev = wdev_to_ndev(wdev);
\r
4893 u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
\r
4894 u8 ready_on_channel = _FALSE;
\r
4895 _adapter *padapter;
\r
4896 struct rtw_wdev_priv *pwdev_priv;
\r
4897 struct mlme_ext_priv *pmlmeext;
\r
4898 struct wifidirect_info *pwdinfo;
\r
4899 struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
\r
4900 u8 is_p2p_find = _FALSE;
\r
4902 #ifndef CONFIG_RADIO_WORK
\r
4903 #define RTW_ROCH_DURATION_ENLARGE
\r
4904 #define RTW_ROCH_BACK_OP
\r
4907 if (ndev == NULL) {
\r
4911 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4912 pwdev_priv = adapter_wdev_data(padapter);
\r
4913 pmlmeext = &padapter->mlmeextpriv;
\r
4914 pwdinfo = &padapter->wdinfo;
\r
4915 pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
4916 #ifdef CONFIG_CONCURRENT_MODE
\r
4917 is_p2p_find=(duration < (pwdinfo->ext_listen_interval))? _TRUE : _FALSE;
\r
4920 *cookie = ATOMIC_INC_RETURN(&pcfg80211_wdinfo->ro_ch_cookie_gen);
\r
4922 DBG_871X(FUNC_ADPT_FMT" ch:%u duration:%d, cookie:0x%llx\n", FUNC_ADPT_ARG(padapter), remain_ch, duration, *cookie);
\r
4924 if(pcfg80211_wdinfo->is_ro_ch == _TRUE)
\r
4926 DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
4927 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
4928 #ifdef CONFIG_CONCURRENT_MODE
\r
4929 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
4930 #endif //CONFIG_CONCURRENT_MODE
\r
4931 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
\r
4934 pcfg80211_wdinfo->is_ro_ch = _TRUE;
\r
4935 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
4937 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
4942 _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
\r
4943 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
4944 pcfg80211_wdinfo->remain_on_ch_type= channel_type;
\r
4946 pcfg80211_wdinfo->remain_on_ch_cookie= *cookie;
\r
4948 rtw_scan_abort(padapter);
\r
4949 #ifdef CONFIG_CONCURRENT_MODE
\r
4950 if ((rtw_buddy_adapter_up(padapter)) && is_p2p_find) //don't scan_abort during p2p_listen.
\r
4951 rtw_scan_abort(padapter->pbuddy_adapter);
\r
4952 #endif //CONFIG_CONCURRENT_MODE
\r
4954 if (check_fwstate(&padapter->mlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
\r
4956 DBG_871X("mlme state:0x%x\n", get_fwstate(&padapter->mlmepriv));
\r
4957 remain_ch = padapter->mlmeextpriv.cur_channel;
\r
4959 #ifdef CONFIG_CONCURRENT_MODE
\r
4960 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
\r
4962 DBG_871X("buddy_intf's mlme state:0x%x\n", get_fwstate(&(padapter->pbuddy_adapter->mlmepriv)));
\r
4963 remain_ch = padapter->pbuddy_adapter->mlmeextpriv.cur_channel;
\r
4965 #endif /* CONFIG_CONCURRENT_MODE */
\r
4967 //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
4968 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4970 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
\r
4971 adapter_wdev_data(padapter)->p2p_enabled = _TRUE;
\r
4972 padapter->wdinfo.listen_channel = remain_ch;
\r
4976 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
4977 #ifdef CONFIG_DEBUG_CFG80211
\r
4978 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
4983 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
\r
4985 #ifdef RTW_ROCH_DURATION_ENLARGE
\r
4986 if (duration < 400)
\r
4987 duration = duration * 3; /* extend from exper */
\r
4990 #ifdef RTW_ROCH_BACK_OP
\r
4991 #ifdef CONFIG_CONCURRENT_MODE
\r
4992 if (check_buddy_fwstate(padapter, _FW_LINKED)) {
\r
4993 if (is_p2p_find) /* p2p_find , duration<1000 */
\r
4994 duration = duration + pwdinfo->ext_listen_interval;
\r
4995 else /* p2p_listen, duration=5000 */
\r
4996 duration = pwdinfo->ext_listen_interval + (pwdinfo->ext_listen_interval / 4);
\r
4999 #endif /* RTW_ROCH_BACK_OP */
\r
5001 pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter);
\r
5003 if(rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) >= 0) {
\r
5004 #ifdef CONFIG_CONCURRENT_MODE
\r
5005 if ( check_buddy_fwstate(padapter, _FW_LINKED) )
\r
5007 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
\r
5008 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
5010 if((remain_ch != pbuddy_mlmeext->cur_channel) && !check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
5012 if(ATOMIC_READ(&pwdev_priv->switch_ch_to)==1 ||
\r
5013 (remain_ch != pmlmeext->cur_channel))
\r
5015 if (check_buddy_fwstate(padapter, WIFI_FW_STATION_STATE)) {
\r
5016 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
\r
5017 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
\r
5020 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
\r
5022 #ifdef RTW_ROCH_BACK_OP
\r
5023 DBG_8192C("%s, set switch ch timer, duration=%d\n", __func__, duration-pwdinfo->ext_listen_interval);
\r
5024 _set_timer(&pwdinfo->ap_p2p_switch_timer, duration-pwdinfo->ext_listen_interval);
\r
5029 ready_on_channel = _TRUE;
\r
5030 //pmlmeext->cur_channel = remain_ch;
\r
5031 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5033 #endif //CONFIG_CONCURRENT_MODE
\r
5034 if(remain_ch != rtw_get_oper_ch(padapter) )
\r
5036 ready_on_channel = _TRUE;
\r
5037 //pmlmeext->cur_channel = remain_ch;
\r
5038 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5041 DBG_871X("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__, remain_ch);
\r
5045 //call this after other things have been done
\r
5046 #ifdef CONFIG_CONCURRENT_MODE
\r
5047 if(ATOMIC_READ(&pwdev_priv->ro_ch_to)==1 ||
\r
5048 (remain_ch != rtw_get_oper_ch(padapter)))
\r
5050 u8 co_channel = 0xff;
\r
5051 ATOMIC_SET(&pwdev_priv->ro_ch_to, 0);
\r
5054 if(ready_on_channel == _TRUE)
\r
5056 if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) )
\r
5058 pmlmeext->cur_channel = remain_ch;
\r
5060 #ifdef CONFIG_CONCURRENT_MODE
\r
5061 co_channel = rtw_get_oper_ch(padapter);
\r
5063 if(co_channel !=remain_ch)
\r
5066 //if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic)
\r
5067 set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5071 DBG_8192C("%s, set ro ch timer, duration=%d\n", __func__, duration);
\r
5072 _set_timer( &pcfg80211_wdinfo->remain_on_ch_timer, duration);
\r
5074 #ifdef CONFIG_CONCURRENT_MODE
\r
5078 rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type, duration, GFP_KERNEL);
\r
5082 pcfg80211_wdinfo->is_ro_ch = _FALSE;
\r
5083 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
5089 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
\r
5090 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5091 struct wireless_dev *wdev,
\r
5093 struct net_device *ndev,
\r
5097 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5098 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5101 _adapter *padapter;
\r
5102 struct rtw_wdev_priv *pwdev_priv;
\r
5103 struct wifidirect_info *pwdinfo;
\r
5104 struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
\r
5106 if (ndev == NULL) {
\r
5111 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5112 pwdev_priv = adapter_wdev_data(padapter);
\r
5113 pwdinfo = &padapter->wdinfo;
\r
5114 pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
5116 DBG_871X(FUNC_ADPT_FMT" cookie:0x%llx\n", FUNC_ADPT_ARG(padapter), cookie);
\r
5118 if (pcfg80211_wdinfo->is_ro_ch == _TRUE) {
\r
5119 DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
5120 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
5121 #ifdef CONFIG_CONCURRENT_MODE
\r
5122 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
5124 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
\r
5128 // Disable P2P Listen State
\r
5129 if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
5131 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
5133 rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
\r
5134 _rtw_memset(pwdinfo, 0x00, sizeof(struct wifidirect_info));
\r
5140 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
5141 #ifdef CONFIG_DEBUG_CFG80211
\r
5142 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
5146 pcfg80211_wdinfo->is_ro_ch = _FALSE;
\r
5147 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
5153 #endif //CONFIG_P2P
\r
5155 static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, const u8 *buf, size_t len)
\r
5157 struct xmit_frame *pmgntframe;
\r
5158 struct pkt_attrib *pattrib;
\r
5159 unsigned char *pframe;
\r
5162 struct rtw_ieee80211_hdr *pwlanhdr;
\r
5163 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
5164 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
5165 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5166 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
5168 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
\r
5169 #endif //CONFIG_P2P
\r
5170 //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
5172 rtw_set_scan_deny(padapter, 1000);
\r
5174 rtw_scan_abort(padapter);
\r
5175 #ifdef CONFIG_CONCURRENT_MODE
\r
5176 if(rtw_buddy_adapter_up(padapter))
\r
5177 rtw_scan_abort(padapter->pbuddy_adapter);
\r
5178 #endif /* CONFIG_CONCURRENT_MODE */
\r
5180 if (padapter->cfg80211_wdinfo.is_ro_ch == _TRUE) {
\r
5181 //DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
5182 //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
5183 //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE;
\r
5184 #ifdef CONFIG_CONCURRENT_MODE
\r
5185 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5187 DBG_8192C("%s, extend ro ch time\n", __func__);
\r
5188 _set_timer( &padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
\r
5190 #endif //CONFIG_CONCURRENT_MODE
\r
5192 #endif //CONFIG_P2P
\r
5193 #ifdef CONFIG_CONCURRENT_MODE
\r
5194 if (check_buddy_fwstate(padapter, _FW_LINKED )) {
\r
5195 u8 co_channel=0xff;
\r
5196 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
\r
5197 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
5199 co_channel = rtw_get_oper_ch(padapter);
\r
5201 if (tx_ch != pbuddy_mlmeext->cur_channel) {
\r
5203 u16 ext_listen_period;
\r
5205 if (ATOMIC_READ(&pwdev_priv->switch_ch_to)==1) {
\r
5206 if (check_buddy_fwstate(padapter, WIFI_FW_STATION_STATE)) {
\r
5207 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
\r
5208 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
\r
5211 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
\r
5213 //DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
\r
5214 //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
\r
5217 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5219 ext_listen_period = 500;// 500ms
\r
5223 ext_listen_period = pwdinfo->ext_listen_period;
\r
5226 DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period);
\r
5227 _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period);
\r
5231 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5232 pmlmeext->cur_channel = tx_ch;
\r
5234 if (tx_ch != co_channel)
\r
5235 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5237 #endif //CONFIG_CONCURRENT_MODE
\r
5238 //if (tx_ch != pmlmeext->cur_channel) {
\r
5239 if(tx_ch != rtw_get_oper_ch(padapter)) {
\r
5240 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5241 pmlmeext->cur_channel = tx_ch;
\r
5242 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5245 //starting alloc mgmt frame to dump it
\r
5246 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
5253 //update attribute
\r
5254 pattrib = &pmgntframe->attrib;
\r
5255 update_mgntframe_attrib(padapter, pattrib);
\r
5256 pattrib->retry_ctrl = _FALSE;
\r
5258 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
5260 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
5262 _rtw_memcpy(pframe, (void*)buf, len);
\r
5263 pattrib->pktlen = len;
\r
5265 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
5266 //update seq number
\r
5267 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
\r
5268 pattrib->seqnum = pmlmeext->mgnt_seq;
\r
5269 pmlmeext->mgnt_seq++;
\r
5273 struct wifi_display_info *pwfd_info;
\r
5275 pwfd_info = padapter->wdinfo.wfd_info;
\r
5277 if ( _TRUE == pwfd_info->wfd_enable )
\r
5279 rtw_append_wfd_ie( padapter, pframe, &pattrib->pktlen );
\r
5282 #endif // CONFIG_WFD
\r
5284 pattrib->last_txcmdsz = pattrib->pktlen;
\r
5286 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
\r
5291 #ifdef CONFIG_DEBUG_CFG80211
\r
5292 DBG_8192C("%s, ack == _FAIL\n", __func__);
\r
5298 #ifdef CONFIG_XMIT_ACK
\r
5299 rtw_msleep_os(50);
\r
5301 #ifdef CONFIG_DEBUG_CFG80211
\r
5302 DBG_8192C("%s, ack=%d, ok!\n", __func__, ack);
\r
5309 #ifdef CONFIG_DEBUG_CFG80211
\r
5310 DBG_8192C("%s, ret=%d\n", __func__, ret);
\r
5317 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
\r
5318 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5319 struct wireless_dev *wdev,
\r
5321 struct net_device *ndev,
\r
5323 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) || defined(COMPAT_KERNEL_RELEASE)
\r
5324 struct ieee80211_channel *chan,
\r
5325 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
5328 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5329 enum nl80211_channel_type channel_type,
\r
5330 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5331 bool channel_type_valid,
\r
5334 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
5335 unsigned int wait,
\r
5337 const u8 *buf, size_t len,
\r
5338 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5341 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
\r
5342 bool dont_wait_for_ack,
\r
5345 struct cfg80211_mgmt_tx_params *params,
\r
5349 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5350 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5352 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) || defined(COMPAT_KERNEL_RELEASE)
\r
5353 struct ieee80211_channel *chan = params->chan;
\r
5354 bool offchan = params->offchan;
\r
5355 unsigned int wait = params->wait;
\r
5356 const u8 *buf = params->buf;
\r
5357 size_t len = params->len;
\r
5358 bool no_cck = params->no_cck;
\r
5359 bool dont_wait_for_ack = params->dont_wait_for_ack;
\r
5363 u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
\r
5366 u8 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
\r
5367 u8 category, action;
\r
5369 u32 start = rtw_get_current_time();
\r
5370 _adapter *padapter;
\r
5371 struct rtw_wdev_priv *pwdev_priv;
\r
5373 if (ndev == NULL) {
\r
5378 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5379 pwdev_priv = adapter_wdev_data(padapter);
\r
5381 /* cookie generation */
\r
5382 *cookie = (unsigned long) buf;
\r
5384 #ifdef CONFIG_DEBUG_CFG80211
\r
5385 DBG_871X(FUNC_ADPT_FMT" len=%zu, ch=%d"
\r
5386 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5388 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5389 ", channel_type_valid=%d"
\r
5392 "\n", FUNC_ADPT_ARG(padapter),
\r
5394 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5396 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5397 , channel_type_valid
\r
5401 #endif /* CONFIG_DEBUG_CFG80211 */
\r
5403 /* indicate ack before issue frame to avoid racing with rsp frame */
\r
5404 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5405 rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL);
\r
5406 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
\r
5407 cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
\r
5410 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
\r
5411 DBG_8192C(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
\r
5412 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
\r
5416 DBG_8192C("RTW_Tx:tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
\r
5418 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0) {
\r
5422 if (category == RTW_WLAN_CATEGORY_PUBLIC)
\r
5423 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
\r
5425 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
\r
5429 rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
\r
5430 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
5432 goto cancel_ps_deny;
\r
5437 u32 retry_guarantee_ms = 0;
\r
5440 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
\r
5443 case ACT_PUBLIC_GAS_INITIAL_REQ:
\r
5444 case ACT_PUBLIC_GAS_INITIAL_RSP:
\r
5446 retry_guarantee_ms = RTW_MAX_MGMT_TX_MS_GAS;
\r
5449 if (tx_ret == _SUCCESS
\r
5450 || (dump_cnt >= dump_limit && rtw_get_passing_time_ms(start) >= retry_guarantee_ms))
\r
5454 rtw_msleep_os(sleep_ms);
\r
5457 if (tx_ret != _SUCCESS || dump_cnt > 1) {
\r
5458 DBG_871X(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
\r
5459 tx_ret==_SUCCESS?"OK":"FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
\r
5463 case P2P_GO_NEGO_CONF:
\r
5464 rtw_clear_scan_deny(padapter);
\r
5466 case P2P_INVIT_RESP:
\r
5467 if (pwdev_priv->invit_info.flags & BIT(0)
\r
5468 && pwdev_priv->invit_info.status == 0)
\r
5470 DBG_871X(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
\r
5471 FUNC_ADPT_ARG(padapter));
\r
5472 rtw_set_scan_deny(padapter, 5000);
\r
5473 rtw_pwr_wakeup_ex(padapter, 5000);
\r
5474 rtw_clear_scan_deny(padapter);
\r
5480 rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
\r
5485 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
\r
5486 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
\r
5487 struct wireless_dev *wdev,
\r
5489 struct net_device *ndev,
\r
5491 u16 frame_type, bool reg)
\r
5493 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5494 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5496 _adapter *adapter;
\r
5501 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5503 #ifdef CONFIG_DEBUG_CFG80211
\r
5504 DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
\r
5508 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
\r
5514 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5515 static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy,
\r
5516 struct net_device *ndev,
\r
5524 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5525 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
5526 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
\r
5528 struct tdls_txmgmt txmgmt;
\r
5530 if (rtw_tdls_is_driver_setup(padapter)) {
\r
5531 DBG_871X("Discard tdls action:%d, let driver to set up direct link\n", action_code);
\r
5535 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
5536 _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
\r
5537 txmgmt.action_code = action_code;
\r
5538 txmgmt.dialog_token= dialog_token;
\r
5539 txmgmt.status_code = status_code;
\r
5541 txmgmt.buf = (u8 *)rtw_malloc(txmgmt.len);
\r
5542 if (txmgmt.buf == NULL) {
\r
5546 _rtw_memcpy(txmgmt.buf, (void*)buf, txmgmt.len);
\r
5548 /* Debug purpose */
\r
5550 DBG_871X("%s %d\n", __FUNCTION__, __LINE__);
\r
5551 DBG_871X("peer:"MAC_FMT", action code:%d, dialog:%d, status code:%d\n",
\r
5552 MAC_ARG(txmgmt.peer), txmgmt.action_code,
\r
5553 txmgmt.dialog_token, txmgmt.status_code);
\r
5554 if (txmgmt.len > 0) {
\r
5556 for(;i < len; i++)
\r
5557 printk("%02x ", *(txmgmt.buf+i));
\r
5558 DBG_871X("len:%d\n", txmgmt.len);
\r
5562 switch (txmgmt.action_code) {
\r
5563 case TDLS_SETUP_REQUEST:
\r
5564 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5566 case TDLS_SETUP_RESPONSE:
\r
5567 issue_tdls_setup_rsp(padapter, &txmgmt);
\r
5569 case TDLS_SETUP_CONFIRM:
\r
5570 issue_tdls_setup_cfm(padapter, &txmgmt);
\r
5572 case TDLS_TEARDOWN:
\r
5573 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
\r
5575 case TDLS_DISCOVERY_REQUEST:
\r
5576 issue_tdls_dis_req(padapter, &txmgmt);
\r
5578 case TDLS_DISCOVERY_RESPONSE:
\r
5579 issue_tdls_dis_rsp(padapter, &txmgmt, pmlmeinfo->enc_algo? _TRUE : _FALSE);
\r
5585 rtw_mfree(txmgmt.buf, txmgmt.len);
\r
5591 static int cfg80211_rtw_tdls_oper(struct wiphy *wiphy,
\r
5592 struct net_device *ndev,
\r
5594 enum nl80211_tdls_operation oper)
\r
5596 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5597 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
5598 struct tdls_txmgmt txmgmt;
\r
5599 struct sta_info *ptdls_sta = NULL;
\r
5601 DBG_871X(FUNC_NDEV_FMT", nl80211_tdls_operation:%d\n", FUNC_NDEV_ARG(ndev), oper);
\r
5604 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1);
\r
5605 #endif //CONFIG_LPS
\r
5607 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
5609 _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
\r
5611 if (rtw_tdls_is_driver_setup(padapter)) {
\r
5612 /* these two cases are done by driver itself */
\r
5613 if (oper == NL80211_TDLS_ENABLE_LINK || oper == NL80211_TDLS_DISABLE_LINK)
\r
5618 case NL80211_TDLS_DISCOVERY_REQ:
\r
5619 issue_tdls_dis_req(padapter, &txmgmt);
\r
5621 case NL80211_TDLS_SETUP:
\r
5623 if ( _AES_ != padapter->securitypriv.dot11PrivacyAlgrthm ) {
\r
5624 if ( padapter->wdinfo.wfd_tdls_weaksec == _TRUE)
\r
5625 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5627 DBG_871X( "[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__ );
\r
5629 #endif // CONFIG_WFD
\r
5631 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5634 case NL80211_TDLS_TEARDOWN:
\r
5635 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), txmgmt.peer);
\r
5636 if (ptdls_sta != NULL) {
\r
5637 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
\r
5638 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
\r
5640 DBG_871X( "TDLS peer not found\n");
\r
5643 case NL80211_TDLS_ENABLE_LINK:
\r
5644 DBG_871X(FUNC_NDEV_FMT", NL80211_TDLS_ENABLE_LINK;mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(peer));
\r
5645 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), peer);
\r
5646 if (ptdls_sta != NULL) {
\r
5647 ptdlsinfo->link_established = _TRUE;
\r
5648 ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE;
\r
5649 ptdls_sta->state |= _FW_LINKED;
\r
5650 rtw_tdls_cmd(padapter, txmgmt.peer, TDLS_ESTABLISHED);
\r
5653 case NL80211_TDLS_DISABLE_LINK:
\r
5654 DBG_871X(FUNC_NDEV_FMT", NL80211_TDLS_DISABLE_LINK;mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(peer));
\r
5655 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), peer);
\r
5656 if (ptdls_sta != NULL) {
\r
5657 rtw_tdls_cmd(padapter, peer, TDLS_TEAR_STA );
\r
5663 #endif /* CONFIG_TDLS */
\r
5665 #if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
5666 static int cfg80211_rtw_sched_scan_start(struct wiphy *wiphy,
\r
5667 struct net_device *dev,
\r
5668 struct cfg80211_sched_scan_request *request) {
\r
5670 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
5671 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5674 if (padapter->bup == _FALSE) {
\r
5675 DBG_871X("%s: net device is down.\n", __func__);
\r
5679 if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE ||
\r
5680 check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ||
\r
5681 check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
5682 DBG_871X("%s: device is busy.\n", __func__);
\r
5683 rtw_scan_abort(padapter);
\r
5686 if (request == NULL) {
\r
5687 DBG_871X("%s: invalid cfg80211_requests parameters.\n", __func__);
\r
5691 ret = rtw_android_cfg80211_pno_setup(dev, request->ssids,
\r
5692 request->n_ssids, request->interval);
\r
5695 DBG_871X("%s ret: %d\n", __func__, ret);
\r
5699 ret = rtw_android_pno_enable(dev, _TRUE);
\r
5701 DBG_871X("%s ret: %d\n", __func__, ret);
\r
5708 static int cfg80211_rtw_sched_scan_stop(struct wiphy *wiphy,
\r
5709 struct net_device *dev) {
\r
5710 return rtw_android_pno_enable(dev, _FALSE);
\r
5712 #endif /* CONFIG_PNO_SUPPORT */
\r
5714 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
\r
5717 uint wps_ielen = 0;
\r
5719 u32 p2p_ielen = 0;
\r
5720 u8 wps_oui[8]={0x0,0x50,0xf2,0x04};
\r
5722 u32 wfd_ielen = 0;
\r
5724 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5725 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5726 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
5728 DBG_871X(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
\r
5732 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
5734 #ifdef CONFIG_DEBUG_CFG80211
\r
5735 DBG_8192C("bcn_wps_ielen=%d\n", wps_ielen);
\r
5738 if(pmlmepriv->wps_beacon_ie)
\r
5740 u32 free_len = pmlmepriv->wps_beacon_ie_len;
\r
5741 pmlmepriv->wps_beacon_ie_len = 0;
\r
5742 rtw_mfree(pmlmepriv->wps_beacon_ie, free_len);
\r
5743 pmlmepriv->wps_beacon_ie = NULL;
\r
5746 pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen);
\r
5747 if ( pmlmepriv->wps_beacon_ie == NULL) {
\r
5748 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5753 _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
\r
5754 pmlmepriv->wps_beacon_ie_len = wps_ielen;
\r
5756 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
\r
5760 //buf += wps_ielen;
\r
5761 //len -= wps_ielen;
\r
5764 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
5766 #ifdef CONFIG_DEBUG_CFG80211
\r
5767 DBG_8192C("bcn_p2p_ielen=%d\n", p2p_ielen);
\r
5770 if(pmlmepriv->p2p_beacon_ie)
\r
5772 u32 free_len = pmlmepriv->p2p_beacon_ie_len;
\r
5773 pmlmepriv->p2p_beacon_ie_len = 0;
\r
5774 rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len);
\r
5775 pmlmepriv->p2p_beacon_ie = NULL;
\r
5778 pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen);
\r
5779 if ( pmlmepriv->p2p_beacon_ie == NULL) {
\r
5780 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5785 _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
\r
5786 pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
\r
5789 #endif //CONFIG_P2P
\r
5791 //buf += p2p_ielen;
\r
5792 //len -= p2p_ielen;
\r
5795 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
5797 #ifdef CONFIG_DEBUG_CFG80211
\r
5798 DBG_8192C("bcn_wfd_ielen=%d\n", wfd_ielen);
\r
5801 if(pmlmepriv->wfd_beacon_ie)
\r
5803 u32 free_len = pmlmepriv->wfd_beacon_ie_len;
\r
5804 pmlmepriv->wfd_beacon_ie_len = 0;
\r
5805 rtw_mfree(pmlmepriv->wfd_beacon_ie, free_len);
\r
5806 pmlmepriv->wfd_beacon_ie = NULL;
\r
5809 pmlmepriv->wfd_beacon_ie = rtw_malloc(wfd_ielen);
\r
5810 if ( pmlmepriv->wfd_beacon_ie == NULL) {
\r
5811 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5815 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
\r
5817 #endif //CONFIG_WFD
\r
5819 pmlmeext->bstart_bss = _TRUE;
\r
5827 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
\r
5830 uint wps_ielen = 0;
\r
5832 u32 p2p_ielen = 0;
\r
5834 u32 wfd_ielen = 0;
\r
5836 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
\r
5837 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5839 #ifdef CONFIG_DEBUG_CFG80211
\r
5840 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5845 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
5847 uint attr_contentlen = 0;
\r
5848 u16 uconfig_method, *puconfig_method = NULL;
\r
5850 #ifdef CONFIG_DEBUG_CFG80211
\r
5851 DBG_8192C("probe_resp_wps_ielen=%d\n", wps_ielen);
\r
5854 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
\r
5857 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
\r
5861 DBG_871X("%s, got sr\n", __func__);
\r
5865 DBG_8192C("GO mode process WPS under site-survey, sr no set\n");
\r
5870 if(pmlmepriv->wps_probe_resp_ie)
\r
5872 u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
\r
5873 pmlmepriv->wps_probe_resp_ie_len = 0;
\r
5874 rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len);
\r
5875 pmlmepriv->wps_probe_resp_ie = NULL;
\r
5878 pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen);
\r
5879 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
\r
5880 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5885 //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode
\r
5886 if ( (puconfig_method = (u16*)rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen)) != NULL )
\r
5888 //struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
5889 struct wireless_dev *wdev = padapter->rtw_wdev;
\r
5891 #ifdef CONFIG_DEBUG_CFG80211
\r
5892 //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method));
\r
5895 //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
\r
5896 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5897 if(wdev->iftype != NL80211_IFTYPE_P2P_GO) //for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags
\r
5899 uconfig_method = WPS_CM_PUSH_BUTTON;
\r
5900 uconfig_method = cpu_to_be16( uconfig_method );
\r
5902 *puconfig_method |= uconfig_method;
\r
5907 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
\r
5908 pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
\r
5912 //buf += wps_ielen;
\r
5913 //len -= wps_ielen;
\r
5916 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
5918 u8 is_GO = _FALSE;
\r
5919 u32 attr_contentlen = 0;
\r
5922 #ifdef CONFIG_DEBUG_CFG80211
\r
5923 DBG_8192C("probe_resp_p2p_ielen=%d\n", p2p_ielen);
\r
5926 //Check P2P Capability ATTR
\r
5927 if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) )
\r
5930 //DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
\r
5931 cap_attr = le16_to_cpu(cap_attr);
\r
5932 grp_cap = (u8)((cap_attr >> 8)&0xff);
\r
5934 is_GO = (grp_cap&BIT(0)) ? _TRUE:_FALSE;
\r
5937 DBG_8192C("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
\r
5941 if(is_GO == _FALSE)
\r
5943 if(pmlmepriv->p2p_probe_resp_ie)
\r
5945 u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
\r
5946 pmlmepriv->p2p_probe_resp_ie_len = 0;
\r
5947 rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len);
\r
5948 pmlmepriv->p2p_probe_resp_ie = NULL;
\r
5951 pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen);
\r
5952 if ( pmlmepriv->p2p_probe_resp_ie == NULL) {
\r
5953 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5957 _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
\r
5958 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
\r
5962 if(pmlmepriv->p2p_go_probe_resp_ie)
\r
5964 u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
\r
5965 pmlmepriv->p2p_go_probe_resp_ie_len = 0;
\r
5966 rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len);
\r
5967 pmlmepriv->p2p_go_probe_resp_ie = NULL;
\r
5970 pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen);
\r
5971 if ( pmlmepriv->p2p_go_probe_resp_ie == NULL) {
\r
5972 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5976 _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
\r
5977 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
\r
5981 #endif //CONFIG_P2P
\r
5983 //buf += p2p_ielen;
\r
5984 //len -= p2p_ielen;
\r
5987 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
5989 #ifdef CONFIG_DEBUG_CFG80211
\r
5990 DBG_8192C("probe_resp_wfd_ielen=%d\n", wfd_ielen);
\r
5993 if(pmlmepriv->wfd_probe_resp_ie)
\r
5995 u32 free_len = pmlmepriv->wfd_probe_resp_ie_len;
\r
5996 pmlmepriv->wfd_probe_resp_ie_len = 0;
\r
5997 rtw_mfree(pmlmepriv->wfd_probe_resp_ie, free_len);
\r
5998 pmlmepriv->wfd_probe_resp_ie = NULL;
\r
6001 pmlmepriv->wfd_probe_resp_ie = rtw_malloc(wfd_ielen);
\r
6002 if ( pmlmepriv->wfd_probe_resp_ie == NULL) {
\r
6003 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
6007 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
\r
6009 #endif //CONFIG_WFD
\r
6017 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
\r
6020 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
\r
6021 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
6023 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
6027 if(pmlmepriv->wps_assoc_resp_ie)
\r
6029 u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
\r
6030 pmlmepriv->wps_assoc_resp_ie_len = 0;
\r
6031 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len);
\r
6032 pmlmepriv->wps_assoc_resp_ie = NULL;
\r
6035 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(len);
\r
6036 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
\r
6037 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
6041 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len);
\r
6042 pmlmepriv->wps_assoc_resp_ie_len = len;
\r
6049 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
\r
6053 uint wps_ielen = 0;
\r
6054 u32 p2p_ielen = 0;
\r
6056 #ifdef CONFIG_DEBUG_CFG80211
\r
6057 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
6060 if( (rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen>0))
\r
6062 || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen>0))
\r
6070 case 0x1: //BEACON
\r
6071 ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
\r
6073 case 0x2: //PROBE_RESP
\r
6074 ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
\r
6076 case 0x4: //ASSOC_RESP
\r
6077 ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
\r
6087 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
\r
6090 #define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
\r
6091 #define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
\r
6093 ht_cap->ht_supported = _TRUE;
\r
6095 ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
\r
6096 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
\r
6097 IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
\r
6100 *Maximum length of AMPDU that the STA can receive.
\r
6101 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
\r
6103 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
\r
6105 /*Minimum MPDU start spacing , */
\r
6106 ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
\r
6108 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
\r
6111 *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
\r
6114 *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
\r
6115 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
\r
6116 *if rx_ant >=3 rx_mask[2]=0xff;
\r
6117 *if BW_40 rx_mask[4]=0x01;
\r
6118 *highest supported RX rate
\r
6120 if(rf_type == RF_1T1R)
\r
6122 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
6123 ht_cap->mcs.rx_mask[1] = 0x00;
\r
6124 ht_cap->mcs.rx_mask[4] = 0x01;
\r
6126 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
\r
6128 else if((rf_type == RF_1T2R) || (rf_type==RF_2T2R))
\r
6130 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
6131 ht_cap->mcs.rx_mask[1] = 0xFF;
\r
6132 ht_cap->mcs.rx_mask[4] = 0x01;
\r
6134 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
\r
6138 DBG_8192C("%s, error rf_type=%d\n", __func__, rf_type);
\r
6143 void rtw_cfg80211_init_wiphy(_adapter *padapter)
\r
6146 struct ieee80211_supported_band *bands;
\r
6147 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
6148 struct wiphy *wiphy = pwdev->wiphy;
\r
6150 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
\r
6152 DBG_8192C("%s:rf_type=%d\n", __func__, rf_type);
\r
6154 if (padapter->registrypriv.wireless_mode & WIRELESS_11G)
\r
6156 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
\r
6158 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type);
\r
6161 if (padapter->registrypriv.wireless_mode & WIRELESS_11A)
\r
6163 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
\r
6165 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type);
\r
6168 /* init regulary domain */
\r
6169 rtw_regd_init(padapter);
\r
6171 /* copy mac_addr to wiphy */
\r
6172 _rtw_memcpy(wiphy->perm_addr, adapter_mac_addr(padapter), ETH_ALEN);
\r
6177 struct ieee80211_iface_limit rtw_limits[] = {
\r
6178 { .max = 1, .types = BIT(NL80211_IFTYPE_STATION)
\r
6179 | BIT(NL80211_IFTYPE_ADHOC)
\r
6180 #ifdef CONFIG_AP_MODE
\r
6181 | BIT(NL80211_IFTYPE_AP)
\r
6183 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
6184 | BIT(NL80211_IFTYPE_P2P_CLIENT)
\r
6185 | BIT(NL80211_IFTYPE_P2P_GO)
\r
6188 {.max = 1, .types = BIT(NL80211_IFTYPE_MONITOR)},
\r
6191 struct ieee80211_iface_combination rtw_combinations = {
\r
6192 .limits = rtw_limits,
\r
6193 .n_limits = ARRAY_SIZE(rtw_limits),
\r
6194 .max_interfaces = 2,
\r
6195 .num_different_channels = 1,
\r
6199 static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy)
\r
6202 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
\r
6204 wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
\r
6205 wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
\r
6206 wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
\r
6208 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
6209 wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
\r
6212 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
\r
6213 | BIT(NL80211_IFTYPE_ADHOC)
\r
6214 #ifdef CONFIG_AP_MODE
\r
6215 | BIT(NL80211_IFTYPE_AP)
\r
6216 #ifndef CONFIG_RADIO_WORK
\r
6217 | BIT(NL80211_IFTYPE_MONITOR)
\r
6220 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
6221 | BIT(NL80211_IFTYPE_P2P_CLIENT)
\r
6222 | BIT(NL80211_IFTYPE_P2P_GO)
\r
6226 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
6227 #ifdef CONFIG_AP_MODE
\r
6228 wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
\r
6229 #endif //CONFIG_AP_MODE
\r
6232 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
6233 #ifndef CONFIG_RADIO_WORK
\r
6234 wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
\r
6239 wiphy->iface_combinations = &rtw_combinations;
\r
6240 wiphy->n_iface_combinations = 1;
\r
6243 wiphy->cipher_suites = rtw_cipher_suites;
\r
6244 wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
\r
6246 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
\r
6247 wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
\r
6248 #ifdef CONFIG_IEEE80211_BAND_5GHZ
\r
6249 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
\r
6250 wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
\r
6253 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
\r
6254 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
\r
6257 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
\r
6258 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
\r
6259 wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
\r
6262 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
6263 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
\r
6264 #ifdef CONFIG_PNO_SUPPORT
\r
6265 wiphy->max_sched_scan_ssids = MAX_PNO_LIST_COUNT;
\r
6269 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
6270 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0))
\r
6271 wiphy->wowlan = wowlan_stub;
\r
6273 wiphy->wowlan = &wowlan_stub;
\r
6277 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
6278 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
\r
6279 #ifndef CONFIG_TDLS_DRIVER_SETUP
\r
6280 wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; //Driver handles key exchange
\r
6281 wiphy->flags |= NL80211_ATTR_HT_CAPABILITY;
\r
6282 #endif //CONFIG_TDLS_DRIVER_SETUP
\r
6283 #endif /* CONFIG_TDLS */
\r
6285 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
\r
6286 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
\r
6288 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
\r
6290 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
6291 //wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
\r
6294 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
\r
6295 rtw_cfgvendor_attach(wiphy);
\r
6299 static struct cfg80211_ops rtw_cfg80211_ops = {
\r
6300 .change_virtual_intf = cfg80211_rtw_change_iface,
\r
6301 .add_key = cfg80211_rtw_add_key,
\r
6302 .get_key = cfg80211_rtw_get_key,
\r
6303 .del_key = cfg80211_rtw_del_key,
\r
6304 .set_default_key = cfg80211_rtw_set_default_key,
\r
6305 #if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
\r
6306 .set_rekey_data = cfg80211_rtw_set_rekey_data,
\r
6307 #endif /*CONFIG_GTK_OL*/
\r
6308 .get_station = cfg80211_rtw_get_station,
\r
6309 .scan = cfg80211_rtw_scan,
\r
6310 .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
\r
6311 .connect = cfg80211_rtw_connect,
\r
6312 .disconnect = cfg80211_rtw_disconnect,
\r
6313 .join_ibss = cfg80211_rtw_join_ibss,
\r
6314 .leave_ibss = cfg80211_rtw_leave_ibss,
\r
6315 .set_tx_power = cfg80211_rtw_set_txpower,
\r
6316 .get_tx_power = cfg80211_rtw_get_txpower,
\r
6317 .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
\r
6318 .set_pmksa = cfg80211_rtw_set_pmksa,
\r
6319 .del_pmksa = cfg80211_rtw_del_pmksa,
\r
6320 .flush_pmksa = cfg80211_rtw_flush_pmksa,
\r
6322 #ifdef CONFIG_AP_MODE
\r
6323 .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
\r
6324 .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
\r
6326 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
\r
6327 .add_beacon = cfg80211_rtw_add_beacon,
\r
6328 .set_beacon = cfg80211_rtw_set_beacon,
\r
6329 .del_beacon = cfg80211_rtw_del_beacon,
\r
6331 .start_ap = cfg80211_rtw_start_ap,
\r
6332 .change_beacon = cfg80211_rtw_change_beacon,
\r
6333 .stop_ap = cfg80211_rtw_stop_ap,
\r
6336 .add_station = cfg80211_rtw_add_station,
\r
6337 .del_station = cfg80211_rtw_del_station,
\r
6338 .change_station = cfg80211_rtw_change_station,
\r
6339 .dump_station = cfg80211_rtw_dump_station,
\r
6340 .change_bss = cfg80211_rtw_change_bss,
\r
6341 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
\r
6342 .set_channel = cfg80211_rtw_set_channel,
\r
6344 //.auth = cfg80211_rtw_auth,
\r
6345 //.assoc = cfg80211_rtw_assoc,
\r
6346 #endif //CONFIG_AP_MODE
\r
6349 .remain_on_channel = cfg80211_rtw_remain_on_channel,
\r
6350 .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
\r
6353 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
6354 .mgmt_tx = cfg80211_rtw_mgmt_tx,
\r
6355 .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
\r
6356 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
\r
6357 .action = cfg80211_rtw_mgmt_tx,
\r
6360 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
6361 .tdls_mgmt = cfg80211_rtw_tdls_mgmt,
\r
6362 .tdls_oper = cfg80211_rtw_tdls_oper,
\r
6363 #endif /* CONFIG_TDLS */
\r
6365 #if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
6366 .sched_scan_start = cfg80211_rtw_sched_scan_start,
\r
6367 .sched_scan_stop = cfg80211_rtw_sched_scan_stop,
\r
6368 #endif /* CONFIG_PNO_SUPPORT */
\r
6371 int rtw_wdev_alloc(_adapter *padapter, struct device *dev)
\r
6374 struct wiphy *wiphy;
\r
6375 struct wireless_dev *wdev;
\r
6376 struct rtw_wdev_priv *pwdev_priv;
\r
6377 struct net_device *pnetdev = padapter->pnetdev;
\r
6379 DBG_8192C("%s(padapter=%p)\n", __func__, padapter);
\r
6382 wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(_adapter*));
\r
6384 DBG_8192C("Couldn't allocate wiphy device\n");
\r
6388 set_wiphy_dev(wiphy, dev);
\r
6389 *((_adapter**)wiphy_priv(wiphy)) = padapter;
\r
6390 rtw_cfg80211_preinit_wiphy(padapter, wiphy);
\r
6392 ret = wiphy_register(wiphy);
\r
6394 DBG_8192C("Couldn't register wiphy device\n");
\r
6399 wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
\r
6401 DBG_8192C("Couldn't allocate wireless device\n");
\r
6403 goto unregister_wiphy;
\r
6405 wdev->wiphy = wiphy;
\r
6406 wdev->netdev = pnetdev;
\r
6408 wdev->iftype = NL80211_IFTYPE_STATION; // will be init in rtw_hal_init()
\r
6409 // Must sync with _rtw_init_mlme_priv()
\r
6410 // pmlmepriv->fw_state = WIFI_STATION_STATE
\r
6411 //wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
\r
6412 padapter->rtw_wdev = wdev;
\r
6413 pnetdev->ieee80211_ptr = wdev;
\r
6416 pwdev_priv = adapter_wdev_data(padapter);
\r
6417 pwdev_priv->rtw_wdev = wdev;
\r
6418 pwdev_priv->pmon_ndev = NULL;
\r
6419 pwdev_priv->ifname_mon[0] = '\0';
\r
6420 pwdev_priv->padapter = padapter;
\r
6421 pwdev_priv->scan_request = NULL;
\r
6422 _rtw_spinlock_init(&pwdev_priv->scan_req_lock);
\r
6424 pwdev_priv->p2p_enabled = _FALSE;
\r
6425 pwdev_priv->provdisc_req_issued = _FALSE;
\r
6426 rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
\r
6427 rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
\r
6429 pwdev_priv->bandroid_scan = _FALSE;
\r
6431 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
\r
6432 pwdev_priv->power_mgmt = _TRUE;
\r
6434 pwdev_priv->power_mgmt = _FALSE;
\r
6436 #ifdef CONFIG_CONCURRENT_MODE
\r
6437 ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
\r
6438 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
6443 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
\r
6445 wiphy_unregister(wiphy);
\r
6447 wiphy_free(wiphy);
\r
6453 void rtw_wdev_free(struct wireless_dev *wdev)
\r
6455 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
\r
6460 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
\r
6461 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
\r
6463 wiphy_free(wdev->wiphy);
\r
6465 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
\r
6468 void rtw_wdev_unregister(struct wireless_dev *wdev)
\r
6470 struct net_device *ndev;
\r
6471 _adapter *adapter;
\r
6472 struct rtw_wdev_priv *pwdev_priv;
\r
6474 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
\r
6479 if(!(ndev = wdev_to_ndev(wdev)))
\r
6482 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
6483 pwdev_priv = adapter_wdev_data(adapter);
\r
6485 rtw_cfg80211_indicate_scan_done(adapter, _TRUE);
\r
6487 if (pwdev_priv->pmon_ndev) {
\r
6488 DBG_8192C("%s, unregister monitor interface\n", __func__);
\r
6489 unregister_netdev(pwdev_priv->pmon_ndev);
\r
6492 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
\r
6493 rtw_cfgvendor_detach(wdev->wiphy);
\r
6496 wiphy_unregister(wdev->wiphy);
\r
6499 #endif //CONFIG_IOCTL_CFG80211
\r