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, myid(&(padapter->eeprompriv)), 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
678 int freq = (int)cur_network->network.Configuration.DSConfig;
\r
679 struct ieee80211_channel *chan;
\r
682 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
683 if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
\r
688 if (!rtw_cfg80211_check_bss(padapter)) {
\r
689 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
690 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
\r
692 if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE)
\r
695 _rtw_memcpy(&cur_network->network, pnetwork, sizeof(WLAN_BSSID_EX));
\r
698 if (!rtw_cfg80211_inform_bss(padapter,cur_network))
\r
699 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
701 DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
705 DBG_871X("cur_network is not exist!!!\n");
\r
711 if(scanned == NULL)
\r
714 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
\r
715 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
\r
717 if (!rtw_cfg80211_inform_bss(padapter,scanned)) {
\r
718 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
720 //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
723 DBG_871X("scanned & pnetwork compare fail\n");
\r
728 if (!rtw_cfg80211_check_bss(padapter))
\r
729 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
\r
731 //notify cfg80211 that device joined an IBSS
\r
732 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
\r
733 chan = ieee80211_get_channel(wiphy, freq);
\r
734 cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, chan, GFP_ATOMIC);
\r
736 cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, GFP_ATOMIC);
\r
740 void rtw_cfg80211_indicate_connect(_adapter *padapter)
\r
742 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
743 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
744 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
746 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
748 struct cfg80211_bss *bss = NULL;
\r
750 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
751 if (pwdev->iftype != NL80211_IFTYPE_STATION
\r
752 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
753 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
\r
759 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
763 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
765 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
767 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
768 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
\r
769 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
\r
770 DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
\r
773 #endif //CONFIG_P2P
\r
776 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
777 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
\r
779 //DBG_871X(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter));
\r
781 if(scanned == NULL) {
\r
786 if (_rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
\r
787 && _rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
\r
789 if (!rtw_cfg80211_inform_bss(padapter,scanned)) {
\r
790 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
792 //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
795 DBG_871X("scanned: %s("MAC_FMT"), cur: %s("MAC_FMT")\n",
\r
796 scanned->network.Ssid.Ssid, MAC_ARG(scanned->network.MacAddress),
\r
797 pnetwork->Ssid.Ssid, MAC_ARG(pnetwork->MacAddress)
\r
804 if (!rtw_cfg80211_check_bss(padapter))
\r
805 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
\r
807 if (rtw_to_roam(padapter) > 0) {
\r
808 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
\r
809 struct wiphy *wiphy = pwdev->wiphy;
\r
810 struct ieee80211_channel *notify_channel;
\r
812 u16 channel = cur_network->network.Configuration.DSConfig;
\r
814 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
815 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
817 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
819 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
822 DBG_871X(FUNC_ADPT_FMT" call cfg80211_roamed\n", FUNC_ADPT_ARG(padapter));
\r
823 cfg80211_roamed(padapter->pnetdev
\r
824 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
\r
827 , cur_network->network.MacAddress
\r
828 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
\r
829 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
\r
830 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
\r
831 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
\r
836 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
\r
837 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
\r
839 cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
\r
840 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
\r
841 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
\r
842 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
\r
843 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
\r
844 , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
\r
845 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
\r
846 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
\r
851 void rtw_cfg80211_indicate_disconnect(_adapter *padapter)
\r
853 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
854 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
856 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
859 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
861 if (pwdev->iftype != NL80211_IFTYPE_STATION
\r
862 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
863 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
\r
869 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
873 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
875 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
877 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
878 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
880 DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
\r
883 #endif //CONFIG_P2P
\r
885 if (!padapter->mlmepriv.not_indic_disco) {
\r
886 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
\r
887 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
\r
889 if(pwdev->sme_state==CFG80211_SME_CONNECTING)
\r
890 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
\r
891 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
\r
892 else if(pwdev->sme_state==CFG80211_SME_CONNECTED)
\r
893 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
\r
895 //DBG_8192C("pwdev->sme_state=%d\n", pwdev->sme_state);
\r
897 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
\r
900 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
901 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
\r
903 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
\r
904 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
\r
910 #ifdef CONFIG_AP_MODE
\r
911 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
\r
914 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
915 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
\r
916 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
917 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
918 struct security_priv* psecuritypriv=&(padapter->securitypriv);
\r
919 struct sta_priv *pstapriv = &padapter->stapriv;
\r
921 DBG_8192C("%s\n", __FUNCTION__);
\r
923 param->u.crypt.err = 0;
\r
924 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
\r
926 //sizeof(struct ieee_param) = 64 bytes;
\r
927 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
\r
928 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
\r
934 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
\r
935 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
\r
936 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
\r
938 if (param->u.crypt.idx >= WEP_KEYS)
\r
946 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
\r
950 DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n");
\r
955 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
\r
957 //todo:clear default encryption keys
\r
959 DBG_8192C("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
\r
965 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
\r
967 DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
\r
969 wep_key_idx = param->u.crypt.idx;
\r
970 wep_key_len = param->u.crypt.key_len;
\r
972 DBG_8192C("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
\r
974 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
\r
980 if (wep_key_len > 0)
\r
982 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
985 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
\r
987 //wep default key has not been set, so use this key index as default key.
\r
989 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
\r
990 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
991 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
\r
992 psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
\r
994 if(wep_key_len == 13)
\r
996 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
\r
997 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
\r
1000 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
\r
1003 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
\r
1005 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
\r
1007 rtw_ap_set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx, 1);
\r
1014 if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
\r
1016 if(param->u.crypt.set_tx == 0) //group key
\r
1018 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1020 DBG_8192C("%s, set group_key, WEP\n", __FUNCTION__);
\r
1022 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1024 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1025 if(param->u.crypt.key_len==13)
\r
1027 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1031 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1033 DBG_8192C("%s, set group_key, TKIP\n", __FUNCTION__);
\r
1035 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
\r
1037 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1039 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1041 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
\r
1042 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
\r
1044 psecuritypriv->busetkipkey = _TRUE;
\r
1047 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1049 DBG_8192C("%s, set group_key, CCMP\n", __FUNCTION__);
\r
1051 psecuritypriv->dot118021XGrpPrivacy = _AES_;
\r
1053 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1057 DBG_8192C("%s, set group_key, none\n", __FUNCTION__);
\r
1059 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
1062 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
\r
1064 psecuritypriv->binstallGrpkey = _TRUE;
\r
1066 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
\r
1068 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
\r
1070 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1073 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1074 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
\r
1083 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
\r
1085 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
1087 if(param->u.crypt.set_tx ==1) //pairwise key
\r
1089 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1091 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1093 DBG_8192C("%s, set pairwise key, WEP\n", __FUNCTION__);
\r
1095 psta->dot118021XPrivacy = _WEP40_;
\r
1096 if(param->u.crypt.key_len==13)
\r
1098 psta->dot118021XPrivacy = _WEP104_;
\r
1101 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1103 DBG_8192C("%s, set pairwise key, TKIP\n", __FUNCTION__);
\r
1105 psta->dot118021XPrivacy = _TKIP_;
\r
1107 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1109 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
\r
1110 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
\r
1112 psecuritypriv->busetkipkey = _TRUE;
\r
1115 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1118 DBG_8192C("%s, set pairwise key, CCMP\n", __FUNCTION__);
\r
1120 psta->dot118021XPrivacy = _AES_;
\r
1124 DBG_8192C("%s, set pairwise key, none\n", __FUNCTION__);
\r
1126 psta->dot118021XPrivacy = _NO_PRIVACY_;
\r
1129 rtw_ap_set_pairwise_key(padapter, psta);
\r
1131 psta->ieee8021x_blocked = _FALSE;
\r
1133 psta->bpairwise_key_installed = _TRUE;
\r
1136 else//group key???
\r
1138 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1140 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1142 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1143 if(param->u.crypt.key_len==13)
\r
1145 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1148 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1150 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
\r
1152 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1154 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1156 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
\r
1157 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
\r
1159 psecuritypriv->busetkipkey = _TRUE;
\r
1162 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1164 psecuritypriv->dot118021XGrpPrivacy = _AES_;
\r
1166 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1170 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
1173 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
\r
1175 psecuritypriv->binstallGrpkey = _TRUE;
\r
1177 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
\r
1179 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
\r
1181 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1184 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1185 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
\r
1201 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
\r
1204 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
1205 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
1206 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1207 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1209 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
\r
1210 #endif //CONFIG_P2P
\r
1214 DBG_8192C("%s\n", __func__);
\r
1216 param->u.crypt.err = 0;
\r
1217 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
\r
1219 if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
\r
1225 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
\r
1226 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
\r
1227 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
\r
1229 if (param->u.crypt.idx >= WEP_KEYS
\r
1230 #ifdef CONFIG_IEEE80211W
\r
1231 && param->u.crypt.idx > BIP_MAX_KEYID
\r
1232 #endif //CONFIG_IEEE80211W
\r
1239 #ifdef CONFIG_WAPI_SUPPORT
\r
1240 if (strcmp(param->u.crypt.alg, "SMS4"))
\r
1248 if (strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1250 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
\r
1251 DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n");
\r
1253 wep_key_idx = param->u.crypt.idx;
\r
1254 wep_key_len = param->u.crypt.key_len;
\r
1256 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0))
\r
1262 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
\r
1264 //wep default key has not been set, so use this key index as default key.
\r
1266 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
1268 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1269 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
\r
1270 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1272 if(wep_key_len==13)
\r
1274 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
\r
1275 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1278 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
\r
1281 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
\r
1283 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
\r
1285 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, _TRUE);
\r
1290 if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
\r
1292 struct sta_info * psta,*pbcmc_sta;
\r
1293 struct sta_priv * pstapriv = &padapter->stapriv;
\r
1295 //DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__);
\r
1297 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
\r
1299 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
\r
1300 if (psta == NULL) {
\r
1301 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
\r
1302 DBG_8192C("%s, : Obtain Sta_info fail \n", __func__);
\r
1306 //Jeff: don't disable ieee8021x_blocked while clearing key
\r
1307 if (strcmp(param->u.crypt.alg, "none") != 0)
\r
1308 psta->ieee8021x_blocked = _FALSE;
\r
1311 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
\r
1312 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
\r
1314 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
\r
1317 if(param->u.crypt.set_tx ==1)//pairwise key
\r
1320 DBG_8192C("%s, : param->u.crypt.set_tx ==1 \n", __func__);
\r
1322 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1324 if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
\r
1326 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
\r
1327 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
\r
1328 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
\r
1330 padapter->securitypriv.busetkipkey=_FALSE;
\r
1331 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
\r
1334 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
\r
1335 DBG_871X(" ~~~~set sta key:unicastkey\n");
\r
1337 rtw_setstakey_cmd(padapter, psta, _TRUE, _TRUE);
\r
1341 if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1343 _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1344 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
\r
1345 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
\r
1346 padapter->securitypriv.binstallGrpkey = _TRUE;
\r
1347 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
\r
1348 DBG_871X(" ~~~~set sta key:groupkey\n");
\r
1350 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
\r
1351 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1, _TRUE);
\r
1353 #ifdef CONFIG_IEEE80211W
\r
1354 else if(strcmp(param->u.crypt.alg, "BIP") == 0)
\r
1357 //DBG_871X("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx);
\r
1358 //save the IGTK key, length 16 bytes
\r
1359 _rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1360 /*DBG_871X("IGTK key below:\n");
\r
1361 for(no=0;no<16;no++)
\r
1362 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
\r
1364 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
\r
1365 padapter->securitypriv.binstallBIPkey = _TRUE;
\r
1366 DBG_871X(" ~~~~set sta key:IGKT\n");
\r
1368 #endif //CONFIG_IEEE80211W
\r
1371 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1373 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
\r
1375 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
\r
1378 #endif //CONFIG_P2P
\r
1383 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1384 if(pbcmc_sta==NULL)
\r
1386 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
\r
1390 //Jeff: don't disable ieee8021x_blocked while clearing key
\r
1391 if (strcmp(param->u.crypt.alg, "none") != 0)
\r
1392 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1394 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
\r
1395 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
\r
1397 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
\r
1401 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
\r
1406 #ifdef CONFIG_WAPI_SUPPORT
\r
1407 if (strcmp(param->u.crypt.alg, "SMS4") == 0)
\r
1409 PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
\r
1410 PRT_WAPI_STA_INFO pWapiSta;
\r
1411 u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1412 u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1413 u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1415 if(param->u.crypt.set_tx == 1)
\r
1417 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
\r
1418 if(_rtw_memcmp(pWapiSta->PeerMacAddr,param->sta_addr,6))
\r
1420 _rtw_memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
\r
1422 pWapiSta->wapiUsk.bSet = true;
\r
1423 _rtw_memcpy(pWapiSta->wapiUsk.dataKey,param->u.crypt.key,16);
\r
1424 _rtw_memcpy(pWapiSta->wapiUsk.micKey,param->u.crypt.key+16,16);
\r
1425 pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
\r
1426 pWapiSta->wapiUsk.bTxEnable = true;
\r
1428 _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16);
\r
1429 _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16);
\r
1430 _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16);
\r
1431 _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16);
\r
1432 _rtw_memcpy(pWapiSta->lastRxUnicastPN,WapiAEPNInitialValueSrc,16);
\r
1433 pWapiSta->wapiUskUpdate.bTxEnable = false;
\r
1434 pWapiSta->wapiUskUpdate.bSet = false;
\r
1436 if (psecuritypriv->sw_encrypt== false || psecuritypriv->sw_decrypt == false)
\r
1438 //set unicast key for ASUE
\r
1439 rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
\r
1446 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
\r
1447 if(_rtw_memcmp(pWapiSta->PeerMacAddr,get_bssid(pmlmepriv),6))
\r
1449 pWapiSta->wapiMsk.bSet = true;
\r
1450 _rtw_memcpy(pWapiSta->wapiMsk.dataKey,param->u.crypt.key,16);
\r
1451 _rtw_memcpy(pWapiSta->wapiMsk.micKey,param->u.crypt.key+16,16);
\r
1452 pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
\r
1453 pWapiSta->wapiMsk.bTxEnable = false;
\r
1454 if(!pWapiSta->bSetkeyOk)
\r
1455 pWapiSta->bSetkeyOk = true;
\r
1456 pWapiSta->bAuthenticateInProgress = false;
\r
1458 _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
\r
1460 if (psecuritypriv->sw_decrypt == false)
\r
1462 //set rx broadcast key for ASUE
\r
1463 rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
\r
1475 DBG_8192C("%s, ret=%d\n", __func__, ret);
\r
1482 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1483 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1484 u8 key_index, bool pairwise, const u8 *mac_addr,
\r
1485 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1486 u8 key_index, const u8 *mac_addr,
\r
1487 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1488 struct key_params *params)
\r
1492 struct ieee_param *param = NULL;
\r
1494 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1495 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
1496 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1498 DBG_871X(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
\r
1499 DBG_871X("cipher=0x%x\n", params->cipher);
\r
1500 DBG_871X("key_len=0x%x\n", params->key_len);
\r
1501 DBG_871X("seq_len=0x%x\n", params->seq_len);
\r
1502 DBG_871X("key_index=%d\n", key_index);
\r
1503 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1504 DBG_871X("pairwise=%d\n", pairwise);
\r
1505 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1507 param_len = sizeof(struct ieee_param) + params->key_len;
\r
1508 param = (struct ieee_param *)rtw_malloc(param_len);
\r
1509 if (param == NULL)
\r
1512 _rtw_memset(param, 0, param_len);
\r
1514 param->cmd = IEEE_CMD_SET_ENCRYPTION;
\r
1515 _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
\r
1517 switch (params->cipher) {
\r
1518 case IW_AUTH_CIPHER_NONE:
\r
1519 //todo: remove key
\r
1521 alg_name = "none";
\r
1523 case WLAN_CIPHER_SUITE_WEP40:
\r
1524 case WLAN_CIPHER_SUITE_WEP104:
\r
1527 case WLAN_CIPHER_SUITE_TKIP:
\r
1528 alg_name = "TKIP";
\r
1530 case WLAN_CIPHER_SUITE_CCMP:
\r
1531 alg_name = "CCMP";
\r
1533 #ifdef CONFIG_IEEE80211W
\r
1534 case WLAN_CIPHER_SUITE_AES_CMAC:
\r
1537 #endif //CONFIG_IEEE80211W
\r
1538 #ifdef CONFIG_WAPI_SUPPORT
\r
1539 case WLAN_CIPHER_SUITE_SMS4:
\r
1541 if(pairwise == NL80211_KEYTYPE_PAIRWISE) {
\r
1542 if (key_index != 0 && key_index != 1) {
\r
1546 _rtw_memcpy((void*)param->sta_addr, (void*)mac_addr, ETH_ALEN);
\r
1548 DBG_871X("mac_addr is null \n");
\r
1550 DBG_871X("rtw_wx_set_enc_ext: SMS4 case \n");
\r
1559 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
\r
1562 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
\r
1564 param->u.crypt.set_tx = 0; //for wpa/wpa2 group key
\r
1566 param->u.crypt.set_tx = 1; //for wpa/wpa2 pairwise key
\r
1570 //param->u.crypt.idx = key_index - 1;
\r
1571 param->u.crypt.idx = key_index;
\r
1573 if (params->seq_len && params->seq)
\r
1575 _rtw_memcpy(param->u.crypt.seq, (u8 *)params->seq, params->seq_len);
\r
1578 if(params->key_len && params->key)
\r
1580 param->u.crypt.key_len = params->key_len;
\r
1581 _rtw_memcpy(param->u.crypt.key, (u8 *)params->key, params->key_len);
\r
1584 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
\r
1586 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
\r
1588 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
1590 #ifdef CONFIG_AP_MODE
\r
1592 _rtw_memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN);
\r
1594 ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
\r
1597 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE
\r
1598 || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)
\r
1600 //DBG_8192C("@@@@@@@@@@ fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
\r
1601 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
\r
1605 DBG_8192C("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
\r
1612 rtw_mfree((u8*)param, param_len);
\r
1619 static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1620 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1621 u8 key_index, bool pairwise, const u8 *mac_addr,
\r
1622 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1623 u8 key_index, const u8 *mac_addr,
\r
1624 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1626 void (*callback)(void *cookie,
\r
1627 struct key_params*))
\r
1630 struct iwm_priv *iwm = ndev_to_iwm(ndev);
\r
1631 struct iwm_key *key = &iwm->keys[key_index];
\r
1632 struct key_params params;
\r
1634 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
\r
1636 memset(¶ms, 0, sizeof(params));
\r
1638 params.cipher = key->cipher;
\r
1639 params.key_len = key->key_len;
\r
1640 params.seq_len = key->seq_len;
\r
1641 params.seq = key->seq;
\r
1642 params.key = key->key;
\r
1644 callback(cookie, ¶ms);
\r
1646 return key->key_len ? 0 : -ENOENT;
\r
1648 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
1652 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1653 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1654 u8 key_index, bool pairwise, const u8 *mac_addr)
\r
1655 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1656 u8 key_index, const u8 *mac_addr)
\r
1657 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1659 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1660 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1662 DBG_871X(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index);
\r
1664 if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
\r
1666 //clear the flag of wep default key set.
\r
1667 psecuritypriv->bWepDefaultKeyIdxSet = 0;
\r
1673 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
\r
1674 struct net_device *ndev, u8 key_index
\r
1675 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1676 , bool unicast, bool multicast
\r
1680 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1681 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1683 DBG_871X(FUNC_NDEV_FMT" key_index=%d"
\r
1684 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1685 ", unicast=%d, multicast=%d"
\r
1687 ".\n", FUNC_NDEV_ARG(ndev), key_index
\r
1688 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1689 , unicast, multicast
\r
1693 if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) //set wep default key
\r
1695 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1697 psecuritypriv->dot11PrivacyKeyIndex = key_index;
\r
1699 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
\r
1700 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1701 if (psecuritypriv->dot11DefKeylen[key_index] == 13)
\r
1703 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
\r
1704 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1707 psecuritypriv->bWepDefaultKeyIdxSet = 1; //set the flag to represent that wep default key has been set
\r
1714 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
\r
1715 struct net_device *ndev,
\r
1716 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
1721 struct station_info *sinfo)
\r
1724 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1725 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1726 struct sta_info *psta = NULL;
\r
1727 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1729 sinfo->filled = 0;
\r
1732 DBG_871X(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
\r
1737 psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
\r
1738 if (psta == NULL) {
\r
1739 DBG_8192C("%s, sta_info is null\n", __func__);
\r
1744 #ifdef CONFIG_DEBUG_CFG80211
\r
1745 DBG_871X(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
\r
1748 //for infra./P2PClient mode
\r
1749 if( check_fwstate(pmlmepriv, WIFI_STATION_STATE)
\r
1750 && check_fwstate(pmlmepriv, _FW_LINKED)
\r
1753 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
1755 if (_rtw_memcmp((u8 *)mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) {
\r
1756 DBG_871X("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
\r
1761 sinfo->filled |= STATION_INFO_SIGNAL;
\r
1762 sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
\r
1764 sinfo->filled |= STATION_INFO_TX_BITRATE;
\r
1765 sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
\r
1767 sinfo->filled |= STATION_INFO_RX_PACKETS;
\r
1768 sinfo->rx_packets = sta_rx_data_pkts(psta);
\r
1770 sinfo->filled |= STATION_INFO_TX_PACKETS;
\r
1771 sinfo->tx_packets = psta->sta_stats.tx_pkts;
\r
1775 //for Ad-Hoc/AP mode
\r
1776 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
\r
1777 ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
\r
1778 ||check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
1779 && check_fwstate(pmlmepriv, _FW_LINKED)
\r
1782 //TODO: should acquire station info...
\r
1789 extern int netdev_open(struct net_device *pnetdev);
\r
1790 #ifdef CONFIG_CONCURRENT_MODE
\r
1791 extern int netdev_if2_open(struct net_device *pnetdev);
\r
1795 enum nl80211_iftype {
\r
1796 NL80211_IFTYPE_UNSPECIFIED,
\r
1797 NL80211_IFTYPE_ADHOC, //1
\r
1798 NL80211_IFTYPE_STATION, //2
\r
1799 NL80211_IFTYPE_AP, //3
\r
1800 NL80211_IFTYPE_AP_VLAN,
\r
1801 NL80211_IFTYPE_WDS,
\r
1802 NL80211_IFTYPE_MONITOR, //6
\r
1803 NL80211_IFTYPE_MESH_POINT,
\r
1804 NL80211_IFTYPE_P2P_CLIENT, //8
\r
1805 NL80211_IFTYPE_P2P_GO, //9
\r
1807 NUM_NL80211_IFTYPES,
\r
1808 NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
\r
1811 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
\r
1812 struct net_device *ndev,
\r
1813 enum nl80211_iftype type, u32 *flags,
\r
1814 struct vif_params *params)
\r
1816 enum nl80211_iftype old_type;
\r
1817 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
\r
1818 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1819 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
1820 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
1822 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
1825 u8 change = _FALSE;
\r
1827 DBG_871X(FUNC_NDEV_FMT" type=%d\n", FUNC_NDEV_ARG(ndev), type);
\r
1829 if(adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE)
\r
1835 #ifdef CONFIG_CONCURRENT_MODE
\r
1836 if(padapter->adapter_type == SECONDARY_ADAPTER)
\r
1838 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev));
\r
1839 if(netdev_if2_open(ndev) != 0) {
\r
1840 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open fail\n", FUNC_NDEV_ARG(ndev));
\r
1845 else if(padapter->adapter_type == PRIMARY_ADAPTER)
\r
1846 #endif //CONFIG_CONCURRENT_MODE
\r
1848 DBG_871X(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
\r
1849 if(netdev_open(ndev) != 0) {
\r
1850 DBG_871X(FUNC_NDEV_FMT" call netdev_open fail\n", FUNC_NDEV_ARG(ndev));
\r
1856 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
1857 DBG_871X(FUNC_NDEV_FMT" call rtw_pwr_wakeup fail\n", FUNC_NDEV_ARG(ndev));
\r
1862 old_type = rtw_wdev->iftype;
\r
1863 DBG_871X(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
\r
1864 FUNC_NDEV_ARG(ndev), old_type, type);
\r
1866 if(old_type != type)
\r
1869 pmlmeext->action_public_rxseq = 0xffff;
\r
1870 pmlmeext->action_public_dialog_token = 0xff;
\r
1874 case NL80211_IFTYPE_ADHOC:
\r
1875 networkType = Ndis802_11IBSS;
\r
1877 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1878 case NL80211_IFTYPE_P2P_CLIENT:
\r
1880 case NL80211_IFTYPE_STATION:
\r
1881 networkType = Ndis802_11Infrastructure;
\r
1883 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1885 if(change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
1887 //it means remove GO and change mode from AP(GO) to station(P2P DEVICE)
\r
1888 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
1889 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
1891 DBG_8192C("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
\r
1894 #endif //CONFIG_P2P
\r
1896 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1897 case NL80211_IFTYPE_P2P_GO:
\r
1899 case NL80211_IFTYPE_AP:
\r
1900 networkType = Ndis802_11APMode;
\r
1902 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1904 if(change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
1906 //it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO)
\r
1907 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
\r
1910 #endif //CONFIG_P2P
\r
1913 ret = -EOPNOTSUPP;
\r
1917 rtw_wdev->iftype = type;
\r
1919 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE)
\r
1921 rtw_wdev->iftype = old_type;
\r
1926 rtw_setopmode_cmd(padapter, networkType,_TRUE);
\r
1930 DBG_871X(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret);
\r
1934 void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted)
\r
1936 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
1939 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
1940 if (pwdev_priv->scan_request != NULL) {
\r
1941 #ifdef CONFIG_DEBUG_CFG80211
\r
1942 DBG_871X("%s with scan req\n", __FUNCTION__);
\r
1945 /* avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); */
\r
1946 if(pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
\r
1948 DBG_8192C("error wiphy compare\n");
\r
1952 cfg80211_scan_done(pwdev_priv->scan_request, aborted);
\r
1955 pwdev_priv->scan_request = NULL;
\r
1957 #ifdef CONFIG_DEBUG_CFG80211
\r
1958 DBG_871X("%s without scan req\n", __FUNCTION__);
\r
1961 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
1964 void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork)
\r
1966 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
1967 struct wiphy *wiphy = pwdev->wiphy;
\r
1968 struct cfg80211_bss *bss = NULL;
\r
1969 WLAN_BSSID_EX select_network = pnetwork->network;
\r
1971 bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
\r
1972 select_network.MacAddress, select_network.Ssid.Ssid,
\r
1973 select_network.Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
\r
1974 0/*WLAN_CAPABILITY_ESS*/);
\r
1977 cfg80211_unlink_bss(wiphy, bss);
\r
1978 DBG_8192C("%s(): cfg80211_unlink %s!! () ",__func__,select_network.Ssid.Ssid );
\r
1979 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
1980 cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
\r
1982 cfg80211_put_bss(bss);
\r
1988 void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
\r
1991 _list *plist, *phead;
\r
1992 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
1993 _queue *queue = &(pmlmepriv->scanned_queue);
\r
1994 struct wlan_network *pnetwork = NULL;
\r
1996 u32 wait_for_surveydone;
\r
1999 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
\r
2000 #endif //CONFIG_P2P
\r
2001 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
2003 #ifdef CONFIG_DEBUG_CFG80211
\r
2004 DBG_8192C("%s\n", __func__);
\r
2007 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
2009 phead = get_list_head(queue);
\r
2010 plist = get_next(phead);
\r
2014 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
\r
2017 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
\r
2019 //report network only if the current channel set contains the channel to which this network belongs
\r
2020 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
\r
2021 && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
\r
2022 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
\r
2025 //ev=translate_scan(padapter, a, pnetwork, ev, stop);
\r
2026 rtw_cfg80211_inform_bss(padapter, pnetwork);
\r
2028 /* //check ralink testbed RSN IE length
\r
2030 if(_rtw_memcmp(pnetwork->network.Ssid.Ssid, "Ralink_11n_AP",13))
\r
2034 p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
\r
2035 DBG_871X("ie_len=%d\n", ie_len);
\r
2038 plist = get_next(plist);
\r
2042 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
2045 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
\r
2048 uint wps_ielen = 0;
\r
2050 u32 p2p_ielen = 0;
\r
2052 u32 wfd_ielen = 0;
\r
2054 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2056 #ifdef CONFIG_DEBUG_CFG80211
\r
2057 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
2062 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
2064 #ifdef CONFIG_DEBUG_CFG80211
\r
2065 DBG_8192C("probe_req_wps_ielen=%d\n", wps_ielen);
\r
2068 if(pmlmepriv->wps_probe_req_ie)
\r
2070 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
\r
2071 pmlmepriv->wps_probe_req_ie_len = 0;
\r
2072 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
\r
2073 pmlmepriv->wps_probe_req_ie = NULL;
\r
2076 pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
\r
2077 if ( pmlmepriv->wps_probe_req_ie == NULL) {
\r
2078 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2082 _rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
\r
2083 pmlmepriv->wps_probe_req_ie_len = wps_ielen;
\r
2086 //buf += wps_ielen;
\r
2087 //len -= wps_ielen;
\r
2090 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
2092 struct wifidirect_info *wdinfo = &padapter->wdinfo;
\r
2093 u32 attr_contentlen = 0;
\r
2094 u8 listen_ch_attr[5];
\r
2096 #ifdef CONFIG_DEBUG_CFG80211
\r
2097 DBG_8192C("probe_req_p2p_ielen=%d\n", p2p_ielen);
\r
2100 if(pmlmepriv->p2p_probe_req_ie)
\r
2102 u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
\r
2103 pmlmepriv->p2p_probe_req_ie_len = 0;
\r
2104 rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len);
\r
2105 pmlmepriv->p2p_probe_req_ie = NULL;
\r
2108 pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen);
\r
2109 if ( pmlmepriv->p2p_probe_req_ie == NULL) {
\r
2110 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2114 _rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
\r
2115 pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
\r
2117 if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8*)listen_ch_attr, (uint*) &attr_contentlen)
\r
2118 && attr_contentlen == 5)
\r
2120 if (wdinfo->listen_channel != listen_ch_attr[4]) {
\r
2121 DBG_871X(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n",
\r
2122 FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2],
\r
2123 listen_ch_attr[3], listen_ch_attr[4]);
\r
2124 wdinfo->listen_channel = listen_ch_attr[4];
\r
2128 #endif //CONFIG_P2P
\r
2130 //buf += p2p_ielen;
\r
2131 //len -= p2p_ielen;
\r
2134 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
2136 #ifdef CONFIG_DEBUG_CFG80211
\r
2137 DBG_8192C("probe_req_wfd_ielen=%d\n", wfd_ielen);
\r
2140 if(pmlmepriv->wfd_probe_req_ie)
\r
2142 u32 free_len = pmlmepriv->wfd_probe_req_ie_len;
\r
2143 pmlmepriv->wfd_probe_req_ie_len = 0;
\r
2144 rtw_mfree(pmlmepriv->wfd_probe_req_ie, free_len);
\r
2145 pmlmepriv->wfd_probe_req_ie = NULL;
\r
2148 pmlmepriv->wfd_probe_req_ie = rtw_malloc(wfd_ielen);
\r
2149 if ( pmlmepriv->wfd_probe_req_ie == NULL) {
\r
2150 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2154 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
\r
2156 #endif //CONFIG_WFD
\r
2164 static int cfg80211_rtw_scan(struct wiphy *wiphy
\r
2165 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
\r
2166 , struct net_device *ndev
\r
2168 , struct cfg80211_scan_request *request)
\r
2170 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
2171 struct net_device *ndev = wdev_to_ndev(request->wdev);
\r
2174 u8 _status = _FALSE;
\r
2176 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
\r
2177 struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
\r
2180 uint wps_ielen=0;
\r
2183 u8 survey_times=3;
\r
2184 u8 survey_times_for_one_ch=6;
\r
2185 struct cfg80211_ssid *ssids = request->ssids;
\r
2186 int social_channel = 0, j = 0;
\r
2187 bool need_indicate_scan_done = _FALSE;
\r
2189 _adapter *padapter;
\r
2190 struct rtw_wdev_priv *pwdev_priv;
\r
2191 struct mlme_priv *pmlmepriv;
\r
2193 struct wifidirect_info *pwdinfo;
\r
2194 #endif //CONFIG_P2P
\r
2195 #ifdef CONFIG_CONCURRENT_MODE
\r
2196 PADAPTER pbuddy_adapter = NULL;
\r
2197 struct mlme_priv *pbuddy_mlmepriv = NULL;
\r
2198 #endif //CONFIG_CONCURRENT_MODE
\r
2200 if (ndev == NULL) {
\r
2205 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2206 pwdev_priv = adapter_wdev_data(padapter);
\r
2207 pmlmepriv= &padapter->mlmepriv;
\r
2209 pwdinfo= &(padapter->wdinfo);
\r
2210 #endif //CONFIG_P2P
\r
2212 //#ifdef CONFIG_DEBUG_CFG80211
\r
2213 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
2216 #ifdef CONFIG_CONCURRENT_MODE
\r
2217 if (padapter->pbuddy_adapter) {
\r
2218 pbuddy_adapter = padapter->pbuddy_adapter;
\r
2219 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
\r
2221 #endif //CONFIG_CONCURRENT_MODE
\r
2223 #ifdef CONFIG_MP_INCLUDED
\r
2224 if (padapter->registrypriv.mp_mode == 1)
\r
2226 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter));
\r
2230 #ifdef CONFIG_CONCURRENT_MODE
\r
2231 if (padapter->pbuddy_adapter) {
\r
2232 if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1)
\r
2234 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter));
\r
2239 #endif //CONFIG_CONCURRENT_MODE
\r
2242 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2243 pwdev_priv->scan_request = request;
\r
2244 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2246 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
2248 #ifdef CONFIG_DEBUG_CFG80211
\r
2249 DBG_871X("%s under WIFI_AP_STATE\n", __FUNCTION__);
\r
2252 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
\r
2254 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2256 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
\r
2258 DBG_8192C("AP mode process WPS \n");
\r
2261 need_indicate_scan_done = _TRUE;
\r
2262 goto check_need_indicate_scan_done;
\r
2266 rtw_ps_deny(padapter, PS_DENY_SCAN);
\r
2267 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
2268 need_indicate_scan_done = _TRUE;
\r
2269 goto check_need_indicate_scan_done;
\r
2273 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
2275 if(ssids->ssid != NULL
\r
2276 && _rtw_memcmp(ssids->ssid, "DIRECT-", 7)
\r
2277 && rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
\r
2280 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2282 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
\r
2283 adapter_wdev_data(padapter)->p2p_enabled = _TRUE;
\r
2287 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
2288 #ifdef CONFIG_DEBUG_CFG80211
\r
2289 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
2292 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
\r
2294 if(request->n_channels == 3 &&
\r
2295 request->channels[0]->hw_value == 1 &&
\r
2296 request->channels[1]->hw_value == 6 &&
\r
2297 request->channels[2]->hw_value == 11
\r
2300 social_channel = 1;
\r
2304 #endif //CONFIG_P2P
\r
2306 if(request->ie && request->ie_len>0)
\r
2308 rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len );
\r
2311 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
\r
2312 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2313 need_indicate_scan_done = _TRUE;
\r
2314 goto check_need_indicate_scan_done;
\r
2315 } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
2316 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2318 goto check_need_indicate_scan_done;
\r
2321 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)
\r
2323 #if 1 // Miracast can't do AP scan
\r
2324 static u32 lastscantime = 0;
\r
2327 passtime = rtw_get_passing_time_ms(lastscantime);
\r
2328 lastscantime = rtw_get_current_time();
\r
2329 if (passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD)
\r
2332 DBG_871X("%s: bBusyTraffic == _TRUE\n", __FUNCTION__);
\r
2333 need_indicate_scan_done = _TRUE;
\r
2334 goto check_need_indicate_scan_done;
\r
2338 if (rtw_is_scan_deny(padapter)){
\r
2339 DBG_871X(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter));
\r
2340 need_indicate_scan_done = _TRUE;
\r
2341 goto check_need_indicate_scan_done;
\r
2344 #ifdef CONFIG_CONCURRENT_MODE
\r
2345 if(pbuddy_mlmepriv && (pbuddy_mlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))
\r
2347 #if 1 // Miracast can't do AP scan
\r
2348 static u32 buddylastscantime = 0;
\r
2351 passtime = rtw_get_passing_time_ms(buddylastscantime);
\r
2352 buddylastscantime = rtw_get_current_time();
\r
2353 if ((passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD)
\r
2354 //#ifdef CONFIG_P2P
\r
2355 // ||(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
\r
2356 //#endif //CONFIG_P2P
\r
2360 DBG_871X("%s: bBusyTraffic == _TRUE at buddy_intf\n", __FUNCTION__);
\r
2361 need_indicate_scan_done = _TRUE;
\r
2362 goto check_need_indicate_scan_done;
\r
2366 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE) {
\r
2367 DBG_871X("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv->fw_state);
\r
2368 need_indicate_scan_done = _TRUE;
\r
2369 goto check_need_indicate_scan_done;
\r
2371 } else if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY)) {
\r
2372 bool scan_via_buddy = _FALSE;
\r
2373 struct rtw_wdev_priv *buddy_wdev_priv = adapter_wdev_data(pbuddy_adapter);
\r
2375 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2376 _enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
\r
2377 if (buddy_wdev_priv->scan_request) {
\r
2378 DBG_871X("scan via buddy\n");
\r
2379 pmlmepriv->scanning_via_buddy_intf = _TRUE;
\r
2380 _enter_critical_bh(&pmlmepriv->lock, &irqL);
\r
2381 set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
\r
2382 _exit_critical_bh(&pmlmepriv->lock, &irqL);
\r
2383 scan_via_buddy = _TRUE;
\r
2385 _exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
\r
2386 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2388 if (scan_via_buddy == _FALSE)
\r
2389 need_indicate_scan_done = _TRUE;
\r
2391 goto check_need_indicate_scan_done;
\r
2393 #endif /* CONFIG_CONCURRENT_MODE */
\r
2396 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
\r
2398 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
\r
2399 rtw_free_network_queue(padapter, _TRUE);
\r
2401 if(social_channel == 0)
\r
2402 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
\r
2404 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
\r
2406 #endif //CONFIG_P2P
\r
2409 _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
\r
2410 //parsing request ssids, n_ssids
\r
2411 for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
\r
2412 #ifdef CONFIG_DEBUG_CFG80211
\r
2413 DBG_8192C("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
\r
2415 _rtw_memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
\r
2416 ssid[i].SsidLength = ssids[i].ssid_len;
\r
2419 /* parsing channels, n_channels */
\r
2420 _rtw_memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
\r
2421 for (i=0;i<request->n_channels && i<RTW_CHANNEL_SCAN_AMOUNT;i++) {
\r
2422 #ifdef CONFIG_DEBUG_CFG80211
\r
2423 DBG_871X(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
\r
2425 ch[i].hw_value = request->channels[i]->hw_value;
\r
2426 ch[i].flags = request->channels[i]->flags;
\r
2429 _enter_critical_bh(&pmlmepriv->lock, &irqL);
\r
2430 if (request->n_channels == 1) {
\r
2431 for(i=1;i<survey_times_for_one_ch;i++)
\r
2432 _rtw_memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
\r
2433 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times_for_one_ch);
\r
2434 } else if (request->n_channels <= 4) {
\r
2435 for(j=request->n_channels-1;j>=0;j--)
\r
2436 for(i=0;i<survey_times;i++)
\r
2438 _rtw_memcpy(&ch[j*survey_times+i], &ch[j], sizeof(struct rtw_ieee80211_channel));
\r
2440 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * request->n_channels);
\r
2442 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
\r
2444 _exit_critical_bh(&pmlmepriv->lock, &irqL);
\r
2447 if(_status == _FALSE)
\r
2452 check_need_indicate_scan_done:
\r
2453 if (_TRUE == need_indicate_scan_done)
\r
2455 rtw_cfg80211_surveydone_event_callback(padapter);
\r
2456 rtw_cfg80211_indicate_scan_done(padapter, _FALSE);
\r
2460 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
\r
2467 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
\r
2470 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
\r
2472 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
\r
2473 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
\r
2476 iwm->conf.rts_threshold = wiphy->rts_threshold;
\r
2478 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
\r
2479 CFG_RTS_THRESHOLD,
\r
2480 iwm->conf.rts_threshold);
\r
2485 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
\r
2486 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
\r
2489 iwm->conf.frag_threshold = wiphy->frag_threshold;
\r
2491 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
\r
2492 CFG_FRAG_THRESHOLD,
\r
2493 iwm->conf.frag_threshold);
\r
2498 DBG_8192C("%s\n", __func__);
\r
2504 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
\r
2506 DBG_8192C("%s, wpa_version=%d\n", __func__, wpa_version);
\r
2508 if (!wpa_version) {
\r
2509 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
2514 if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
\r
2516 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
\r
2520 if (wpa_version & NL80211_WPA_VERSION_2)
\r
2522 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
\r
2526 #ifdef CONFIG_WAPI_SUPPORT
\r
2527 if (wpa_version & NL80211_WAPI_VERSION_1)
\r
2529 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWAPI;
\r
2537 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
\r
2538 enum nl80211_auth_type sme_auth_type)
\r
2540 DBG_8192C("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
\r
2543 switch (sme_auth_type) {
\r
2544 case NL80211_AUTHTYPE_AUTOMATIC:
\r
2546 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
\r
2549 case NL80211_AUTHTYPE_OPEN_SYSTEM:
\r
2551 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
\r
2553 if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
\r
2554 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2556 #ifdef CONFIG_WAPI_SUPPORT
\r
2557 if(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI)
\r
2558 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2562 case NL80211_AUTHTYPE_SHARED_KEY:
\r
2564 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
\r
2566 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2571 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
\r
2572 //return -ENOTSUPP;
\r
2579 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
\r
2581 u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2583 u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
\r
2584 &psecuritypriv->dot118021XGrpPrivacy;
\r
2586 DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
\r
2590 *profile_cipher = _NO_PRIVACY_;
\r
2591 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
\r
2596 case IW_AUTH_CIPHER_NONE:
\r
2597 *profile_cipher = _NO_PRIVACY_;
\r
2598 ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2599 #ifdef CONFIG_WAPI_SUPPORT
\r
2600 if(psecuritypriv->dot11PrivacyAlgrthm ==_SMS4_ )
\r
2602 *profile_cipher = _SMS4_;
\r
2606 case WLAN_CIPHER_SUITE_WEP40:
\r
2607 *profile_cipher = _WEP40_;
\r
2608 ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2610 case WLAN_CIPHER_SUITE_WEP104:
\r
2611 *profile_cipher = _WEP104_;
\r
2612 ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2614 case WLAN_CIPHER_SUITE_TKIP:
\r
2615 *profile_cipher = _TKIP_;
\r
2616 ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2618 case WLAN_CIPHER_SUITE_CCMP:
\r
2619 *profile_cipher = _AES_;
\r
2620 ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2622 #ifdef CONFIG_WAPI_SUPPORT
\r
2623 case WLAN_CIPHER_SUITE_SMS4:
\r
2624 *profile_cipher = _SMS4_;
\r
2625 ndisencryptstatus = Ndis802_11_EncrypteionWAPI;
\r
2629 DBG_8192C("Unsupported cipher: 0x%x\n", cipher);
\r
2635 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
\r
2637 //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
\r
2638 // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
\r
2644 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
\r
2646 DBG_8192C("%s, key_mgt=0x%x\n", __func__, key_mgt);
\r
2648 if (key_mgt == WLAN_AKM_SUITE_8021X)
\r
2649 //*auth_type = UMAC_AUTH_TYPE_8021X;
\r
2650 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2651 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
\r
2652 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2654 #ifdef CONFIG_WAPI_SUPPORT
\r
2655 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_PSK){
\r
2656 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2658 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_CERT){
\r
2659 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2665 DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt);
\r
2672 static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
\r
2674 u8 *buf=NULL, *pos=NULL;
\r
2676 int group_cipher = 0, pairwise_cipher = 0;
\r
2681 u8 null_addr[]= {0,0,0,0,0,0};
\r
2683 if (pie == NULL || !ielen) {
\r
2684 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
\r
2685 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2689 if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
\r
2694 buf = rtw_zmalloc(ielen);
\r
2700 _rtw_memcpy(buf, pie , ielen);
\r
2705 DBG_8192C("set wpa_ie(length:%zu):\n", ielen);
\r
2706 for(i=0;i<ielen;i=i+8)
\r
2707 DBG_8192C("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x \n",buf[i],buf[i+1],buf[i+2],buf[i+3],buf[i+4],buf[i+5],buf[i+6],buf[i+7]);
\r
2711 if(ielen < RSN_HEADER_LEN){
\r
2712 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
\r
2717 pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
\r
2718 if(pwpa && wpa_ielen>0)
\r
2720 if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
2722 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
2723 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
\r
2724 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
\r
2726 DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
\r
2730 pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
\r
2731 if(pwpa2 && wpa2_ielen>0)
\r
2733 if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
2735 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
2736 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
\r
2737 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
\r
2739 DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
\r
2743 if (group_cipher == 0)
\r
2745 group_cipher = WPA_CIPHER_NONE;
\r
2747 if (pairwise_cipher == 0)
\r
2749 pairwise_cipher = WPA_CIPHER_NONE;
\r
2752 switch(group_cipher)
\r
2754 case WPA_CIPHER_NONE:
\r
2755 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
\r
2756 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
\r
2758 case WPA_CIPHER_WEP40:
\r
2759 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
\r
2760 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2762 case WPA_CIPHER_TKIP:
\r
2763 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
\r
2764 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2766 case WPA_CIPHER_CCMP:
\r
2767 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
\r
2768 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2770 case WPA_CIPHER_WEP104:
\r
2771 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
\r
2772 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2776 switch(pairwise_cipher)
\r
2778 case WPA_CIPHER_NONE:
\r
2779 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
\r
2780 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
\r
2782 case WPA_CIPHER_WEP40:
\r
2783 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
\r
2784 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2786 case WPA_CIPHER_TKIP:
\r
2787 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
\r
2788 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2790 case WPA_CIPHER_CCMP:
\r
2791 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
\r
2792 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2794 case WPA_CIPHER_WEP104:
\r
2795 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
\r
2796 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2800 {/* handle wps_ie */
\r
2804 wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
\r
2805 if (wps_ie && wps_ielen > 0) {
\r
2806 DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen);
\r
2807 padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
\r
2808 _rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
\r
2809 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2811 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2816 {//check p2p_ie for assoc req;
\r
2819 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2821 if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen)))
\r
2823 #ifdef CONFIG_DEBUG_CFG80211
\r
2824 DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
\r
2827 if(pmlmepriv->p2p_assoc_req_ie)
\r
2829 u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
\r
2830 pmlmepriv->p2p_assoc_req_ie_len = 0;
\r
2831 rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
\r
2832 pmlmepriv->p2p_assoc_req_ie = NULL;
\r
2835 pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
\r
2836 if ( pmlmepriv->p2p_assoc_req_ie == NULL) {
\r
2837 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2840 _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
\r
2841 pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
\r
2844 #endif //CONFIG_P2P
\r
2847 {//check wfd_ie for assoc req;
\r
2850 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2852 if(rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen))
\r
2854 #ifdef CONFIG_DEBUG_CFG80211
\r
2855 DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
\r
2858 if(pmlmepriv->wfd_assoc_req_ie)
\r
2860 u32 free_len = pmlmepriv->wfd_assoc_req_ie_len;
\r
2861 pmlmepriv->wfd_assoc_req_ie_len = 0;
\r
2862 rtw_mfree(pmlmepriv->wfd_assoc_req_ie, free_len);
\r
2863 pmlmepriv->wfd_assoc_req_ie = NULL;
\r
2866 pmlmepriv->wfd_assoc_req_ie = rtw_malloc(wfd_ielen);
\r
2867 if ( pmlmepriv->wfd_assoc_req_ie == NULL) {
\r
2868 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2871 rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
\r
2874 #endif //CONFIG_WFD
\r
2876 //TKIP and AES disallow multicast packets until installing group key
\r
2877 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
\r
2878 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
\r
2879 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
\r
2880 //WPS open need to enable multicast
\r
2881 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
\r
2882 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
\r
2884 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
\r
2885 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
\r
2886 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
\r
2890 rtw_mfree(buf, ielen);
\r
2892 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2896 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
\r
2897 struct cfg80211_ibss_params *params)
\r
2899 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2900 NDIS_802_11_SSID ndis_ssid;
\r
2901 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
2902 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2905 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
2910 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
\r
2915 #ifdef CONFIG_CONCURRENT_MODE
\r
2916 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
\r
2917 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
\r
2921 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
\r
2922 rtw_scan_abort(padapter->pbuddy_adapter);
\r
2924 #endif //CONFIG_CONCURRENT_MODE
\r
2926 if (!params->ssid || !params->ssid_len)
\r
2932 if (params->ssid_len > IW_ESSID_MAX_SIZE){
\r
2938 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
\r
2939 ndis_ssid.SsidLength = params->ssid_len;
\r
2940 _rtw_memcpy(ndis_ssid.Ssid, (u8 *)params->ssid, params->ssid_len);
\r
2942 //DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, params->ssid_len);
\r
2944 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2945 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
\r
2946 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
2947 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
\r
2948 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
2950 ret = rtw_cfg80211_set_auth_type(psecuritypriv, NL80211_AUTHTYPE_OPEN_SYSTEM);
\r
2951 rtw_set_802_11_authentication_mode(padapter, psecuritypriv->ndisauthtype);
\r
2953 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE)
\r
2963 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
\r
2965 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2966 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
2967 enum nl80211_iftype old_type;
\r
2970 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
2972 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
2974 old_type = rtw_wdev->iftype;
\r
2976 rtw_set_to_roam(padapter, 0);
\r
2978 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
2980 rtw_scan_abort(padapter);
\r
2981 LeaveAllPowerSaveMode(padapter);
\r
2983 rtw_wdev->iftype = NL80211_IFTYPE_STATION;
\r
2985 if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) ==_FALSE)
\r
2987 rtw_wdev->iftype = old_type;
\r
2991 rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure,_TRUE);
\r
2995 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3000 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
\r
3001 struct cfg80211_connect_params *sme)
\r
3006 struct wlan_network *pnetwork = NULL;
\r
3007 NDIS_802_11_AUTHENTICATION_MODE authmode;
\r
3008 NDIS_802_11_SSID ndis_ssid;
\r
3009 u8 *dst_ssid, *src_ssid;
\r
3010 u8 *dst_bssid, *src_bssid;
\r
3011 //u8 matched_by_bssid=_FALSE;
\r
3012 //u8 matched_by_ssid=_FALSE;
\r
3013 u8 matched=_FALSE;
\r
3014 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3015 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
3016 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3017 _queue *queue = &pmlmepriv->scanned_queue;
\r
3019 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
3021 DBG_871X("=>"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3022 DBG_871X("privacy=%d, key=%p, key_len=%d, key_idx=%d\n",
\r
3023 sme->privacy, sme->key, sme->key_len, sme->key_idx);
\r
3026 if(adapter_wdev_data(padapter)->block == _TRUE)
\r
3029 DBG_871X("%s wdev_priv.block is set\n", __FUNCTION__);
\r
3033 #ifdef CONFIG_PLATFORM_MSTAR_SCAN_BEFORE_CONNECT
\r
3034 printk("MStar Android!\n");
\r
3035 if(adapter_wdev_data(padapter)->bandroid_scan == _FALSE)
\r
3038 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
3039 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
3040 #endif //CONFIG_P2P
\r
3043 printk("Android hasn't attached yet!\n");
\r
3049 rtw_ps_deny(padapter, PS_DENY_JOIN);
\r
3050 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
3055 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
\r
3060 #ifdef CONFIG_CONCURRENT_MODE
\r
3061 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
\r
3062 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
\r
3066 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
\r
3067 rtw_scan_abort(padapter->pbuddy_adapter);
\r
3071 if (!sme->ssid || !sme->ssid_len)
\r
3077 if (sme->ssid_len > IW_ESSID_MAX_SIZE){
\r
3083 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
\r
3084 ndis_ssid.SsidLength = sme->ssid_len;
\r
3085 _rtw_memcpy(ndis_ssid.Ssid, (u8 *)sme->ssid, sme->ssid_len);
\r
3087 DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
\r
3091 DBG_8192C("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
\r
3094 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
3096 DBG_8192C("%s, fw_state=0x%x, goto exit\n", __FUNCTION__, pmlmepriv->fw_state);
\r
3099 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
\r
3100 rtw_scan_abort(padapter);
\r
3103 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
3104 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
\r
3105 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
3106 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
\r
3107 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
3109 #ifdef CONFIG_WAPI_SUPPORT
\r
3110 padapter->wapiInfo.bWapiEnable = false;
\r
3113 ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
\r
3117 #ifdef CONFIG_WAPI_SUPPORT
\r
3118 if(sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1)
\r
3120 padapter->wapiInfo.bWapiEnable = true;
\r
3121 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
\r
3122 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
\r
3126 ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
\r
3128 #ifdef CONFIG_WAPI_SUPPORT
\r
3129 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI)
\r
3130 padapter->mlmeextpriv.mlmext_info.auth_algo = psecuritypriv->dot11AuthAlgrthm;
\r
3137 DBG_8192C("%s, ie_len=%zu\n", __func__, sme->ie_len);
\r
3139 ret = rtw_cfg80211_set_wpa_ie(padapter, (u8 *)sme->ie, sme->ie_len);
\r
3143 if (sme->crypto.n_ciphers_pairwise) {
\r
3144 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
\r
3149 //For WEP Shared auth
\r
3150 if((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared
\r
3151 || psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && sme->key
\r
3154 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
3155 NDIS_802_11_WEP *pwep = NULL;
\r
3156 DBG_871X("%s(): Shared/Auto WEP\n",__FUNCTION__);
\r
3158 wep_key_idx = sme->key_idx;
\r
3159 wep_key_len = sme->key_len;
\r
3161 if (sme->key_idx > WEP_KEYS) {
\r
3166 if (wep_key_len > 0)
\r
3168 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
3169 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
\r
3170 pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
\r
3172 DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
\r
3177 _rtw_memset(pwep, 0, wep_total_len);
\r
3179 pwep->KeyLength = wep_key_len;
\r
3180 pwep->Length = wep_total_len;
\r
3182 if(wep_key_len==13)
\r
3184 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
\r
3185 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
\r
3193 pwep->KeyIndex = wep_key_idx;
\r
3194 pwep->KeyIndex |= 0x80000000;
\r
3196 _rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
\r
3198 if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
\r
3200 ret = -EOPNOTSUPP ;
\r
3204 rtw_mfree((u8 *)pwep,wep_total_len);
\r
3211 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
\r
3215 if (sme->crypto.n_akm_suites) {
\r
3216 ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
\r
3221 #ifdef CONFIG_WAPI_SUPPORT
\r
3222 if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_PSK){
\r
3223 padapter->wapiInfo.bWapiPSK = true;
\r
3225 else if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_CERT){
\r
3226 padapter->wapiInfo.bWapiPSK = false;
\r
3230 authmode = psecuritypriv->ndisauthtype;
\r
3231 rtw_set_802_11_authentication_mode(padapter, authmode);
\r
3233 //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
\r
3235 if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid) == _FALSE) {
\r
3240 DBG_8192C("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy);
\r
3244 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
\r
3246 DBG_8192C("<=%s, ret %d\n",__FUNCTION__, ret);
\r
3248 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3253 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
\r
3256 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3258 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3260 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
3262 rtw_set_to_roam(padapter, 0);
\r
3264 //if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
3266 rtw_scan_abort(padapter);
\r
3267 LeaveAllPowerSaveMode(padapter);
\r
3268 rtw_disassoc_cmd(padapter, 500, _FALSE);
\r
3270 DBG_871X("%s...call rtw_indicate_disconnect\n", __FUNCTION__);
\r
3272 rtw_indicate_disconnect(padapter);
\r
3274 rtw_free_assoc_resources(padapter, 1);
\r
3275 rtw_pwr_wakeup(padapter);
\r
3278 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3280 DBG_871X(FUNC_NDEV_FMT" return 0\n", FUNC_NDEV_ARG(ndev));
\r
3284 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
\r
3285 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
\r
3286 struct wireless_dev *wdev,
\r
3288 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE)
\r
3289 enum nl80211_tx_power_setting type, int mbm)
\r
3291 enum tx_power_setting type, int dbm)
\r
3295 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
\r
3299 case NL80211_TX_POWER_AUTOMATIC:
\r
3301 case NL80211_TX_POWER_FIXED:
\r
3302 if (mbm < 0 || (mbm % 100))
\r
3303 return -EOPNOTSUPP;
\r
3305 if (!test_bit(IWM_STATUS_READY, &iwm->status))
\r
3308 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
\r
3309 CFG_TX_PWR_LIMIT_USR,
\r
3310 MBM_TO_DBM(mbm) * 2);
\r
3314 return iwm_tx_power_trigger(iwm);
\r
3316 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
\r
3317 return -EOPNOTSUPP;
\r
3320 DBG_8192C("%s\n", __func__);
\r
3324 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
\r
3325 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
\r
3326 struct wireless_dev *wdev,
\r
3330 DBG_8192C("%s\n", __func__);
\r
3337 inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
\r
3339 struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter);
\r
3340 return rtw_wdev_priv->power_mgmt;
\r
3343 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
\r
3344 struct net_device *ndev,
\r
3345 bool enabled, int timeout)
\r
3347 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3348 struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter);
\r
3350 DBG_871X(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
\r
3351 enabled, timeout);
\r
3353 rtw_wdev_priv->power_mgmt = enabled;
\r
3357 LPS_Leave(padapter, "CFG80211_PWRMGMT");
\r
3363 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
\r
3364 struct net_device *ndev,
\r
3365 struct cfg80211_pmksa *pmksa)
\r
3367 u8 index,blInserted = _FALSE;
\r
3368 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3369 struct mlme_priv *mlme = &padapter->mlmepriv;
\r
3370 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3371 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
\r
3373 DBG_871X(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
\r
3374 , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
\r
3376 if ( _rtw_memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
\r
3381 if (check_fwstate(mlme, _FW_LINKED) == _FALSE) {
\r
3382 DBG_871X(FUNC_NDEV_FMT" not set pmksa cause not in linked state\n", FUNC_NDEV_ARG(ndev));
\r
3386 blInserted = _FALSE;
\r
3389 for(index=0 ; index<NUM_PMKID_CACHE; index++)
\r
3391 if( _rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) ==_TRUE )
\r
3392 { // BSSID is matched, the same AP => rewrite with new PMKID.
\r
3393 DBG_871X(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(ndev));
\r
3395 _rtw_memcpy( psecuritypriv->PMKIDList[index].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
\r
3396 psecuritypriv->PMKIDList[index].bUsed = _TRUE;
\r
3397 psecuritypriv->PMKIDIndex = index+1;
\r
3398 blInserted = _TRUE;
\r
3405 // Find a new entry
\r
3406 DBG_871X(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
\r
3407 FUNC_NDEV_ARG(ndev), psecuritypriv->PMKIDIndex );
\r
3409 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, (u8 *)pmksa->bssid, ETH_ALEN);
\r
3410 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
\r
3412 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
\r
3413 psecuritypriv->PMKIDIndex++ ;
\r
3414 if(psecuritypriv->PMKIDIndex==16)
\r
3416 psecuritypriv->PMKIDIndex =0;
\r
3423 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
\r
3424 struct net_device *ndev,
\r
3425 struct cfg80211_pmksa *pmksa)
\r
3427 u8 index, bMatched = _FALSE;
\r
3428 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3429 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3431 DBG_871X(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
\r
3432 , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
\r
3434 for(index=0 ; index<NUM_PMKID_CACHE; index++)
\r
3436 if( _rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) ==_TRUE )
\r
3437 { // BSSID is matched, the same AP => Remove this PMKID information and reset it.
\r
3438 _rtw_memset(psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN );
\r
3439 _rtw_memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN );
\r
3440 psecuritypriv->PMKIDList[index].bUsed = _FALSE;
\r
3442 DBG_871X(FUNC_NDEV_FMT" clear id:%hhu\n", FUNC_NDEV_ARG(ndev), index);
\r
3447 if(_FALSE == bMatched)
\r
3449 DBG_871X(FUNC_NDEV_FMT" do not have matched BSSID\n"
\r
3450 , FUNC_NDEV_ARG(ndev));
\r
3457 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
\r
3458 struct net_device *ndev)
\r
3460 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3461 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3463 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3465 _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
\r
3466 psecuritypriv->PMKIDIndex = 0;
\r
3471 #ifdef CONFIG_AP_MODE
\r
3472 void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
3476 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
3477 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3478 struct net_device *ndev = padapter->pnetdev;
\r
3480 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
3482 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
\r
3484 struct station_info sinfo;
\r
3486 if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
\r
3487 ie_offset = _ASOCREQ_IE_OFFSET_;
\r
3488 else // WIFI_REASSOCREQ
\r
3489 ie_offset = _REASOCREQ_IE_OFFSET_;
\r
3492 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
\r
3493 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
\r
3494 sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
\r
3495 cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
\r
3497 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3498 channel = pmlmeext->cur_channel;
\r
3499 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
3500 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
3502 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
3504 #ifdef COMPAT_KERNEL_RELEASE
\r
3505 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3506 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
3507 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3508 #else //COMPAT_KERNEL_RELEASE
\r
3510 //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc()
\r
3511 #ifndef CONFIG_PLATFORM_MSTAR
\r
3512 pwdev->iftype = NL80211_IFTYPE_STATION;
\r
3513 #endif //CONFIG_PLATFORM_MSTAR
\r
3514 DBG_8192C("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
\r
3515 rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
\r
3516 DBG_8192C("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
\r
3517 pwdev->iftype = NL80211_IFTYPE_AP;
\r
3518 //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3520 #endif //COMPAT_KERNEL_RELEASE
\r
3521 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3525 void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason)
\r
3531 struct rtw_ieee80211_hdr *pwlanhdr;
\r
3532 unsigned short *fctrl;
\r
3533 u8 mgmt_buf[128] = {0};
\r
3534 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3535 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
3536 struct net_device *ndev = padapter->pnetdev;
\r
3538 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
3540 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
\r
3541 cfg80211_del_sta(ndev, da, GFP_ATOMIC);
\r
3542 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3543 channel = pmlmeext->cur_channel;
\r
3544 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
3545 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
3547 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
3549 pmgmt_frame = mgmt_buf;
\r
3550 pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
\r
3552 fctrl = &(pwlanhdr->frame_ctl);
\r
3555 //_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
\r
3556 //_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
3557 _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
3558 _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN);
\r
3559 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
3561 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
3562 pmlmeext->mgnt_seq++;
\r
3563 SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
\r
3565 pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
3566 frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
3568 reason = cpu_to_le16(reason);
\r
3569 pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
\r
3571 #ifdef COMPAT_KERNEL_RELEASE
\r
3572 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3573 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
3574 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3575 #else //COMPAT_KERNEL_RELEASE
\r
3576 cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len);
\r
3577 //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3578 #endif //COMPAT_KERNEL_RELEASE
\r
3579 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3582 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
\r
3586 DBG_8192C("%s\n", __func__);
\r
3591 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
\r
3595 DBG_8192C("%s\n", __func__);
\r
3600 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
\r
3605 int dot11_hdr_len = 24;
\r
3607 unsigned char *pdata;
\r
3609 unsigned char src_mac_addr[6];
\r
3610 unsigned char dst_mac_addr[6];
\r
3611 struct ieee80211_hdr *dot11_hdr;
\r
3612 struct ieee80211_radiotap_header *rtap_hdr;
\r
3613 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3615 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3618 rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
\r
3620 if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
\r
3623 rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
\r
3624 if (unlikely(rtap_hdr->it_version))
\r
3627 rtap_len = ieee80211_get_radiotap_len(skb->data);
\r
3628 if (unlikely(skb->len < rtap_len))
\r
3631 if(rtap_len != 14)
\r
3633 DBG_8192C("radiotap len (should be 14): %d\n", rtap_len);
\r
3637 /* Skip the ratio tap header */
\r
3638 skb_pull(skb, rtap_len);
\r
3640 dot11_hdr = (struct ieee80211_hdr *)skb->data;
\r
3641 frame_ctl = le16_to_cpu(dot11_hdr->frame_control);
\r
3642 /* Check if the QoS bit is set */
\r
3643 if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
\r
3644 /* Check if this ia a Wireless Distribution System (WDS) frame
\r
3645 * which has 4 MAC addresses
\r
3647 if (dot11_hdr->frame_control & 0x0080)
\r
3649 if ((dot11_hdr->frame_control & 0x0300) == 0x0300)
\r
3650 dot11_hdr_len += 6;
\r
3652 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
\r
3653 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
\r
3655 /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
\r
3656 * for two MAC addresses
\r
3658 skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
\r
3659 pdata = (unsigned char*)skb->data;
\r
3660 memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
\r
3661 memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
\r
3663 DBG_8192C("should be eapol packet\n");
\r
3665 /* Use the real net device to transmit the packet */
\r
3666 ret = _rtw_xmit_entry(skb, padapter->pnetdev);
\r
3671 else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE))
\r
3672 == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION)
\r
3675 //only for action frames
\r
3676 struct xmit_frame *pmgntframe;
\r
3677 struct pkt_attrib *pattrib;
\r
3678 unsigned char *pframe;
\r
3679 //u8 category, action, OUI_Subtype, dialogToken=0;
\r
3680 //unsigned char *frame_body;
\r
3681 struct rtw_ieee80211_hdr *pwlanhdr;
\r
3682 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
3683 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3684 u8 *buf = skb->data;
\r
3685 u32 len = skb->len;
\r
3686 u8 category, action;
\r
3689 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
\r
3690 DBG_8192C(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
\r
3691 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
\r
3695 DBG_8192C("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
\r
3696 MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
\r
3698 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0)
\r
3701 if (category == RTW_WLAN_CATEGORY_PUBLIC)
\r
3702 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
\r
3704 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
\r
3707 //starting alloc mgmt frame to dump it
\r
3708 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
3713 //update attribute
\r
3714 pattrib = &pmgntframe->attrib;
\r
3715 update_mgntframe_attrib(padapter, pattrib);
\r
3716 pattrib->retry_ctrl = _FALSE;
\r
3718 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
3720 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
3722 _rtw_memcpy(pframe, (void*)buf, len);
\r
3726 struct wifi_display_info *pwfd_info;
\r
3728 pwfd_info = padapter->wdinfo.wfd_info;
\r
3730 if ( _TRUE == pwfd_info->wfd_enable )
\r
3732 rtw_append_wfd_ie( padapter, pframe, &len );
\r
3735 #endif // CONFIG_WFD
\r
3736 pattrib->pktlen = len;
\r
3738 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
3739 //update seq number
\r
3740 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
\r
3741 pattrib->seqnum = pmlmeext->mgnt_seq;
\r
3742 pmlmeext->mgnt_seq++;
\r
3745 pattrib->last_txcmdsz = pattrib->pktlen;
\r
3747 dump_mgntframe(padapter, pmgntframe);
\r
3752 DBG_8192C("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE));
\r
3758 rtw_skb_free(skb);
\r
3764 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
\r
3766 DBG_8192C("%s\n", __func__);
\r
3769 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
\r
3773 DBG_8192C("%s\n", __func__);
\r
3778 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
\r
3779 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
\r
3780 .ndo_open = rtw_cfg80211_monitor_if_open,
\r
3781 .ndo_stop = rtw_cfg80211_monitor_if_close,
\r
3782 .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
\r
3783 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
\r
3784 .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
\r
3786 .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
\r
3790 static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
\r
3793 struct net_device* mon_ndev = NULL;
\r
3794 struct wireless_dev* mon_wdev = NULL;
\r
3795 struct rtw_netdev_priv_indicator *pnpi;
\r
3796 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
3799 DBG_871X(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
\r
3804 if (pwdev_priv->pmon_ndev) {
\r
3805 DBG_871X(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
\r
3806 FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
\r
3811 mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
\r
3813 DBG_871X(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
\r
3818 mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
\r
3819 strncpy(mon_ndev->name, name, IFNAMSIZ);
\r
3820 mon_ndev->name[IFNAMSIZ - 1] = 0;
\r
3821 mon_ndev->destructor = rtw_ndev_destructor;
\r
3823 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
\r
3824 mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
\r
3826 mon_ndev->open = rtw_cfg80211_monitor_if_open;
\r
3827 mon_ndev->stop = rtw_cfg80211_monitor_if_close;
\r
3828 mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry;
\r
3829 mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address;
\r
3832 pnpi = netdev_priv(mon_ndev);
\r
3833 pnpi->priv = padapter;
\r
3834 pnpi->sizeof_priv = sizeof(_adapter);
\r
3837 mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
\r
3839 DBG_871X(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
\r
3844 mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
\r
3845 mon_wdev->netdev = mon_ndev;
\r
3846 mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
\r
3847 mon_ndev->ieee80211_ptr = mon_wdev;
\r
3849 ret = register_netdevice(mon_ndev);
\r
3854 *ndev = pwdev_priv->pmon_ndev = mon_ndev;
\r
3855 _rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
\r
3858 if (ret && mon_wdev) {
\r
3859 rtw_mfree((u8*)mon_wdev, sizeof(struct wireless_dev));
\r
3863 if (ret && mon_ndev) {
\r
3864 free_netdev(mon_ndev);
\r
3865 *ndev = mon_ndev = NULL;
\r
3871 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3872 static struct wireless_dev *
\r
3873 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
3874 static struct net_device *
\r
3878 cfg80211_rtw_add_virtual_intf(
\r
3879 struct wiphy *wiphy,
\r
3880 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
\r
3885 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
\r
3888 struct net_device* ndev = NULL;
\r
3889 _adapter *padapter = wiphy_to_adapter(wiphy);
\r
3891 DBG_871X(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
\r
3892 FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
\r
3895 case NL80211_IFTYPE_ADHOC:
\r
3896 case NL80211_IFTYPE_AP_VLAN:
\r
3897 case NL80211_IFTYPE_WDS:
\r
3898 case NL80211_IFTYPE_MESH_POINT:
\r
3901 case NL80211_IFTYPE_MONITOR:
\r
3902 ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
\r
3905 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
3906 case NL80211_IFTYPE_P2P_CLIENT:
\r
3908 case NL80211_IFTYPE_STATION:
\r
3912 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
3913 case NL80211_IFTYPE_P2P_GO:
\r
3915 case NL80211_IFTYPE_AP:
\r
3920 DBG_871X("Unsupported interface type\n");
\r
3924 DBG_871X(FUNC_ADPT_FMT" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter), ndev, ret);
\r
3926 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3927 return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
\r
3928 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
3929 return ndev ? ndev : ERR_PTR(ret);
\r
3935 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
\r
3936 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3937 struct wireless_dev *wdev
\r
3939 struct net_device *ndev
\r
3943 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3944 struct net_device *ndev = wdev_to_ndev(wdev);
\r
3947 _adapter *adapter;
\r
3948 struct rtw_wdev_priv *pwdev_priv;
\r
3955 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3956 pwdev_priv = adapter_wdev_data(adapter);
\r
3958 unregister_netdevice(ndev);
\r
3960 if (ndev == pwdev_priv->pmon_ndev) {
\r
3961 pwdev_priv->pmon_ndev = NULL;
\r
3962 pwdev_priv->ifname_mon[0] = '\0';
\r
3963 DBG_871X(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev));
\r
3970 static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
\r
3974 uint len, wps_ielen=0;
\r
3977 u8 got_p2p_ie = _FALSE;
\r
3978 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
3979 //struct sta_priv *pstapriv = &padapter->stapriv;
\r
3982 DBG_8192C("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
\r
3985 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
\r
3992 pbuf = rtw_zmalloc(head_len+tail_len);
\r
3997 //_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
\r
3999 //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
\r
4000 // pstapriv->max_num_sta = NUM_STA;
\r
4003 _rtw_memcpy(pbuf, (void *)head+24, head_len-24);// 24=beacon header len.
\r
4004 _rtw_memcpy(pbuf+head_len-24, (void *)tail, tail_len);
\r
4006 len = head_len+tail_len-24;
\r
4008 //check wps ie if inclued
\r
4009 if(rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
\r
4010 DBG_8192C("add bcn, wps_ielen=%d\n", wps_ielen);
\r
4013 if( adapter->wdinfo.driver_interface == DRIVER_CFG80211 )
\r
4015 //check p2p if enable
\r
4016 if(rtw_get_p2p_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &p2p_ielen))
\r
4018 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
\r
4019 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
\r
4021 DBG_8192C("got p2p_ie, len=%d\n", p2p_ielen);
\r
4023 got_p2p_ie = _TRUE;
\r
4025 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4027 DBG_8192C("Enable P2P function for the first time\n");
\r
4028 rtw_p2p_enable(adapter, P2P_ROLE_GO);
\r
4029 adapter_wdev_data(adapter)->p2p_enabled = _TRUE;
\r
4031 adapter->stapriv.expire_to = 3; // 3x2 = 6 sec in p2p mode
\r
4035 DBG_8192C("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);
\r
4037 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
\r
4038 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
\r
4039 pwdinfo->intent = 15;
\r
4043 #endif // CONFIG_P2P
\r
4045 /* pbss_network->IEs will not include p2p_ie, wfd ie */
\r
4046 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
\r
4047 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
\r
4049 if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS)
\r
4051 #ifdef CONFIG_P2P
\r
4052 //check p2p if enable
\r
4053 if(got_p2p_ie == _TRUE)
\r
4055 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
\r
4056 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
\r
4057 pwdinfo->operating_channel = pmlmeext->cur_channel;
\r
4059 #endif //CONFIG_P2P
\r
4068 rtw_mfree(pbuf, head_len+tail_len);
\r
4073 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE)
\r
4074 static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4075 struct beacon_parameters *info)
\r
4078 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4080 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4081 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
\r
4086 static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4087 struct beacon_parameters *info)
\r
4089 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4090 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
4092 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4094 pmlmeext->bstart_bss = _TRUE;
\r
4096 cfg80211_rtw_add_beacon(wiphy, ndev, info);
\r
4101 static int cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
\r
4103 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4108 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
\r
4109 struct cfg80211_ap_settings *settings)
\r
4112 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4114 DBG_871X(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
\r
4115 settings->hidden_ssid, settings->auth_type);
\r
4117 ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
\r
4118 settings->beacon.tail, settings->beacon.tail_len);
\r
4120 adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
\r
4122 if (settings->ssid && settings->ssid_len) {
\r
4123 WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
\r
4124 WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
\r
4127 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%zu), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
\r
4128 settings->ssid, settings->ssid_len,
\r
4129 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
\r
4131 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
\r
4132 pbss_network->Ssid.SsidLength = settings->ssid_len;
\r
4133 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
\r
4134 pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
\r
4137 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
\r
4138 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
\r
4139 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
\r
4145 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4146 struct cfg80211_beacon_data *info)
\r
4149 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4151 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4153 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
\r
4158 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
\r
4160 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4164 #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
\r
4166 static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4167 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
4172 struct station_parameters *params)
\r
4174 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4179 static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4180 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
4189 _list *phead, *plist;
\r
4190 u8 updated = _FALSE;
\r
4191 struct sta_info *psta = NULL;
\r
4192 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4193 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
4194 struct sta_priv *pstapriv = &padapter->stapriv;
\r
4196 DBG_871X("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4198 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
\r
4200 DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
\r
4207 DBG_8192C("flush all sta, and cam_entry\n");
\r
4209 flush_all_cam_entry(padapter); //clear CAM
\r
4211 ret = rtw_sta_flush(padapter);
\r
4217 DBG_8192C("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
\r
4219 if (mac[0] == 0xff && mac[1] == 0xff &&
\r
4220 mac[2] == 0xff && mac[3] == 0xff &&
\r
4221 mac[4] == 0xff && mac[5] == 0xff)
\r
4227 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4229 phead = &pstapriv->asoc_list;
\r
4230 plist = get_next(phead);
\r
4232 //check asoc_queue
\r
4233 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
4235 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
4237 plist = get_next(plist);
\r
4239 if(_rtw_memcmp((u8 *)mac, psta->hwaddr, ETH_ALEN))
\r
4241 if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE)
\r
4243 DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
\r
4247 DBG_8192C("free psta=%p, aid=%d\n", psta, psta->aid);
\r
4249 rtw_list_delete(&psta->asoc_list);
\r
4250 pstapriv->asoc_list_cnt--;
\r
4252 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4253 if (check_fwstate(pmlmepriv, (WIFI_AP_STATE)) == _TRUE)
\r
4254 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID);
\r
4256 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
\r
4257 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4268 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4270 associated_clients_update(padapter, updated);
\r
4272 DBG_871X("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4278 static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4279 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
4284 struct station_parameters *params)
\r
4286 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4291 struct sta_info *rtw_sta_info_get_by_idx(const int idx, struct sta_priv *pstapriv)
\r
4294 _list *phead, *plist;
\r
4295 struct sta_info *psta = NULL;
\r
4298 phead = &pstapriv->asoc_list;
\r
4299 plist = get_next(phead);
\r
4301 //check asoc_queue
\r
4302 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
4304 if(idx == i) psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
4305 plist = get_next(plist);
\r
4311 static int cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4312 int idx, u8 *mac, struct station_info *sinfo)
\r
4317 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4318 struct sta_info *psta = NULL;
\r
4319 struct sta_priv *pstapriv = &padapter->stapriv;
\r
4320 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4322 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4323 psta = rtw_sta_info_get_by_idx(idx, pstapriv);
\r
4324 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4327 DBG_871X("Station is not found\n");
\r
4331 _rtw_memcpy(mac, psta->hwaddr, ETH_ALEN);
\r
4332 sinfo->filled = 0;
\r
4333 sinfo->filled |= STATION_INFO_SIGNAL;
\r
4334 sinfo->signal = psta->rssi;
\r
4340 static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
\r
4341 struct bss_parameters *params)
\r
4345 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4347 DBG_8192C("use_cts_prot=%d\n", params->use_cts_prot);
\r
4348 DBG_8192C("use_short_preamble=%d\n", params->use_short_preamble);
\r
4349 DBG_8192C("use_short_slot_time=%d\n", params->use_short_slot_time);
\r
4350 DBG_8192C("ap_isolate=%d\n", params->ap_isolate);
\r
4352 DBG_8192C("basic_rates_len=%d\n", params->basic_rates_len);
\r
4353 for(i=0; i<params->basic_rates_len; i++)
\r
4355 DBG_8192C("basic_rates=%d\n", params->basic_rates[i]);
\r
4363 static int cfg80211_rtw_set_channel(struct wiphy *wiphy
\r
4364 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
\r
4365 , struct net_device *ndev
\r
4367 , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
\r
4369 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
\r
4370 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4376 static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
\r
4377 struct cfg80211_auth_request *req)
\r
4379 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4384 static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
\r
4385 struct cfg80211_assoc_request *req)
\r
4387 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4391 #endif //CONFIG_AP_MODE
\r
4393 void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
4398 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4399 u8 category, action;
\r
4401 channel = rtw_get_oper_ch(padapter);
\r
4403 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4405 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
\r
4409 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
\r
4410 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4413 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4414 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4416 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4418 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4419 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4421 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4425 void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
4430 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4431 u8 category, action;
\r
4433 channel = rtw_get_oper_ch(padapter);
\r
4435 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4437 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
\r
4440 case P2P_GO_NEGO_CONF:
\r
4441 case P2P_PROVISION_DISC_RESP:
\r
4442 case P2P_INVIT_RESP:
\r
4443 rtw_set_scan_deny(padapter, 2000);
\r
4444 rtw_clear_scan_deny(padapter);
\r
4449 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
\r
4450 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4453 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4454 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4456 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4458 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4459 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4461 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4465 void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg)
\r
4469 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
4470 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
4471 u8 category, action;
\r
4473 channel = rtw_get_oper_ch(adapter);
\r
4475 rtw_action_frame_parse(frame, frame_len, &category, &action);
\r
4477 if (action == ACT_PUBLIC_GAS_INITIAL_REQ) {
\r
4478 rtw_set_scan_deny(adapter, 200);
\r
4479 rtw_scan_abort_no_wait(adapter);
\r
4480 #ifdef CONFIG_CONCURRENT_MODE
\r
4481 if (rtw_buddy_adapter_up(adapter))
\r
4482 rtw_scan_abort_no_wait(adapter->pbuddy_adapter);
\r
4486 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4487 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4489 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4491 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4492 rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
\r
4494 cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
\r
4497 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4499 DBG_871X("RTW_Rx:%s\n", msg);
\r
4501 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4505 void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
\r
4507 u16 wps_devicepassword_id = 0x0000;
\r
4508 uint wps_devicepassword_id_len = 0;
\r
4509 u8 wpsie[ 255 ] = { 0x00 }, p2p_ie[ 255 ] = { 0x00 };
\r
4510 uint p2p_ielen = 0;
\r
4511 uint wpsielen = 0;
\r
4512 u32 devinfo_contentlen = 0;
\r
4513 u8 devinfo_content[64] = { 0x00 };
\r
4514 u16 capability = 0;
\r
4515 uint capability_len = 0;
\r
4517 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
\r
4518 u8 action = P2P_PUB_ACTION_ACTION;
\r
4519 u8 dialogToken = 1;
\r
4520 u32 p2poui = cpu_to_be32(P2POUI);
\r
4521 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
\r
4525 #endif //CONFIG_WFD
\r
4527 struct xmit_frame *pmgntframe;
\r
4528 struct pkt_attrib *pattrib;
\r
4529 unsigned char *pframe;
\r
4530 struct rtw_ieee80211_hdr *pwlanhdr;
\r
4531 unsigned short *fctrl;
\r
4532 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
4533 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4534 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
4536 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
\r
4537 u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
\r
4538 size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4541 DBG_871X( "[%s] In\n", __FUNCTION__ );
\r
4543 //prepare for building provision_request frame
\r
4544 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
\r
4545 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
\r
4547 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
\r
4549 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
\r
4550 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
\r
4551 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
\r
4553 switch(wps_devicepassword_id)
\r
4555 case WPS_DPID_PIN:
\r
4556 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
\r
4558 case WPS_DPID_USER_SPEC:
\r
4559 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
\r
4561 case WPS_DPID_MACHINE_SPEC:
\r
4563 case WPS_DPID_REKEY:
\r
4565 case WPS_DPID_PBC:
\r
4566 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
\r
4568 case WPS_DPID_REGISTRAR_SPEC:
\r
4569 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
\r
4576 if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) )
\r
4579 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);
\r
4580 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&capability, &capability_len);
\r
4585 //start to build provision_request frame
\r
4586 _rtw_memset(wpsie, 0, sizeof(wpsie));
\r
4587 _rtw_memset(p2p_ie, 0, sizeof(p2p_ie));
\r
4590 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
4596 //update attribute
\r
4597 pattrib = &pmgntframe->attrib;
\r
4598 update_mgntframe_attrib(padapter, pattrib);
\r
4600 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
4602 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
4603 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
4605 fctrl = &(pwlanhdr->frame_ctl);
\r
4608 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
\r
4609 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
4610 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
\r
4612 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
4613 pmlmeext->mgnt_seq++;
\r
4614 SetFrameSubType(pframe, WIFI_ACTION);
\r
4616 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4617 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4619 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
4620 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
4621 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
\r
4622 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
\r
4623 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
\r
4626 //build_prov_disc_request_p2p_ie
\r
4629 p2p_ie[ p2pielen++ ] = 0x50;
\r
4630 p2p_ie[ p2pielen++ ] = 0x6F;
\r
4631 p2p_ie[ p2pielen++ ] = 0x9A;
\r
4632 p2p_ie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
\r
4634 // Commented by Albert 20110301
\r
4635 // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
\r
4636 // 1. P2P Capability
\r
4638 // 3. Group ID ( When joining an operating P2P Group )
\r
4640 // P2P Capability ATTR
\r
4642 p2p_ie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
\r
4645 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
\r
4646 RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
\r
4650 // Device Capability Bitmap, 1 byte
\r
4651 // Group Capability Bitmap, 1 byte
\r
4652 _rtw_memcpy(p2p_ie + p2pielen, &capability, 2);
\r
4656 // Device Info ATTR
\r
4658 p2p_ie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
\r
4661 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
\r
4662 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
\r
4663 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
\r
4664 RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
\r
4668 _rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
\r
4669 p2pielen += devinfo_contentlen;
\r
4672 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);
\r
4673 //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr);
\r
4674 //pframe += p2pielen;
\r
4675 pattrib->pktlen += p2p_ielen;
\r
4679 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
\r
4684 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
\r
4688 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
\r
4692 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
\r
4696 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
\r
4700 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
\r
4704 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
\r
4707 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
\r
4711 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
\r
4712 pframe += wfdielen;
\r
4713 pattrib->pktlen += wfdielen;
\r
4714 #endif //CONFIG_WFD
\r
4716 pattrib->last_txcmdsz = pattrib->pktlen;
\r
4718 //dump_mgntframe(padapter, pmgntframe);
\r
4719 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
\r
4720 DBG_8192C("%s, ack to\n", __func__);
\r
4722 //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
\r
4724 // DBG_8192C("waiting for p2p peer key-in PIN CODE\n");
\r
4725 // rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req.
\r
4730 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
\r
4731 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4732 struct wireless_dev *wdev,
\r
4734 struct net_device *ndev,
\r
4736 struct ieee80211_channel * channel,
\r
4737 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
4738 enum nl80211_channel_type channel_type,
\r
4740 unsigned int duration, u64 *cookie)
\r
4742 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4743 struct net_device *ndev = wdev_to_ndev(wdev);
\r
4746 u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
\r
4747 u8 ready_on_channel = _FALSE;
\r
4748 _adapter *padapter;
\r
4749 struct rtw_wdev_priv *pwdev_priv;
\r
4750 struct mlme_ext_priv *pmlmeext;
\r
4751 struct wifidirect_info *pwdinfo;
\r
4752 struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
\r
4753 u8 is_p2p_find = _FALSE;
\r
4756 #ifndef CONFIG_RADIO_WORK
\r
4757 #define RTW_ROCH_DURATION_ENLARGE
\r
4758 #define RTW_ROCH_BACK_OP
\r
4761 if (ndev == NULL) {
\r
4765 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4766 pwdev_priv = adapter_wdev_data(padapter);
\r
4767 pmlmeext = &padapter->mlmeextpriv;
\r
4768 pwdinfo = &padapter->wdinfo;
\r
4769 pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
4770 #ifdef CONFIG_CONCURRENT_MODE
\r
4771 is_p2p_find=(duration < (pwdinfo->ext_listen_interval))? _TRUE : _FALSE;
\r
4773 *cookie = ATOMIC_INC_RETURN(&pcfg80211_wdinfo->ro_ch_cookie_gen);
\r
4775 DBG_871X(FUNC_ADPT_FMT" ch:%u duration:%d, cookie:0x%llx\n", FUNC_ADPT_ARG(padapter), remain_ch, duration, *cookie);
\r
4777 if(pcfg80211_wdinfo->is_ro_ch == _TRUE)
\r
4779 DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
4780 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
4781 #ifdef CONFIG_CONCURRENT_MODE
\r
4782 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
4783 #endif //CONFIG_CONCURRENT_MODE
\r
4784 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
\r
4787 pcfg80211_wdinfo->is_ro_ch = _TRUE;
\r
4788 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
4790 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
4795 _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
\r
4796 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
4797 pcfg80211_wdinfo->remain_on_ch_type= channel_type;
\r
4799 pcfg80211_wdinfo->remain_on_ch_cookie= *cookie;
\r
4801 rtw_scan_abort(padapter);
\r
4802 #ifdef CONFIG_CONCURRENT_MODE
\r
4803 if ((rtw_buddy_adapter_up(padapter)) && is_p2p_find) //don't scan_abort during p2p_listen.
\r
4804 rtw_scan_abort(padapter->pbuddy_adapter);
\r
4805 #endif //CONFIG_CONCURRENT_MODE
\r
4807 if (check_fwstate(&padapter->mlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
\r
4809 DBG_871X("mlme state:0x%x\n", get_fwstate(&padapter->mlmepriv));
\r
4810 remain_ch = padapter->mlmeextpriv.cur_channel;
\r
4812 #ifdef CONFIG_CONCURRENT_MODE
\r
4813 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
\r
4815 DBG_871X("buddy_intf's mlme state:0x%x\n", get_fwstate(&(padapter->pbuddy_adapter->mlmepriv)));
\r
4816 remain_ch = padapter->pbuddy_adapter->mlmeextpriv.cur_channel;
\r
4818 #endif /* CONFIG_CONCURRENT_MODE */
\r
4820 //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
4821 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4823 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
\r
4824 adapter_wdev_data(padapter)->p2p_enabled = _TRUE;
\r
4825 padapter->wdinfo.listen_channel = remain_ch;
\r
4829 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
4830 #ifdef CONFIG_DEBUG_CFG80211
\r
4831 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
4836 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
\r
4838 #ifdef RTW_ROCH_DURATION_ENLARGE
\r
4839 if(duration < 400)
\r
4840 duration = duration*3;//extend from exper.
\r
4841 #endif /* RTW_ROCH_DURATION_ENLARGE */
\r
4843 #ifdef RTW_ROCH_BACK_OP
\r
4844 #ifdef CONFIG_CONCURRENT_MODE
\r
4845 if (check_buddy_fwstate(padapter, _FW_LINKED))
\r
4847 if (is_p2p_find) // p2p_find , duration<1000
\r
4848 duration = duration + pwdinfo->ext_listen_interval;
\r
4849 else // p2p_listen, duration=5000
\r
4850 duration = pwdinfo->ext_listen_interval
\r
4851 + (pwdinfo->ext_listen_interval/4);
\r
4854 #endif /* RTW_ROCH_BACK_OP */
\r
4856 pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter);
\r
4858 if(rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) >= 0) {
\r
4859 #ifdef CONFIG_CONCURRENT_MODE
\r
4860 if ( check_buddy_fwstate(padapter, _FW_LINKED) )
\r
4862 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
\r
4863 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
4865 if((remain_ch != pbuddy_mlmeext->cur_channel) && !check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
4867 if(ATOMIC_READ(&pwdev_priv->switch_ch_to)==1 ||
\r
4868 (remain_ch != pmlmeext->cur_channel))
\r
4870 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
\r
4871 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
\r
4873 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
\r
4875 #ifdef RTW_ROCH_BACK_OP
\r
4876 DBG_8192C("%s, set switch ch timer, duration=%d\n", __func__, duration-pwdinfo->ext_listen_interval);
\r
4877 _set_timer(&pwdinfo->ap_p2p_switch_timer, duration-pwdinfo->ext_listen_interval);
\r
4878 #endif /* RTW_ROCH_BACK_OP */
\r
4882 ready_on_channel = _TRUE;
\r
4883 //pmlmeext->cur_channel = remain_ch;
\r
4884 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4886 #endif //CONFIG_CONCURRENT_MODE
\r
4887 if(remain_ch != rtw_get_oper_ch(padapter) )
\r
4889 ready_on_channel = _TRUE;
\r
4890 //pmlmeext->cur_channel = remain_ch;
\r
4891 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4894 DBG_871X("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__, remain_ch);
\r
4898 //call this after other things have been done
\r
4899 #ifdef CONFIG_CONCURRENT_MODE
\r
4900 if(ATOMIC_READ(&pwdev_priv->ro_ch_to)==1 ||
\r
4901 (remain_ch != rtw_get_oper_ch(padapter)))
\r
4903 u8 co_channel = 0xff;
\r
4904 ATOMIC_SET(&pwdev_priv->ro_ch_to, 0);
\r
4907 if(ready_on_channel == _TRUE)
\r
4909 if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) )
\r
4911 pmlmeext->cur_channel = remain_ch;
\r
4913 #ifdef CONFIG_CONCURRENT_MODE
\r
4914 co_channel = rtw_get_oper_ch(padapter);
\r
4916 if(co_channel !=remain_ch)
\r
4919 //if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic)
\r
4920 set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4924 DBG_8192C("%s, set ro ch timer, duration=%d\n", __func__, duration);
\r
4925 _set_timer( &pcfg80211_wdinfo->remain_on_ch_timer, duration);
\r
4927 #ifdef CONFIG_CONCURRENT_MODE
\r
4931 rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type, duration, GFP_KERNEL);
\r
4935 pcfg80211_wdinfo->is_ro_ch = _FALSE;
\r
4936 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
4942 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
\r
4943 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4944 struct wireless_dev *wdev,
\r
4946 struct net_device *ndev,
\r
4950 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4951 struct net_device *ndev = wdev_to_ndev(wdev);
\r
4954 _adapter *padapter;
\r
4955 struct rtw_wdev_priv *pwdev_priv;
\r
4956 struct wifidirect_info *pwdinfo;
\r
4957 struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
\r
4959 if (ndev == NULL) {
\r
4964 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4965 pwdev_priv = adapter_wdev_data(padapter);
\r
4966 pwdinfo = &padapter->wdinfo;
\r
4967 pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
4969 DBG_871X(FUNC_ADPT_FMT" cookie:0x%llx\n", FUNC_ADPT_ARG(padapter), cookie);
\r
4971 if (pcfg80211_wdinfo->is_ro_ch == _TRUE) {
\r
4972 DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
4973 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
4974 #ifdef CONFIG_CONCURRENT_MODE
\r
4975 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
4977 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
\r
4981 // Disable P2P Listen State
\r
4982 if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
4984 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4986 rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
\r
4987 _rtw_memset(pwdinfo, 0x00, sizeof(struct wifidirect_info));
\r
4993 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
4994 #ifdef CONFIG_DEBUG_CFG80211
\r
4995 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
4999 pcfg80211_wdinfo->is_ro_ch = _FALSE;
\r
5000 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
5006 #endif //CONFIG_P2P
\r
5008 static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, const u8 *buf, size_t len)
\r
5010 struct xmit_frame *pmgntframe;
\r
5011 struct pkt_attrib *pattrib;
\r
5012 unsigned char *pframe;
\r
5015 struct rtw_ieee80211_hdr *pwlanhdr;
\r
5016 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
5017 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
5018 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5019 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
5021 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
\r
5022 #endif //CONFIG_P2P
\r
5023 //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
5025 rtw_set_scan_deny(padapter, 1000);
\r
5027 rtw_scan_abort(padapter);
\r
5028 #ifdef CONFIG_CONCURRENT_MODE
\r
5029 if(rtw_buddy_adapter_up(padapter))
\r
5030 rtw_scan_abort(padapter->pbuddy_adapter);
\r
5031 #endif /* CONFIG_CONCURRENT_MODE */
\r
5033 if (padapter->cfg80211_wdinfo.is_ro_ch == _TRUE) {
\r
5034 //DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
5035 //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
5036 //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE;
\r
5037 #ifdef CONFIG_CONCURRENT_MODE
\r
5038 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5040 DBG_8192C("%s, extend ro ch time\n", __func__);
\r
5041 _set_timer( &padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
\r
5043 #endif //CONFIG_CONCURRENT_MODE
\r
5045 #endif //CONFIG_P2P
\r
5046 #ifdef CONFIG_CONCURRENT_MODE
\r
5047 if (check_buddy_fwstate(padapter, _FW_LINKED )) {
\r
5048 u8 co_channel=0xff;
\r
5049 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
\r
5050 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
5052 co_channel = rtw_get_oper_ch(padapter);
\r
5054 if (tx_ch != pbuddy_mlmeext->cur_channel) {
\r
5056 u16 ext_listen_period;
\r
5058 if (ATOMIC_READ(&pwdev_priv->switch_ch_to)==1) {
\r
5059 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
\r
5060 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
\r
5062 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
\r
5064 //DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
\r
5065 //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
\r
5068 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5070 ext_listen_period = 500;// 500ms
\r
5074 ext_listen_period = pwdinfo->ext_listen_period;
\r
5077 DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period);
\r
5078 _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period);
\r
5082 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5083 pmlmeext->cur_channel = tx_ch;
\r
5085 if (tx_ch != co_channel)
\r
5086 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5088 #endif //CONFIG_CONCURRENT_MODE
\r
5089 //if (tx_ch != pmlmeext->cur_channel) {
\r
5090 if(tx_ch != rtw_get_oper_ch(padapter)) {
\r
5091 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5092 pmlmeext->cur_channel = tx_ch;
\r
5093 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5096 //starting alloc mgmt frame to dump it
\r
5097 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
5104 //update attribute
\r
5105 pattrib = &pmgntframe->attrib;
\r
5106 update_mgntframe_attrib(padapter, pattrib);
\r
5107 pattrib->retry_ctrl = _FALSE;
\r
5109 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
5111 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
5113 _rtw_memcpy(pframe, (void*)buf, len);
\r
5114 pattrib->pktlen = len;
\r
5116 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
5117 //update seq number
\r
5118 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
\r
5119 pattrib->seqnum = pmlmeext->mgnt_seq;
\r
5120 pmlmeext->mgnt_seq++;
\r
5124 struct wifi_display_info *pwfd_info;
\r
5126 pwfd_info = padapter->wdinfo.wfd_info;
\r
5128 if ( _TRUE == pwfd_info->wfd_enable )
\r
5130 rtw_append_wfd_ie( padapter, pframe, &pattrib->pktlen );
\r
5133 #endif // CONFIG_WFD
\r
5135 pattrib->last_txcmdsz = pattrib->pktlen;
\r
5137 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
\r
5142 #ifdef CONFIG_DEBUG_CFG80211
\r
5143 DBG_8192C("%s, ack == _FAIL\n", __func__);
\r
5149 #ifdef CONFIG_XMIT_ACK
\r
5150 rtw_msleep_os(50);
\r
5152 #ifdef CONFIG_DEBUG_CFG80211
\r
5153 DBG_8192C("%s, ack=%d, ok!\n", __func__, ack);
\r
5160 #ifdef CONFIG_DEBUG_CFG80211
\r
5161 DBG_8192C("%s, ret=%d\n", __func__, ret);
\r
5168 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
\r
5169 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5170 struct wireless_dev *wdev,
\r
5172 struct net_device *ndev,
\r
5174 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) || defined(COMPAT_KERNEL_RELEASE)
\r
5175 struct ieee80211_channel *chan,
\r
5176 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
5179 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5180 enum nl80211_channel_type channel_type,
\r
5181 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5182 bool channel_type_valid,
\r
5185 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
5186 unsigned int wait,
\r
5188 const u8 *buf, size_t len,
\r
5189 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5192 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
\r
5193 bool dont_wait_for_ack,
\r
5196 struct cfg80211_mgmt_tx_params *params,
\r
5200 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5201 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5203 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) || defined(COMPAT_KERNEL_RELEASE)
\r
5204 struct ieee80211_channel *chan = params->chan;
\r
5205 bool offchan = params->offchan;
\r
5206 unsigned int wait = params->wait;
\r
5207 const u8 *buf = params->buf;
\r
5208 size_t len = params->len;
\r
5209 bool no_cck = params->no_cck;
\r
5210 bool dont_wait_for_ack = params->dont_wait_for_ack;
\r
5214 u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
\r
5217 u8 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
\r
5218 u8 category, action;
\r
5220 u32 start = rtw_get_current_time();
\r
5221 _adapter *padapter;
\r
5222 struct rtw_wdev_priv *pwdev_priv;
\r
5224 if (ndev == NULL) {
\r
5229 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5230 pwdev_priv = adapter_wdev_data(padapter);
\r
5232 /* cookie generation */
\r
5233 *cookie = (unsigned long) buf;
\r
5235 #ifdef CONFIG_DEBUG_CFG80211
\r
5236 DBG_871X(FUNC_ADPT_FMT" len=%zu, ch=%d"
\r
5237 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5239 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5240 ", channel_type_valid=%d"
\r
5243 "\n", FUNC_ADPT_ARG(padapter),
\r
5245 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5247 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5248 , channel_type_valid
\r
5252 #endif /* CONFIG_DEBUG_CFG80211 */
\r
5254 /* indicate ack before issue frame to avoid racing with rsp frame */
\r
5255 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5256 rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL);
\r
5257 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
\r
5258 cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
\r
5261 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
\r
5262 DBG_8192C(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
\r
5263 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
\r
5267 DBG_8192C("RTW_Tx:tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
\r
5269 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0) {
\r
5273 if (category == RTW_WLAN_CATEGORY_PUBLIC)
\r
5274 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
\r
5276 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
\r
5280 rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
\r
5281 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
5283 goto cancel_ps_deny;
\r
5288 u32 retry_guarantee_ms = 0;
\r
5291 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
\r
5294 case ACT_PUBLIC_GAS_INITIAL_REQ:
\r
5295 case ACT_PUBLIC_GAS_INITIAL_RSP:
\r
5297 retry_guarantee_ms = RTW_MAX_MGMT_TX_MS_GAS;
\r
5300 if (tx_ret == _SUCCESS
\r
5301 || (dump_cnt >= dump_limit && rtw_get_passing_time_ms(start) >= retry_guarantee_ms))
\r
5305 rtw_msleep_os(sleep_ms);
\r
5308 if (tx_ret != _SUCCESS || dump_cnt > 1) {
\r
5309 DBG_871X(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
\r
5310 tx_ret==_SUCCESS?"OK":"FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
\r
5314 case P2P_GO_NEGO_CONF:
\r
5315 rtw_clear_scan_deny(padapter);
\r
5317 case P2P_INVIT_RESP:
\r
5318 if (pwdev_priv->invit_info.flags & BIT(0)
\r
5319 && pwdev_priv->invit_info.status == 0)
\r
5321 DBG_871X(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
\r
5322 FUNC_ADPT_ARG(padapter));
\r
5323 rtw_set_scan_deny(padapter, 5000);
\r
5324 rtw_pwr_wakeup_ex(padapter, 5000);
\r
5325 rtw_clear_scan_deny(padapter);
\r
5331 rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
\r
5336 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
\r
5337 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
\r
5338 struct wireless_dev *wdev,
\r
5340 struct net_device *ndev,
\r
5342 u16 frame_type, bool reg)
\r
5344 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5345 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5347 _adapter *adapter;
\r
5352 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5354 #ifdef CONFIG_DEBUG_CFG80211
\r
5355 DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
\r
5359 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
\r
5365 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5366 static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy,
\r
5367 struct net_device *ndev,
\r
5375 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5377 struct tdls_txmgmt txmgmt;
\r
5379 //TDLS: discard wpa_supplicant's frame mgmt
\r
5380 DBG_871X("%s %d\n", __FUNCTION__, __LINE__);
\r
5383 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
5384 _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
\r
5385 txmgmt.action_code = action_code;
\r
5386 txmgmt.dialog_token= dialog_token;
\r
5387 txmgmt.status_code = status_code;
\r
5389 txmgmt.buf = (u8 *)rtw_malloc(txmgmt.len);
\r
5390 if (txmgmt.buf == NULL)
\r
5395 _rtw_memcpy(txmgmt.buf, (void*)buf, txmgmt.len);
\r
5396 txmgmt.external_support = _TRUE;
\r
5398 //TDLS: Debug purpose
\r
5400 DBG_871X("%s %d\n", __FUNCTION__, __LINE__);
\r
5401 DBG_871X("peer:"MAC_FMT" ", MAC_ARG(txmgmt.peer));
\r
5402 DBG_871X("action code:%d ", txmgmt.action_code);
\r
5403 DBG_871X("dialog:%d ", txmgmt.dialog_token);
\r
5404 DBG_871X("status code:%d\n", txmgmt.status_code);
\r
5405 if( txmgmt.len > 0 )
\r
5408 for(;i < len; i++)
\r
5409 DBG_871X("%02x ", *(txmgmt.buf+i));
\r
5410 DBG_871X("\n len:%d\n", txmgmt.len);
\r
5414 switch(txmgmt.action_code) {
\r
5415 case TDLS_SETUP_REQUEST:
\r
5416 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5418 case TDLS_SETUP_RESPONSE:
\r
5419 issue_tdls_setup_rsp(padapter, &txmgmt);
\r
5421 case TDLS_SETUP_CONFIRM:
\r
5422 issue_tdls_setup_cfm(padapter, &txmgmt);
\r
5424 case TDLS_TEARDOWN:
\r
5426 case TDLS_DISCOVERY_REQUEST:
\r
5427 issue_tdls_dis_req(padapter, &txmgmt);
\r
5434 rtw_mfree(txmgmt.buf, txmgmt.len);
\r
5440 static int cfg80211_rtw_tdls_oper(struct wiphy *wiphy,
\r
5441 struct net_device *ndev,
\r
5443 enum nl80211_tdls_operation oper)
\r
5445 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5446 struct tdls_txmgmt txmgmt;
\r
5447 struct sta_info *ptdls_sta = NULL;
\r
5449 DBG_871X(FUNC_NDEV_FMT", nl80211_tdls_operation:%d\n", FUNC_NDEV_ARG(ndev), oper);
\r
5452 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1);
\r
5453 #endif //CONFIG_LPS
\r
5455 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
5457 _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
\r
5459 CFG80211_TDLS_DISCOVERY_REQ,
\r
5460 CFG80211_TDLS_SETUP,
\r
5461 CFG80211_TDLS_TEARDOWN,
\r
5462 CFG80211_TDLS_ENABLE_LINK,
\r
5463 CFG80211_TDLS_DISABLE_LINK,
\r
5464 CFG80211_TDLS_ENABLE,
\r
5465 CFG80211_TDLS_DISABLE
\r
5468 case NL80211_TDLS_DISCOVERY_REQ:
\r
5469 issue_tdls_dis_req(padapter, &txmgmt);
\r
5471 case NL80211_TDLS_SETUP:
\r
5473 if ( _AES_ != padapter->securitypriv.dot11PrivacyAlgrthm )
\r
5475 if ( padapter->wdinfo.wfd_tdls_weaksec == _TRUE)
\r
5476 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5478 DBG_871X( "[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__ );
\r
5481 #endif // CONFIG_WFD
\r
5483 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5486 case NL80211_TDLS_TEARDOWN:
\r
5487 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), txmgmt.peer);
\r
5488 if(ptdls_sta != NULL)
\r
5490 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
\r
5491 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
\r
5494 DBG_871X( "TDLS peer not found\n");
\r
5496 case NL80211_TDLS_ENABLE_LINK:
\r
5498 case NL80211_TDLS_DISABLE_LINK:
\r
5503 #endif /* CONFIG_TDLS */
\r
5505 #if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
5506 static int cfg80211_rtw_sched_scan_start(struct wiphy *wiphy,
\r
5507 struct net_device *dev,
\r
5508 struct cfg80211_sched_scan_request *request) {
\r
5510 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
5511 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5514 if (padapter->bup == _FALSE) {
\r
5515 DBG_871X("%s: net device is down.\n", __func__);
\r
5519 if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE ||
\r
5520 check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ||
\r
5521 check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
5522 DBG_871X("%s: device is busy.\n", __func__);
\r
5523 rtw_scan_abort(padapter);
\r
5526 if (request == NULL) {
\r
5527 DBG_871X("%s: invalid cfg80211_requests parameters.\n", __func__);
\r
5531 ret = rtw_android_cfg80211_pno_setup(dev, request->ssids,
\r
5532 request->n_ssids, request->interval);
\r
5535 DBG_871X("%s ret: %d\n", __func__, ret);
\r
5539 ret = rtw_android_pno_enable(dev, _TRUE);
\r
5541 DBG_871X("%s ret: %d\n", __func__, ret);
\r
5548 static int cfg80211_rtw_sched_scan_stop(struct wiphy *wiphy,
\r
5549 struct net_device *dev) {
\r
5550 return rtw_android_pno_enable(dev, _FALSE);
\r
5552 #endif /* CONFIG_PNO_SUPPORT */
\r
5554 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
\r
5557 uint wps_ielen = 0;
\r
5559 u32 p2p_ielen = 0;
\r
5560 u8 wps_oui[8]={0x0,0x50,0xf2,0x04};
\r
5562 u32 wfd_ielen = 0;
\r
5564 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5565 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5566 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
5568 DBG_871X(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
\r
5572 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
5574 #ifdef CONFIG_DEBUG_CFG80211
\r
5575 DBG_8192C("bcn_wps_ielen=%d\n", wps_ielen);
\r
5578 if(pmlmepriv->wps_beacon_ie)
\r
5580 u32 free_len = pmlmepriv->wps_beacon_ie_len;
\r
5581 pmlmepriv->wps_beacon_ie_len = 0;
\r
5582 rtw_mfree(pmlmepriv->wps_beacon_ie, free_len);
\r
5583 pmlmepriv->wps_beacon_ie = NULL;
\r
5586 pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen);
\r
5587 if ( pmlmepriv->wps_beacon_ie == NULL) {
\r
5588 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5593 _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
\r
5594 pmlmepriv->wps_beacon_ie_len = wps_ielen;
\r
5596 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
\r
5600 //buf += wps_ielen;
\r
5601 //len -= wps_ielen;
\r
5604 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
5606 #ifdef CONFIG_DEBUG_CFG80211
\r
5607 DBG_8192C("bcn_p2p_ielen=%d\n", p2p_ielen);
\r
5610 if(pmlmepriv->p2p_beacon_ie)
\r
5612 u32 free_len = pmlmepriv->p2p_beacon_ie_len;
\r
5613 pmlmepriv->p2p_beacon_ie_len = 0;
\r
5614 rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len);
\r
5615 pmlmepriv->p2p_beacon_ie = NULL;
\r
5618 pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen);
\r
5619 if ( pmlmepriv->p2p_beacon_ie == NULL) {
\r
5620 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5625 _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
\r
5626 pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
\r
5629 #endif //CONFIG_P2P
\r
5631 //buf += p2p_ielen;
\r
5632 //len -= p2p_ielen;
\r
5635 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
5637 #ifdef CONFIG_DEBUG_CFG80211
\r
5638 DBG_8192C("bcn_wfd_ielen=%d\n", wfd_ielen);
\r
5641 if(pmlmepriv->wfd_beacon_ie)
\r
5643 u32 free_len = pmlmepriv->wfd_beacon_ie_len;
\r
5644 pmlmepriv->wfd_beacon_ie_len = 0;
\r
5645 rtw_mfree(pmlmepriv->wfd_beacon_ie, free_len);
\r
5646 pmlmepriv->wfd_beacon_ie = NULL;
\r
5649 pmlmepriv->wfd_beacon_ie = rtw_malloc(wfd_ielen);
\r
5650 if ( pmlmepriv->wfd_beacon_ie == NULL) {
\r
5651 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5655 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
\r
5657 #endif //CONFIG_WFD
\r
5659 pmlmeext->bstart_bss = _TRUE;
\r
5667 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
\r
5670 uint wps_ielen = 0;
\r
5672 u32 p2p_ielen = 0;
\r
5674 u32 wfd_ielen = 0;
\r
5676 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
\r
5677 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5679 #ifdef CONFIG_DEBUG_CFG80211
\r
5680 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5685 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
5687 uint attr_contentlen = 0;
\r
5688 u16 uconfig_method, *puconfig_method = NULL;
\r
5690 #ifdef CONFIG_DEBUG_CFG80211
\r
5691 DBG_8192C("probe_resp_wps_ielen=%d\n", wps_ielen);
\r
5694 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
\r
5697 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
\r
5701 DBG_871X("%s, got sr\n", __func__);
\r
5705 DBG_8192C("GO mode process WPS under site-survey, sr no set\n");
\r
5710 if(pmlmepriv->wps_probe_resp_ie)
\r
5712 u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
\r
5713 pmlmepriv->wps_probe_resp_ie_len = 0;
\r
5714 rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len);
\r
5715 pmlmepriv->wps_probe_resp_ie = NULL;
\r
5718 pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen);
\r
5719 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
\r
5720 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5725 //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode
\r
5726 if ( (puconfig_method = (u16*)rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen)) != NULL )
\r
5728 //struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
5729 struct wireless_dev *wdev = padapter->rtw_wdev;
\r
5731 #ifdef CONFIG_DEBUG_CFG80211
\r
5732 //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method));
\r
5735 //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
\r
5736 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5737 if(wdev->iftype != NL80211_IFTYPE_P2P_GO) //for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags
\r
5739 uconfig_method = WPS_CM_PUSH_BUTTON;
\r
5740 uconfig_method = cpu_to_be16( uconfig_method );
\r
5742 *puconfig_method |= uconfig_method;
\r
5747 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
\r
5748 pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
\r
5752 //buf += wps_ielen;
\r
5753 //len -= wps_ielen;
\r
5756 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
5758 u8 is_GO = _FALSE;
\r
5759 u32 attr_contentlen = 0;
\r
5762 #ifdef CONFIG_DEBUG_CFG80211
\r
5763 DBG_8192C("probe_resp_p2p_ielen=%d\n", p2p_ielen);
\r
5766 //Check P2P Capability ATTR
\r
5767 if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) )
\r
5770 //DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
\r
5771 cap_attr = le16_to_cpu(cap_attr);
\r
5772 grp_cap = (u8)((cap_attr >> 8)&0xff);
\r
5774 is_GO = (grp_cap&BIT(0)) ? _TRUE:_FALSE;
\r
5777 DBG_8192C("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
\r
5781 if(is_GO == _FALSE)
\r
5783 if(pmlmepriv->p2p_probe_resp_ie)
\r
5785 u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
\r
5786 pmlmepriv->p2p_probe_resp_ie_len = 0;
\r
5787 rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len);
\r
5788 pmlmepriv->p2p_probe_resp_ie = NULL;
\r
5791 pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen);
\r
5792 if ( pmlmepriv->p2p_probe_resp_ie == NULL) {
\r
5793 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5797 _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
\r
5798 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
\r
5802 if(pmlmepriv->p2p_go_probe_resp_ie)
\r
5804 u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
\r
5805 pmlmepriv->p2p_go_probe_resp_ie_len = 0;
\r
5806 rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len);
\r
5807 pmlmepriv->p2p_go_probe_resp_ie = NULL;
\r
5810 pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen);
\r
5811 if ( pmlmepriv->p2p_go_probe_resp_ie == NULL) {
\r
5812 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5816 _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
\r
5817 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
\r
5821 #endif //CONFIG_P2P
\r
5823 //buf += p2p_ielen;
\r
5824 //len -= p2p_ielen;
\r
5827 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
5829 #ifdef CONFIG_DEBUG_CFG80211
\r
5830 DBG_8192C("probe_resp_wfd_ielen=%d\n", wfd_ielen);
\r
5833 if(pmlmepriv->wfd_probe_resp_ie)
\r
5835 u32 free_len = pmlmepriv->wfd_probe_resp_ie_len;
\r
5836 pmlmepriv->wfd_probe_resp_ie_len = 0;
\r
5837 rtw_mfree(pmlmepriv->wfd_probe_resp_ie, free_len);
\r
5838 pmlmepriv->wfd_probe_resp_ie = NULL;
\r
5841 pmlmepriv->wfd_probe_resp_ie = rtw_malloc(wfd_ielen);
\r
5842 if ( pmlmepriv->wfd_probe_resp_ie == NULL) {
\r
5843 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5847 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
\r
5849 #endif //CONFIG_WFD
\r
5857 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
\r
5860 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
\r
5861 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5863 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5867 if(pmlmepriv->wps_assoc_resp_ie)
\r
5869 u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
\r
5870 pmlmepriv->wps_assoc_resp_ie_len = 0;
\r
5871 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len);
\r
5872 pmlmepriv->wps_assoc_resp_ie = NULL;
\r
5875 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(len);
\r
5876 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
\r
5877 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5881 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len);
\r
5882 pmlmepriv->wps_assoc_resp_ie_len = len;
\r
5889 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
\r
5893 uint wps_ielen = 0;
\r
5894 u32 p2p_ielen = 0;
\r
5896 #ifdef CONFIG_DEBUG_CFG80211
\r
5897 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5900 if( (rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen>0))
\r
5902 || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen>0))
\r
5910 case 0x1: //BEACON
\r
5911 ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
\r
5913 case 0x2: //PROBE_RESP
\r
5914 ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
\r
5916 case 0x4: //ASSOC_RESP
\r
5917 ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
\r
5927 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
\r
5930 #define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
\r
5931 #define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
\r
5933 ht_cap->ht_supported = _TRUE;
\r
5935 ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
\r
5936 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
\r
5937 IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
\r
5940 *Maximum length of AMPDU that the STA can receive.
\r
5941 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
\r
5943 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
\r
5945 /*Minimum MPDU start spacing , */
\r
5946 ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
\r
5948 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
\r
5951 *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
\r
5954 *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
\r
5955 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
\r
5956 *if rx_ant >=3 rx_mask[2]=0xff;
\r
5957 *if BW_40 rx_mask[4]=0x01;
\r
5958 *highest supported RX rate
\r
5960 if(rf_type == RF_1T1R)
\r
5962 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
5963 ht_cap->mcs.rx_mask[1] = 0x00;
\r
5964 ht_cap->mcs.rx_mask[4] = 0x01;
\r
5966 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
\r
5968 else if((rf_type == RF_1T2R) || (rf_type==RF_2T2R))
\r
5970 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
5971 ht_cap->mcs.rx_mask[1] = 0xFF;
\r
5972 ht_cap->mcs.rx_mask[4] = 0x01;
\r
5974 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
\r
5978 DBG_8192C("%s, error rf_type=%d\n", __func__, rf_type);
\r
5983 void rtw_cfg80211_init_wiphy(_adapter *padapter)
\r
5986 struct ieee80211_supported_band *bands;
\r
5987 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
5988 struct wiphy *wiphy = pwdev->wiphy;
\r
5990 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
\r
5992 DBG_8192C("%s:rf_type=%d\n", __func__, rf_type);
\r
5994 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
\r
5996 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
\r
5998 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type);
\r
6001 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
\r
6003 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
\r
6005 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type);
\r
6008 /* init regulary domain */
\r
6009 rtw_regd_init(padapter);
\r
6011 /* copy mac_addr to wiphy */
\r
6012 _rtw_memcpy(wiphy->perm_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
\r
6017 struct ieee80211_iface_limit rtw_limits[] = {
\r
6018 { .max = 1, .types = BIT(NL80211_IFTYPE_STATION)
\r
6019 | BIT(NL80211_IFTYPE_ADHOC)
\r
6020 #ifdef CONFIG_AP_MODE
\r
6021 | BIT(NL80211_IFTYPE_AP)
\r
6023 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
6024 | BIT(NL80211_IFTYPE_P2P_CLIENT)
\r
6025 | BIT(NL80211_IFTYPE_P2P_GO)
\r
6028 {.max = 1, .types = BIT(NL80211_IFTYPE_MONITOR)},
\r
6031 struct ieee80211_iface_combination rtw_combinations = {
\r
6032 .limits = rtw_limits,
\r
6033 .n_limits = ARRAY_SIZE(rtw_limits),
\r
6034 .max_interfaces = 2,
\r
6035 .num_different_channels = 1,
\r
6039 static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy)
\r
6042 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
\r
6044 wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
\r
6045 wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
\r
6046 wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
\r
6048 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
6049 wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
\r
6052 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
\r
6053 | BIT(NL80211_IFTYPE_ADHOC)
\r
6054 #ifdef CONFIG_AP_MODE
\r
6055 | BIT(NL80211_IFTYPE_AP)
\r
6056 #ifndef CONFIG_RADIO_WORK
\r
6057 | BIT(NL80211_IFTYPE_MONITOR)
\r
6058 #endif /* !CONFIG_RADIO_WORK */
\r
6060 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
6061 | BIT(NL80211_IFTYPE_P2P_CLIENT)
\r
6062 | BIT(NL80211_IFTYPE_P2P_GO)
\r
6066 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
6067 #ifdef CONFIG_AP_MODE
\r
6068 wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
\r
6069 #endif //CONFIG_AP_MODE
\r
6072 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
6073 #ifndef CONFIG_RADIO_WORK
\r
6074 wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
\r
6075 #endif /* !CONFIG_RADIO_WORK */
\r
6079 wiphy->iface_combinations = &rtw_combinations;
\r
6080 wiphy->n_iface_combinations = 1;
\r
6083 wiphy->cipher_suites = rtw_cipher_suites;
\r
6084 wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
\r
6086 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
\r
6087 wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
\r
6088 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
\r
6089 wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
\r
6091 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
\r
6092 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
\r
6095 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
\r
6096 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
\r
6097 wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
\r
6100 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
6101 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
\r
6102 #ifdef CONFIG_PNO_SUPPORT
\r
6103 wiphy->max_sched_scan_ssids = MAX_PNO_LIST_COUNT;
\r
6107 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
6108 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0))
\r
6109 wiphy->wowlan = wowlan_stub;
\r
6111 wiphy->wowlan = &wowlan_stub;
\r
6115 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
6116 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
\r
6117 //wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
\r
6118 #endif /* CONFIG_TDLS */
\r
6120 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
\r
6121 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
\r
6123 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
\r
6125 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
6126 //wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
\r
6129 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
\r
6130 rtw_cfgvendor_attach(wiphy);
\r
6134 static struct cfg80211_ops rtw_cfg80211_ops = {
\r
6135 .change_virtual_intf = cfg80211_rtw_change_iface,
\r
6136 .add_key = cfg80211_rtw_add_key,
\r
6137 .get_key = cfg80211_rtw_get_key,
\r
6138 .del_key = cfg80211_rtw_del_key,
\r
6139 .set_default_key = cfg80211_rtw_set_default_key,
\r
6140 .get_station = cfg80211_rtw_get_station,
\r
6141 .scan = cfg80211_rtw_scan,
\r
6142 .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
\r
6143 .connect = cfg80211_rtw_connect,
\r
6144 .disconnect = cfg80211_rtw_disconnect,
\r
6145 .join_ibss = cfg80211_rtw_join_ibss,
\r
6146 .leave_ibss = cfg80211_rtw_leave_ibss,
\r
6147 .set_tx_power = cfg80211_rtw_set_txpower,
\r
6148 .get_tx_power = cfg80211_rtw_get_txpower,
\r
6149 .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
\r
6150 .set_pmksa = cfg80211_rtw_set_pmksa,
\r
6151 .del_pmksa = cfg80211_rtw_del_pmksa,
\r
6152 .flush_pmksa = cfg80211_rtw_flush_pmksa,
\r
6154 #ifdef CONFIG_AP_MODE
\r
6155 .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
\r
6156 .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
\r
6158 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
\r
6159 .add_beacon = cfg80211_rtw_add_beacon,
\r
6160 .set_beacon = cfg80211_rtw_set_beacon,
\r
6161 .del_beacon = cfg80211_rtw_del_beacon,
\r
6163 .start_ap = cfg80211_rtw_start_ap,
\r
6164 .change_beacon = cfg80211_rtw_change_beacon,
\r
6165 .stop_ap = cfg80211_rtw_stop_ap,
\r
6168 .add_station = cfg80211_rtw_add_station,
\r
6169 .del_station = cfg80211_rtw_del_station,
\r
6170 .change_station = cfg80211_rtw_change_station,
\r
6171 .dump_station = cfg80211_rtw_dump_station,
\r
6172 .change_bss = cfg80211_rtw_change_bss,
\r
6173 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
\r
6174 .set_channel = cfg80211_rtw_set_channel,
\r
6176 //.auth = cfg80211_rtw_auth,
\r
6177 //.assoc = cfg80211_rtw_assoc,
\r
6178 #endif //CONFIG_AP_MODE
\r
6181 .remain_on_channel = cfg80211_rtw_remain_on_channel,
\r
6182 .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
\r
6185 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
6186 .mgmt_tx = cfg80211_rtw_mgmt_tx,
\r
6187 .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
\r
6188 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
\r
6189 .action = cfg80211_rtw_mgmt_tx,
\r
6192 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
6193 .tdls_mgmt = cfg80211_rtw_tdls_mgmt,
\r
6194 .tdls_oper = cfg80211_rtw_tdls_oper,
\r
6195 #endif /* CONFIG_TDLS */
\r
6197 #if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
6198 .sched_scan_start = cfg80211_rtw_sched_scan_start,
\r
6199 .sched_scan_stop = cfg80211_rtw_sched_scan_stop,
\r
6200 #endif /* CONFIG_PNO_SUPPORT */
\r
6203 int rtw_wdev_alloc(_adapter *padapter, struct device *dev)
\r
6206 struct wiphy *wiphy;
\r
6207 struct wireless_dev *wdev;
\r
6208 struct rtw_wdev_priv *pwdev_priv;
\r
6209 struct net_device *pnetdev = padapter->pnetdev;
\r
6211 DBG_8192C("%s(padapter=%p)\n", __func__, padapter);
\r
6214 wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(_adapter*));
\r
6216 DBG_8192C("Couldn't allocate wiphy device\n");
\r
6220 set_wiphy_dev(wiphy, dev);
\r
6221 *((_adapter**)wiphy_priv(wiphy)) = padapter;
\r
6222 rtw_cfg80211_preinit_wiphy(padapter, wiphy);
\r
6224 ret = wiphy_register(wiphy);
\r
6226 DBG_8192C("Couldn't register wiphy device\n");
\r
6231 wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
\r
6233 DBG_8192C("Couldn't allocate wireless device\n");
\r
6235 goto unregister_wiphy;
\r
6237 wdev->wiphy = wiphy;
\r
6238 wdev->netdev = pnetdev;
\r
6240 wdev->iftype = NL80211_IFTYPE_STATION; // will be init in rtw_hal_init()
\r
6241 // Must sync with _rtw_init_mlme_priv()
\r
6242 // pmlmepriv->fw_state = WIFI_STATION_STATE
\r
6243 //wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
\r
6244 padapter->rtw_wdev = wdev;
\r
6245 pnetdev->ieee80211_ptr = wdev;
\r
6248 pwdev_priv = adapter_wdev_data(padapter);
\r
6249 pwdev_priv->rtw_wdev = wdev;
\r
6250 pwdev_priv->pmon_ndev = NULL;
\r
6251 pwdev_priv->ifname_mon[0] = '\0';
\r
6252 pwdev_priv->padapter = padapter;
\r
6253 pwdev_priv->scan_request = NULL;
\r
6254 _rtw_spinlock_init(&pwdev_priv->scan_req_lock);
\r
6256 pwdev_priv->p2p_enabled = _FALSE;
\r
6257 pwdev_priv->provdisc_req_issued = _FALSE;
\r
6258 rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
\r
6259 rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
\r
6261 pwdev_priv->bandroid_scan = _FALSE;
\r
6263 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
\r
6264 pwdev_priv->power_mgmt = _TRUE;
\r
6266 pwdev_priv->power_mgmt = _FALSE;
\r
6268 #ifdef CONFIG_CONCURRENT_MODE
\r
6269 ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
\r
6270 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
6275 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
\r
6277 wiphy_unregister(wiphy);
\r
6279 wiphy_free(wiphy);
\r
6285 void rtw_wdev_free(struct wireless_dev *wdev)
\r
6287 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
\r
6292 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
\r
6293 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
\r
6295 wiphy_free(wdev->wiphy);
\r
6297 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
\r
6300 void rtw_wdev_unregister(struct wireless_dev *wdev)
\r
6302 struct net_device *ndev;
\r
6303 _adapter *adapter;
\r
6304 struct rtw_wdev_priv *pwdev_priv;
\r
6306 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
\r
6311 if(!(ndev = wdev_to_ndev(wdev)))
\r
6314 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
6315 pwdev_priv = adapter_wdev_data(adapter);
\r
6317 rtw_cfg80211_indicate_scan_done(adapter, _TRUE);
\r
6319 if (pwdev_priv->pmon_ndev) {
\r
6320 DBG_8192C("%s, unregister monitor interface\n", __func__);
\r
6321 unregister_netdev(pwdev_priv->pmon_ndev);
\r
6324 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
\r
6325 rtw_cfgvendor_detach(wdev->wiphy);
\r
6328 wiphy_unregister(wdev->wiphy);
\r
6331 #endif //CONFIG_IOCTL_CFG80211
\r