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 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
\r
27 #define STATION_INFO_SIGNAL BIT(NL80211_STA_INFO_SIGNAL)
\r
28 #define STATION_INFO_TX_BITRATE BIT(NL80211_STA_INFO_TX_BITRATE)
\r
29 #define STATION_INFO_RX_PACKETS BIT(NL80211_STA_INFO_RX_PACKETS)
\r
30 #define STATION_INFO_TX_PACKETS BIT(NL80211_STA_INFO_TX_PACKETS)
\r
31 #define STATION_INFO_ASSOC_REQ_IES 0
\r
32 #endif /* Linux kernel >= 4.0.0 */
\r
34 #include <rtw_wifi_regd.h>
\r
36 #define RTW_MAX_MGMT_TX_CNT (8)
\r
37 #define RTW_MAX_MGMT_TX_MS_GAS (500)
\r
39 #define RTW_SCAN_IE_LEN_MAX 2304
\r
40 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 5000 //ms
\r
41 #define RTW_MAX_NUM_PMKIDS 4
\r
43 #define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
\r
45 #ifdef CONFIG_WAPI_SUPPORT
\r
47 #ifndef WLAN_CIPHER_SUITE_SMS4
\r
48 #define WLAN_CIPHER_SUITE_SMS4 0x00147201
\r
51 #ifndef WLAN_AKM_SUITE_WAPI_PSK
\r
52 #define WLAN_AKM_SUITE_WAPI_PSK 0x000FAC04
\r
55 #ifndef WLAN_AKM_SUITE_WAPI_CERT
\r
56 #define WLAN_AKM_SUITE_WAPI_CERT 0x000FAC12
\r
59 #ifndef NL80211_WAPI_VERSION_1
\r
60 #define NL80211_WAPI_VERSION_1 (1 << 2)
\r
65 #ifdef CONFIG_PLATFORM_ARM_SUN8I
\r
66 #define BUSY_TRAFFIC_SCAN_DENY_PERIOD 8000
\r
68 #define BUSY_TRAFFIC_SCAN_DENY_PERIOD 12000
\r
71 static const u32 rtw_cipher_suites[] = {
\r
72 WLAN_CIPHER_SUITE_WEP40,
\r
73 WLAN_CIPHER_SUITE_WEP104,
\r
74 WLAN_CIPHER_SUITE_TKIP,
\r
75 WLAN_CIPHER_SUITE_CCMP,
\r
76 #ifdef CONFIG_WAPI_SUPPORT
\r
77 WLAN_CIPHER_SUITE_SMS4,
\r
78 #endif // CONFIG_WAPI_SUPPORT
\r
79 #ifdef CONFIG_IEEE80211W
\r
80 WLAN_CIPHER_SUITE_AES_CMAC,
\r
81 #endif //CONFIG_IEEE80211W
\r
84 #define RATETAB_ENT(_rate, _rateid, _flags) \
\r
86 .bitrate = (_rate), \
\r
87 .hw_value = (_rateid), \
\r
88 .flags = (_flags), \
\r
91 #define CHAN2G(_channel, _freq, _flags) { \
\r
92 .band = IEEE80211_BAND_2GHZ, \
\r
93 .center_freq = (_freq), \
\r
94 .hw_value = (_channel), \
\r
95 .flags = (_flags), \
\r
96 .max_antenna_gain = 0, \
\r
100 #define CHAN5G(_channel, _flags) { \
\r
101 .band = IEEE80211_BAND_5GHZ, \
\r
102 .center_freq = 5000 + (5 * (_channel)), \
\r
103 .hw_value = (_channel), \
\r
104 .flags = (_flags), \
\r
105 .max_antenna_gain = 0, \
\r
109 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
110 /* if wowlan is not supported, kernel generate a disconnect at each suspend
\r
111 * cf: /net/wireless/sysfs.c, so register a stub wowlan.
\r
112 * Moreover wowlan has to be enabled via a the nl80211_set_wowlan callback.
\r
113 * (from user space, e.g. iw phy0 wowlan enable)
\r
115 static const struct wiphy_wowlan_support wowlan_stub = {
\r
116 .flags = WIPHY_WOWLAN_ANY,
\r
118 .pattern_max_len = 0,
\r
119 .pattern_min_len = 0,
\r
120 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
\r
121 .max_pkt_offset = 0,
\r
126 static struct ieee80211_rate rtw_rates[] = {
\r
127 RATETAB_ENT(10, 0x1, 0),
\r
128 RATETAB_ENT(20, 0x2, 0),
\r
129 RATETAB_ENT(55, 0x4, 0),
\r
130 RATETAB_ENT(110, 0x8, 0),
\r
131 RATETAB_ENT(60, 0x10, 0),
\r
132 RATETAB_ENT(90, 0x20, 0),
\r
133 RATETAB_ENT(120, 0x40, 0),
\r
134 RATETAB_ENT(180, 0x80, 0),
\r
135 RATETAB_ENT(240, 0x100, 0),
\r
136 RATETAB_ENT(360, 0x200, 0),
\r
137 RATETAB_ENT(480, 0x400, 0),
\r
138 RATETAB_ENT(540, 0x800, 0),
\r
141 #define rtw_a_rates (rtw_rates + 4)
\r
142 #define RTW_A_RATES_NUM 8
\r
143 #define rtw_g_rates (rtw_rates + 0)
\r
144 #define RTW_G_RATES_NUM 12
\r
146 #define RTW_2G_CHANNELS_NUM 14
\r
147 #define RTW_5G_CHANNELS_NUM 37
\r
149 static struct ieee80211_channel rtw_2ghz_channels[] = {
\r
150 CHAN2G(1, 2412, 0),
\r
151 CHAN2G(2, 2417, 0),
\r
152 CHAN2G(3, 2422, 0),
\r
153 CHAN2G(4, 2427, 0),
\r
154 CHAN2G(5, 2432, 0),
\r
155 CHAN2G(6, 2437, 0),
\r
156 CHAN2G(7, 2442, 0),
\r
157 CHAN2G(8, 2447, 0),
\r
158 CHAN2G(9, 2452, 0),
\r
159 CHAN2G(10, 2457, 0),
\r
160 CHAN2G(11, 2462, 0),
\r
161 CHAN2G(12, 2467, 0),
\r
162 CHAN2G(13, 2472, 0),
\r
163 CHAN2G(14, 2484, 0),
\r
166 static struct ieee80211_channel rtw_5ghz_a_channels[] = {
\r
167 CHAN5G(34, 0), CHAN5G(36, 0),
\r
168 CHAN5G(38, 0), CHAN5G(40, 0),
\r
169 CHAN5G(42, 0), CHAN5G(44, 0),
\r
170 CHAN5G(46, 0), CHAN5G(48, 0),
\r
171 CHAN5G(52, 0), CHAN5G(56, 0),
\r
172 CHAN5G(60, 0), CHAN5G(64, 0),
\r
173 CHAN5G(100, 0), CHAN5G(104, 0),
\r
174 CHAN5G(108, 0), CHAN5G(112, 0),
\r
175 CHAN5G(116, 0), CHAN5G(120, 0),
\r
176 CHAN5G(124, 0), CHAN5G(128, 0),
\r
177 CHAN5G(132, 0), CHAN5G(136, 0),
\r
178 CHAN5G(140, 0), CHAN5G(149, 0),
\r
179 CHAN5G(153, 0), CHAN5G(157, 0),
\r
180 CHAN5G(161, 0), CHAN5G(165, 0),
\r
181 CHAN5G(184, 0), CHAN5G(188, 0),
\r
182 CHAN5G(192, 0), CHAN5G(196, 0),
\r
183 CHAN5G(200, 0), CHAN5G(204, 0),
\r
184 CHAN5G(208, 0), CHAN5G(212, 0),
\r
189 void rtw_2g_channels_init(struct ieee80211_channel *channels)
\r
191 _rtw_memcpy((void*)channels, (void*)rtw_2ghz_channels,
\r
192 sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
\r
196 void rtw_5g_channels_init(struct ieee80211_channel *channels)
\r
198 _rtw_memcpy((void*)channels, (void*)rtw_5ghz_a_channels,
\r
199 sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
\r
203 void rtw_2g_rates_init(struct ieee80211_rate *rates)
\r
205 _rtw_memcpy(rates, rtw_g_rates,
\r
206 sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
\r
210 void rtw_5g_rates_init(struct ieee80211_rate *rates)
\r
212 _rtw_memcpy(rates, rtw_a_rates,
\r
213 sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM
\r
217 struct ieee80211_supported_band *rtw_spt_band_alloc(
\r
218 enum ieee80211_band band
\r
221 struct ieee80211_supported_band *spt_band = NULL;
\r
222 int n_channels, n_bitrates;
\r
224 if(band == IEEE80211_BAND_2GHZ)
\r
226 n_channels = RTW_2G_CHANNELS_NUM;
\r
227 n_bitrates = RTW_G_RATES_NUM;
\r
229 else if(band == IEEE80211_BAND_5GHZ)
\r
231 n_channels = RTW_5G_CHANNELS_NUM;
\r
232 n_bitrates = RTW_A_RATES_NUM;
\r
239 spt_band = (struct ieee80211_supported_band *)rtw_zmalloc(
\r
240 sizeof(struct ieee80211_supported_band)
\r
241 + sizeof(struct ieee80211_channel)*n_channels
\r
242 + sizeof(struct ieee80211_rate)*n_bitrates
\r
247 spt_band->channels = (struct ieee80211_channel*)(((u8*)spt_band)+sizeof(struct ieee80211_supported_band));
\r
248 spt_band->bitrates= (struct ieee80211_rate*)(((u8*)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
\r
249 spt_band->band = band;
\r
250 spt_band->n_channels = n_channels;
\r
251 spt_band->n_bitrates = n_bitrates;
\r
253 if(band == IEEE80211_BAND_2GHZ)
\r
255 rtw_2g_channels_init(spt_band->channels);
\r
256 rtw_2g_rates_init(spt_band->bitrates);
\r
258 else if(band == IEEE80211_BAND_5GHZ)
\r
260 rtw_5g_channels_init(spt_band->channels);
\r
261 rtw_5g_rates_init(spt_band->bitrates);
\r
271 void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
\r
278 if(spt_band->band == IEEE80211_BAND_2GHZ)
\r
280 size = sizeof(struct ieee80211_supported_band)
\r
281 + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
\r
282 + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM;
\r
284 else if(spt_band->band == IEEE80211_BAND_5GHZ)
\r
286 size = sizeof(struct ieee80211_supported_band)
\r
287 + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
\r
288 + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM;
\r
294 rtw_mfree((u8*)spt_band, size);
\r
297 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
298 static const struct ieee80211_txrx_stypes
\r
299 rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
\r
300 [NL80211_IFTYPE_ADHOC] = {
\r
302 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
\r
304 [NL80211_IFTYPE_STATION] = {
\r
306 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
\r
307 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
\r
309 [NL80211_IFTYPE_AP] = {
\r
311 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
312 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
313 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
314 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
315 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
316 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
317 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
319 [NL80211_IFTYPE_AP_VLAN] = {
\r
322 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
323 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
324 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
325 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
326 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
327 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
328 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
330 [NL80211_IFTYPE_P2P_CLIENT] = {
\r
332 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
\r
333 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
\r
335 [NL80211_IFTYPE_P2P_GO] = {
\r
337 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
338 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
339 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
340 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
341 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
342 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
343 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
348 static u64 rtw_get_systime_us(void)
\r
350 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
\r
351 struct timespec ts;
\r
352 get_monotonic_boottime(&ts);
\r
353 return ((u64)ts.tv_sec*1000000) + ts.tv_nsec / 1000;
\r
356 do_gettimeofday(&tv);
\r
357 return ((u64)tv.tv_sec*1000000) + tv.tv_usec;
\r
361 #define MAX_BSSINFO_LEN 1000
\r
362 struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork)
\r
364 struct ieee80211_channel *notify_channel;
\r
365 struct cfg80211_bss *bss = NULL;
\r
366 //struct ieee80211_supported_band *band;
\r
369 u64 notify_timestamp;
\r
370 u16 notify_capability;
\r
371 u16 notify_interval;
\r
373 size_t notify_ielen;
\r
375 //u8 buf[MAX_BSSINFO_LEN];
\r
378 size_t buf_size = MAX_BSSINFO_LEN;
\r
379 size_t len,bssinf_len=0;
\r
380 struct rtw_ieee80211_hdr *pwlanhdr;
\r
381 unsigned short *fctrl;
\r
382 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
\r
384 struct wireless_dev *wdev = padapter->rtw_wdev;
\r
385 struct wiphy *wiphy = wdev->wiphy;
\r
386 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
388 pbuf = rtw_zmalloc(buf_size);
\r
390 DBG_871X("%s pbuf allocate failed !! \n",__FUNCTION__);
\r
394 //DBG_8192C("%s\n", __func__);
\r
396 bssinf_len = pnetwork->network.IELength+sizeof (struct rtw_ieee80211_hdr_3addr);
\r
397 if(bssinf_len > buf_size){
\r
398 DBG_871X("%s IE Length too long > %zu byte \n",__FUNCTION__,buf_size);
\r
402 #ifndef CONFIG_WAPI_SUPPORT
\r
406 if(rtw_get_wapi_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &wapi_len)>0)
\r
410 DBG_871X("%s, no support wapi!\n",__FUNCTION__);
\r
415 #endif //!CONFIG_WAPI_SUPPORT
\r
417 //To reduce PBC Overlap rate
\r
418 //_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
419 if(adapter_wdev_data(padapter)->scan_request != NULL)
\r
421 u8 *psr=NULL, sr = 0;
\r
422 NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid;
\r
423 struct cfg80211_scan_request *request = adapter_wdev_data(padapter)->scan_request;
\r
424 struct cfg80211_ssid *ssids = request->ssids;
\r
428 wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
\r
430 if(wpsie && wpsielen>0)
\r
431 psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
\r
435 if(request->n_ssids == 1 && request->n_channels == 1) // it means under processing WPS
\r
437 DBG_8192C("ssid=%s, len=%d\n", pssid->Ssid, pssid->SsidLength);
\r
439 if (ssids[0].ssid_len == 0) {
\r
441 else if(pssid->SsidLength == ssids[0].ssid_len &&
\r
442 _rtw_memcmp(pssid->Ssid, ssids[0].ssid, ssids[0].ssid_len))
\r
444 DBG_871X("%s, got sr and ssid match!\n", __func__);
\r
449 *psr = 0; //clear sr
\r
452 WLAN_BSSID_EX *pselect_network = &pnetwork->network;
\r
453 struct cfg80211_bss *pselect_bss = NULL;
\r
454 struct ieee80211_channel *notify_channel = NULL;
\r
457 DBG_871X("%s, got sr, but ssid mismatch, to remove this bss\n", __func__);
\r
459 freq = rtw_ch2freq(pselect_network->Configuration.DSConfig);
\r
460 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
461 pselect_bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
\r
462 pselect_network->MacAddress, pselect_network->Ssid.Ssid,
\r
463 pselect_network->Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
\r
464 0/*WLAN_CAPABILITY_ESS*/);
\r
468 DBG_871X("%s, got bss for cfg80211 for unlinking bss\n", __func__);
\r
470 cfg80211_unlink_bss(wiphy, pselect_bss);
\r
471 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
472 cfg80211_put_bss(wiphy, pselect_bss);
\r
474 cfg80211_put_bss(pselect_bss);
\r
485 //_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
488 channel = pnetwork->network.Configuration.DSConfig;
\r
489 freq = rtw_ch2freq(channel);
\r
490 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
493 notify_timestamp = le64_to_cpu(*(u64*)rtw_get_timestampe_from_ie(pnetwork->network.IEs));
\r
495 notify_timestamp = rtw_get_systime_us();
\r
497 notify_interval = le16_to_cpu(*(u16*)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
\r
498 notify_capability = le16_to_cpu(*(u16*)rtw_get_capability_from_ie(pnetwork->network.IEs));
\r
500 notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_;
\r
501 notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_;
\r
503 //We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm)
\r
504 if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
\r
505 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
\r
506 notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);//dbm
\r
508 notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);//dbm
\r
512 DBG_8192C("bssid: "MAC_FMT"\n", MAC_ARG(pnetwork->network.MacAddress));
\r
513 DBG_8192C("Channel: %d(%d)\n", channel, freq);
\r
514 DBG_8192C("Capability: %X\n", notify_capability);
\r
515 DBG_8192C("Beacon interval: %d\n", notify_interval);
\r
516 DBG_8192C("Signal: %d\n", notify_signal);
\r
517 DBG_8192C("notify_timestamp: %llu\n", notify_timestamp);
\r
522 pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;
\r
523 fctrl = &(pwlanhdr->frame_ctl);
\r
526 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
\r
527 //pmlmeext->mgnt_seq++;
\r
529 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
\r
530 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
\r
531 SetFrameSubType(pbuf, WIFI_BEACON);
\r
533 _rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN);
\r
534 SetFrameSubType(pbuf, WIFI_PROBERSP);
\r
537 _rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
\r
538 _rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
\r
541 //pbuf += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
542 len = sizeof (struct rtw_ieee80211_hdr_3addr);
\r
543 _rtw_memcpy((pbuf+len), pnetwork->network.IEs, pnetwork->network.IELength);
\r
544 *((u64*)(pbuf+len)) = cpu_to_le64(notify_timestamp);
\r
546 len += pnetwork->network.IELength;
\r
548 //#ifdef CONFIG_P2P
\r
549 //if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
\r
551 // DBG_8192C("%s, got p2p_ie\n", __func__);
\r
556 bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)pbuf,
\r
557 len, notify_signal, GFP_ATOMIC);
\r
560 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress,
\r
561 notify_timestamp, notify_capability, notify_interval, notify_ie,
\r
562 notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/);
\r
565 if (unlikely(!bss)) {
\r
566 DBG_8192C(FUNC_ADPT_FMT" bss NULL\n", FUNC_ADPT_ARG(padapter));
\r
570 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
\r
571 #ifndef COMPAT_KERNEL_RELEASE
\r
572 //patch for cfg80211, update beacon ies to information_elements
\r
573 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
\r
575 if(bss->len_information_elements != bss->len_beacon_ies)
\r
577 bss->information_elements = bss->beacon_ies;
\r
578 bss->len_information_elements = bss->len_beacon_ies;
\r
581 #endif //COMPAT_KERNEL_RELEASE
\r
582 #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
\r
586 if( bss->information_elements == bss->proberesp_ies)
\r
588 if( bss->len_information_elements != bss->len_proberesp_ies)
\r
590 DBG_8192C("error!, len_information_elements != bss->len_proberesp_ies\n");
\r
594 else if(bss->len_information_elements < bss->len_beacon_ies)
\r
596 bss->information_elements = bss->beacon_ies;
\r
597 bss->len_information_elements = bss->len_beacon_ies;
\r
601 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
602 cfg80211_put_bss(wiphy, bss);
\r
604 cfg80211_put_bss(bss);
\r
609 rtw_mfree(pbuf, buf_size);
\r
615 Check the given bss is valid by kernel API cfg80211_get_bss()
\r
616 @padapter : the given adapter
\r
618 return _TRUE if bss is valid, _FALSE for not found.
\r
620 int rtw_cfg80211_check_bss(_adapter *padapter)
\r
622 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
623 struct cfg80211_bss *bss = NULL;
\r
624 struct ieee80211_channel *notify_channel = NULL;
\r
627 if (!(pnetwork) || !(padapter->rtw_wdev))
\r
630 freq = rtw_ch2freq(pnetwork->Configuration.DSConfig);
\r
631 notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
\r
632 bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
\r
633 pnetwork->MacAddress, pnetwork->Ssid.Ssid,
\r
634 pnetwork->Ssid.SsidLength,
\r
635 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
\r
637 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
638 cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
\r
640 cfg80211_put_bss(bss);
\r
643 return (bss!=NULL);
\r
646 void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter)
\r
648 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
649 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
650 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
651 struct cfg80211_bss *bss = NULL;
\r
652 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
\r
653 struct wiphy *wiphy = pwdev->wiphy;
\r
655 struct ieee80211_channel *notify_channel;
\r
658 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
660 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
\r
661 freq = rtw_ch2freq(cur_network->network.Configuration.DSConfig);
\r
664 DBG_871X("chan: %d, freq: %d\n", cur_network->network.Configuration.DSConfig, freq);
\r
667 if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
\r
672 if (!rtw_cfg80211_check_bss(padapter)) {
\r
673 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
674 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
\r
676 if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE)
\r
679 _rtw_memcpy(&cur_network->network, pnetwork, sizeof(WLAN_BSSID_EX));
\r
682 if (!rtw_cfg80211_inform_bss(padapter,cur_network))
\r
683 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
685 DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
689 DBG_871X("cur_network is not exist!!!\n");
\r
695 if(scanned == NULL)
\r
698 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
\r
699 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
\r
701 if (!rtw_cfg80211_inform_bss(padapter,scanned)) {
\r
702 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
704 //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
707 DBG_871X("scanned & pnetwork compare fail\n");
\r
712 if (!rtw_cfg80211_check_bss(padapter))
\r
713 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
\r
715 //notify cfg80211 that device joined an IBSS
\r
716 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
\r
717 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
718 cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, notify_channel, GFP_ATOMIC);
\r
720 cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, GFP_ATOMIC);
\r
724 void rtw_cfg80211_indicate_connect(_adapter *padapter)
\r
726 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
727 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
728 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
730 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
732 struct cfg80211_bss *bss = NULL;
\r
734 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
735 if (pwdev->iftype != NL80211_IFTYPE_STATION
\r
736 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
737 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
\r
743 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
747 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
749 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
751 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
752 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
\r
753 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
\r
754 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
757 #endif //CONFIG_P2P
\r
759 if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) {
\r
760 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
761 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
\r
763 //DBG_871X(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter));
\r
765 if(scanned == NULL) {
\r
770 if (_rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
\r
771 && _rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
\r
773 if (!rtw_cfg80211_inform_bss(padapter,scanned)) {
\r
774 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
776 //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
779 DBG_871X("scanned: %s("MAC_FMT"), cur: %s("MAC_FMT")\n",
\r
780 scanned->network.Ssid.Ssid, MAC_ARG(scanned->network.MacAddress),
\r
781 pnetwork->Ssid.Ssid, MAC_ARG(pnetwork->MacAddress)
\r
788 if (!rtw_cfg80211_check_bss(padapter))
\r
789 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
\r
791 if (rtw_to_roam(padapter) > 0) {
\r
792 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
\r
793 struct wiphy *wiphy = pwdev->wiphy;
\r
794 struct ieee80211_channel *notify_channel;
\r
796 u16 channel = cur_network->network.Configuration.DSConfig;
\r
798 freq = rtw_ch2freq(channel);
\r
799 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
802 DBG_871X(FUNC_ADPT_FMT" call cfg80211_roamed\n", FUNC_ADPT_ARG(padapter));
\r
803 cfg80211_roamed(padapter->pnetdev
\r
804 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
\r
807 , cur_network->network.MacAddress
\r
808 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
\r
809 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
\r
810 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
\r
811 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
\r
816 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
\r
817 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
\r
819 cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
\r
820 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
\r
821 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
\r
822 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
\r
823 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
\r
824 , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
\r
825 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
\r
826 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
\r
831 void rtw_cfg80211_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generated)
\r
833 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
834 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
836 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
839 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
841 /*always replace privated definitions with wifi reserved value 0*/
\r
842 if ((reason == WLAN_REASON_ACTIVE_ROAM) || (reason == WLAN_REASON_JOIN_WRONG_CHANNEL) || (reason == WLAN_REASON_EXPIRATION_CHK)) {
\r
846 if (pwdev->iftype != NL80211_IFTYPE_STATION
\r
847 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
848 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
\r
854 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
858 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
860 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
862 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
864 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
\r
865 if (pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
\r
867 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
869 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
872 #endif //CONFIG_P2P
\r
874 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
\r
875 if (!padapter->mlmepriv.not_indic_disco || padapter->ndev_unregistering) {
\r
879 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
\r
880 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
\r
882 if(pwdev->sme_state==CFG80211_SME_CONNECTING)
\r
883 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
\r
884 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
\r
885 else if (pwdev->sme_state == CFG80211_SME_CONNECTED) {
\r
886 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
\r
887 cfg80211_disconnected(padapter->pnetdev, reason, NULL, 0, locally_generated, GFP_ATOMIC);
\r
889 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
\r
893 //DBG_8192C("pwdev->sme_state=%d\n", pwdev->sme_state);
\r
895 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
\r
898 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
\r
899 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
\r
900 DBG_871X(FUNC_ADPT_FMT" call cfg80211_disconnected\n", FUNC_ADPT_ARG(padapter));
\r
901 cfg80211_disconnected(padapter->pnetdev, reason, NULL, 0, locally_generated, GFP_ATOMIC);
\r
903 DBG_871X(FUNC_ADPT_FMT" call cfg80211_disconnected\n", FUNC_ADPT_ARG(padapter));
\r
904 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
\r
907 DBG_871X(FUNC_ADPT_FMT" call cfg80211_connect_result\n", FUNC_ADPT_ARG(padapter));
\r
908 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
\r
909 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC);
\r
916 #ifdef CONFIG_AP_MODE
\r
917 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
\r
920 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
921 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
\r
922 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
923 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
924 struct security_priv* psecuritypriv=&(padapter->securitypriv);
\r
925 struct sta_priv *pstapriv = &padapter->stapriv;
\r
927 DBG_8192C("%s\n", __FUNCTION__);
\r
929 param->u.crypt.err = 0;
\r
930 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
\r
932 //sizeof(struct ieee_param) = 64 bytes;
\r
933 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
\r
934 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
\r
940 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
\r
941 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
\r
942 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
\r
944 if (param->u.crypt.idx >= WEP_KEYS
\r
945 #ifdef CONFIG_IEEE80211W
\r
946 && param->u.crypt.idx > BIP_MAX_KEYID
\r
947 #endif /* CONFIG_IEEE80211W */
\r
956 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
\r
960 DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n");
\r
965 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
\r
967 //todo:clear default encryption keys
\r
969 DBG_8192C("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
\r
975 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
\r
977 DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
\r
979 wep_key_idx = param->u.crypt.idx;
\r
980 wep_key_len = param->u.crypt.key_len;
\r
982 DBG_8192C("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
\r
984 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
\r
990 if (wep_key_len > 0)
\r
992 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
995 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
\r
997 //wep default key has not been set, so use this key index as default key.
\r
999 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
\r
1000 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1001 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
\r
1002 psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
\r
1004 if(wep_key_len == 13)
\r
1006 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
\r
1007 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
\r
1010 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
\r
1013 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
\r
1015 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
\r
1017 rtw_ap_set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx, 1);
\r
1024 if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
\r
1026 if(param->u.crypt.set_tx == 0) //group key
\r
1028 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1030 DBG_8192C("%s, set group_key, WEP\n", __FUNCTION__);
\r
1032 _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
1034 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1035 if(param->u.crypt.key_len==13)
\r
1037 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1041 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1043 DBG_8192C("%s, set group_key, TKIP\n", __FUNCTION__);
\r
1045 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
\r
1047 _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
1049 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1051 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
\r
1052 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
\r
1054 psecuritypriv->busetkipkey = _TRUE;
\r
1057 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1059 DBG_8192C("%s, set group_key, CCMP\n", __FUNCTION__);
\r
1061 psecuritypriv->dot118021XGrpPrivacy = _AES_;
\r
1063 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1065 #ifdef CONFIG_IEEE80211W
\r
1066 else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
\r
1069 DBG_871X("BIP key_len=%d , index=%d\n", param->u.crypt.key_len, param->u.crypt.idx);
\r
1070 /* save the IGTK key, length 16 bytes */
\r
1071 _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
1072 /* DBG_871X("IGTK key below:\n");
\r
1073 for(no=0;no<16;no++)
\r
1074 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
\r
1075 DBG_871X("\n"); */
\r
1076 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
\r
1077 padapter->securitypriv.binstallBIPkey = _TRUE;
\r
1078 DBG_871X(" ~~~~set sta key:IGKT\n");
\r
1081 #endif /* CONFIG_IEEE80211W */
\r
1084 DBG_8192C("%s, set group_key, none\n", __FUNCTION__);
\r
1086 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
1089 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
\r
1091 psecuritypriv->binstallGrpkey = _TRUE;
\r
1093 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
\r
1095 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
\r
1097 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1100 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1101 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
\r
1110 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
\r
1112 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
1114 if(param->u.crypt.set_tx ==1) //pairwise key
\r
1116 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1118 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1120 DBG_8192C("%s, set pairwise key, WEP\n", __FUNCTION__);
\r
1122 psta->dot118021XPrivacy = _WEP40_;
\r
1123 if(param->u.crypt.key_len==13)
\r
1125 psta->dot118021XPrivacy = _WEP104_;
\r
1128 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1130 DBG_8192C("%s, set pairwise key, TKIP\n", __FUNCTION__);
\r
1132 psta->dot118021XPrivacy = _TKIP_;
\r
1134 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1136 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
\r
1137 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
\r
1139 psecuritypriv->busetkipkey = _TRUE;
\r
1142 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1145 DBG_8192C("%s, set pairwise key, CCMP\n", __FUNCTION__);
\r
1147 psta->dot118021XPrivacy = _AES_;
\r
1151 DBG_8192C("%s, set pairwise key, none\n", __FUNCTION__);
\r
1153 psta->dot118021XPrivacy = _NO_PRIVACY_;
\r
1156 rtw_ap_set_pairwise_key(padapter, psta);
\r
1158 psta->ieee8021x_blocked = _FALSE;
\r
1160 psta->bpairwise_key_installed = _TRUE;
\r
1163 else//group key???
\r
1165 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1167 _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
1169 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1170 if(param->u.crypt.key_len==13)
\r
1172 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1175 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1177 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
\r
1179 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1181 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1183 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
\r
1184 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
\r
1186 psecuritypriv->busetkipkey = _TRUE;
\r
1189 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1191 psecuritypriv->dot118021XGrpPrivacy = _AES_;
\r
1193 _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
1197 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
1200 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
\r
1202 psecuritypriv->binstallGrpkey = _TRUE;
\r
1204 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
\r
1206 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
\r
1208 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1211 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1212 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
\r
1228 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
\r
1231 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
1232 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
1233 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1234 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1236 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
\r
1237 #endif //CONFIG_P2P
\r
1241 DBG_8192C("%s\n", __func__);
\r
1243 param->u.crypt.err = 0;
\r
1244 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
\r
1246 if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
\r
1252 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
\r
1253 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
\r
1254 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
\r
1256 if (param->u.crypt.idx >= WEP_KEYS
\r
1257 #ifdef CONFIG_IEEE80211W
\r
1258 && param->u.crypt.idx > BIP_MAX_KEYID
\r
1259 #endif //CONFIG_IEEE80211W
\r
1266 #ifdef CONFIG_WAPI_SUPPORT
\r
1267 if (strcmp(param->u.crypt.alg, "SMS4"))
\r
1275 if (strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1277 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
\r
1278 DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n");
\r
1280 wep_key_idx = param->u.crypt.idx;
\r
1281 wep_key_len = param->u.crypt.key_len;
\r
1283 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0))
\r
1289 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
\r
1291 //wep default key has not been set, so use this key index as default key.
\r
1293 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
1295 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1296 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
\r
1297 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1299 if(wep_key_len==13)
\r
1301 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
\r
1302 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1305 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
\r
1308 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
\r
1310 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
\r
1312 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, _TRUE);
\r
1317 if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
\r
1319 struct sta_info * psta,*pbcmc_sta;
\r
1320 struct sta_priv * pstapriv = &padapter->stapriv;
\r
1322 //DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__);
\r
1324 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
\r
1326 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
\r
1327 if (psta == NULL) {
\r
1328 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
\r
1329 DBG_8192C("%s, : Obtain Sta_info fail \n", __func__);
\r
1333 //Jeff: don't disable ieee8021x_blocked while clearing key
\r
1334 if (strcmp(param->u.crypt.alg, "none") != 0)
\r
1335 psta->ieee8021x_blocked = _FALSE;
\r
1338 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
\r
1339 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
\r
1341 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
\r
1344 if(param->u.crypt.set_tx ==1)//pairwise key
\r
1347 DBG_8192C("%s, : param->u.crypt.set_tx ==1 \n", __func__);
\r
1349 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1351 if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
\r
1353 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
\r
1354 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
\r
1355 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
\r
1357 padapter->securitypriv.busetkipkey=_FALSE;
\r
1358 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
\r
1360 psta->bpairwise_key_installed = _TRUE;
\r
1361 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
\r
1362 DBG_871X(" ~~~~set sta key:unicastkey\n");
\r
1364 rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE);
\r
1368 if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1370 _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
1371 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
\r
1372 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
\r
1373 padapter->securitypriv.binstallGrpkey = _TRUE;
\r
1374 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
\r
1375 DBG_871X(" ~~~~set sta key:groupkey\n");
\r
1377 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
\r
1378 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1, _TRUE);
\r
1380 #ifdef CONFIG_IEEE80211W
\r
1381 else if(strcmp(param->u.crypt.alg, "BIP") == 0)
\r
1384 //DBG_871X("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx);
\r
1385 //save the IGTK key, length 16 bytes
\r
1386 _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
1387 /*DBG_871X("IGTK key below:\n");
\r
1388 for(no=0;no<16;no++)
\r
1389 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
\r
1391 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
\r
1392 padapter->securitypriv.binstallBIPkey = _TRUE;
\r
1393 DBG_871X(" ~~~~set sta key:IGKT\n");
\r
1395 #endif //CONFIG_IEEE80211W
\r
1398 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1400 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
\r
1402 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
\r
1405 #endif //CONFIG_P2P
\r
1410 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1411 if(pbcmc_sta==NULL)
\r
1413 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
\r
1417 //Jeff: don't disable ieee8021x_blocked while clearing key
\r
1418 if (strcmp(param->u.crypt.alg, "none") != 0)
\r
1419 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1421 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
\r
1422 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
\r
1424 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
\r
1428 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
\r
1433 #ifdef CONFIG_WAPI_SUPPORT
\r
1434 if (strcmp(param->u.crypt.alg, "SMS4") == 0)
\r
1436 PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
\r
1437 PRT_WAPI_STA_INFO pWapiSta;
\r
1438 u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1439 u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1440 u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1442 if(param->u.crypt.set_tx == 1)
\r
1444 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
\r
1445 if(_rtw_memcmp(pWapiSta->PeerMacAddr,param->sta_addr,6))
\r
1447 _rtw_memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
\r
1449 pWapiSta->wapiUsk.bSet = true;
\r
1450 _rtw_memcpy(pWapiSta->wapiUsk.dataKey,param->u.crypt.key,16);
\r
1451 _rtw_memcpy(pWapiSta->wapiUsk.micKey,param->u.crypt.key+16,16);
\r
1452 pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
\r
1453 pWapiSta->wapiUsk.bTxEnable = true;
\r
1455 _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16);
\r
1456 _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16);
\r
1457 _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16);
\r
1458 _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16);
\r
1459 _rtw_memcpy(pWapiSta->lastRxUnicastPN,WapiAEPNInitialValueSrc,16);
\r
1460 pWapiSta->wapiUskUpdate.bTxEnable = false;
\r
1461 pWapiSta->wapiUskUpdate.bSet = false;
\r
1463 if (psecuritypriv->sw_encrypt== false || psecuritypriv->sw_decrypt == false)
\r
1465 //set unicast key for ASUE
\r
1466 rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
\r
1473 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
\r
1474 if(_rtw_memcmp(pWapiSta->PeerMacAddr,get_bssid(pmlmepriv),6))
\r
1476 pWapiSta->wapiMsk.bSet = true;
\r
1477 _rtw_memcpy(pWapiSta->wapiMsk.dataKey,param->u.crypt.key,16);
\r
1478 _rtw_memcpy(pWapiSta->wapiMsk.micKey,param->u.crypt.key+16,16);
\r
1479 pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
\r
1480 pWapiSta->wapiMsk.bTxEnable = false;
\r
1481 if(!pWapiSta->bSetkeyOk)
\r
1482 pWapiSta->bSetkeyOk = true;
\r
1483 pWapiSta->bAuthenticateInProgress = false;
\r
1485 _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
\r
1487 if (psecuritypriv->sw_decrypt == false)
\r
1489 //set rx broadcast key for ASUE
\r
1490 rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
\r
1502 DBG_8192C("%s, ret=%d\n", __func__, ret);
\r
1509 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1510 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1511 u8 key_index, bool pairwise, const u8 *mac_addr,
\r
1512 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1513 u8 key_index, const u8 *mac_addr,
\r
1514 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1515 struct key_params *params)
\r
1519 struct ieee_param *param = NULL;
\r
1521 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1522 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
1523 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1524 #ifdef CONFIG_TDLS
\r
1525 struct sta_info *ptdls_sta;
\r
1526 #endif /* CONFIG_TDLS */
\r
1528 DBG_871X(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
\r
1529 DBG_871X("cipher=0x%x\n", params->cipher);
\r
1530 DBG_871X("key_len=0x%x\n", params->key_len);
\r
1531 DBG_871X("seq_len=0x%x\n", params->seq_len);
\r
1532 DBG_871X("key_index=%d\n", key_index);
\r
1533 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1534 DBG_871X("pairwise=%d\n", pairwise);
\r
1535 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1537 param_len = sizeof(struct ieee_param) + params->key_len;
\r
1538 param = (struct ieee_param *)rtw_malloc(param_len);
\r
1539 if (param == NULL)
\r
1542 _rtw_memset(param, 0, param_len);
\r
1544 param->cmd = IEEE_CMD_SET_ENCRYPTION;
\r
1545 _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
\r
1547 switch (params->cipher) {
\r
1548 case IW_AUTH_CIPHER_NONE:
\r
1549 //todo: remove key
\r
1551 alg_name = "none";
\r
1553 case WLAN_CIPHER_SUITE_WEP40:
\r
1554 case WLAN_CIPHER_SUITE_WEP104:
\r
1557 case WLAN_CIPHER_SUITE_TKIP:
\r
1558 alg_name = "TKIP";
\r
1560 case WLAN_CIPHER_SUITE_CCMP:
\r
1561 alg_name = "CCMP";
\r
1563 #ifdef CONFIG_IEEE80211W
\r
1564 case WLAN_CIPHER_SUITE_AES_CMAC:
\r
1567 #endif //CONFIG_IEEE80211W
\r
1568 #ifdef CONFIG_WAPI_SUPPORT
\r
1569 case WLAN_CIPHER_SUITE_SMS4:
\r
1571 if(pairwise == NL80211_KEYTYPE_PAIRWISE) {
\r
1572 if (key_index != 0 && key_index != 1) {
\r
1576 _rtw_memcpy((void*)param->sta_addr, (void*)mac_addr, ETH_ALEN);
\r
1578 DBG_871X("mac_addr is null \n");
\r
1580 DBG_871X("rtw_wx_set_enc_ext: SMS4 case \n");
\r
1589 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
\r
1592 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
\r
1594 param->u.crypt.set_tx = 0; //for wpa/wpa2 group key
\r
1596 param->u.crypt.set_tx = 1; //for wpa/wpa2 pairwise key
\r
1600 //param->u.crypt.idx = key_index - 1;
\r
1601 param->u.crypt.idx = key_index;
\r
1603 if (params->seq_len && params->seq)
\r
1605 _rtw_memcpy(param->u.crypt.seq, (u8 *)params->seq, params->seq_len);
\r
1608 if(params->key_len && params->key)
\r
1610 param->u.crypt.key_len = params->key_len;
\r
1611 _rtw_memcpy(param->u.crypt.key, (u8 *)params->key, params->key_len);
\r
1614 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
\r
1616 #ifdef CONFIG_TDLS
\r
1617 if (rtw_tdls_is_driver_setup(padapter) == _FALSE && mac_addr) {
\r
1618 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, (void *)mac_addr);
\r
1619 if (ptdls_sta != NULL && ptdls_sta->tdls_sta_state) {
\r
1620 _rtw_memcpy(ptdls_sta->tpk.tk, params->key, params->key_len);
\r
1621 rtw_tdls_set_key(padapter, ptdls_sta);
\r
1625 #endif /* CONFIG_TDLS */
\r
1627 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
\r
1629 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
1631 #ifdef CONFIG_AP_MODE
\r
1633 _rtw_memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN);
\r
1635 ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
\r
1638 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE
\r
1639 || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)
\r
1641 //DBG_8192C("@@@@@@@@@@ fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
\r
1642 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
\r
1646 DBG_8192C("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
\r
1653 rtw_mfree((u8*)param, param_len);
\r
1660 static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1661 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1662 u8 key_index, bool pairwise, const u8 *mac_addr,
\r
1663 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1664 u8 key_index, const u8 *mac_addr,
\r
1665 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1667 void (*callback)(void *cookie,
\r
1668 struct key_params*))
\r
1671 struct iwm_priv *iwm = ndev_to_iwm(ndev);
\r
1672 struct iwm_key *key = &iwm->keys[key_index];
\r
1673 struct key_params params;
\r
1675 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
\r
1677 memset(¶ms, 0, sizeof(params));
\r
1679 params.cipher = key->cipher;
\r
1680 params.key_len = key->key_len;
\r
1681 params.seq_len = key->seq_len;
\r
1682 params.seq = key->seq;
\r
1683 params.key = key->key;
\r
1685 callback(cookie, ¶ms);
\r
1687 return key->key_len ? 0 : -ENOENT;
\r
1689 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
1693 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1694 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1695 u8 key_index, bool pairwise, const u8 *mac_addr)
\r
1696 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1697 u8 key_index, const u8 *mac_addr)
\r
1698 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1700 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1701 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1703 DBG_871X(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index);
\r
1705 if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
\r
1707 //clear the flag of wep default key set.
\r
1708 psecuritypriv->bWepDefaultKeyIdxSet = 0;
\r
1714 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
\r
1715 struct net_device *ndev, u8 key_index
\r
1716 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1717 , bool unicast, bool multicast
\r
1721 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1722 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1724 #define SET_DEF_KEY_PARAM_FMT " key_index=%d"
\r
1725 #define SET_DEF_KEY_PARAM_ARG , key_index
\r
1726 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1727 #define SET_DEF_KEY_PARAM_FMT_2_6_38 ", unicast=%d, multicast=%d"
\r
1728 #define SET_DEF_KEY_PARAM_ARG_2_6_38 , unicast, multicast
\r
1730 #define SET_DEF_KEY_PARAM_FMT_2_6_38 ""
\r
1731 #define SET_DEF_KEY_PARAM_ARG_2_6_38
\r
1734 DBG_871X(FUNC_NDEV_FMT
\r
1735 SET_DEF_KEY_PARAM_FMT
\r
1736 SET_DEF_KEY_PARAM_FMT_2_6_38
\r
1737 "\n", FUNC_NDEV_ARG(ndev)
\r
1738 SET_DEF_KEY_PARAM_ARG
\r
1739 SET_DEF_KEY_PARAM_ARG_2_6_38
\r
1742 if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) //set wep default key
\r
1744 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1746 psecuritypriv->dot11PrivacyKeyIndex = key_index;
\r
1748 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
\r
1749 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1750 if (psecuritypriv->dot11DefKeylen[key_index] == 13)
\r
1752 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
\r
1753 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1756 psecuritypriv->bWepDefaultKeyIdxSet = 1; //set the flag to represent that wep default key has been set
\r
1762 #if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
\r
1763 static int cfg80211_rtw_set_rekey_data(struct wiphy *wiphy,
\r
1764 struct net_device *ndev,
\r
1765 struct cfg80211_gtk_rekey_data *data)
\r
1768 struct sta_info *psta;
\r
1769 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1770 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1771 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1772 struct security_priv *psecuritypriv = &(padapter->securitypriv);
\r
1774 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
\r
1775 if (psta == NULL) {
\r
1776 DBG_871X("%s, : Obtain Sta_info fail\n", __func__);
\r
1780 _rtw_memcpy(psta->kek, data->kek, NL80211_KEK_LEN);
\r
1781 /*printk("\ncfg80211_rtw_set_rekey_data KEK:");
\r
1782 for(i=0;i<NL80211_KEK_LEN; i++)
\r
1783 printk(" %02x ", psta->kek[i]);*/
\r
1784 _rtw_memcpy(psta->kck, data->kck, NL80211_KCK_LEN);
\r
1785 /*printk("\ncfg80211_rtw_set_rekey_data KCK:");
\r
1786 for(i=0;i<NL80211_KCK_LEN; i++)
\r
1787 printk(" %02x ", psta->kck[i]);*/
\r
1788 _rtw_memcpy(psta->replay_ctr, data->replay_ctr, NL80211_REPLAY_CTR_LEN);
\r
1789 psecuritypriv->binstallKCK_KEK = _TRUE;
\r
1790 /*printk("\nREPLAY_CTR: ");
\r
1791 for(i=0;i<RTW_REPLAY_CTR_LEN; i++)
\r
1792 printk(" %02x ", psta->replay_ctr[i]);*/
\r
1796 #endif /*CONFIG_GTK_OL*/
\r
1797 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
\r
1798 struct net_device *ndev,
\r
1799 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
1804 struct station_info *sinfo)
\r
1807 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1808 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1809 struct sta_info *psta = NULL;
\r
1810 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1812 sinfo->filled = 0;
\r
1815 DBG_871X(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
\r
1820 psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
\r
1821 if (psta == NULL) {
\r
1822 DBG_8192C("%s, sta_info is null\n", __func__);
\r
1827 #ifdef CONFIG_DEBUG_CFG80211
\r
1828 DBG_871X(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
\r
1831 //for infra./P2PClient mode
\r
1832 if( check_fwstate(pmlmepriv, WIFI_STATION_STATE)
\r
1833 && check_fwstate(pmlmepriv, _FW_LINKED)
\r
1836 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
1838 if (_rtw_memcmp((u8 *)mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) {
\r
1839 DBG_871X("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
\r
1844 sinfo->filled |= STATION_INFO_SIGNAL;
\r
1845 sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
\r
1847 sinfo->filled |= STATION_INFO_TX_BITRATE;
\r
1848 sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
\r
1850 sinfo->filled |= STATION_INFO_RX_PACKETS;
\r
1851 sinfo->rx_packets = sta_rx_data_pkts(psta);
\r
1853 sinfo->filled |= STATION_INFO_TX_PACKETS;
\r
1854 sinfo->tx_packets = psta->sta_stats.tx_pkts;
\r
1858 //for Ad-Hoc/AP mode
\r
1859 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
\r
1860 ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
\r
1861 ||check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
1862 && check_fwstate(pmlmepriv, _FW_LINKED)
\r
1865 //TODO: should acquire station info...
\r
1872 extern int netdev_open(struct net_device *pnetdev);
\r
1873 #ifdef CONFIG_CONCURRENT_MODE
\r
1874 extern int netdev_if2_open(struct net_device *pnetdev);
\r
1878 enum nl80211_iftype {
\r
1879 NL80211_IFTYPE_UNSPECIFIED,
\r
1880 NL80211_IFTYPE_ADHOC, //1
\r
1881 NL80211_IFTYPE_STATION, //2
\r
1882 NL80211_IFTYPE_AP, //3
\r
1883 NL80211_IFTYPE_AP_VLAN,
\r
1884 NL80211_IFTYPE_WDS,
\r
1885 NL80211_IFTYPE_MONITOR, //6
\r
1886 NL80211_IFTYPE_MESH_POINT,
\r
1887 NL80211_IFTYPE_P2P_CLIENT, //8
\r
1888 NL80211_IFTYPE_P2P_GO, //9
\r
1890 NUM_NL80211_IFTYPES,
\r
1891 NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
\r
1894 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
\r
1895 struct net_device *ndev,
\r
1896 enum nl80211_iftype type, u32 *flags,
\r
1897 struct vif_params *params)
\r
1899 enum nl80211_iftype old_type;
\r
1900 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
\r
1901 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1902 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
1903 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
1905 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
1908 u8 change = _FALSE;
\r
1910 DBG_871X(FUNC_NDEV_FMT" type=%d\n", FUNC_NDEV_ARG(ndev), type);
\r
1912 if(adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE)
\r
1918 #ifdef CONFIG_CONCURRENT_MODE
\r
1919 if(padapter->adapter_type == SECONDARY_ADAPTER)
\r
1921 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev));
\r
1922 if(netdev_if2_open(ndev) != 0) {
\r
1923 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open fail\n", FUNC_NDEV_ARG(ndev));
\r
1928 else if(padapter->adapter_type == PRIMARY_ADAPTER)
\r
1929 #endif //CONFIG_CONCURRENT_MODE
\r
1931 DBG_871X(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
\r
1932 if(netdev_open(ndev) != 0) {
\r
1933 DBG_871X(FUNC_NDEV_FMT" call netdev_open fail\n", FUNC_NDEV_ARG(ndev));
\r
1939 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
1940 DBG_871X(FUNC_NDEV_FMT" call rtw_pwr_wakeup fail\n", FUNC_NDEV_ARG(ndev));
\r
1945 old_type = rtw_wdev->iftype;
\r
1946 DBG_871X(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
\r
1947 FUNC_NDEV_ARG(ndev), old_type, type);
\r
1949 if(old_type != type)
\r
1952 pmlmeext->action_public_rxseq = 0xffff;
\r
1953 pmlmeext->action_public_dialog_token = 0xff;
\r
1956 /* initial default type */
\r
1957 ndev->type = ARPHRD_ETHER;
\r
1960 case NL80211_IFTYPE_ADHOC:
\r
1961 networkType = Ndis802_11IBSS;
\r
1963 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1964 case NL80211_IFTYPE_P2P_CLIENT:
\r
1966 case NL80211_IFTYPE_STATION:
\r
1967 networkType = Ndis802_11Infrastructure;
\r
1969 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1971 if(change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
1973 //it means remove GO and change mode from AP(GO) to station(P2P DEVICE)
\r
1974 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
1975 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
1977 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
1979 #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1980 if (type == NL80211_IFTYPE_P2P_CLIENT)
\r
1981 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
\r
1983 /* NL80211_IFTYPE_STATION */
\r
1984 if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT)
\r
1985 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
1989 #endif //CONFIG_P2P
\r
1991 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1992 case NL80211_IFTYPE_P2P_GO:
\r
1994 case NL80211_IFTYPE_AP:
\r
1995 networkType = Ndis802_11APMode;
\r
1997 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1999 if(change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2001 //it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO)
\r
2002 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
\r
2005 #endif //CONFIG_P2P
\r
2007 case NL80211_IFTYPE_MONITOR:
\r
2008 networkType = Ndis802_11Monitor;
\r
2010 ndev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */
\r
2012 ndev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */
\r
2015 ret = -EOPNOTSUPP;
\r
2019 rtw_wdev->iftype = type;
\r
2021 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE)
\r
2023 rtw_wdev->iftype = old_type;
\r
2028 rtw_setopmode_cmd(padapter, networkType, _TRUE);
\r
2032 DBG_871X(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret);
\r
2036 void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted)
\r
2038 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
2041 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2042 if (pwdev_priv->scan_request != NULL) {
\r
2043 #ifdef CONFIG_DEBUG_CFG80211
\r
2044 DBG_871X("%s with scan req\n", __FUNCTION__);
\r
2047 /* avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); */
\r
2048 if(pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
\r
2050 DBG_8192C("error wiphy compare\n");
\r
2054 cfg80211_scan_done(pwdev_priv->scan_request, aborted);
\r
2057 pwdev_priv->scan_request = NULL;
\r
2059 #ifdef CONFIG_DEBUG_CFG80211
\r
2060 DBG_871X("%s without scan req\n", __FUNCTION__);
\r
2063 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2066 u32 rtw_cfg80211_wait_scan_req_empty(_adapter *adapter, u32 timeout_ms)
\r
2068 struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
\r
2069 u8 empty = _FALSE;
\r
2073 start = rtw_get_current_time();
\r
2075 while (rtw_get_passing_time_ms(start) <= timeout_ms) {
\r
2077 if (RTW_CANNOT_RUN(adapter))
\r
2080 if (!wdev_priv->scan_request) {
\r
2085 rtw_msleep_os(10);
\r
2088 pass_ms = rtw_get_passing_time_ms(start);
\r
2090 if (empty == _FALSE && pass_ms > timeout_ms)
\r
2091 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pass_ms:%u, timeout\n"
\r
2092 , FUNC_ADPT_ARG(adapter), pass_ms);
\r
2097 void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork)
\r
2099 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
2100 struct wiphy *wiphy = pwdev->wiphy;
\r
2101 struct cfg80211_bss *bss = NULL;
\r
2102 WLAN_BSSID_EX select_network = pnetwork->network;
\r
2104 bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
\r
2105 select_network.MacAddress, select_network.Ssid.Ssid,
\r
2106 select_network.Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
\r
2107 0/*WLAN_CAPABILITY_ESS*/);
\r
2110 cfg80211_unlink_bss(wiphy, bss);
\r
2111 DBG_8192C("%s(): cfg80211_unlink %s!! () ",__func__,select_network.Ssid.Ssid );
\r
2112 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
2113 cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
\r
2115 cfg80211_put_bss(bss);
\r
2121 void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
\r
2124 _list *plist, *phead;
\r
2125 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2126 _queue *queue = &(pmlmepriv->scanned_queue);
\r
2127 struct wlan_network *pnetwork = NULL;
\r
2129 u32 wait_for_surveydone;
\r
2132 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
\r
2133 #endif //CONFIG_P2P
\r
2134 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
2136 #ifdef CONFIG_DEBUG_CFG80211
\r
2137 DBG_8192C("%s\n", __func__);
\r
2140 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
2142 phead = get_list_head(queue);
\r
2143 plist = get_next(phead);
\r
2147 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
\r
2150 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
\r
2152 //report network only if the current channel set contains the channel to which this network belongs
\r
2153 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
\r
2154 && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
\r
2155 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
\r
2158 //ev=translate_scan(padapter, a, pnetwork, ev, stop);
\r
2159 rtw_cfg80211_inform_bss(padapter, pnetwork);
\r
2161 /* //check ralink testbed RSN IE length
\r
2163 if(_rtw_memcmp(pnetwork->network.Ssid.Ssid, "Ralink_11n_AP",13))
\r
2167 p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
\r
2168 DBG_871X("ie_len=%d\n", ie_len);
\r
2171 plist = get_next(plist);
\r
2175 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
2178 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
\r
2181 uint wps_ielen = 0;
\r
2183 u32 p2p_ielen = 0;
\r
2185 u32 wfd_ielen = 0;
\r
2187 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2189 #ifdef CONFIG_DEBUG_CFG80211
\r
2190 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
2195 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
2197 #ifdef CONFIG_DEBUG_CFG80211
\r
2198 DBG_8192C("probe_req_wps_ielen=%d\n", wps_ielen);
\r
2201 if(pmlmepriv->wps_probe_req_ie)
\r
2203 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
\r
2204 pmlmepriv->wps_probe_req_ie_len = 0;
\r
2205 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
\r
2206 pmlmepriv->wps_probe_req_ie = NULL;
\r
2209 pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
\r
2210 if ( pmlmepriv->wps_probe_req_ie == NULL) {
\r
2211 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2215 _rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
\r
2216 pmlmepriv->wps_probe_req_ie_len = wps_ielen;
\r
2219 //buf += wps_ielen;
\r
2220 //len -= wps_ielen;
\r
2223 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
2225 struct wifidirect_info *wdinfo = &padapter->wdinfo;
\r
2226 u32 attr_contentlen = 0;
\r
2227 u8 listen_ch_attr[5];
\r
2229 #ifdef CONFIG_DEBUG_CFG80211
\r
2230 DBG_8192C("probe_req_p2p_ielen=%d\n", p2p_ielen);
\r
2233 if(pmlmepriv->p2p_probe_req_ie)
\r
2235 u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
\r
2236 pmlmepriv->p2p_probe_req_ie_len = 0;
\r
2237 rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len);
\r
2238 pmlmepriv->p2p_probe_req_ie = NULL;
\r
2241 pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen);
\r
2242 if ( pmlmepriv->p2p_probe_req_ie == NULL) {
\r
2243 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2247 _rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
\r
2248 pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
\r
2250 if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8*)listen_ch_attr, (uint*) &attr_contentlen)
\r
2251 && attr_contentlen == 5)
\r
2253 if (wdinfo->listen_channel != listen_ch_attr[4]) {
\r
2254 DBG_871X(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n",
\r
2255 FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2],
\r
2256 listen_ch_attr[3], listen_ch_attr[4]);
\r
2257 wdinfo->listen_channel = listen_ch_attr[4];
\r
2261 #endif //CONFIG_P2P
\r
2264 wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen);
\r
2266 #ifdef CONFIG_DEBUG_CFG80211
\r
2267 DBG_8192C("probe_req_wfd_ielen=%d\n", wfd_ielen);
\r
2270 if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_REQ_IE, wfd_ie, wfd_ielen) != _SUCCESS)
\r
2273 #endif /* CONFIG_WFD */
\r
2280 static int cfg80211_rtw_scan(struct wiphy *wiphy
\r
2281 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
\r
2282 , struct net_device *ndev
\r
2284 , struct cfg80211_scan_request *request)
\r
2286 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
2287 struct net_device *ndev = wdev_to_ndev(request->wdev);
\r
2290 u8 _status = _FALSE;
\r
2292 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
\r
2293 struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
\r
2296 uint wps_ielen=0;
\r
2299 u8 survey_times=3;
\r
2300 u8 survey_times_for_one_ch=6;
\r
2301 struct cfg80211_ssid *ssids = request->ssids;
\r
2302 int social_channel = 0, j = 0;
\r
2303 bool need_indicate_scan_done = _FALSE;
\r
2304 bool ps_denied = _FALSE;
\r
2306 _adapter *padapter;
\r
2307 struct rtw_wdev_priv *pwdev_priv;
\r
2308 struct mlme_priv *pmlmepriv;
\r
2310 struct wifidirect_info *pwdinfo;
\r
2311 #endif //CONFIG_P2P
\r
2312 #ifdef CONFIG_CONCURRENT_MODE
\r
2313 PADAPTER pbuddy_adapter = NULL;
\r
2314 struct mlme_priv *pbuddy_mlmepriv = NULL;
\r
2315 #endif //CONFIG_CONCURRENT_MODE
\r
2317 if (ndev == NULL) {
\r
2322 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2323 pwdev_priv = adapter_wdev_data(padapter);
\r
2324 pmlmepriv= &padapter->mlmepriv;
\r
2326 pwdinfo= &(padapter->wdinfo);
\r
2327 #endif //CONFIG_P2P
\r
2329 //#ifdef CONFIG_DEBUG_CFG80211
\r
2330 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
2333 #ifdef CONFIG_CONCURRENT_MODE
\r
2334 if (padapter->pbuddy_adapter) {
\r
2335 pbuddy_adapter = padapter->pbuddy_adapter;
\r
2336 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
\r
2338 #endif //CONFIG_CONCURRENT_MODE
\r
2340 #ifdef CONFIG_MP_INCLUDED
\r
2341 if (padapter->registrypriv.mp_mode == 1)
\r
2343 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter));
\r
2347 #ifdef CONFIG_CONCURRENT_MODE
\r
2348 if (padapter->pbuddy_adapter) {
\r
2349 if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1)
\r
2351 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter));
\r
2356 #endif //CONFIG_CONCURRENT_MODE
\r
2359 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2360 pwdev_priv->scan_request = request;
\r
2361 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2363 if (adapter_wdev_data(padapter)->block_scan == _TRUE) {
\r
2364 DBG_871X(FUNC_ADPT_FMT" wdev_priv.block_scan is set\n", FUNC_ADPT_ARG(padapter));
\r
2365 need_indicate_scan_done = _TRUE;
\r
2366 goto check_need_indicate_scan_done;
\r
2369 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
2371 #ifdef CONFIG_DEBUG_CFG80211
\r
2372 DBG_871X("%s under WIFI_AP_STATE\n", __FUNCTION__);
\r
2375 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
\r
2377 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2379 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
\r
2381 DBG_8192C("AP mode process WPS \n");
\r
2384 need_indicate_scan_done = _TRUE;
\r
2385 goto check_need_indicate_scan_done;
\r
2389 rtw_ps_deny(padapter, PS_DENY_SCAN);
\r
2390 ps_denied = _TRUE;
\r
2391 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
2392 need_indicate_scan_done = _TRUE;
\r
2393 goto check_need_indicate_scan_done;
\r
2397 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
2399 if(ssids->ssid != NULL
\r
2400 && _rtw_memcmp(ssids->ssid, "DIRECT-", 7)
\r
2401 && rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
\r
2404 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2406 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
\r
2407 adapter_wdev_data(padapter)->p2p_enabled = _TRUE;
\r
2411 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
2412 #ifdef CONFIG_DEBUG_CFG80211
\r
2413 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
2416 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
\r
2418 if(request->n_channels == 3 &&
\r
2419 request->channels[0]->hw_value == 1 &&
\r
2420 request->channels[1]->hw_value == 6 &&
\r
2421 request->channels[2]->hw_value == 11
\r
2424 social_channel = 1;
\r
2428 #endif //CONFIG_P2P
\r
2430 if(request->ie && request->ie_len>0)
\r
2432 rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len );
\r
2435 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
\r
2436 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2437 need_indicate_scan_done = _TRUE;
\r
2438 goto check_need_indicate_scan_done;
\r
2439 } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
2440 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2442 goto check_need_indicate_scan_done;
\r
2445 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)
\r
2447 #if 1 // Miracast can't do AP scan
\r
2448 static u32 lastscantime = 0;
\r
2451 passtime = rtw_get_passing_time_ms(lastscantime);
\r
2452 lastscantime = rtw_get_current_time();
\r
2453 if (passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD)
\r
2456 DBG_871X("%s: bBusyTraffic == _TRUE\n", __FUNCTION__);
\r
2457 need_indicate_scan_done = _TRUE;
\r
2458 goto check_need_indicate_scan_done;
\r
2462 if (rtw_is_scan_deny(padapter)){
\r
2463 DBG_871X(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter));
\r
2464 need_indicate_scan_done = _TRUE;
\r
2465 goto check_need_indicate_scan_done;
\r
2468 #ifdef CONFIG_CONCURRENT_MODE
\r
2469 if(pbuddy_mlmepriv && (pbuddy_mlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))
\r
2471 #if 1 // Miracast can't do AP scan
\r
2472 static u32 buddylastscantime = 0;
\r
2475 passtime = rtw_get_passing_time_ms(buddylastscantime);
\r
2476 buddylastscantime = rtw_get_current_time();
\r
2477 if ((passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD)
\r
2478 //#ifdef CONFIG_P2P
\r
2479 // ||(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
\r
2480 //#endif //CONFIG_P2P
\r
2484 DBG_871X("%s: bBusyTraffic == _TRUE at buddy_intf\n", __FUNCTION__);
\r
2485 need_indicate_scan_done = _TRUE;
\r
2486 goto check_need_indicate_scan_done;
\r
2490 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE) {
\r
2491 DBG_871X("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv->fw_state);
\r
2492 need_indicate_scan_done = _TRUE;
\r
2493 goto check_need_indicate_scan_done;
\r
2495 } else if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY)) {
\r
2496 bool scan_via_buddy = _FALSE;
\r
2497 struct rtw_wdev_priv *buddy_wdev_priv = adapter_wdev_data(pbuddy_adapter);
\r
2499 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2500 _enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
\r
2501 if (buddy_wdev_priv->scan_request) {
\r
2502 DBG_871X("scan via buddy\n");
\r
2503 pmlmepriv->scanning_via_buddy_intf = _TRUE;
\r
2504 _enter_critical_bh(&pmlmepriv->lock, &irqL);
\r
2505 set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
\r
2506 _exit_critical_bh(&pmlmepriv->lock, &irqL);
\r
2507 scan_via_buddy = _TRUE;
\r
2509 _exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
\r
2510 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2512 if (scan_via_buddy == _FALSE)
\r
2513 need_indicate_scan_done = _TRUE;
\r
2515 goto check_need_indicate_scan_done;
\r
2517 #endif /* CONFIG_CONCURRENT_MODE */
\r
2520 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
\r
2522 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
\r
2523 rtw_free_network_queue(padapter, _TRUE);
\r
2525 if(social_channel == 0)
\r
2526 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
\r
2528 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
\r
2530 #endif //CONFIG_P2P
\r
2533 _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
\r
2534 //parsing request ssids, n_ssids
\r
2535 for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
\r
2536 #ifdef CONFIG_DEBUG_CFG80211
\r
2537 DBG_8192C("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
\r
2539 _rtw_memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
\r
2540 ssid[i].SsidLength = ssids[i].ssid_len;
\r
2543 /* parsing channels, n_channels */
\r
2544 _rtw_memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
\r
2545 for (i=0;i<request->n_channels && i<RTW_CHANNEL_SCAN_AMOUNT;i++) {
\r
2546 #ifdef CONFIG_DEBUG_CFG80211
\r
2547 DBG_871X(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
\r
2549 ch[i].hw_value = request->channels[i]->hw_value;
\r
2550 ch[i].flags = request->channels[i]->flags;
\r
2553 _enter_critical_bh(&pmlmepriv->lock, &irqL);
\r
2554 if (request->n_channels == 1) {
\r
2555 for(i=1;i<survey_times_for_one_ch;i++)
\r
2556 _rtw_memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
\r
2557 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times_for_one_ch);
\r
2558 } else if (request->n_channels <= 4) {
\r
2559 for(j=request->n_channels-1;j>=0;j--)
\r
2560 for(i=0;i<survey_times;i++)
\r
2562 _rtw_memcpy(&ch[j*survey_times+i], &ch[j], sizeof(struct rtw_ieee80211_channel));
\r
2564 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * request->n_channels);
\r
2566 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
\r
2568 _exit_critical_bh(&pmlmepriv->lock, &irqL);
\r
2571 if(_status == _FALSE)
\r
2576 check_need_indicate_scan_done:
\r
2577 if (_TRUE == need_indicate_scan_done)
\r
2579 rtw_cfg80211_surveydone_event_callback(padapter);
\r
2580 rtw_cfg80211_indicate_scan_done(padapter, _FALSE);
\r
2584 if (ps_denied == _TRUE)
\r
2585 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
\r
2592 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
\r
2595 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
\r
2597 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
\r
2598 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
\r
2601 iwm->conf.rts_threshold = wiphy->rts_threshold;
\r
2603 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
\r
2604 CFG_RTS_THRESHOLD,
\r
2605 iwm->conf.rts_threshold);
\r
2610 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
\r
2611 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
\r
2614 iwm->conf.frag_threshold = wiphy->frag_threshold;
\r
2616 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
\r
2617 CFG_FRAG_THRESHOLD,
\r
2618 iwm->conf.frag_threshold);
\r
2623 DBG_8192C("%s\n", __func__);
\r
2629 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
\r
2631 DBG_8192C("%s, wpa_version=%d\n", __func__, wpa_version);
\r
2633 if (!wpa_version) {
\r
2634 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
2639 if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
\r
2641 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
\r
2645 if (wpa_version & NL80211_WPA_VERSION_2)
\r
2647 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
\r
2651 #ifdef CONFIG_WAPI_SUPPORT
\r
2652 if (wpa_version & NL80211_WAPI_VERSION_1)
\r
2654 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWAPI;
\r
2662 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
\r
2663 enum nl80211_auth_type sme_auth_type)
\r
2665 DBG_8192C("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
\r
2668 switch (sme_auth_type) {
\r
2669 case NL80211_AUTHTYPE_AUTOMATIC:
\r
2671 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
\r
2674 case NL80211_AUTHTYPE_OPEN_SYSTEM:
\r
2676 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
\r
2678 if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
\r
2679 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2681 #ifdef CONFIG_WAPI_SUPPORT
\r
2682 if(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI)
\r
2683 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2687 case NL80211_AUTHTYPE_SHARED_KEY:
\r
2689 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
\r
2691 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2696 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
\r
2697 //return -ENOTSUPP;
\r
2704 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
\r
2706 u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2708 u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
\r
2709 &psecuritypriv->dot118021XGrpPrivacy;
\r
2711 DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
\r
2715 *profile_cipher = _NO_PRIVACY_;
\r
2716 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
\r
2721 case IW_AUTH_CIPHER_NONE:
\r
2722 *profile_cipher = _NO_PRIVACY_;
\r
2723 ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2724 #ifdef CONFIG_WAPI_SUPPORT
\r
2725 if(psecuritypriv->dot11PrivacyAlgrthm ==_SMS4_ )
\r
2727 *profile_cipher = _SMS4_;
\r
2731 case WLAN_CIPHER_SUITE_WEP40:
\r
2732 *profile_cipher = _WEP40_;
\r
2733 ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2735 case WLAN_CIPHER_SUITE_WEP104:
\r
2736 *profile_cipher = _WEP104_;
\r
2737 ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2739 case WLAN_CIPHER_SUITE_TKIP:
\r
2740 *profile_cipher = _TKIP_;
\r
2741 ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2743 case WLAN_CIPHER_SUITE_CCMP:
\r
2744 *profile_cipher = _AES_;
\r
2745 ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2747 #ifdef CONFIG_WAPI_SUPPORT
\r
2748 case WLAN_CIPHER_SUITE_SMS4:
\r
2749 *profile_cipher = _SMS4_;
\r
2750 ndisencryptstatus = Ndis802_11_EncrypteionWAPI;
\r
2754 DBG_8192C("Unsupported cipher: 0x%x\n", cipher);
\r
2760 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
\r
2762 //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
\r
2763 // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
\r
2769 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
\r
2771 DBG_8192C("%s, key_mgt=0x%x\n", __func__, key_mgt);
\r
2773 if (key_mgt == WLAN_AKM_SUITE_8021X)
\r
2774 //*auth_type = UMAC_AUTH_TYPE_8021X;
\r
2775 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2776 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
\r
2777 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2779 #ifdef CONFIG_WAPI_SUPPORT
\r
2780 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_PSK){
\r
2781 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2783 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_CERT){
\r
2784 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2790 DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt);
\r
2797 static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
\r
2799 u8 *buf=NULL, *pos=NULL;
\r
2801 int group_cipher = 0, pairwise_cipher = 0;
\r
2806 u8 null_addr[]= {0,0,0,0,0,0};
\r
2808 if (pie == NULL || !ielen) {
\r
2809 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
\r
2810 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2814 if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
\r
2819 buf = rtw_zmalloc(ielen);
\r
2825 _rtw_memcpy(buf, pie , ielen);
\r
2830 DBG_8192C("set wpa_ie(length:%zu):\n", ielen);
\r
2831 for(i=0;i<ielen;i=i+8)
\r
2832 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
2836 if(ielen < RSN_HEADER_LEN){
\r
2837 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
\r
2842 pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
\r
2843 if(pwpa && wpa_ielen>0)
\r
2845 if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
2847 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
2848 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
\r
2849 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
\r
2851 DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
\r
2855 pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
\r
2856 if(pwpa2 && wpa2_ielen>0)
\r
2858 if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
2860 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
2861 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
\r
2862 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
\r
2864 DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
\r
2868 if (group_cipher == 0)
\r
2870 group_cipher = WPA_CIPHER_NONE;
\r
2872 if (pairwise_cipher == 0)
\r
2874 pairwise_cipher = WPA_CIPHER_NONE;
\r
2877 switch(group_cipher)
\r
2879 case WPA_CIPHER_NONE:
\r
2880 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
\r
2881 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
\r
2883 case WPA_CIPHER_WEP40:
\r
2884 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
\r
2885 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2887 case WPA_CIPHER_TKIP:
\r
2888 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
\r
2889 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2891 case WPA_CIPHER_CCMP:
\r
2892 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
\r
2893 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2895 case WPA_CIPHER_WEP104:
\r
2896 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
\r
2897 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2901 switch(pairwise_cipher)
\r
2903 case WPA_CIPHER_NONE:
\r
2904 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
\r
2905 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
\r
2907 case WPA_CIPHER_WEP40:
\r
2908 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
\r
2909 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2911 case WPA_CIPHER_TKIP:
\r
2912 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
\r
2913 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2915 case WPA_CIPHER_CCMP:
\r
2916 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
\r
2917 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2919 case WPA_CIPHER_WEP104:
\r
2920 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
\r
2921 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2925 {/* handle wps_ie */
\r
2929 wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
\r
2930 if (wps_ie && wps_ielen > 0) {
\r
2931 DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen);
\r
2932 padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
\r
2933 _rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
\r
2934 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2936 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2941 {//check p2p_ie for assoc req;
\r
2944 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2946 if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen)))
\r
2948 #ifdef CONFIG_DEBUG_CFG80211
\r
2949 DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
\r
2952 if(pmlmepriv->p2p_assoc_req_ie)
\r
2954 u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
\r
2955 pmlmepriv->p2p_assoc_req_ie_len = 0;
\r
2956 rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
\r
2957 pmlmepriv->p2p_assoc_req_ie = NULL;
\r
2960 pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
\r
2961 if ( pmlmepriv->p2p_assoc_req_ie == NULL) {
\r
2962 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2965 _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
\r
2966 pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
\r
2969 #endif //CONFIG_P2P
\r
2975 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2977 wfd_ie = rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen);
\r
2979 #ifdef CONFIG_DEBUG_CFG80211
\r
2980 DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
\r
2983 if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_REQ_IE, wfd_ie, wfd_ielen) != _SUCCESS)
\r
2987 #endif /* CONFIG_WFD */
\r
2989 //TKIP and AES disallow multicast packets until installing group key
\r
2990 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
\r
2991 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
\r
2992 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
\r
2993 //WPS open need to enable multicast
\r
2994 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
\r
2995 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
\r
2997 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
\r
2998 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
\r
2999 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
\r
3003 rtw_mfree(buf, ielen);
\r
3005 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
3009 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
\r
3010 struct cfg80211_ibss_params *params)
\r
3012 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3013 NDIS_802_11_SSID ndis_ssid;
\r
3014 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3015 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
3016 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
3017 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
3018 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
\r
3019 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
\r
3020 struct cfg80211_chan_def *pch_def;
\r
3022 struct ieee80211_channel *pch;
\r
3025 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
\r
3026 pch_def = (struct cfg80211_chan_def *)(¶ms->chandef);
\r
3027 pch = (struct ieee80211_channel *) pch_def->chan;
\r
3028 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
\r
3029 pch = (struct ieee80211_channel *)(params->channel);
\r
3032 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
3037 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
\r
3042 #ifdef CONFIG_CONCURRENT_MODE
\r
3043 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
\r
3044 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
\r
3048 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
\r
3049 rtw_scan_abort(padapter->pbuddy_adapter);
\r
3051 #endif //CONFIG_CONCURRENT_MODE
\r
3053 if (!params->ssid || !params->ssid_len)
\r
3059 if (params->ssid_len > IW_ESSID_MAX_SIZE){
\r
3065 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
\r
3066 ndis_ssid.SsidLength = params->ssid_len;
\r
3067 _rtw_memcpy(ndis_ssid.Ssid, (u8 *)params->ssid, params->ssid_len);
\r
3069 //DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, params->ssid_len);
\r
3071 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
3072 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
\r
3073 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
3074 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
\r
3075 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
3077 ret = rtw_cfg80211_set_auth_type(psecuritypriv, NL80211_AUTHTYPE_OPEN_SYSTEM);
\r
3078 rtw_set_802_11_authentication_mode(padapter, psecuritypriv->ndisauthtype);
\r
3080 DBG_871X("%s: center_freq = %d\n", __func__, pch->center_freq);
\r
3081 pmlmeext->cur_channel = rtw_freq2ch(pch->center_freq);
\r
3083 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE)
\r
3093 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
\r
3095 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3096 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
3097 enum nl80211_iftype old_type;
\r
3100 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3102 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
\r
3103 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
3106 old_type = rtw_wdev->iftype;
\r
3108 rtw_set_to_roam(padapter, 0);
\r
3110 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
3112 rtw_scan_abort(padapter);
\r
3113 LeaveAllPowerSaveMode(padapter);
\r
3115 rtw_wdev->iftype = NL80211_IFTYPE_STATION;
\r
3117 if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) ==_FALSE)
\r
3119 rtw_wdev->iftype = old_type;
\r
3123 rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure,_TRUE);
\r
3127 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
\r
3128 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3134 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
\r
3135 struct cfg80211_connect_params *sme)
\r
3140 struct wlan_network *pnetwork = NULL;
\r
3141 NDIS_802_11_AUTHENTICATION_MODE authmode;
\r
3142 NDIS_802_11_SSID ndis_ssid;
\r
3143 u8 *dst_ssid, *src_ssid;
\r
3144 u8 *dst_bssid, *src_bssid;
\r
3145 //u8 matched_by_bssid=_FALSE;
\r
3146 //u8 matched_by_ssid=_FALSE;
\r
3147 u8 matched=_FALSE;
\r
3148 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3149 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
3150 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3151 _queue *queue = &pmlmepriv->scanned_queue;
\r
3153 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
\r
3154 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
3157 DBG_871X("=>"FUNC_NDEV_FMT" - Start to Connection\n", FUNC_NDEV_ARG(ndev));
\r
3158 DBG_871X("privacy=%d, key=%p, key_len=%d, key_idx=%d, auth_type=%d\n",
\r
3159 sme->privacy, sme->key, sme->key_len, sme->key_idx, sme->auth_type);
\r
3162 if(adapter_wdev_data(padapter)->block == _TRUE)
\r
3165 DBG_871X("%s wdev_priv.block is set\n", __FUNCTION__);
\r
3169 #ifdef CONFIG_PLATFORM_MSTAR_SCAN_BEFORE_CONNECT
\r
3170 printk("MStar Android!\n");
\r
3171 if(adapter_wdev_data(padapter)->bandroid_scan == _FALSE)
\r
3174 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
3175 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
3176 #endif //CONFIG_P2P
\r
3179 printk("Android hasn't attached yet!\n");
\r
3185 rtw_ps_deny(padapter, PS_DENY_JOIN);
\r
3186 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
3191 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
\r
3196 #ifdef CONFIG_CONCURRENT_MODE
\r
3197 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
\r
3198 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
\r
3202 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
\r
3203 rtw_scan_abort(padapter->pbuddy_adapter);
\r
3207 if (!sme->ssid || !sme->ssid_len)
\r
3213 if (sme->ssid_len > IW_ESSID_MAX_SIZE){
\r
3219 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
\r
3220 ndis_ssid.SsidLength = sme->ssid_len;
\r
3221 _rtw_memcpy(ndis_ssid.Ssid, (u8 *)sme->ssid, sme->ssid_len);
\r
3223 DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
\r
3227 DBG_8192C("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
\r
3230 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
3232 DBG_8192C("%s, fw_state=0x%x, goto exit\n", __FUNCTION__, pmlmepriv->fw_state);
\r
3235 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
\r
3236 rtw_scan_abort(padapter);
\r
3239 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
3240 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
\r
3241 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
3242 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
\r
3243 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
3245 #ifdef CONFIG_WAPI_SUPPORT
\r
3246 padapter->wapiInfo.bWapiEnable = false;
\r
3249 ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
\r
3253 #ifdef CONFIG_WAPI_SUPPORT
\r
3254 if(sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1)
\r
3256 padapter->wapiInfo.bWapiEnable = true;
\r
3257 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
\r
3258 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
\r
3262 ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
\r
3264 #ifdef CONFIG_WAPI_SUPPORT
\r
3265 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI)
\r
3266 padapter->mlmeextpriv.mlmext_info.auth_algo = psecuritypriv->dot11AuthAlgrthm;
\r
3273 DBG_8192C("%s, ie_len=%zu\n", __func__, sme->ie_len);
\r
3275 ret = rtw_cfg80211_set_wpa_ie(padapter, (u8 *)sme->ie, sme->ie_len);
\r
3279 if (sme->crypto.n_ciphers_pairwise) {
\r
3280 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
\r
3285 //For WEP Shared auth
\r
3286 if (sme->key_len > 0 && sme->key)
\r
3288 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
3289 NDIS_802_11_WEP *pwep = NULL;
\r
3290 DBG_871X("%s(): Shared/Auto WEP\n",__FUNCTION__);
\r
3292 wep_key_idx = sme->key_idx;
\r
3293 wep_key_len = sme->key_len;
\r
3295 if (sme->key_idx > WEP_KEYS) {
\r
3300 if (wep_key_len > 0)
\r
3302 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
3303 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
\r
3304 pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
\r
3306 DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
\r
3311 _rtw_memset(pwep, 0, wep_total_len);
\r
3313 pwep->KeyLength = wep_key_len;
\r
3314 pwep->Length = wep_total_len;
\r
3316 if(wep_key_len==13)
\r
3318 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
\r
3319 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
\r
3327 pwep->KeyIndex = wep_key_idx;
\r
3328 pwep->KeyIndex |= 0x80000000;
\r
3330 _rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
\r
3332 if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
\r
3334 ret = -EOPNOTSUPP ;
\r
3338 rtw_mfree((u8 *)pwep,wep_total_len);
\r
3345 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
\r
3349 if (sme->crypto.n_akm_suites) {
\r
3350 ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
\r
3355 #ifdef CONFIG_WAPI_SUPPORT
\r
3356 if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_PSK){
\r
3357 padapter->wapiInfo.bWapiPSK = true;
\r
3359 else if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_CERT){
\r
3360 padapter->wapiInfo.bWapiPSK = false;
\r
3364 authmode = psecuritypriv->ndisauthtype;
\r
3365 rtw_set_802_11_authentication_mode(padapter, authmode);
\r
3367 //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
\r
3369 if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid) == _FALSE) {
\r
3374 DBG_8192C("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy);
\r
3378 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
\r
3380 DBG_8192C("<=%s, ret %d\n",__FUNCTION__, ret);
\r
3382 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
\r
3383 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3389 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
\r
3392 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3394 DBG_871X(FUNC_NDEV_FMT" - Start to Disconnect\n", FUNC_NDEV_ARG(ndev));
\r
3396 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
\r
3397 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
3400 rtw_set_to_roam(padapter, 0);
\r
3402 //if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
3404 rtw_scan_abort(padapter);
\r
3405 LeaveAllPowerSaveMode(padapter);
\r
3406 rtw_disassoc_cmd(padapter, 500, _FALSE);
\r
3408 DBG_871X("%s...call rtw_indicate_disconnect\n", __FUNCTION__);
\r
3410 rtw_indicate_disconnect(padapter, 0, _TRUE);
\r
3412 rtw_free_assoc_resources(padapter, 1);
\r
3413 rtw_pwr_wakeup(padapter);
\r
3416 #ifdef SUPPLICANT_RTK_VERSION_LOWER_THAN_JB42
\r
3417 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3420 DBG_871X(FUNC_NDEV_FMT" return 0\n", FUNC_NDEV_ARG(ndev));
\r
3424 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
\r
3425 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
\r
3426 struct wireless_dev *wdev,
\r
3428 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE)
\r
3429 enum nl80211_tx_power_setting type, int mbm)
\r
3431 enum tx_power_setting type, int dbm)
\r
3435 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
\r
3439 case NL80211_TX_POWER_AUTOMATIC:
\r
3441 case NL80211_TX_POWER_FIXED:
\r
3442 if (mbm < 0 || (mbm % 100))
\r
3443 return -EOPNOTSUPP;
\r
3445 if (!test_bit(IWM_STATUS_READY, &iwm->status))
\r
3448 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
\r
3449 CFG_TX_PWR_LIMIT_USR,
\r
3450 MBM_TO_DBM(mbm) * 2);
\r
3454 return iwm_tx_power_trigger(iwm);
\r
3456 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
\r
3457 return -EOPNOTSUPP;
\r
3460 DBG_8192C("%s\n", __func__);
\r
3464 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
\r
3465 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
\r
3466 struct wireless_dev *wdev,
\r
3470 DBG_8192C("%s\n", __func__);
\r
3477 inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
\r
3479 struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter);
\r
3480 return rtw_wdev_priv->power_mgmt;
\r
3483 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
\r
3484 struct net_device *ndev,
\r
3485 bool enabled, int timeout)
\r
3487 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3488 struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter);
\r
3490 DBG_871X(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
\r
3491 enabled, timeout);
\r
3493 rtw_wdev_priv->power_mgmt = enabled;
\r
3497 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE_CFG80211_PWRMGMT, 1);
\r
3503 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
\r
3504 struct net_device *ndev,
\r
3505 struct cfg80211_pmksa *pmksa)
\r
3507 u8 index,blInserted = _FALSE;
\r
3508 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3509 struct mlme_priv *mlme = &padapter->mlmepriv;
\r
3510 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3511 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
\r
3513 DBG_871X(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
\r
3514 , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
\r
3516 if ( _rtw_memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
\r
3521 if (check_fwstate(mlme, _FW_LINKED) == _FALSE) {
\r
3522 DBG_871X(FUNC_NDEV_FMT" not set pmksa cause not in linked state\n", FUNC_NDEV_ARG(ndev));
\r
3526 blInserted = _FALSE;
\r
3529 for(index=0 ; index<NUM_PMKID_CACHE; index++)
\r
3531 if( _rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) ==_TRUE )
\r
3532 { // BSSID is matched, the same AP => rewrite with new PMKID.
\r
3533 DBG_871X(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(ndev));
\r
3535 _rtw_memcpy( psecuritypriv->PMKIDList[index].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
\r
3536 psecuritypriv->PMKIDList[index].bUsed = _TRUE;
\r
3537 psecuritypriv->PMKIDIndex = index+1;
\r
3538 blInserted = _TRUE;
\r
3545 // Find a new entry
\r
3546 DBG_871X(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
\r
3547 FUNC_NDEV_ARG(ndev), psecuritypriv->PMKIDIndex );
\r
3549 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, (u8 *)pmksa->bssid, ETH_ALEN);
\r
3550 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
\r
3552 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
\r
3553 psecuritypriv->PMKIDIndex++ ;
\r
3554 if(psecuritypriv->PMKIDIndex==16)
\r
3556 psecuritypriv->PMKIDIndex =0;
\r
3563 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
\r
3564 struct net_device *ndev,
\r
3565 struct cfg80211_pmksa *pmksa)
\r
3567 u8 index, bMatched = _FALSE;
\r
3568 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3569 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3571 DBG_871X(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
\r
3572 , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
\r
3574 for(index=0 ; index<NUM_PMKID_CACHE; index++)
\r
3576 if( _rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) ==_TRUE )
\r
3577 { // BSSID is matched, the same AP => Remove this PMKID information and reset it.
\r
3578 _rtw_memset(psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN );
\r
3579 _rtw_memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN );
\r
3580 psecuritypriv->PMKIDList[index].bUsed = _FALSE;
\r
3582 DBG_871X(FUNC_NDEV_FMT" clear id:%hhu\n", FUNC_NDEV_ARG(ndev), index);
\r
3587 if(_FALSE == bMatched)
\r
3589 DBG_871X(FUNC_NDEV_FMT" do not have matched BSSID\n"
\r
3590 , FUNC_NDEV_ARG(ndev));
\r
3597 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
\r
3598 struct net_device *ndev)
\r
3600 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3601 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3603 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3605 _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
\r
3606 psecuritypriv->PMKIDIndex = 0;
\r
3611 #ifdef CONFIG_AP_MODE
\r
3612 void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
3616 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
3617 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3618 struct net_device *ndev = padapter->pnetdev;
\r
3620 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
3622 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
\r
3624 struct station_info sinfo;
\r
3626 if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
\r
3627 ie_offset = _ASOCREQ_IE_OFFSET_;
\r
3628 else // WIFI_REASSOCREQ
\r
3629 ie_offset = _REASOCREQ_IE_OFFSET_;
\r
3631 memset(&sinfo, 0, sizeof(sinfo));
\r
3632 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
\r
3633 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
\r
3634 sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
\r
3635 cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
\r
3637 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3638 channel = pmlmeext->cur_channel;
\r
3639 freq = rtw_ch2freq(channel);
\r
3641 #ifdef COMPAT_KERNEL_RELEASE
\r
3642 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3643 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
3644 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3645 #else //COMPAT_KERNEL_RELEASE
\r
3647 //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc()
\r
3648 #ifndef CONFIG_PLATFORM_MSTAR
\r
3649 pwdev->iftype = NL80211_IFTYPE_STATION;
\r
3650 #endif //CONFIG_PLATFORM_MSTAR
\r
3651 DBG_8192C("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
\r
3652 rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
\r
3653 DBG_8192C("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
\r
3654 pwdev->iftype = NL80211_IFTYPE_AP;
\r
3655 //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3657 #endif //COMPAT_KERNEL_RELEASE
\r
3658 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3662 void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason)
\r
3668 struct rtw_ieee80211_hdr *pwlanhdr;
\r
3669 unsigned short *fctrl;
\r
3670 u8 mgmt_buf[128] = {0};
\r
3671 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3672 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
3673 struct net_device *ndev = padapter->pnetdev;
\r
3675 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
3677 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
\r
3678 cfg80211_del_sta(ndev, da, GFP_ATOMIC);
\r
3679 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3680 channel = pmlmeext->cur_channel;
\r
3681 freq = rtw_ch2freq(channel);
\r
3683 pmgmt_frame = mgmt_buf;
\r
3684 pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
\r
3686 fctrl = &(pwlanhdr->frame_ctl);
\r
3689 _rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN);
\r
3690 _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN);
\r
3691 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
3693 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
3694 pmlmeext->mgnt_seq++;
\r
3695 SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
\r
3697 pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
3698 frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
3700 reason = cpu_to_le16(reason);
\r
3701 pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
\r
3703 #ifdef COMPAT_KERNEL_RELEASE
\r
3704 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3705 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
3706 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3707 #else //COMPAT_KERNEL_RELEASE
\r
3708 cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len);
\r
3709 //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3710 #endif //COMPAT_KERNEL_RELEASE
\r
3711 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3714 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
\r
3718 DBG_8192C("%s\n", __func__);
\r
3723 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
\r
3727 DBG_8192C("%s\n", __func__);
\r
3732 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
\r
3737 int dot11_hdr_len = 24;
\r
3739 unsigned char *pdata;
\r
3741 unsigned char src_mac_addr[6];
\r
3742 unsigned char dst_mac_addr[6];
\r
3743 struct rtw_ieee80211_hdr *dot11_hdr;
\r
3744 struct ieee80211_radiotap_header *rtap_hdr;
\r
3745 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3747 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3750 rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
\r
3752 if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
\r
3755 rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
\r
3756 if (unlikely(rtap_hdr->it_version))
\r
3759 rtap_len = ieee80211_get_radiotap_len(skb->data);
\r
3760 if (unlikely(skb->len < rtap_len))
\r
3763 if(rtap_len != 14)
\r
3765 DBG_8192C("radiotap len (should be 14): %d\n", rtap_len);
\r
3769 /* Skip the ratio tap header */
\r
3770 skb_pull(skb, rtap_len);
\r
3772 dot11_hdr = (struct rtw_ieee80211_hdr *)skb->data;
\r
3773 frame_ctl = le16_to_cpu(dot11_hdr->frame_ctl);
\r
3774 /* Check if the QoS bit is set */
\r
3775 if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
\r
3776 /* Check if this ia a Wireless Distribution System (WDS) frame
\r
3777 * which has 4 MAC addresses
\r
3779 if (dot11_hdr->frame_ctl & 0x0080)
\r
3781 if ((dot11_hdr->frame_ctl & 0x0300) == 0x0300)
\r
3782 dot11_hdr_len += 6;
\r
3784 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
\r
3785 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
\r
3787 /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
\r
3788 * for two MAC addresses
\r
3790 skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
\r
3791 pdata = (unsigned char*)skb->data;
\r
3792 memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
\r
3793 memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
\r
3795 DBG_8192C("should be eapol packet\n");
\r
3797 /* Use the real net device to transmit the packet */
\r
3798 ret = _rtw_xmit_entry(skb, padapter->pnetdev);
\r
3803 else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE))
\r
3804 == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION)
\r
3807 //only for action frames
\r
3808 struct xmit_frame *pmgntframe;
\r
3809 struct pkt_attrib *pattrib;
\r
3810 unsigned char *pframe;
\r
3811 //u8 category, action, OUI_Subtype, dialogToken=0;
\r
3812 //unsigned char *frame_body;
\r
3813 struct rtw_ieee80211_hdr *pwlanhdr;
\r
3814 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
3815 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3816 u8 *buf = skb->data;
\r
3817 u32 len = skb->len;
\r
3818 u8 category, action;
\r
3821 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
\r
3822 DBG_8192C(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
\r
3823 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
\r
3827 DBG_8192C("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
\r
3828 MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
\r
3830 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0)
\r
3833 if (category == RTW_WLAN_CATEGORY_PUBLIC)
\r
3834 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
\r
3836 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
\r
3839 //starting alloc mgmt frame to dump it
\r
3840 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
3845 //update attribute
\r
3846 pattrib = &pmgntframe->attrib;
\r
3847 update_mgntframe_attrib(padapter, pattrib);
\r
3848 pattrib->retry_ctrl = _FALSE;
\r
3850 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
3852 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
3854 _rtw_memcpy(pframe, (void*)buf, len);
\r
3855 pattrib->pktlen = len;
\r
3859 rtw_xframe_chk_wfd_ie(pmgntframe);
\r
3860 #endif /* CONFIG_P2P */
\r
3862 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
3863 //update seq number
\r
3864 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
\r
3865 pattrib->seqnum = pmlmeext->mgnt_seq;
\r
3866 pmlmeext->mgnt_seq++;
\r
3869 pattrib->last_txcmdsz = pattrib->pktlen;
\r
3871 dump_mgntframe(padapter, pmgntframe);
\r
3876 DBG_8192C("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE));
\r
3882 rtw_skb_free(skb);
\r
3888 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
\r
3890 DBG_8192C("%s\n", __func__);
\r
3893 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
\r
3897 DBG_8192C("%s\n", __func__);
\r
3902 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
\r
3903 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
\r
3904 .ndo_open = rtw_cfg80211_monitor_if_open,
\r
3905 .ndo_stop = rtw_cfg80211_monitor_if_close,
\r
3906 .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
\r
3907 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
\r
3908 .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
\r
3910 .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
\r
3914 static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
\r
3917 struct net_device* mon_ndev = NULL;
\r
3918 struct wireless_dev* mon_wdev = NULL;
\r
3919 struct rtw_netdev_priv_indicator *pnpi;
\r
3920 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
3923 DBG_871X(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
\r
3928 if (pwdev_priv->pmon_ndev) {
\r
3929 DBG_871X(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
\r
3930 FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
\r
3935 mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
\r
3937 DBG_871X(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
\r
3942 mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
\r
3943 strncpy(mon_ndev->name, name, IFNAMSIZ);
\r
3944 mon_ndev->name[IFNAMSIZ - 1] = 0;
\r
3945 mon_ndev->destructor = rtw_ndev_destructor;
\r
3947 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
\r
3948 mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
\r
3950 mon_ndev->open = rtw_cfg80211_monitor_if_open;
\r
3951 mon_ndev->stop = rtw_cfg80211_monitor_if_close;
\r
3952 mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry;
\r
3953 mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address;
\r
3956 pnpi = netdev_priv(mon_ndev);
\r
3957 pnpi->priv = padapter;
\r
3958 pnpi->sizeof_priv = sizeof(_adapter);
\r
3961 mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
\r
3963 DBG_871X(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
\r
3968 mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
\r
3969 mon_wdev->netdev = mon_ndev;
\r
3970 mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
\r
3971 mon_ndev->ieee80211_ptr = mon_wdev;
\r
3973 ret = register_netdevice(mon_ndev);
\r
3978 *ndev = pwdev_priv->pmon_ndev = mon_ndev;
\r
3979 _rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
\r
3982 if (ret && mon_wdev) {
\r
3983 rtw_mfree((u8*)mon_wdev, sizeof(struct wireless_dev));
\r
3987 if (ret && mon_ndev) {
\r
3988 free_netdev(mon_ndev);
\r
3989 *ndev = mon_ndev = NULL;
\r
3995 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3996 static struct wireless_dev *
\r
3997 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
3998 static struct net_device *
\r
4002 cfg80211_rtw_add_virtual_intf(
\r
4003 struct wiphy *wiphy,
\r
4004 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
\r
4009 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
\r
4010 unsigned char name_assign_type,
\r
4012 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
\r
4015 struct net_device* ndev = NULL;
\r
4016 _adapter *padapter = wiphy_to_adapter(wiphy);
\r
4018 DBG_871X("%s wiphy:%s, name:%s, type:%d\n",
\r
4019 __func__, wiphy_name(wiphy), name, type);
\r
4022 case NL80211_IFTYPE_ADHOC:
\r
4023 case NL80211_IFTYPE_AP_VLAN:
\r
4024 case NL80211_IFTYPE_WDS:
\r
4025 case NL80211_IFTYPE_MESH_POINT:
\r
4028 case NL80211_IFTYPE_MONITOR:
\r
4029 ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
\r
4032 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4033 case NL80211_IFTYPE_P2P_CLIENT:
\r
4035 case NL80211_IFTYPE_STATION:
\r
4039 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4040 case NL80211_IFTYPE_P2P_GO:
\r
4042 case NL80211_IFTYPE_AP:
\r
4047 DBG_871X("Unsupported interface type\n");
\r
4051 DBG_871X("%s ndev:%p, ret:%d\n", __func__, ndev, ret);
\r
4053 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4054 return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
\r
4055 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
4056 return ndev ? ndev : ERR_PTR(ret);
\r
4062 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
\r
4063 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4064 struct wireless_dev *wdev
\r
4066 struct net_device *ndev
\r
4070 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4071 struct net_device *ndev = wdev_to_ndev(wdev);
\r
4074 _adapter *adapter;
\r
4075 struct rtw_wdev_priv *pwdev_priv;
\r
4082 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4083 pwdev_priv = adapter_wdev_data(adapter);
\r
4085 unregister_netdevice(ndev);
\r
4087 if (ndev == pwdev_priv->pmon_ndev) {
\r
4088 pwdev_priv->pmon_ndev = NULL;
\r
4089 pwdev_priv->ifname_mon[0] = '\0';
\r
4090 DBG_871X(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev));
\r
4097 static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
\r
4101 uint len, wps_ielen=0;
\r
4104 u8 got_p2p_ie = _FALSE;
\r
4105 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
4106 //struct sta_priv *pstapriv = &padapter->stapriv;
\r
4109 DBG_8192C("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
\r
4112 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
\r
4119 pbuf = rtw_zmalloc(head_len+tail_len);
\r
4124 //_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
\r
4126 //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
\r
4127 // pstapriv->max_num_sta = NUM_STA;
\r
4130 _rtw_memcpy(pbuf, (void *)head+24, head_len-24);// 24=beacon header len.
\r
4131 _rtw_memcpy(pbuf+head_len-24, (void *)tail, tail_len);
\r
4133 len = head_len+tail_len-24;
\r
4135 //check wps ie if inclued
\r
4136 if(rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
\r
4137 DBG_8192C("add bcn, wps_ielen=%d\n", wps_ielen);
\r
4140 if( adapter->wdinfo.driver_interface == DRIVER_CFG80211 )
\r
4142 //check p2p if enable
\r
4143 if(rtw_get_p2p_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &p2p_ielen))
\r
4145 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
\r
4146 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
\r
4148 DBG_8192C("got p2p_ie, len=%d\n", p2p_ielen);
\r
4150 got_p2p_ie = _TRUE;
\r
4152 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4154 DBG_8192C("Enable P2P function for the first time\n");
\r
4155 rtw_p2p_enable(adapter, P2P_ROLE_GO);
\r
4156 adapter_wdev_data(adapter)->p2p_enabled = _TRUE;
\r
4158 adapter->stapriv.expire_to = 3; // 3x2 = 6 sec in p2p mode
\r
4162 DBG_8192C("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);
\r
4164 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
\r
4165 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
\r
4166 pwdinfo->intent = 15;
\r
4170 #endif // CONFIG_P2P
\r
4172 /* pbss_network->IEs will not include p2p_ie, wfd ie */
\r
4173 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
\r
4174 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
\r
4176 if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS)
\r
4178 #ifdef CONFIG_P2P
\r
4179 //check p2p if enable
\r
4180 if(got_p2p_ie == _TRUE)
\r
4182 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
\r
4183 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
\r
4184 pwdinfo->operating_channel = pmlmeext->cur_channel;
\r
4186 #endif //CONFIG_P2P
\r
4195 rtw_mfree(pbuf, head_len+tail_len);
\r
4200 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE)
\r
4201 static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4202 struct beacon_parameters *info)
\r
4205 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4207 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4208 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
\r
4213 static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4214 struct beacon_parameters *info)
\r
4216 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4217 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
4219 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4221 pmlmeext->bstart_bss = _TRUE;
\r
4223 cfg80211_rtw_add_beacon(wiphy, ndev, info);
\r
4228 static int cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
\r
4230 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4235 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
\r
4236 struct cfg80211_ap_settings *settings)
\r
4239 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4241 DBG_871X(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
\r
4242 settings->hidden_ssid, settings->auth_type);
\r
4244 ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
\r
4245 settings->beacon.tail, settings->beacon.tail_len);
\r
4247 adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
\r
4249 if (settings->ssid && settings->ssid_len) {
\r
4250 WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
\r
4251 WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
\r
4254 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%zu), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
\r
4255 settings->ssid, settings->ssid_len,
\r
4256 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
\r
4258 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
\r
4259 pbss_network->Ssid.SsidLength = settings->ssid_len;
\r
4260 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
\r
4261 pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
\r
4264 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
\r
4265 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
\r
4266 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
\r
4272 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4273 struct cfg80211_beacon_data *info)
\r
4276 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4278 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4280 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
\r
4285 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
\r
4287 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4291 #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
\r
4293 static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4294 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
4299 struct station_parameters *params)
\r
4302 #ifdef CONFIG_TDLS
\r
4303 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4304 struct sta_priv *pstapriv = &padapter->stapriv;
\r
4305 struct sta_info *psta;
\r
4306 #endif /* CONFIG_TDLS */
\r
4307 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4309 #ifdef CONFIG_TDLS
\r
4310 psta = rtw_get_stainfo(pstapriv, mac);
\r
4311 if (psta == NULL) {
\r
4312 psta = rtw_alloc_stainfo(pstapriv, mac);
\r
4313 if (psta ==NULL) {
\r
4314 DBG_871X("[%s] Alloc station for "MAC_FMT" fail\n", __FUNCTION__, MAC_ARG(mac));
\r
4319 #endif /* CONFIG_TDLS */
\r
4325 static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4326 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
4328 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
\r
4331 struct station_del_parameters *params
\r
4337 _list *phead, *plist;
\r
4338 u8 updated = _FALSE;
\r
4339 const u8 *target_mac;
\r
4340 struct sta_info *psta = NULL;
\r
4341 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4342 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
4343 struct sta_priv *pstapriv = &padapter->stapriv;
\r
4345 DBG_871X("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4348 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
\r
4351 target_mac = params->mac;
\r
4354 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
\r
4356 DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
\r
4363 DBG_8192C("flush all sta, and cam_entry\n");
\r
4365 flush_all_cam_entry(padapter); //clear CAM
\r
4367 ret = rtw_sta_flush(padapter, _TRUE);
\r
4373 DBG_8192C("free sta macaddr =" MAC_FMT "\n", MAC_ARG(target_mac));
\r
4375 if (target_mac[0] == 0xff && target_mac[1] == 0xff &&
\r
4376 target_mac[2] == 0xff && target_mac[3] == 0xff &&
\r
4377 target_mac[4] == 0xff && target_mac[5] == 0xff)
\r
4383 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4385 phead = &pstapriv->asoc_list;
\r
4386 plist = get_next(phead);
\r
4388 //check asoc_queue
\r
4389 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
4391 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
4393 plist = get_next(plist);
\r
4395 if (_rtw_memcmp((u8 *)target_mac, psta->hwaddr, ETH_ALEN))
\r
4397 if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE)
\r
4399 DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
\r
4403 DBG_8192C("free psta=%p, aid=%d\n", psta, psta->aid);
\r
4405 rtw_list_delete(&psta->asoc_list);
\r
4406 pstapriv->asoc_list_cnt--;
\r
4408 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4409 if (check_fwstate(pmlmepriv, (WIFI_AP_STATE)) == _TRUE)
\r
4410 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID, _TRUE);
\r
4412 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);
\r
4413 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4424 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4426 associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
\r
4428 DBG_871X("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4434 static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4435 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
4440 struct station_parameters *params)
\r
4442 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4447 struct sta_info *rtw_sta_info_get_by_idx(const int idx, struct sta_priv *pstapriv)
\r
4451 _list *phead, *plist;
\r
4452 struct sta_info *psta = NULL;
\r
4455 phead = &pstapriv->asoc_list;
\r
4456 plist = get_next(phead);
\r
4458 //check asoc_queue
\r
4459 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
4461 if(idx == i) psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
4462 plist = get_next(plist);
\r
4468 static int cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4469 int idx, u8 *mac, struct station_info *sinfo)
\r
4474 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4475 struct sta_info *psta = NULL;
\r
4476 struct sta_priv *pstapriv = &padapter->stapriv;
\r
4477 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4479 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4480 psta = rtw_sta_info_get_by_idx(idx, pstapriv);
\r
4481 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4484 DBG_871X("Station is not found\n");
\r
4488 _rtw_memcpy(mac, psta->hwaddr, ETH_ALEN);
\r
4489 sinfo->filled = 0;
\r
4490 sinfo->filled |= STATION_INFO_SIGNAL;
\r
4491 sinfo->signal = psta->rssi;
\r
4497 static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
\r
4498 struct bss_parameters *params)
\r
4502 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4504 DBG_8192C("use_cts_prot=%d\n", params->use_cts_prot);
\r
4505 DBG_8192C("use_short_preamble=%d\n", params->use_short_preamble);
\r
4506 DBG_8192C("use_short_slot_time=%d\n", params->use_short_slot_time);
\r
4507 DBG_8192C("ap_isolate=%d\n", params->ap_isolate);
\r
4509 DBG_8192C("basic_rates_len=%d\n", params->basic_rates_len);
\r
4510 for(i=0; i<params->basic_rates_len; i++)
\r
4512 DBG_8192C("basic_rates=%d\n", params->basic_rates[i]);
\r
4520 static int cfg80211_rtw_set_channel(struct wiphy *wiphy
\r
4521 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
\r
4522 , struct net_device *ndev
\r
4524 , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
\r
4526 int chan_target = (u8) ieee80211_frequency_to_channel(chan->center_freq);
\r
4527 int chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4528 int chan_width = CHANNEL_WIDTH_20;
\r
4529 _adapter *padapter = wiphy_to_adapter(wiphy);
\r
4531 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
\r
4532 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4535 switch (channel_type) {
\r
4536 case NL80211_CHAN_NO_HT:
\r
4537 case NL80211_CHAN_HT20:
\r
4538 chan_width = CHANNEL_WIDTH_20;
\r
4539 chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4541 case NL80211_CHAN_HT40MINUS:
\r
4542 chan_width = CHANNEL_WIDTH_40;
\r
4543 chan_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
\r
4545 case NL80211_CHAN_HT40PLUS:
\r
4546 chan_width = CHANNEL_WIDTH_40;
\r
4547 chan_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
\r
4550 chan_width = CHANNEL_WIDTH_20;
\r
4551 chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4555 set_channel_bwmode(padapter, chan_target, chan_offset, chan_width);
\r
4560 static int cfg80211_rtw_set_monitor_channel(struct wiphy *wiphy
\r
4561 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
\r
4562 , struct cfg80211_chan_def *chandef
\r
4564 , struct ieee80211_channel *chan
\r
4565 , enum nl80211_channel_type channel_type
\r
4569 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
\r
4570 struct ieee80211_channel *chan = chandef->chan;
\r
4573 _adapter *padapter = wiphy_to_adapter(wiphy);
\r
4574 int target_channal = chan->hw_value;
\r
4575 int target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4576 int target_width = CHANNEL_WIDTH_20;
\r
4578 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
\r
4579 #ifdef CONFIG_DEBUG_CFG80211
\r
4580 DBG_8192C("center_freq %u Mhz ch %u width %u freq1 %u freq2 %u\n"
\r
4581 , chan->center_freq
\r
4584 , chandef->center_freq1
\r
4585 , chandef->center_freq2);
\r
4586 #endif /* CONFIG_DEBUG_CFG80211 */
\r
4588 switch (chandef->width) {
\r
4589 case NL80211_CHAN_WIDTH_20_NOHT:
\r
4590 case NL80211_CHAN_WIDTH_20:
\r
4591 target_width = CHANNEL_WIDTH_20;
\r
4592 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4594 case NL80211_CHAN_WIDTH_40:
\r
4595 target_width = CHANNEL_WIDTH_40;
\r
4596 if (chandef->center_freq1 > chan->center_freq)
\r
4597 target_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
\r
4599 target_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
\r
4601 case NL80211_CHAN_WIDTH_80:
\r
4602 target_width = CHANNEL_WIDTH_80;
\r
4603 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4605 case NL80211_CHAN_WIDTH_80P80:
\r
4606 target_width = CHANNEL_WIDTH_80_80;
\r
4607 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4609 case NL80211_CHAN_WIDTH_160:
\r
4610 target_width = CHANNEL_WIDTH_160;
\r
4611 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4613 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
\r
4614 case NL80211_CHAN_WIDTH_5:
\r
4615 case NL80211_CHAN_WIDTH_10:
\r
4618 target_width = CHANNEL_WIDTH_20;
\r
4619 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4623 #ifdef CONFIG_DEBUG_CFG80211
\r
4624 DBG_8192C("center_freq %u Mhz ch %u channel_type %u\n"
\r
4625 , chan->center_freq
\r
4628 #endif /* CONFIG_DEBUG_CFG80211 */
\r
4630 switch (channel_type) {
\r
4631 case NL80211_CHAN_NO_HT:
\r
4632 case NL80211_CHAN_HT20:
\r
4633 target_width = CHANNEL_WIDTH_20;
\r
4634 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4636 case NL80211_CHAN_HT40MINUS:
\r
4637 target_width = CHANNEL_WIDTH_40;
\r
4638 target_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
\r
4640 case NL80211_CHAN_HT40PLUS:
\r
4641 target_width = CHANNEL_WIDTH_40;
\r
4642 target_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
\r
4645 target_width = CHANNEL_WIDTH_20;
\r
4646 target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
\r
4651 set_channel_bwmode(padapter, target_channal, target_offset, target_width);
\r
4656 static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
\r
4657 struct cfg80211_auth_request *req)
\r
4659 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4664 static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
\r
4665 struct cfg80211_assoc_request *req)
\r
4667 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4671 #endif //CONFIG_AP_MODE
\r
4673 void rtw_cfg80211_rx_probe_request(_adapter *adapter, u8 *frame, uint frame_len)
\r
4677 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
4678 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
4679 u8 category, action;
\r
4681 channel = rtw_get_oper_ch(adapter);
\r
4682 freq = rtw_ch2freq(channel);
\r
4684 #ifdef CONFIG_DEBUG_CFG80211
\r
4685 DBG_8192C("RTW_Rx: probe request, cur_ch=%d\n", channel);
\r
4686 #endif /* CONFIG_DEBUG_CFG80211 */
\r
4687 rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
\r
4690 void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
4695 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4696 u8 category, action;
\r
4698 channel = rtw_get_oper_ch(padapter);
\r
4700 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4702 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
\r
4706 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
\r
4707 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4710 freq = rtw_ch2freq(channel);
\r
4712 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4713 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4715 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4719 void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
4724 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4725 u8 category, action;
\r
4727 channel = rtw_get_oper_ch(padapter);
\r
4729 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4731 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
\r
4734 case P2P_GO_NEGO_CONF:
\r
4735 case P2P_PROVISION_DISC_RESP:
\r
4736 case P2P_INVIT_RESP:
\r
4737 rtw_set_scan_deny(padapter, 2000);
\r
4738 rtw_clear_scan_deny(padapter);
\r
4743 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
\r
4744 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4747 freq = rtw_ch2freq(channel);
\r
4749 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4750 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4752 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4756 void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg)
\r
4760 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
4761 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
4762 u8 category, action;
\r
4764 channel = rtw_get_oper_ch(adapter);
\r
4766 rtw_action_frame_parse(frame, frame_len, &category, &action);
\r
4768 if (action == ACT_PUBLIC_GAS_INITIAL_REQ) {
\r
4769 rtw_set_scan_deny(adapter, 200);
\r
4770 rtw_scan_abort_no_wait(adapter);
\r
4771 #ifdef CONFIG_CONCURRENT_MODE
\r
4772 if (rtw_buddy_adapter_up(adapter))
\r
4773 rtw_scan_abort_no_wait(adapter->pbuddy_adapter);
\r
4777 freq = rtw_ch2freq(channel);
\r
4779 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4780 rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
\r
4782 cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
\r
4785 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4787 DBG_871X("RTW_Rx:%s\n", msg);
\r
4789 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4793 void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
\r
4795 u16 wps_devicepassword_id = 0x0000;
\r
4796 uint wps_devicepassword_id_len = 0;
\r
4797 u8 wpsie[ 255 ] = { 0x00 }, p2p_ie[ 255 ] = { 0x00 };
\r
4798 uint p2p_ielen = 0;
\r
4799 uint wpsielen = 0;
\r
4800 u32 devinfo_contentlen = 0;
\r
4801 u8 devinfo_content[64] = { 0x00 };
\r
4802 u16 capability = 0;
\r
4803 uint capability_len = 0;
\r
4805 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
\r
4806 u8 action = P2P_PUB_ACTION_ACTION;
\r
4807 u8 dialogToken = 1;
\r
4808 u32 p2poui = cpu_to_be32(P2POUI);
\r
4809 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
\r
4815 struct xmit_frame *pmgntframe;
\r
4816 struct pkt_attrib *pattrib;
\r
4817 unsigned char *pframe;
\r
4818 struct rtw_ieee80211_hdr *pwlanhdr;
\r
4819 unsigned short *fctrl;
\r
4820 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
4821 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4822 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
4824 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
\r
4825 u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
\r
4826 size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4829 DBG_871X( "[%s] In\n", __FUNCTION__ );
\r
4831 //prepare for building provision_request frame
\r
4832 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
\r
4833 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
\r
4835 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
\r
4837 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
\r
4838 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
\r
4839 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
\r
4841 switch(wps_devicepassword_id)
\r
4843 case WPS_DPID_PIN:
\r
4844 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
\r
4846 case WPS_DPID_USER_SPEC:
\r
4847 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
\r
4849 case WPS_DPID_MACHINE_SPEC:
\r
4851 case WPS_DPID_REKEY:
\r
4853 case WPS_DPID_PBC:
\r
4854 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
\r
4856 case WPS_DPID_REGISTRAR_SPEC:
\r
4857 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
\r
4864 if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) )
\r
4867 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);
\r
4868 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&capability, &capability_len);
\r
4873 //start to build provision_request frame
\r
4874 _rtw_memset(wpsie, 0, sizeof(wpsie));
\r
4875 _rtw_memset(p2p_ie, 0, sizeof(p2p_ie));
\r
4878 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
4884 //update attribute
\r
4885 pattrib = &pmgntframe->attrib;
\r
4886 update_mgntframe_attrib(padapter, pattrib);
\r
4888 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
4890 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
4891 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
4893 fctrl = &(pwlanhdr->frame_ctl);
\r
4896 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
\r
4897 _rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
\r
4898 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
\r
4900 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
4901 pmlmeext->mgnt_seq++;
\r
4902 SetFrameSubType(pframe, WIFI_ACTION);
\r
4904 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4905 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4907 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
4908 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
4909 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
\r
4910 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
\r
4911 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
\r
4914 //build_prov_disc_request_p2p_ie
\r
4917 p2p_ie[ p2pielen++ ] = 0x50;
\r
4918 p2p_ie[ p2pielen++ ] = 0x6F;
\r
4919 p2p_ie[ p2pielen++ ] = 0x9A;
\r
4920 p2p_ie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
\r
4922 // Commented by Albert 20110301
\r
4923 // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
\r
4924 // 1. P2P Capability
\r
4926 // 3. Group ID ( When joining an operating P2P Group )
\r
4928 // P2P Capability ATTR
\r
4930 p2p_ie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
\r
4933 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
\r
4934 RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
\r
4938 // Device Capability Bitmap, 1 byte
\r
4939 // Group Capability Bitmap, 1 byte
\r
4940 _rtw_memcpy(p2p_ie + p2pielen, &capability, 2);
\r
4944 // Device Info ATTR
\r
4946 p2p_ie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
\r
4949 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
\r
4950 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
\r
4951 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
\r
4952 RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
\r
4956 _rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
\r
4957 p2pielen += devinfo_contentlen;
\r
4960 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);
\r
4961 //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr);
\r
4962 //pframe += p2pielen;
\r
4963 pattrib->pktlen += p2p_ielen;
\r
4967 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
\r
4972 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
\r
4976 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
\r
4980 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
\r
4984 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
\r
4988 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
\r
4992 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
\r
4995 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
\r
4999 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
\r
5000 pframe += wfdielen;
\r
5001 pattrib->pktlen += wfdielen;
\r
5004 pattrib->last_txcmdsz = pattrib->pktlen;
\r
5006 //dump_mgntframe(padapter, pmgntframe);
\r
5007 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
\r
5008 DBG_8192C("%s, ack to\n", __func__);
\r
5010 //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
\r
5012 // DBG_8192C("waiting for p2p peer key-in PIN CODE\n");
\r
5013 // rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req.
\r
5018 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
\r
5019 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5020 struct wireless_dev *wdev,
\r
5022 struct net_device *ndev,
\r
5024 struct ieee80211_channel * channel,
\r
5025 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5026 enum nl80211_channel_type channel_type,
\r
5028 unsigned int duration, u64 *cookie)
\r
5030 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5031 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5034 u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
\r
5035 u8 ready_on_channel = _FALSE;
\r
5036 _adapter *padapter;
\r
5037 struct rtw_wdev_priv *pwdev_priv;
\r
5038 struct mlme_ext_priv *pmlmeext;
\r
5039 struct wifidirect_info *pwdinfo;
\r
5040 struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
\r
5041 u8 is_p2p_find = _FALSE;
\r
5043 #ifndef CONFIG_RADIO_WORK
\r
5044 #define RTW_ROCH_DURATION_ENLARGE
\r
5045 #define RTW_ROCH_BACK_OP
\r
5048 if (ndev == NULL) {
\r
5052 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5053 pwdev_priv = adapter_wdev_data(padapter);
\r
5054 pmlmeext = &padapter->mlmeextpriv;
\r
5055 pwdinfo = &padapter->wdinfo;
\r
5056 pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
5057 #ifdef CONFIG_CONCURRENT_MODE
\r
5058 is_p2p_find=(duration < (pwdinfo->ext_listen_interval))? _TRUE : _FALSE;
\r
5061 *cookie = ATOMIC_INC_RETURN(&pcfg80211_wdinfo->ro_ch_cookie_gen);
\r
5063 DBG_871X(FUNC_ADPT_FMT" ch:%u duration:%d, cookie:0x%llx\n", FUNC_ADPT_ARG(padapter), remain_ch, duration, *cookie);
\r
5065 #ifdef CONFIG_MP_INCLUDED
\r
5066 if (padapter->registrypriv.mp_mode == 1) {
\r
5067 DBG_871X(FUNC_ADPT_FMT ": MP mode block remain_on_channel request\n", FUNC_ADPT_ARG(padapter));
\r
5071 #ifdef CONFIG_CONCURRENT_MODE
\r
5072 if (padapter->pbuddy_adapter) {
\r
5073 if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1) {
\r
5074 DBG_871X(FUNC_ADPT_FMT ": MP mode block remain_on_channel request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter));
\r
5082 if(pcfg80211_wdinfo->is_ro_ch == _TRUE)
\r
5084 DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
5085 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
5086 #ifdef CONFIG_CONCURRENT_MODE
\r
5087 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
5088 #endif //CONFIG_CONCURRENT_MODE
\r
5089 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
\r
5092 pcfg80211_wdinfo->is_ro_ch = _TRUE;
\r
5093 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
5095 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
5100 _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
\r
5101 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5102 pcfg80211_wdinfo->remain_on_ch_type= channel_type;
\r
5104 pcfg80211_wdinfo->remain_on_ch_cookie= *cookie;
\r
5106 rtw_scan_abort(padapter);
\r
5107 #ifdef CONFIG_CONCURRENT_MODE
\r
5108 if ((rtw_buddy_adapter_up(padapter)) && is_p2p_find) //don't scan_abort during p2p_listen.
\r
5109 rtw_scan_abort(padapter->pbuddy_adapter);
\r
5110 #endif //CONFIG_CONCURRENT_MODE
\r
5112 if (check_fwstate(&padapter->mlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
\r
5114 DBG_871X("mlme state:0x%x\n", get_fwstate(&padapter->mlmepriv));
\r
5115 remain_ch = padapter->mlmeextpriv.cur_channel;
\r
5117 #ifdef CONFIG_CONCURRENT_MODE
\r
5118 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
\r
5120 DBG_871X("buddy_intf's mlme state:0x%x\n", get_fwstate(&(padapter->pbuddy_adapter->mlmepriv)));
\r
5121 remain_ch = padapter->pbuddy_adapter->mlmeextpriv.cur_channel;
\r
5123 #endif /* CONFIG_CONCURRENT_MODE */
\r
5125 //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
5126 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
5128 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
\r
5129 adapter_wdev_data(padapter)->p2p_enabled = _TRUE;
\r
5130 padapter->wdinfo.listen_channel = remain_ch;
\r
5131 } else if (rtw_p2p_chk_state(pwdinfo , P2P_STATE_LISTEN)) {
\r
5132 padapter->wdinfo.listen_channel = remain_ch;
\r
5134 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
5135 #ifdef CONFIG_DEBUG_CFG80211
\r
5136 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
5141 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
\r
5143 #ifdef RTW_ROCH_DURATION_ENLARGE
\r
5144 if (duration < 400)
\r
5145 duration = duration * 3; /* extend from exper */
\r
5148 #ifdef RTW_ROCH_BACK_OP
\r
5149 #ifdef CONFIG_CONCURRENT_MODE
\r
5150 if (check_buddy_fwstate(padapter, _FW_LINKED)) {
\r
5151 if (is_p2p_find) /* p2p_find , duration<1000 */
\r
5152 duration = duration + pwdinfo->ext_listen_interval;
\r
5153 else /* p2p_listen, duration=5000 */
\r
5154 duration = pwdinfo->ext_listen_interval + (pwdinfo->ext_listen_interval / 4);
\r
5157 #endif /* RTW_ROCH_BACK_OP */
\r
5159 pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter);
\r
5161 if(rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) >= 0) {
\r
5162 #ifdef CONFIG_CONCURRENT_MODE
\r
5163 if ( check_buddy_fwstate(padapter, _FW_LINKED) )
\r
5165 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
\r
5166 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
5168 if((remain_ch != pbuddy_mlmeext->cur_channel) && !check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
5170 if(ATOMIC_READ(&pwdev_priv->switch_ch_to)==1 ||
\r
5171 (remain_ch != pmlmeext->cur_channel))
\r
5173 if (check_buddy_fwstate(padapter, WIFI_FW_STATION_STATE)) {
\r
5174 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
\r
5175 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
\r
5178 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
\r
5180 #ifdef RTW_ROCH_BACK_OP
\r
5181 DBG_8192C("%s, set switch ch timer, duration=%d\n", __func__, duration-pwdinfo->ext_listen_interval);
\r
5182 _set_timer(&pwdinfo->ap_p2p_switch_timer, duration-pwdinfo->ext_listen_interval);
\r
5187 ready_on_channel = _TRUE;
\r
5188 //pmlmeext->cur_channel = remain_ch;
\r
5189 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5191 #endif //CONFIG_CONCURRENT_MODE
\r
5192 if(remain_ch != rtw_get_oper_ch(padapter) )
\r
5194 ready_on_channel = _TRUE;
\r
5195 //pmlmeext->cur_channel = remain_ch;
\r
5196 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5199 DBG_871X("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__, remain_ch);
\r
5203 //call this after other things have been done
\r
5204 #ifdef CONFIG_CONCURRENT_MODE
\r
5205 if(ATOMIC_READ(&pwdev_priv->ro_ch_to)==1 ||
\r
5206 (remain_ch != rtw_get_oper_ch(padapter)))
\r
5208 u8 co_channel = 0xff;
\r
5209 ATOMIC_SET(&pwdev_priv->ro_ch_to, 0);
\r
5212 if(ready_on_channel == _TRUE)
\r
5214 if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) )
\r
5216 pmlmeext->cur_channel = remain_ch;
\r
5218 #ifdef CONFIG_CONCURRENT_MODE
\r
5219 co_channel = rtw_get_oper_ch(padapter);
\r
5221 if(co_channel !=remain_ch)
\r
5224 //if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic)
\r
5225 set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5229 DBG_8192C("%s, set ro ch timer, duration=%d\n", __func__, duration);
\r
5230 _set_timer( &pcfg80211_wdinfo->remain_on_ch_timer, duration);
\r
5232 #ifdef CONFIG_CONCURRENT_MODE
\r
5236 rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type, duration, GFP_KERNEL);
\r
5240 pcfg80211_wdinfo->is_ro_ch = _FALSE;
\r
5241 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
5247 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
\r
5248 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5249 struct wireless_dev *wdev,
\r
5251 struct net_device *ndev,
\r
5255 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5256 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5259 _adapter *padapter;
\r
5260 struct rtw_wdev_priv *pwdev_priv;
\r
5261 struct wifidirect_info *pwdinfo;
\r
5262 struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
\r
5264 if (ndev == NULL) {
\r
5269 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5270 pwdev_priv = adapter_wdev_data(padapter);
\r
5271 pwdinfo = &padapter->wdinfo;
\r
5272 pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
5274 DBG_871X(FUNC_ADPT_FMT" cookie:0x%llx\n", FUNC_ADPT_ARG(padapter), cookie);
\r
5276 if (pcfg80211_wdinfo->is_ro_ch == _TRUE) {
\r
5277 DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
5278 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
5279 #ifdef CONFIG_CONCURRENT_MODE
\r
5280 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
5282 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
\r
5286 // Disable P2P Listen State
\r
5287 if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
5289 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
5291 rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
\r
5292 _rtw_memset(pwdinfo, 0x00, sizeof(struct wifidirect_info));
\r
5298 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
5299 #ifdef CONFIG_DEBUG_CFG80211
\r
5300 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
5304 pcfg80211_wdinfo->is_ro_ch = _FALSE;
\r
5305 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
5311 #endif //CONFIG_P2P
\r
5313 static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, const u8 *buf, size_t len, int wait_ack)
\r
5315 struct xmit_frame *pmgntframe;
\r
5316 struct pkt_attrib *pattrib;
\r
5317 unsigned char *pframe;
\r
5320 struct rtw_ieee80211_hdr *pwlanhdr;
\r
5321 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
5322 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
5323 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5324 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
5326 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
\r
5327 #endif //CONFIG_P2P
\r
5328 //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
5330 rtw_set_scan_deny(padapter, 1000);
\r
5332 rtw_scan_abort(padapter);
\r
5333 #ifdef CONFIG_CONCURRENT_MODE
\r
5334 if(rtw_buddy_adapter_up(padapter))
\r
5335 rtw_scan_abort(padapter->pbuddy_adapter);
\r
5336 #endif /* CONFIG_CONCURRENT_MODE */
\r
5338 if (padapter->cfg80211_wdinfo.is_ro_ch == _TRUE) {
\r
5339 //DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
5340 //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
5341 //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE;
\r
5342 #ifdef CONFIG_CONCURRENT_MODE
\r
5343 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5345 DBG_8192C("%s, extend ro ch time\n", __func__);
\r
5346 _set_timer( &padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
\r
5348 #endif //CONFIG_CONCURRENT_MODE
\r
5350 #endif //CONFIG_P2P
\r
5351 #ifdef CONFIG_CONCURRENT_MODE
\r
5352 if (check_buddy_fwstate(padapter, _FW_LINKED )) {
\r
5353 u8 co_channel=0xff;
\r
5354 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
\r
5355 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
5357 co_channel = rtw_get_oper_ch(padapter);
\r
5359 if (tx_ch != pbuddy_mlmeext->cur_channel) {
\r
5361 u16 ext_listen_period;
\r
5363 if (ATOMIC_READ(&pwdev_priv->switch_ch_to)==1) {
\r
5364 if (check_buddy_fwstate(padapter, WIFI_FW_STATION_STATE)) {
\r
5365 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
\r
5366 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
\r
5369 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
\r
5371 //DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
\r
5372 //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
\r
5375 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5377 ext_listen_period = 500;// 500ms
\r
5381 ext_listen_period = pwdinfo->ext_listen_period;
\r
5384 DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period);
\r
5385 _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period);
\r
5389 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5390 pmlmeext->cur_channel = tx_ch;
\r
5392 if (tx_ch != co_channel)
\r
5393 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5395 #endif //CONFIG_CONCURRENT_MODE
\r
5396 //if (tx_ch != pmlmeext->cur_channel) {
\r
5397 if(tx_ch != rtw_get_oper_ch(padapter)) {
\r
5398 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5399 pmlmeext->cur_channel = tx_ch;
\r
5400 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5403 //starting alloc mgmt frame to dump it
\r
5404 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
5411 //update attribute
\r
5412 pattrib = &pmgntframe->attrib;
\r
5413 update_mgntframe_attrib(padapter, pattrib);
\r
5414 pattrib->retry_ctrl = _FALSE;
\r
5416 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
5418 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
5420 _rtw_memcpy(pframe, (void*)buf, len);
\r
5421 pattrib->pktlen = len;
\r
5423 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
5424 //update seq number
\r
5425 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
\r
5426 pattrib->seqnum = pmlmeext->mgnt_seq;
\r
5427 pmlmeext->mgnt_seq++;
\r
5430 rtw_xframe_chk_wfd_ie(pmgntframe);
\r
5431 #endif /* CONFIG_P2P */
\r
5433 pattrib->last_txcmdsz = pattrib->pktlen;
\r
5436 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS) {
\r
5440 #ifdef CONFIG_DEBUG_CFG80211
\r
5441 DBG_8192C("%s, ack == _FAIL\n", __func__);
\r
5445 #ifdef CONFIG_XMIT_ACK
\r
5446 rtw_msleep_os(50);
\r
5448 #ifdef CONFIG_DEBUG_CFG80211
\r
5449 DBG_8192C("%s, ack=%d, ok!\n", __func__, ack);
\r
5454 dump_mgntframe(padapter, pmgntframe);
\r
5459 #ifdef CONFIG_DEBUG_CFG80211
\r
5460 DBG_8192C("%s, ret=%d\n", __func__, ret);
\r
5467 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
\r
5468 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5469 struct wireless_dev *wdev,
\r
5471 struct net_device *ndev,
\r
5473 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) || defined(COMPAT_KERNEL_RELEASE)
\r
5474 struct ieee80211_channel *chan,
\r
5475 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
5478 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5479 enum nl80211_channel_type channel_type,
\r
5480 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5481 bool channel_type_valid,
\r
5484 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
5485 unsigned int wait,
\r
5487 const u8 *buf, size_t len,
\r
5488 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5491 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
\r
5492 bool dont_wait_for_ack,
\r
5495 struct cfg80211_mgmt_tx_params *params,
\r
5499 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5500 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5502 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) || defined(COMPAT_KERNEL_RELEASE)
\r
5503 struct ieee80211_channel *chan = params->chan;
\r
5504 bool offchan = params->offchan;
\r
5505 unsigned int wait = params->wait;
\r
5506 const u8 *buf = params->buf;
\r
5507 size_t len = params->len;
\r
5508 bool no_cck = params->no_cck;
\r
5509 bool dont_wait_for_ack = params->dont_wait_for_ack;
\r
5514 u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
\r
5518 u8 category, action;
\r
5521 u32 start = rtw_get_current_time();
\r
5522 _adapter *padapter;
\r
5523 struct rtw_wdev_priv *pwdev_priv;
\r
5525 if ((ndev == NULL) || (chan == NULL)) {
\r
5530 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
\r
5532 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5533 pwdev_priv = adapter_wdev_data(padapter);
\r
5535 /* cookie generation */
\r
5536 *cookie = (unsigned long) buf;
\r
5538 #ifdef CONFIG_DEBUG_CFG80211
\r
5539 DBG_871X(FUNC_ADPT_FMT" len=%zu, ch=%d"
\r
5540 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5542 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5543 ", channel_type_valid=%d"
\r
5546 "\n", FUNC_ADPT_ARG(padapter),
\r
5548 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5550 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5551 , channel_type_valid
\r
5555 #endif /* CONFIG_DEBUG_CFG80211 */
\r
5557 /* indicate ack before issue frame to avoid racing with rsp frame */
\r
5558 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5559 rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL);
\r
5560 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
\r
5561 cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
\r
5564 frame_styp = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl) & IEEE80211_FCTL_STYPE;
\r
5565 if (IEEE80211_STYPE_PROBE_RESP == frame_styp) {
\r
5566 #ifdef CONFIG_DEBUG_CFG80211
\r
5567 DBG_8192C("RTW_Tx: probe_resp tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
\r
5568 #endif /* CONFIG_DEBUG_CFG80211 */
\r
5573 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
\r
5574 DBG_8192C(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
\r
5575 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
\r
5579 DBG_8192C("RTW_Tx:tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
\r
5581 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0) {
\r
5585 if (category == RTW_WLAN_CATEGORY_PUBLIC)
\r
5586 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
\r
5588 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
\r
5592 rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
\r
5593 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
5595 goto cancel_ps_deny;
\r
5600 u32 retry_guarantee_ms = 0;
\r
5603 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len, wait_ack);
\r
5606 case ACT_PUBLIC_GAS_INITIAL_REQ:
\r
5607 case ACT_PUBLIC_GAS_INITIAL_RSP:
\r
5609 retry_guarantee_ms = RTW_MAX_MGMT_TX_MS_GAS;
\r
5612 if (tx_ret == _SUCCESS
\r
5613 || (dump_cnt >= dump_limit && rtw_get_passing_time_ms(start) >= retry_guarantee_ms))
\r
5617 rtw_msleep_os(sleep_ms);
\r
5620 if (tx_ret != _SUCCESS || dump_cnt > 1) {
\r
5621 DBG_871X(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
\r
5622 tx_ret==_SUCCESS?"OK":"FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
\r
5626 case P2P_GO_NEGO_CONF:
\r
5627 rtw_clear_scan_deny(padapter);
\r
5629 case P2P_INVIT_RESP:
\r
5630 if (pwdev_priv->invit_info.flags & BIT(0)
\r
5631 && pwdev_priv->invit_info.status == 0)
\r
5633 DBG_871X(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
\r
5634 FUNC_ADPT_ARG(padapter));
\r
5635 rtw_set_scan_deny(padapter, 5000);
\r
5636 rtw_pwr_wakeup_ex(padapter, 5000);
\r
5637 rtw_clear_scan_deny(padapter);
\r
5643 rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
\r
5648 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
\r
5649 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
\r
5650 struct wireless_dev *wdev,
\r
5652 struct net_device *ndev,
\r
5654 u16 frame_type, bool reg)
\r
5656 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5657 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5659 _adapter *adapter;
\r
5661 struct rtw_wdev_priv *pwdev_priv;
\r
5666 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5667 pwdev_priv = adapter_wdev_data(adapter);
\r
5669 #ifdef CONFIG_DEBUG_CFG80211
\r
5670 DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
\r
5674 /* Wait QC Verify */
\r
5677 switch (frame_type) {
\r
5678 case IEEE80211_STYPE_PROBE_REQ: /* 0x0040 */
\r
5679 SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_PROBE_REQ, reg);
\r
5681 case IEEE80211_STYPE_ACTION: /* 0x00D0 */
\r
5682 SET_CFG80211_REPORT_MGMT(pwdev_priv, IEEE80211_STYPE_ACTION, reg);
\r
5692 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5693 static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy,
\r
5694 struct net_device *ndev,
\r
5695 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
\r
5703 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
\r
5704 u32 peer_capability,
\r
5706 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
\r
5712 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5713 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
\r
5714 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
\r
5716 struct tdls_txmgmt txmgmt;
\r
5718 if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
\r
5719 DBG_871X("Discard tdls action:%d, since hal doesn't support tdls\n", action_code);
\r
5723 if (rtw_tdls_is_driver_setup(padapter)) {
\r
5724 DBG_871X("Discard tdls action:%d, let driver to set up direct link\n", action_code);
\r
5728 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
5729 _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
\r
5730 txmgmt.action_code = action_code;
\r
5731 txmgmt.dialog_token= dialog_token;
\r
5732 txmgmt.status_code = status_code;
\r
5734 txmgmt.buf = (u8 *)rtw_malloc(txmgmt.len);
\r
5735 if (txmgmt.buf == NULL) {
\r
5739 _rtw_memcpy(txmgmt.buf, (void*)buf, txmgmt.len);
\r
5741 /* Debug purpose */
\r
5743 DBG_871X("%s %d\n", __FUNCTION__, __LINE__);
\r
5744 DBG_871X("peer:"MAC_FMT", action code:%d, dialog:%d, status code:%d\n",
\r
5745 MAC_ARG(txmgmt.peer), txmgmt.action_code,
\r
5746 txmgmt.dialog_token, txmgmt.status_code);
\r
5747 if (txmgmt.len > 0) {
\r
5749 for(;i < len; i++)
\r
5750 printk("%02x ", *(txmgmt.buf+i));
\r
5751 DBG_871X("len:%d\n", (u32)txmgmt.len);
\r
5755 switch (txmgmt.action_code) {
\r
5756 case TDLS_SETUP_REQUEST:
\r
5757 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5759 case TDLS_SETUP_RESPONSE:
\r
5760 issue_tdls_setup_rsp(padapter, &txmgmt);
\r
5762 case TDLS_SETUP_CONFIRM:
\r
5763 issue_tdls_setup_cfm(padapter, &txmgmt);
\r
5765 case TDLS_TEARDOWN:
\r
5766 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
\r
5768 case TDLS_DISCOVERY_REQUEST:
\r
5769 issue_tdls_dis_req(padapter, &txmgmt);
\r
5771 case TDLS_DISCOVERY_RESPONSE:
\r
5772 issue_tdls_dis_rsp(padapter, &txmgmt, pmlmeinfo->enc_algo? _TRUE : _FALSE);
\r
5778 rtw_mfree(txmgmt.buf, txmgmt.len);
\r
5784 static int cfg80211_rtw_tdls_oper(struct wiphy *wiphy,
\r
5785 struct net_device *ndev,
\r
5786 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
\r
5791 enum nl80211_tdls_operation oper)
\r
5793 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5794 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
\r
5795 struct tdls_txmgmt txmgmt;
\r
5796 struct sta_info *ptdls_sta = NULL;
\r
5798 DBG_871X(FUNC_NDEV_FMT", nl80211_tdls_operation:%d\n", FUNC_NDEV_ARG(ndev), oper);
\r
5800 if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
\r
5801 DBG_871X("Discard tdls oper:%d, since hal doesn't support tdls\n", oper);
\r
5806 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1);
\r
5807 #endif //CONFIG_LPS
\r
5809 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
5811 _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
\r
5813 if (rtw_tdls_is_driver_setup(padapter)) {
\r
5814 /* these two cases are done by driver itself */
\r
5815 if (oper == NL80211_TDLS_ENABLE_LINK || oper == NL80211_TDLS_DISABLE_LINK)
\r
5820 case NL80211_TDLS_DISCOVERY_REQ:
\r
5821 issue_tdls_dis_req(padapter, &txmgmt);
\r
5823 case NL80211_TDLS_SETUP:
\r
5825 if ( _AES_ != padapter->securitypriv.dot11PrivacyAlgrthm ) {
\r
5826 if ( padapter->wdinfo.wfd_tdls_weaksec == _TRUE)
\r
5827 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5829 DBG_871X( "[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__ );
\r
5831 #endif // CONFIG_WFD
\r
5833 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5836 case NL80211_TDLS_TEARDOWN:
\r
5837 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), txmgmt.peer);
\r
5838 if (ptdls_sta != NULL) {
\r
5839 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
\r
5840 issue_tdls_teardown(padapter, &txmgmt, _TRUE);
\r
5842 DBG_871X( "TDLS peer not found\n");
\r
5845 case NL80211_TDLS_ENABLE_LINK:
\r
5846 DBG_871X(FUNC_NDEV_FMT", NL80211_TDLS_ENABLE_LINK;mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(peer));
\r
5847 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), peer);
\r
5848 if (ptdls_sta != NULL) {
\r
5849 ptdlsinfo->link_established = _TRUE;
\r
5850 ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE;
\r
5851 ptdls_sta->state |= _FW_LINKED;
\r
5852 rtw_tdls_cmd(padapter, txmgmt.peer, TDLS_ESTABLISHED);
\r
5855 case NL80211_TDLS_DISABLE_LINK:
\r
5856 DBG_871X(FUNC_NDEV_FMT", NL80211_TDLS_DISABLE_LINK;mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(peer));
\r
5857 ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), peer);
\r
5858 if (ptdls_sta != NULL) {
\r
5859 rtw_tdls_cmd(padapter, peer, TDLS_TEARDOWN_STA_LOCALLY);
\r
5865 #endif /* CONFIG_TDLS */
\r
5867 #if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
5868 static int cfg80211_rtw_sched_scan_start(struct wiphy *wiphy,
\r
5869 struct net_device *dev,
\r
5870 struct cfg80211_sched_scan_request *request) {
\r
5872 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
5873 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5876 if (padapter->bup == _FALSE) {
\r
5877 DBG_871X("%s: net device is down.\n", __func__);
\r
5881 if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE ||
\r
5882 check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ||
\r
5883 check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
5884 DBG_871X("%s: device is busy.\n", __func__);
\r
5885 rtw_scan_abort(padapter);
\r
5888 if (request == NULL) {
\r
5889 DBG_871X("%s: invalid cfg80211_requests parameters.\n", __func__);
\r
5893 ret = rtw_android_cfg80211_pno_setup(dev, request->ssids,
\r
5894 request->n_ssids, request->interval);
\r
5897 DBG_871X("%s ret: %d\n", __func__, ret);
\r
5901 ret = rtw_android_pno_enable(dev, _TRUE);
\r
5903 DBG_871X("%s ret: %d\n", __func__, ret);
\r
5910 static int cfg80211_rtw_sched_scan_stop(struct wiphy *wiphy,
\r
5911 struct net_device *dev) {
\r
5912 return rtw_android_pno_enable(dev, _FALSE);
\r
5914 #endif /* CONFIG_PNO_SUPPORT */
\r
5916 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
\r
5919 uint wps_ielen = 0;
\r
5921 u32 p2p_ielen = 0;
\r
5922 u8 wps_oui[8]={0x0,0x50,0xf2,0x04};
\r
5924 u32 wfd_ielen = 0;
\r
5926 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5927 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5928 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
5930 DBG_871X(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
\r
5934 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
5936 #ifdef CONFIG_DEBUG_CFG80211
\r
5937 DBG_8192C("bcn_wps_ielen=%d\n", wps_ielen);
\r
5940 if(pmlmepriv->wps_beacon_ie)
\r
5942 u32 free_len = pmlmepriv->wps_beacon_ie_len;
\r
5943 pmlmepriv->wps_beacon_ie_len = 0;
\r
5944 rtw_mfree(pmlmepriv->wps_beacon_ie, free_len);
\r
5945 pmlmepriv->wps_beacon_ie = NULL;
\r
5948 pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen);
\r
5949 if ( pmlmepriv->wps_beacon_ie == NULL) {
\r
5950 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5955 _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
\r
5956 pmlmepriv->wps_beacon_ie_len = wps_ielen;
\r
5958 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
\r
5962 //buf += wps_ielen;
\r
5963 //len -= wps_ielen;
\r
5966 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
5968 #ifdef CONFIG_DEBUG_CFG80211
\r
5969 DBG_8192C("bcn_p2p_ielen=%d\n", p2p_ielen);
\r
5972 if(pmlmepriv->p2p_beacon_ie)
\r
5974 u32 free_len = pmlmepriv->p2p_beacon_ie_len;
\r
5975 pmlmepriv->p2p_beacon_ie_len = 0;
\r
5976 rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len);
\r
5977 pmlmepriv->p2p_beacon_ie = NULL;
\r
5980 pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen);
\r
5981 if ( pmlmepriv->p2p_beacon_ie == NULL) {
\r
5982 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5987 _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
\r
5988 pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
\r
5991 #endif //CONFIG_P2P
\r
5995 wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen);
\r
5997 #ifdef CONFIG_DEBUG_CFG80211
\r
5998 DBG_8192C("bcn_wfd_ielen=%d\n", wfd_ielen);
\r
6001 if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_BEACON_IE, wfd_ie, wfd_ielen) != _SUCCESS)
\r
6004 #endif /* CONFIG_WFD */
\r
6006 pmlmeext->bstart_bss = _TRUE;
\r
6014 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
\r
6017 uint wps_ielen = 0;
\r
6019 u32 p2p_ielen = 0;
\r
6021 u32 wfd_ielen = 0;
\r
6023 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
\r
6024 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
6026 #ifdef CONFIG_DEBUG_CFG80211
\r
6027 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
6032 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
6034 uint attr_contentlen = 0;
\r
6035 u16 uconfig_method, *puconfig_method = NULL;
\r
6037 #ifdef CONFIG_DEBUG_CFG80211
\r
6038 DBG_8192C("probe_resp_wps_ielen=%d\n", wps_ielen);
\r
6041 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
\r
6044 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
\r
6048 DBG_871X("%s, got sr\n", __func__);
\r
6052 DBG_8192C("GO mode process WPS under site-survey, sr no set\n");
\r
6057 if(pmlmepriv->wps_probe_resp_ie)
\r
6059 u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
\r
6060 pmlmepriv->wps_probe_resp_ie_len = 0;
\r
6061 rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len);
\r
6062 pmlmepriv->wps_probe_resp_ie = NULL;
\r
6065 pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen);
\r
6066 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
\r
6067 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
6072 //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode
\r
6073 if ( (puconfig_method = (u16*)rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen)) != NULL )
\r
6075 //struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
6076 struct wireless_dev *wdev = padapter->rtw_wdev;
\r
6078 #ifdef CONFIG_DEBUG_CFG80211
\r
6079 //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method));
\r
6082 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
6083 /* for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags */
\r
6084 if (wdev->iftype == NL80211_IFTYPE_P2P_GO) {
\r
6085 uconfig_method = WPS_CM_PUSH_BUTTON;
\r
6086 uconfig_method = cpu_to_be16(uconfig_method);
\r
6088 *puconfig_method &= ~uconfig_method;
\r
6093 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
\r
6094 pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
\r
6098 //buf += wps_ielen;
\r
6099 //len -= wps_ielen;
\r
6102 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
6104 u8 is_GO = _FALSE;
\r
6105 u32 attr_contentlen = 0;
\r
6108 #ifdef CONFIG_DEBUG_CFG80211
\r
6109 DBG_8192C("probe_resp_p2p_ielen=%d\n", p2p_ielen);
\r
6112 //Check P2P Capability ATTR
\r
6113 if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) )
\r
6116 //DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
\r
6117 cap_attr = le16_to_cpu(cap_attr);
\r
6118 grp_cap = (u8)((cap_attr >> 8)&0xff);
\r
6120 is_GO = (grp_cap&BIT(0)) ? _TRUE:_FALSE;
\r
6123 DBG_8192C("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
\r
6127 if(is_GO == _FALSE)
\r
6129 if(pmlmepriv->p2p_probe_resp_ie)
\r
6131 u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
\r
6132 pmlmepriv->p2p_probe_resp_ie_len = 0;
\r
6133 rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len);
\r
6134 pmlmepriv->p2p_probe_resp_ie = NULL;
\r
6137 pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen);
\r
6138 if ( pmlmepriv->p2p_probe_resp_ie == NULL) {
\r
6139 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
6143 _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
\r
6144 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
\r
6148 if(pmlmepriv->p2p_go_probe_resp_ie)
\r
6150 u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
\r
6151 pmlmepriv->p2p_go_probe_resp_ie_len = 0;
\r
6152 rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len);
\r
6153 pmlmepriv->p2p_go_probe_resp_ie = NULL;
\r
6156 pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen);
\r
6157 if ( pmlmepriv->p2p_go_probe_resp_ie == NULL) {
\r
6158 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
6162 _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
\r
6163 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
\r
6167 #endif //CONFIG_P2P
\r
6171 wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen);
\r
6173 #ifdef CONFIG_DEBUG_CFG80211
\r
6174 DBG_8192C("probe_resp_wfd_ielen=%d\n", wfd_ielen);
\r
6177 if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_RESP_IE, wfd_ie, wfd_ielen) != _SUCCESS)
\r
6180 #endif /* CONFIG_WFD */
\r
6188 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
\r
6191 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
\r
6192 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
6196 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
6201 ie = rtw_get_wps_ie(buf, len, NULL, &ie_len);
\r
6202 if (ie && ie_len) {
\r
6203 if (pmlmepriv->wps_assoc_resp_ie) {
\r
6204 u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
\r
6206 pmlmepriv->wps_assoc_resp_ie_len = 0;
\r
6207 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len);
\r
6208 pmlmepriv->wps_assoc_resp_ie = NULL;
\r
6211 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
\r
6212 if (pmlmepriv->wps_assoc_resp_ie == NULL) {
\r
6213 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
6216 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, ie, ie_len);
\r
6217 pmlmepriv->wps_assoc_resp_ie_len = ie_len;
\r
6220 ie = rtw_get_p2p_ie(buf, len, NULL, &ie_len);
\r
6221 if (ie && ie_len) {
\r
6222 if (pmlmepriv->p2p_assoc_resp_ie) {
\r
6223 u32 free_len = pmlmepriv->p2p_assoc_resp_ie_len;
\r
6225 pmlmepriv->p2p_assoc_resp_ie_len = 0;
\r
6226 rtw_mfree(pmlmepriv->p2p_assoc_resp_ie, free_len);
\r
6227 pmlmepriv->p2p_assoc_resp_ie = NULL;
\r
6230 pmlmepriv->p2p_assoc_resp_ie = rtw_malloc(ie_len);
\r
6231 if (pmlmepriv->p2p_assoc_resp_ie == NULL) {
\r
6232 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
6235 _rtw_memcpy(pmlmepriv->p2p_assoc_resp_ie, ie, ie_len);
\r
6236 pmlmepriv->p2p_assoc_resp_ie_len = ie_len;
\r
6240 ie = rtw_get_wfd_ie(buf, len, NULL, &ie_len);
\r
6241 if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_RESP_IE, ie, ie_len) != _SUCCESS)
\r
6249 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
\r
6253 uint wps_ielen = 0;
\r
6254 u32 p2p_ielen = 0;
\r
6256 #ifdef CONFIG_DEBUG_CFG80211
\r
6257 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
6260 if( (rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen>0))
\r
6262 || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen>0))
\r
6270 case 0x1: //BEACON
\r
6271 ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
\r
6273 case 0x2: //PROBE_RESP
\r
6274 ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
\r
6276 case 0x4: //ASSOC_RESP
\r
6277 ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
\r
6287 static void rtw_cfg80211_init_ht_capab_ex(_adapter *padapter, struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
\r
6289 struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
6290 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
6291 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
\r
6292 u8 stbc_rx_enable = _FALSE;
\r
6294 rtw_ht_use_default_setting(padapter);
\r
6297 if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX))
\r
6298 ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING;
\r
6301 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX))
\r
6302 ht_cap->cap |= IEEE80211_HT_CAP_TX_STBC;
\r
6305 if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) {
\r
6306 /*rtw_rx_stbc 0: disable, bit(0):enable 2.4g, bit(1):enable 5g*/
\r
6307 if (IEEE80211_BAND_2GHZ == band)
\r
6308 stbc_rx_enable = (pregistrypriv->rx_stbc & BIT(0))?_TRUE:_FALSE;
\r
6309 if (IEEE80211_BAND_5GHZ == band)
\r
6310 stbc_rx_enable = (pregistrypriv->rx_stbc & BIT(1))?_TRUE:_FALSE;
\r
6312 if (stbc_rx_enable) {
\r
6313 switch (rf_type) {
\r
6315 ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/*RX STBC One spatial stream*/
\r
6320 ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/* Only one spatial-stream STBC RX is supported */
\r
6325 ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/* Only one spatial-stream STBC RX is supported */
\r
6328 DBG_871X("[warning] rf_type %d is not expected\n", rf_type);
\r
6335 static void rtw_cfg80211_init_ht_capab(_adapter *padapter, struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
\r
6337 #define MAX_BIT_RATE_40MHZ_MCS23 450 /* Mbps */
\r
6338 #define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
\r
6339 #define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
\r
6341 ht_cap->ht_supported = _TRUE;
\r
6343 ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
\r
6344 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
\r
6345 IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
\r
6346 rtw_cfg80211_init_ht_capab_ex(padapter, ht_cap, band, rf_type);
\r
6349 *Maximum length of AMPDU that the STA can receive.
\r
6350 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
\r
6352 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
\r
6354 /*Minimum MPDU start spacing , */
\r
6355 ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
\r
6357 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
\r
6360 *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
\r
6363 *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
\r
6364 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
\r
6365 *if rx_ant >=3 rx_mask[2]=0xff;
\r
6366 *if BW_40 rx_mask[4]=0x01;
\r
6367 *highest supported RX rate
\r
6369 if (rf_type == RF_1T1R) {
\r
6370 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
6372 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
\r
6373 } else if ((rf_type == RF_1T2R) || (rf_type == RF_2T2R) || (rf_type == RF_2T2R_GREEN)) {
\r
6374 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
6375 ht_cap->mcs.rx_mask[1] = 0xFF;
\r
6377 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
\r
6378 } else if ((rf_type == RF_2T3R) || (rf_type == RF_3T3R)) {
\r
6379 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
6380 ht_cap->mcs.rx_mask[1] = 0xFF;
\r
6381 ht_cap->mcs.rx_mask[2] = 0xFF;
\r
6383 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS23;
\r
6386 DBG_8192C("%s, error rf_type=%d\n", __func__, rf_type);
\r
6391 void rtw_cfg80211_init_wiphy(_adapter *padapter)
\r
6394 struct ieee80211_supported_band *bands;
\r
6395 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
6396 struct wiphy *wiphy = pwdev->wiphy;
\r
6398 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
\r
6400 DBG_8192C("%s:rf_type=%d\n", __func__, rf_type);
\r
6402 if (IsSupported24G(padapter->registrypriv.wireless_mode)) {
\r
6403 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
\r
6405 rtw_cfg80211_init_ht_capab(padapter, &bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type);
\r
6407 #ifdef CONFIG_IEEE80211_BAND_5GHZ
\r
6408 if (IsSupported5G(padapter->registrypriv.wireless_mode)) {
\r
6409 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
\r
6411 rtw_cfg80211_init_ht_capab(padapter, &bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type);
\r
6414 /* init regulary domain */
\r
6415 rtw_regd_init(padapter);
\r
6417 /* copy mac_addr to wiphy */
\r
6418 _rtw_memcpy(wiphy->perm_addr, adapter_mac_addr(padapter), ETH_ALEN);
\r
6422 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
6423 struct ieee80211_iface_limit rtw_limits[] = {
\r
6425 .types = BIT(NL80211_IFTYPE_STATION)
\r
6426 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
\r
6427 | BIT(NL80211_IFTYPE_P2P_CLIENT)
\r
6430 #ifdef CONFIG_AP_MODE
\r
6432 .types = BIT(NL80211_IFTYPE_AP)
\r
6433 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
\r
6434 | BIT(NL80211_IFTYPE_P2P_GO)
\r
6440 struct ieee80211_iface_combination rtw_combinations[] = {
\r
6441 { .limits = rtw_limits,
\r
6442 .n_limits = ARRAY_SIZE(rtw_limits),
\r
6443 .max_interfaces = 2,
\r
6444 .num_different_channels = 1,
\r
6447 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) */
\r
6449 static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy)
\r
6451 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
\r
6452 struct registry_priv *regsty = dvobj_to_regsty(dvobj);
\r
6454 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
\r
6456 wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
\r
6457 wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
\r
6458 wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
\r
6460 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
6461 wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
\r
6464 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
\r
6465 | BIT(NL80211_IFTYPE_ADHOC)
\r
6466 #ifdef CONFIG_AP_MODE
\r
6467 | BIT(NL80211_IFTYPE_AP)
\r
6468 #ifdef CONFIG_WIFI_MONITOR
\r
6469 | BIT(NL80211_IFTYPE_MONITOR)
\r
6472 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
6473 | BIT(NL80211_IFTYPE_P2P_CLIENT)
\r
6474 | BIT(NL80211_IFTYPE_P2P_GO)
\r
6478 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
6479 #ifdef CONFIG_AP_MODE
\r
6480 wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
\r
6481 #endif //CONFIG_AP_MODE
\r
6484 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
6485 #ifdef CONFIG_WIFI_MONITOR
\r
6486 wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
\r
6490 #if defined(RTW_SINGLE_WIPHY) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
6491 wiphy->iface_combinations = rtw_combinations;
\r
6492 wiphy->n_iface_combinations = ARRAY_SIZE(rtw_combinations);
\r
6495 wiphy->cipher_suites = rtw_cipher_suites;
\r
6496 wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
\r
6498 if (IsSupported24G(adapter->registrypriv.wireless_mode))
\r
6499 wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
\r
6501 #ifdef CONFIG_IEEE80211_BAND_5GHZ
\r
6502 if (IsSupported5G(adapter->registrypriv.wireless_mode))
\r
6503 wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
\r
6506 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
\r
6507 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
\r
6510 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
\r
6511 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
\r
6512 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
\r
6513 /* remove WIPHY_FLAG_OFFCHAN_TX, because we not support this feature */
\r
6514 /* wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME; */
\r
6517 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
6518 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
\r
6519 #ifdef CONFIG_PNO_SUPPORT
\r
6520 wiphy->max_sched_scan_ssids = MAX_PNO_LIST_COUNT;
\r
6524 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
6525 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0))
\r
6526 wiphy->wowlan = wowlan_stub;
\r
6528 wiphy->wowlan = &wowlan_stub;
\r
6532 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
6533 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
\r
6534 #ifndef CONFIG_TDLS_DRIVER_SETUP
\r
6535 wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; //Driver handles key exchange
\r
6536 wiphy->flags |= NL80211_ATTR_HT_CAPABILITY;
\r
6537 #endif //CONFIG_TDLS_DRIVER_SETUP
\r
6538 #endif /* CONFIG_TDLS */
\r
6540 if (regsty->power_mgnt != PS_MODE_ACTIVE)
\r
6541 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
\r
6543 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
\r
6545 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
6546 //wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
\r
6550 static struct cfg80211_ops rtw_cfg80211_ops = {
\r
6551 .change_virtual_intf = cfg80211_rtw_change_iface,
\r
6552 .add_key = cfg80211_rtw_add_key,
\r
6553 .get_key = cfg80211_rtw_get_key,
\r
6554 .del_key = cfg80211_rtw_del_key,
\r
6555 .set_default_key = cfg80211_rtw_set_default_key,
\r
6556 #if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
\r
6557 .set_rekey_data = cfg80211_rtw_set_rekey_data,
\r
6558 #endif /*CONFIG_GTK_OL*/
\r
6559 .get_station = cfg80211_rtw_get_station,
\r
6560 .scan = cfg80211_rtw_scan,
\r
6561 .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
\r
6562 .connect = cfg80211_rtw_connect,
\r
6563 .disconnect = cfg80211_rtw_disconnect,
\r
6564 .join_ibss = cfg80211_rtw_join_ibss,
\r
6565 .leave_ibss = cfg80211_rtw_leave_ibss,
\r
6566 .set_tx_power = cfg80211_rtw_set_txpower,
\r
6567 .get_tx_power = cfg80211_rtw_get_txpower,
\r
6568 .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
\r
6569 .set_pmksa = cfg80211_rtw_set_pmksa,
\r
6570 .del_pmksa = cfg80211_rtw_del_pmksa,
\r
6571 .flush_pmksa = cfg80211_rtw_flush_pmksa,
\r
6573 #ifdef CONFIG_AP_MODE
\r
6574 .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
\r
6575 .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
\r
6577 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
\r
6578 .add_beacon = cfg80211_rtw_add_beacon,
\r
6579 .set_beacon = cfg80211_rtw_set_beacon,
\r
6580 .del_beacon = cfg80211_rtw_del_beacon,
\r
6582 .start_ap = cfg80211_rtw_start_ap,
\r
6583 .change_beacon = cfg80211_rtw_change_beacon,
\r
6584 .stop_ap = cfg80211_rtw_stop_ap,
\r
6587 .add_station = cfg80211_rtw_add_station,
\r
6588 .del_station = cfg80211_rtw_del_station,
\r
6589 .change_station = cfg80211_rtw_change_station,
\r
6590 .dump_station = cfg80211_rtw_dump_station,
\r
6591 .change_bss = cfg80211_rtw_change_bss,
\r
6592 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
\r
6593 .set_channel = cfg80211_rtw_set_channel,
\r
6595 //.auth = cfg80211_rtw_auth,
\r
6596 //.assoc = cfg80211_rtw_assoc,
\r
6597 #endif //CONFIG_AP_MODE
\r
6599 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
\r
6600 .set_monitor_channel = cfg80211_rtw_set_monitor_channel,
\r
6604 .remain_on_channel = cfg80211_rtw_remain_on_channel,
\r
6605 .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
\r
6608 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
6609 .mgmt_tx = cfg80211_rtw_mgmt_tx,
\r
6610 .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
\r
6611 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
\r
6612 .action = cfg80211_rtw_mgmt_tx,
\r
6615 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
6616 .tdls_mgmt = cfg80211_rtw_tdls_mgmt,
\r
6617 .tdls_oper = cfg80211_rtw_tdls_oper,
\r
6618 #endif /* CONFIG_TDLS */
\r
6620 #if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
6621 .sched_scan_start = cfg80211_rtw_sched_scan_start,
\r
6622 .sched_scan_stop = cfg80211_rtw_sched_scan_stop,
\r
6623 #endif /* CONFIG_PNO_SUPPORT */
\r
6626 struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev)
\r
6628 struct wiphy *wiphy;
\r
6629 struct rtw_wiphy_data *wiphy_data;
\r
6632 wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(_adapter*));
\r
6634 DBG_8192C("Couldn't allocate wiphy device\n");
\r
6637 set_wiphy_dev(wiphy, dev);
\r
6638 *((_adapter**)wiphy_priv(wiphy)) = padapter;
\r
6640 rtw_cfg80211_preinit_wiphy(padapter, wiphy);
\r
6642 DBG_871X(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
\r
6648 void rtw_wiphy_free(struct wiphy *wiphy)
\r
6653 DBG_871X(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
\r
6655 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
\r
6656 rtw_spt_band_free(wiphy->bands[IEEE80211_BAND_2GHZ]);
\r
6657 wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
\r
6659 if (wiphy->bands[IEEE80211_BAND_5GHZ]) {
\r
6660 rtw_spt_band_free(wiphy->bands[IEEE80211_BAND_5GHZ]);
\r
6661 wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
\r
6664 wiphy_free(wiphy);
\r
6667 int rtw_wiphy_register(struct wiphy *wiphy)
\r
6669 DBG_871X(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
\r
6671 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
\r
6672 rtw_cfgvendor_attach(wiphy);
\r
6675 return wiphy_register(wiphy);
\r
6678 void rtw_wiphy_unregister(struct wiphy *wiphy)
\r
6680 DBG_871X(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
\r
6682 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
\r
6683 rtw_cfgvendor_detach(wiphy);
\r
6686 return wiphy_unregister(wiphy);
\r
6689 int rtw_wdev_alloc(_adapter *padapter, struct wiphy *wiphy)
\r
6692 struct net_device *pnetdev = padapter->pnetdev;
\r
6693 struct wireless_dev *wdev;
\r
6694 struct rtw_wdev_priv *pwdev_priv;
\r
6696 DBG_8192C("%s(padapter=%p)\n", __func__, padapter);
\r
6699 wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
\r
6701 DBG_8192C("Couldn't allocate wireless device\n");
\r
6705 wdev->wiphy = wiphy;
\r
6706 wdev->netdev = pnetdev;
\r
6708 wdev->iftype = NL80211_IFTYPE_STATION; // will be init in rtw_hal_init()
\r
6709 // Must sync with _rtw_init_mlme_priv()
\r
6710 // pmlmepriv->fw_state = WIFI_STATION_STATE
\r
6711 //wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
\r
6712 padapter->rtw_wdev = wdev;
\r
6713 pnetdev->ieee80211_ptr = wdev;
\r
6716 pwdev_priv = adapter_wdev_data(padapter);
\r
6717 pwdev_priv->rtw_wdev = wdev;
\r
6718 pwdev_priv->pmon_ndev = NULL;
\r
6719 pwdev_priv->ifname_mon[0] = '\0';
\r
6720 pwdev_priv->padapter = padapter;
\r
6721 pwdev_priv->scan_request = NULL;
\r
6722 _rtw_spinlock_init(&pwdev_priv->scan_req_lock);
\r
6724 pwdev_priv->p2p_enabled = _FALSE;
\r
6725 pwdev_priv->provdisc_req_issued = _FALSE;
\r
6726 rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
\r
6727 rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
\r
6729 pwdev_priv->bandroid_scan = _FALSE;
\r
6731 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
\r
6732 pwdev_priv->power_mgmt = _TRUE;
\r
6734 pwdev_priv->power_mgmt = _FALSE;
\r
6736 #ifdef CONFIG_CONCURRENT_MODE
\r
6737 ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
\r
6738 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
6745 void rtw_wdev_free(struct wireless_dev *wdev)
\r
6747 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
\r
6752 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
\r
6755 void rtw_wdev_unregister(struct wireless_dev *wdev)
\r
6757 struct net_device *ndev;
\r
6758 _adapter *adapter;
\r
6759 struct rtw_wdev_priv *pwdev_priv;
\r
6761 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
\r
6766 if(!(ndev = wdev_to_ndev(wdev)))
\r
6769 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
6770 pwdev_priv = adapter_wdev_data(adapter);
\r
6772 rtw_cfg80211_indicate_scan_done(adapter, _TRUE);
\r
6774 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
\r
6775 if (wdev->current_bss) {
\r
6776 u8 locally_generated = 1;
\r
6777 DBG_871X(FUNC_ADPT_FMT" clear current_bss by cfg80211_disconnected\n", FUNC_ADPT_ARG(adapter));
\r
6778 cfg80211_disconnected(adapter->pnetdev, 0, NULL, 0, locally_generated, GFP_ATOMIC);
\r
6780 #elif ((LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0))) || defined(COMPAT_KERNEL_RELEASE)
\r
6781 if (wdev->current_bss) {
\r
6782 DBG_871X(FUNC_ADPT_FMT" clear current_bss by cfg80211_disconnected\n", FUNC_ADPT_ARG(adapter));
\r
6783 cfg80211_disconnected(adapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
\r
6787 if (pwdev_priv->pmon_ndev) {
\r
6788 DBG_8192C("%s, unregister monitor interface\n", __func__);
\r
6789 unregister_netdev(pwdev_priv->pmon_ndev);
\r
6793 int rtw_cfg80211_ndev_res_alloc(_adapter *adapter)
\r
6797 #if !defined(RTW_SINGLE_WIPHY)
\r
6798 struct wiphy *wiphy;
\r
6799 struct device *dev = dvobj_to_dev(adapter_to_dvobj(adapter));
\r
6801 wiphy = rtw_wiphy_alloc(adapter, dev);
\r
6802 if (wiphy == NULL)
\r
6805 adapter->wiphy = wiphy;
\r
6808 if (rtw_wdev_alloc(adapter, adapter_to_wiphy(adapter)) == 0)
\r
6811 #if !defined(RTW_SINGLE_WIPHY)
\r
6812 if (ret != _SUCCESS) {
\r
6813 rtw_wiphy_free(wiphy);
\r
6814 adapter->wiphy = NULL;
\r
6822 void rtw_cfg80211_ndev_res_free(_adapter *adapter)
\r
6824 rtw_wdev_free(adapter->rtw_wdev);
\r
6825 #if !defined(RTW_SINGLE_WIPHY)
\r
6826 rtw_wiphy_free(adapter_to_wiphy(adapter));
\r
6827 adapter->wiphy = NULL;
\r
6831 int rtw_cfg80211_ndev_res_register(_adapter *adapter)
\r
6835 #if !defined(RTW_SINGLE_WIPHY)
\r
6836 if (rtw_wiphy_register(adapter_to_wiphy(adapter)) < 0) {
\r
6837 DBG_871X("%s rtw_wiphy_register fail for if%d\n", __func__, (adapter->iface_id+1));
\r
6848 void rtw_cfg80211_ndev_res_unregister(_adapter *adapter)
\r
6850 rtw_wdev_unregister(adapter->rtw_wdev);
\r
6853 int rtw_cfg80211_dev_res_alloc(struct dvobj_priv *dvobj)
\r
6857 #if defined(RTW_SINGLE_WIPHY)
\r
6858 struct wiphy *wiphy;
\r
6859 struct device *dev = dvobj_to_dev(dvobj);
\r
6861 wiphy = rtw_wiphy_alloc(dvobj->padapters[IFACE_ID0], dev);
\r
6862 if (wiphy == NULL)
\r
6865 dvobj->wiphy = wiphy;
\r
6874 void rtw_cfg80211_dev_res_free(struct dvobj_priv *dvobj)
\r
6876 #if defined(RTW_SINGLE_WIPHY)
\r
6877 rtw_wiphy_free(dvobj_to_wiphy(dvobj));
\r
6878 dvobj->wiphy = NULL;
\r
6882 int rtw_cfg80211_dev_res_register(struct dvobj_priv *dvobj)
\r
6886 #if defined(RTW_SINGLE_WIPHY)
\r
6887 if (rtw_wiphy_register(dvobj_to_wiphy(dvobj)) != 0)
\r
6897 void rtw_cfg80211_dev_res_unregister(struct dvobj_priv *dvobj)
\r
6899 #if defined(RTW_SINGLE_WIPHY)
\r
6900 rtw_wiphy_unregister(dvobj_to_wiphy(dvobj));
\r
6904 #endif /* CONFIG_IOCTL_CFG80211 */
\r