1 /******************************************************************************
\r
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
\r
5 * This program is free software; you can redistribute it and/or modify it
\r
6 * under the terms of version 2 of the GNU General Public License as
\r
7 * published by the Free Software Foundation.
\r
9 * This program is distributed in the hope that it will be useful, but WITHOUT
\r
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
14 * You should have received a copy of the GNU General Public License along with
\r
15 * this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
\r
19 ******************************************************************************/
\r
20 #define _IOCTL_CFG80211_C_
\r
22 #include <drv_types.h>
\r
24 #ifdef CONFIG_IOCTL_CFG80211
\r
26 #include <rtw_wifi_regd.h>
\r
28 #define RTW_MAX_MGMT_TX_CNT (8)
\r
30 #define RTW_SCAN_IE_LEN_MAX 2304
\r
31 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 5000 //ms
\r
32 #define RTW_MAX_NUM_PMKIDS 4
\r
34 #define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
\r
36 #ifdef CONFIG_WAPI_SUPPORT
\r
38 #ifndef WLAN_CIPHER_SUITE_SMS4
\r
39 #define WLAN_CIPHER_SUITE_SMS4 0x00147201
\r
42 #ifndef WLAN_AKM_SUITE_WAPI_PSK
\r
43 #define WLAN_AKM_SUITE_WAPI_PSK 0x000FAC04
\r
46 #ifndef WLAN_AKM_SUITE_WAPI_CERT
\r
47 #define WLAN_AKM_SUITE_WAPI_CERT 0x000FAC12
\r
50 #ifndef NL80211_WAPI_VERSION_1
\r
51 #define NL80211_WAPI_VERSION_1 (1 << 2)
\r
56 #ifdef CONFIG_PLATFORM_ARM_SUN8I
\r
57 #define BUSY_TRAFFIC_SCAN_DENY_PERIOD 8000
\r
59 #define BUSY_TRAFFIC_SCAN_DENY_PERIOD 12000
\r
62 static const u32 rtw_cipher_suites[] = {
\r
63 WLAN_CIPHER_SUITE_WEP40,
\r
64 WLAN_CIPHER_SUITE_WEP104,
\r
65 WLAN_CIPHER_SUITE_TKIP,
\r
66 WLAN_CIPHER_SUITE_CCMP,
\r
67 #ifdef CONFIG_WAPI_SUPPORT
\r
68 WLAN_CIPHER_SUITE_SMS4,
\r
69 #endif // CONFIG_WAPI_SUPPORT
\r
70 #ifdef CONFIG_IEEE80211W
\r
71 WLAN_CIPHER_SUITE_AES_CMAC,
\r
72 #endif //CONFIG_IEEE80211W
\r
75 #define RATETAB_ENT(_rate, _rateid, _flags) \
\r
77 .bitrate = (_rate), \
\r
78 .hw_value = (_rateid), \
\r
79 .flags = (_flags), \
\r
82 #define CHAN2G(_channel, _freq, _flags) { \
\r
83 .band = IEEE80211_BAND_2GHZ, \
\r
84 .center_freq = (_freq), \
\r
85 .hw_value = (_channel), \
\r
86 .flags = (_flags), \
\r
87 .max_antenna_gain = 0, \
\r
91 #define CHAN5G(_channel, _flags) { \
\r
92 .band = IEEE80211_BAND_5GHZ, \
\r
93 .center_freq = 5000 + (5 * (_channel)), \
\r
94 .hw_value = (_channel), \
\r
95 .flags = (_flags), \
\r
96 .max_antenna_gain = 0, \
\r
100 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
101 /* if wowlan is not supported, kernel generate a disconnect at each suspend
\r
102 * cf: /net/wireless/sysfs.c, so register a stub wowlan.
\r
103 * Moreover wowlan has to be enabled via a the nl80211_set_wowlan callback.
\r
104 * (from user space, e.g. iw phy0 wowlan enable)
\r
106 static const struct wiphy_wowlan_support wowlan_stub = {
\r
107 .flags = WIPHY_WOWLAN_ANY,
\r
109 .pattern_max_len = 0,
\r
110 .pattern_min_len = 0,
\r
111 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
\r
112 .max_pkt_offset = 0,
\r
117 static struct ieee80211_rate rtw_rates[] = {
\r
118 RATETAB_ENT(10, 0x1, 0),
\r
119 RATETAB_ENT(20, 0x2, 0),
\r
120 RATETAB_ENT(55, 0x4, 0),
\r
121 RATETAB_ENT(110, 0x8, 0),
\r
122 RATETAB_ENT(60, 0x10, 0),
\r
123 RATETAB_ENT(90, 0x20, 0),
\r
124 RATETAB_ENT(120, 0x40, 0),
\r
125 RATETAB_ENT(180, 0x80, 0),
\r
126 RATETAB_ENT(240, 0x100, 0),
\r
127 RATETAB_ENT(360, 0x200, 0),
\r
128 RATETAB_ENT(480, 0x400, 0),
\r
129 RATETAB_ENT(540, 0x800, 0),
\r
132 #define rtw_a_rates (rtw_rates + 4)
\r
133 #define RTW_A_RATES_NUM 8
\r
134 #define rtw_g_rates (rtw_rates + 0)
\r
135 #define RTW_G_RATES_NUM 12
\r
137 #define RTW_2G_CHANNELS_NUM 14
\r
138 #define RTW_5G_CHANNELS_NUM 37
\r
140 static struct ieee80211_channel rtw_2ghz_channels[] = {
\r
141 CHAN2G(1, 2412, 0),
\r
142 CHAN2G(2, 2417, 0),
\r
143 CHAN2G(3, 2422, 0),
\r
144 CHAN2G(4, 2427, 0),
\r
145 CHAN2G(5, 2432, 0),
\r
146 CHAN2G(6, 2437, 0),
\r
147 CHAN2G(7, 2442, 0),
\r
148 CHAN2G(8, 2447, 0),
\r
149 CHAN2G(9, 2452, 0),
\r
150 CHAN2G(10, 2457, 0),
\r
151 CHAN2G(11, 2462, 0),
\r
152 CHAN2G(12, 2467, 0),
\r
153 CHAN2G(13, 2472, 0),
\r
154 CHAN2G(14, 2484, 0),
\r
157 static struct ieee80211_channel rtw_5ghz_a_channels[] = {
\r
158 CHAN5G(34, 0), CHAN5G(36, 0),
\r
159 CHAN5G(38, 0), CHAN5G(40, 0),
\r
160 CHAN5G(42, 0), CHAN5G(44, 0),
\r
161 CHAN5G(46, 0), CHAN5G(48, 0),
\r
162 CHAN5G(52, 0), CHAN5G(56, 0),
\r
163 CHAN5G(60, 0), CHAN5G(64, 0),
\r
164 CHAN5G(100, 0), CHAN5G(104, 0),
\r
165 CHAN5G(108, 0), CHAN5G(112, 0),
\r
166 CHAN5G(116, 0), CHAN5G(120, 0),
\r
167 CHAN5G(124, 0), CHAN5G(128, 0),
\r
168 CHAN5G(132, 0), CHAN5G(136, 0),
\r
169 CHAN5G(140, 0), CHAN5G(149, 0),
\r
170 CHAN5G(153, 0), CHAN5G(157, 0),
\r
171 CHAN5G(161, 0), CHAN5G(165, 0),
\r
172 CHAN5G(184, 0), CHAN5G(188, 0),
\r
173 CHAN5G(192, 0), CHAN5G(196, 0),
\r
174 CHAN5G(200, 0), CHAN5G(204, 0),
\r
175 CHAN5G(208, 0), CHAN5G(212, 0),
\r
180 void rtw_2g_channels_init(struct ieee80211_channel *channels)
\r
182 _rtw_memcpy((void*)channels, (void*)rtw_2ghz_channels,
\r
183 sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
\r
187 void rtw_5g_channels_init(struct ieee80211_channel *channels)
\r
189 _rtw_memcpy((void*)channels, (void*)rtw_5ghz_a_channels,
\r
190 sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
\r
194 void rtw_2g_rates_init(struct ieee80211_rate *rates)
\r
196 _rtw_memcpy(rates, rtw_g_rates,
\r
197 sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
\r
201 void rtw_5g_rates_init(struct ieee80211_rate *rates)
\r
203 _rtw_memcpy(rates, rtw_a_rates,
\r
204 sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM
\r
208 struct ieee80211_supported_band *rtw_spt_band_alloc(
\r
209 enum ieee80211_band band
\r
212 struct ieee80211_supported_band *spt_band = NULL;
\r
213 int n_channels, n_bitrates;
\r
215 if(band == IEEE80211_BAND_2GHZ)
\r
217 n_channels = RTW_2G_CHANNELS_NUM;
\r
218 n_bitrates = RTW_G_RATES_NUM;
\r
220 else if(band == IEEE80211_BAND_5GHZ)
\r
222 n_channels = RTW_5G_CHANNELS_NUM;
\r
223 n_bitrates = RTW_A_RATES_NUM;
\r
230 spt_band = (struct ieee80211_supported_band *)rtw_zmalloc(
\r
231 sizeof(struct ieee80211_supported_band)
\r
232 + sizeof(struct ieee80211_channel)*n_channels
\r
233 + sizeof(struct ieee80211_rate)*n_bitrates
\r
238 spt_band->channels = (struct ieee80211_channel*)(((u8*)spt_band)+sizeof(struct ieee80211_supported_band));
\r
239 spt_band->bitrates= (struct ieee80211_rate*)(((u8*)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
\r
240 spt_band->band = band;
\r
241 spt_band->n_channels = n_channels;
\r
242 spt_band->n_bitrates = n_bitrates;
\r
244 if(band == IEEE80211_BAND_2GHZ)
\r
246 rtw_2g_channels_init(spt_band->channels);
\r
247 rtw_2g_rates_init(spt_band->bitrates);
\r
249 else if(band == IEEE80211_BAND_5GHZ)
\r
251 rtw_5g_channels_init(spt_band->channels);
\r
252 rtw_5g_rates_init(spt_band->bitrates);
\r
262 void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
\r
269 if(spt_band->band == IEEE80211_BAND_2GHZ)
\r
271 size = sizeof(struct ieee80211_supported_band)
\r
272 + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
\r
273 + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM;
\r
275 else if(spt_band->band == IEEE80211_BAND_5GHZ)
\r
277 size = sizeof(struct ieee80211_supported_band)
\r
278 + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
\r
279 + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM;
\r
285 rtw_mfree((u8*)spt_band, size);
\r
288 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
289 static const struct ieee80211_txrx_stypes
\r
290 rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
\r
291 [NL80211_IFTYPE_ADHOC] = {
\r
293 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
\r
295 [NL80211_IFTYPE_STATION] = {
\r
297 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
\r
298 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
\r
300 [NL80211_IFTYPE_AP] = {
\r
302 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
303 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
304 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
305 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
306 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
307 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
308 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
310 [NL80211_IFTYPE_AP_VLAN] = {
\r
313 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
314 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
315 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
316 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
317 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
318 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
319 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
321 [NL80211_IFTYPE_P2P_CLIENT] = {
\r
323 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
\r
324 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
\r
326 [NL80211_IFTYPE_P2P_GO] = {
\r
328 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
329 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
330 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
331 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
332 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
333 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
334 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
339 static int rtw_ieee80211_channel_to_frequency(int chan, int band)
\r
341 /* see 802.11 17.3.8.3.2 and Annex J
\r
342 * there are overlapping channel numbers in 5GHz and 2GHz bands */
\r
344 if (band == IEEE80211_BAND_5GHZ) {
\r
345 if (chan >= 182 && chan <= 196)
\r
346 return 4000 + chan * 5;
\r
348 return 5000 + chan * 5;
\r
349 } else { /* IEEE80211_BAND_2GHZ */
\r
352 else if (chan < 14)
\r
353 return 2407 + chan * 5;
\r
355 return 0; /* not supported */
\r
359 static u64 rtw_get_systime_us(void)
\r
361 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39))
\r
362 struct timespec ts;
\r
363 get_monotonic_boottime(&ts);
\r
364 return ((u64)ts.tv_sec*1000000) + ts.tv_nsec / 1000;
\r
367 do_gettimeofday(&tv);
\r
368 return ((u64)tv.tv_sec*1000000) + tv.tv_usec;
\r
372 #define MAX_BSSINFO_LEN 1000
\r
373 struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork)
\r
375 struct ieee80211_channel *notify_channel;
\r
376 struct cfg80211_bss *bss = NULL;
\r
377 //struct ieee80211_supported_band *band;
\r
380 u64 notify_timestamp;
\r
381 u16 notify_capability;
\r
382 u16 notify_interval;
\r
384 size_t notify_ielen;
\r
386 //u8 buf[MAX_BSSINFO_LEN];
\r
389 size_t buf_size = MAX_BSSINFO_LEN;
\r
390 size_t len,bssinf_len=0;
\r
391 struct rtw_ieee80211_hdr *pwlanhdr;
\r
392 unsigned short *fctrl;
\r
393 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
\r
395 struct wireless_dev *wdev = padapter->rtw_wdev;
\r
396 struct wiphy *wiphy = wdev->wiphy;
\r
397 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
399 pbuf = rtw_zmalloc(buf_size);
\r
401 DBG_871X("%s pbuf allocate failed !! \n",__FUNCTION__);
\r
405 //DBG_8192C("%s\n", __func__);
\r
407 bssinf_len = pnetwork->network.IELength+sizeof (struct rtw_ieee80211_hdr_3addr);
\r
408 if(bssinf_len > buf_size){
\r
409 DBG_871X("%s IE Length too long > %zu byte \n",__FUNCTION__,buf_size);
\r
413 #ifndef CONFIG_WAPI_SUPPORT
\r
417 if(rtw_get_wapi_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &wapi_len)>0)
\r
421 DBG_871X("%s, no support wapi!\n",__FUNCTION__);
\r
426 #endif //!CONFIG_WAPI_SUPPORT
\r
428 //To reduce PBC Overlap rate
\r
429 //_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
430 if(adapter_wdev_data(padapter)->scan_request != NULL)
\r
432 u8 *psr=NULL, sr = 0;
\r
433 NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid;
\r
434 struct cfg80211_scan_request *request = adapter_wdev_data(padapter)->scan_request;
\r
435 struct cfg80211_ssid *ssids = request->ssids;
\r
439 wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
\r
441 if(wpsie && wpsielen>0)
\r
442 psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
\r
446 if(request->n_ssids == 1 && request->n_channels == 1) // it means under processing WPS
\r
448 DBG_8192C("ssid=%s, len=%d\n", pssid->Ssid, pssid->SsidLength);
\r
450 if (ssids[0].ssid_len == 0) {
\r
452 else if(pssid->SsidLength == ssids[0].ssid_len &&
\r
453 _rtw_memcmp(pssid->Ssid, ssids[0].ssid, ssids[0].ssid_len))
\r
455 DBG_871X("%s, got sr and ssid match!\n", __func__);
\r
460 *psr = 0; //clear sr
\r
463 WLAN_BSSID_EX *pselect_network = &pnetwork->network;
\r
464 struct cfg80211_bss *pselect_bss = NULL;
\r
465 struct ieee80211_channel *notify_channel = NULL;
\r
468 DBG_871X("%s, got sr, but ssid mismatch, to remove this bss\n", __func__);
\r
470 if (pselect_network->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
\r
471 freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
\r
473 freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
\r
475 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
476 pselect_bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
\r
477 pselect_network->MacAddress, pselect_network->Ssid.Ssid,
\r
478 pselect_network->Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
\r
479 0/*WLAN_CAPABILITY_ESS*/);
\r
483 DBG_871X("%s, got bss for cfg80211 for unlinking bss\n", __func__);
\r
485 cfg80211_unlink_bss(wiphy, pselect_bss);
\r
486 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
487 cfg80211_put_bss(wiphy, pselect_bss);
\r
489 cfg80211_put_bss(pselect_bss);
\r
500 //_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
503 channel = pnetwork->network.Configuration.DSConfig;
\r
504 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
505 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
507 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
509 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
512 notify_timestamp = le64_to_cpu(*(u64*)rtw_get_timestampe_from_ie(pnetwork->network.IEs));
\r
514 notify_timestamp = rtw_get_systime_us();
\r
516 notify_interval = le16_to_cpu(*(u16*)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
\r
517 notify_capability = le16_to_cpu(*(u16*)rtw_get_capability_from_ie(pnetwork->network.IEs));
\r
519 notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_;
\r
520 notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_;
\r
522 //We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm)
\r
523 if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
\r
524 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
\r
525 notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);//dbm
\r
527 notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);//dbm
\r
531 DBG_8192C("bssid: "MAC_FMT"\n", MAC_ARG(pnetwork->network.MacAddress));
\r
532 DBG_8192C("Channel: %d(%d)\n", channel, freq);
\r
533 DBG_8192C("Capability: %X\n", notify_capability);
\r
534 DBG_8192C("Beacon interval: %d\n", notify_interval);
\r
535 DBG_8192C("Signal: %d\n", notify_signal);
\r
536 DBG_8192C("notify_timestamp: %llu\n", notify_timestamp);
\r
541 pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;
\r
542 fctrl = &(pwlanhdr->frame_ctl);
\r
545 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
\r
546 //pmlmeext->mgnt_seq++;
\r
548 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
\r
549 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
\r
550 SetFrameSubType(pbuf, WIFI_BEACON);
\r
552 _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
553 SetFrameSubType(pbuf, WIFI_PROBERSP);
\r
556 _rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
\r
557 _rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
\r
560 //pbuf += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
561 len = sizeof (struct rtw_ieee80211_hdr_3addr);
\r
562 _rtw_memcpy((pbuf+len), pnetwork->network.IEs, pnetwork->network.IELength);
\r
563 *((u64*)(pbuf+len)) = cpu_to_le64(notify_timestamp);
\r
565 len += pnetwork->network.IELength;
\r
567 //#ifdef CONFIG_P2P
\r
568 //if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
\r
570 // DBG_8192C("%s, got p2p_ie\n", __func__);
\r
575 bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)pbuf,
\r
576 len, notify_signal, GFP_ATOMIC);
\r
579 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress,
\r
580 notify_timestamp, notify_capability, notify_interval, notify_ie,
\r
581 notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/);
\r
584 if (unlikely(!bss)) {
\r
585 DBG_8192C(FUNC_ADPT_FMT" bss NULL\n", FUNC_ADPT_ARG(padapter));
\r
589 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
\r
590 #ifndef COMPAT_KERNEL_RELEASE
\r
591 //patch for cfg80211, update beacon ies to information_elements
\r
592 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
\r
594 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
600 #endif //COMPAT_KERNEL_RELEASE
\r
601 #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
\r
605 if( bss->information_elements == bss->proberesp_ies)
\r
607 if( bss->len_information_elements != bss->len_proberesp_ies)
\r
609 DBG_8192C("error!, len_information_elements != bss->len_proberesp_ies\n");
\r
613 else if(bss->len_information_elements < bss->len_beacon_ies)
\r
615 bss->information_elements = bss->beacon_ies;
\r
616 bss->len_information_elements = bss->len_beacon_ies;
\r
620 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
621 cfg80211_put_bss(wiphy, bss);
\r
623 cfg80211_put_bss(bss);
\r
628 rtw_mfree(pbuf, buf_size);
\r
634 Check the given bss is valid by kernel API cfg80211_get_bss()
\r
635 @padapter : the given adapter
\r
637 return _TRUE if bss is valid, _FALSE for not found.
\r
639 int rtw_cfg80211_check_bss(_adapter *padapter)
\r
641 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
642 struct cfg80211_bss *bss = NULL;
\r
643 struct ieee80211_channel *notify_channel = NULL;
\r
646 if (!(pnetwork) || !(padapter->rtw_wdev))
\r
649 if (pnetwork->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
\r
650 freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
\r
652 freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
\r
654 notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
\r
655 bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
\r
656 pnetwork->MacAddress, pnetwork->Ssid.Ssid,
\r
657 pnetwork->Ssid.SsidLength,
\r
658 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
\r
660 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
661 cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
\r
663 cfg80211_put_bss(bss);
\r
666 return (bss!=NULL);
\r
669 void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter)
\r
671 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
672 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
673 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
674 struct cfg80211_bss *bss = NULL;
\r
675 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
\r
676 struct wiphy *wiphy = pwdev->wiphy;
\r
677 int freq = (int)cur_network->network.Configuration.DSConfig;
\r
678 struct ieee80211_channel *chan;
\r
681 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
682 if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
\r
687 if (!rtw_cfg80211_check_bss(padapter)) {
\r
688 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
689 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
\r
691 if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE)
\r
694 _rtw_memcpy(&cur_network->network, pnetwork, sizeof(WLAN_BSSID_EX));
\r
697 if (!rtw_cfg80211_inform_bss(padapter,cur_network))
\r
698 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
700 DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
704 DBG_871X("cur_network is not exist!!!\n");
\r
710 if(scanned == NULL)
\r
713 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
\r
714 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
\r
716 if (!rtw_cfg80211_inform_bss(padapter,scanned)) {
\r
717 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
719 //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
722 DBG_871X("scanned & pnetwork compare fail\n");
\r
727 if (!rtw_cfg80211_check_bss(padapter))
\r
728 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
\r
730 //notify cfg80211 that device joined an IBSS
\r
731 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
\r
732 chan = ieee80211_get_channel(wiphy, freq);
\r
733 cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, chan, GFP_ATOMIC);
\r
735 cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, GFP_ATOMIC);
\r
739 void rtw_cfg80211_indicate_connect(_adapter *padapter)
\r
741 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
742 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
743 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
745 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
747 struct cfg80211_bss *bss = NULL;
\r
749 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
750 if (pwdev->iftype != NL80211_IFTYPE_STATION
\r
751 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
752 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
\r
758 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
762 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
764 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
766 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
767 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
\r
768 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
\r
769 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
772 #endif //CONFIG_P2P
\r
775 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
776 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
\r
778 //DBG_871X(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter));
\r
780 if(scanned == NULL) {
\r
785 if (_rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
\r
786 && _rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
\r
788 if (!rtw_cfg80211_inform_bss(padapter,scanned)) {
\r
789 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
791 //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
794 DBG_871X("scanned: %s("MAC_FMT"), cur: %s("MAC_FMT")\n",
\r
795 scanned->network.Ssid.Ssid, MAC_ARG(scanned->network.MacAddress),
\r
796 pnetwork->Ssid.Ssid, MAC_ARG(pnetwork->MacAddress)
\r
803 if (!rtw_cfg80211_check_bss(padapter))
\r
804 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
\r
806 if (rtw_to_roam(padapter) > 0) {
\r
807 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
\r
808 struct wiphy *wiphy = pwdev->wiphy;
\r
809 struct ieee80211_channel *notify_channel;
\r
811 u16 channel = cur_network->network.Configuration.DSConfig;
\r
813 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
814 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
816 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
818 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
821 DBG_871X(FUNC_ADPT_FMT" call cfg80211_roamed\n", FUNC_ADPT_ARG(padapter));
\r
822 cfg80211_roamed(padapter->pnetdev
\r
823 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
\r
826 , cur_network->network.MacAddress
\r
827 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
\r
828 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
\r
829 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
\r
830 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
\r
835 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
\r
836 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
\r
838 cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
\r
839 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
\r
840 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
\r
841 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
\r
842 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
\r
843 , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
\r
844 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
\r
845 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
\r
850 void rtw_cfg80211_indicate_disconnect(_adapter *padapter)
\r
852 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
853 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
855 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
858 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
860 if (pwdev->iftype != NL80211_IFTYPE_STATION
\r
861 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
862 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
\r
868 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
872 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
874 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
876 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
877 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
879 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
882 #endif //CONFIG_P2P
\r
884 if (!padapter->mlmepriv.not_indic_disco) {
\r
885 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
\r
886 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
\r
888 if(pwdev->sme_state==CFG80211_SME_CONNECTING)
\r
889 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
\r
890 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
\r
891 else if(pwdev->sme_state==CFG80211_SME_CONNECTED)
\r
892 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
\r
894 //DBG_8192C("pwdev->sme_state=%d\n", pwdev->sme_state);
\r
896 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
\r
899 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
900 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
\r
902 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
\r
903 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
\r
909 #ifdef CONFIG_AP_MODE
\r
910 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
\r
913 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
914 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
\r
915 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
916 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
917 struct security_priv* psecuritypriv=&(padapter->securitypriv);
\r
918 struct sta_priv *pstapriv = &padapter->stapriv;
\r
920 DBG_8192C("%s\n", __FUNCTION__);
\r
922 param->u.crypt.err = 0;
\r
923 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
\r
925 //sizeof(struct ieee_param) = 64 bytes;
\r
926 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
\r
927 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
\r
933 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
\r
934 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
\r
935 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
\r
937 if (param->u.crypt.idx >= WEP_KEYS)
\r
945 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
\r
949 DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n");
\r
954 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
\r
956 //todo:clear default encryption keys
\r
958 DBG_8192C("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
\r
964 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
\r
966 DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
\r
968 wep_key_idx = param->u.crypt.idx;
\r
969 wep_key_len = param->u.crypt.key_len;
\r
971 DBG_8192C("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
\r
973 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
\r
979 if (wep_key_len > 0)
\r
981 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
984 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
\r
986 //wep default key has not been set, so use this key index as default key.
\r
988 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
\r
989 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
990 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
\r
991 psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
\r
993 if(wep_key_len == 13)
\r
995 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
\r
996 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
\r
999 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
\r
1002 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
\r
1004 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
\r
1006 rtw_ap_set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx, 1);
\r
1013 if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
\r
1015 if(param->u.crypt.set_tx == 0) //group key
\r
1017 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1019 DBG_8192C("%s, set group_key, WEP\n", __FUNCTION__);
\r
1021 _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
1023 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1024 if(param->u.crypt.key_len==13)
\r
1026 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1030 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1032 DBG_8192C("%s, set group_key, TKIP\n", __FUNCTION__);
\r
1034 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
\r
1036 _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
1038 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1040 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
\r
1041 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
\r
1043 psecuritypriv->busetkipkey = _TRUE;
\r
1046 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1048 DBG_8192C("%s, set group_key, CCMP\n", __FUNCTION__);
\r
1050 psecuritypriv->dot118021XGrpPrivacy = _AES_;
\r
1052 _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
1056 DBG_8192C("%s, set group_key, none\n", __FUNCTION__);
\r
1058 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
1061 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
\r
1063 psecuritypriv->binstallGrpkey = _TRUE;
\r
1065 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
\r
1067 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
\r
1069 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1072 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1073 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
\r
1082 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
\r
1084 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
1086 if(param->u.crypt.set_tx ==1) //pairwise key
\r
1088 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1090 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1092 DBG_8192C("%s, set pairwise key, WEP\n", __FUNCTION__);
\r
1094 psta->dot118021XPrivacy = _WEP40_;
\r
1095 if(param->u.crypt.key_len==13)
\r
1097 psta->dot118021XPrivacy = _WEP104_;
\r
1100 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1102 DBG_8192C("%s, set pairwise key, TKIP\n", __FUNCTION__);
\r
1104 psta->dot118021XPrivacy = _TKIP_;
\r
1106 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1108 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
\r
1109 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
\r
1111 psecuritypriv->busetkipkey = _TRUE;
\r
1114 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1117 DBG_8192C("%s, set pairwise key, CCMP\n", __FUNCTION__);
\r
1119 psta->dot118021XPrivacy = _AES_;
\r
1123 DBG_8192C("%s, set pairwise key, none\n", __FUNCTION__);
\r
1125 psta->dot118021XPrivacy = _NO_PRIVACY_;
\r
1128 rtw_ap_set_pairwise_key(padapter, psta);
\r
1130 psta->ieee8021x_blocked = _FALSE;
\r
1132 psta->bpairwise_key_installed = _TRUE;
\r
1135 else//group key???
\r
1137 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1139 _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
1141 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1142 if(param->u.crypt.key_len==13)
\r
1144 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1147 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1149 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
\r
1151 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1153 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1155 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
\r
1156 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
\r
1158 psecuritypriv->busetkipkey = _TRUE;
\r
1161 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1163 psecuritypriv->dot118021XGrpPrivacy = _AES_;
\r
1165 _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 = _NO_PRIVACY_;
\r
1172 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
\r
1174 psecuritypriv->binstallGrpkey = _TRUE;
\r
1176 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
\r
1178 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
\r
1180 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1183 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1184 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
\r
1200 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
\r
1203 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
1204 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
1205 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1206 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1208 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
\r
1209 #endif //CONFIG_P2P
\r
1213 DBG_8192C("%s\n", __func__);
\r
1215 param->u.crypt.err = 0;
\r
1216 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
\r
1218 if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
\r
1224 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
\r
1225 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
\r
1226 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
\r
1228 if (param->u.crypt.idx >= WEP_KEYS
\r
1229 #ifdef CONFIG_IEEE80211W
\r
1230 && param->u.crypt.idx > BIP_MAX_KEYID
\r
1231 #endif //CONFIG_IEEE80211W
\r
1238 #ifdef CONFIG_WAPI_SUPPORT
\r
1239 if (strcmp(param->u.crypt.alg, "SMS4"))
\r
1247 if (strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1249 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
\r
1250 DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n");
\r
1252 wep_key_idx = param->u.crypt.idx;
\r
1253 wep_key_len = param->u.crypt.key_len;
\r
1255 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0))
\r
1261 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
\r
1263 //wep default key has not been set, so use this key index as default key.
\r
1265 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
1267 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1268 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
\r
1269 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1271 if(wep_key_len==13)
\r
1273 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
\r
1274 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1277 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
\r
1280 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
\r
1282 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
\r
1284 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, _TRUE);
\r
1289 if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
\r
1291 struct sta_info * psta,*pbcmc_sta;
\r
1292 struct sta_priv * pstapriv = &padapter->stapriv;
\r
1294 //DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__);
\r
1296 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
\r
1298 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
\r
1299 if (psta == NULL) {
\r
1300 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
\r
1301 DBG_8192C("%s, : Obtain Sta_info fail \n", __func__);
\r
1305 //Jeff: don't disable ieee8021x_blocked while clearing key
\r
1306 if (strcmp(param->u.crypt.alg, "none") != 0)
\r
1307 psta->ieee8021x_blocked = _FALSE;
\r
1310 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
\r
1311 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
\r
1313 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
\r
1316 if(param->u.crypt.set_tx ==1)//pairwise key
\r
1319 DBG_8192C("%s, : param->u.crypt.set_tx ==1 \n", __func__);
\r
1321 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1323 if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
\r
1325 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
\r
1326 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
\r
1327 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
\r
1329 padapter->securitypriv.busetkipkey=_FALSE;
\r
1330 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
\r
1333 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
\r
1334 DBG_871X(" ~~~~set sta key:unicastkey\n");
\r
1336 rtw_setstakey_cmd(padapter, psta, _TRUE, _TRUE);
\r
1340 if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1342 _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
1343 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
\r
1344 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
\r
1345 padapter->securitypriv.binstallGrpkey = _TRUE;
\r
1346 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
\r
1347 DBG_871X(" ~~~~set sta key:groupkey\n");
\r
1349 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
\r
1350 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1, _TRUE);
\r
1352 #ifdef CONFIG_IEEE80211W
\r
1353 else if(strcmp(param->u.crypt.alg, "BIP") == 0)
\r
1356 //DBG_871X("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx);
\r
1357 //save the IGTK key, length 16 bytes
\r
1358 _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
1359 /*DBG_871X("IGTK key below:\n");
\r
1360 for(no=0;no<16;no++)
\r
1361 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
\r
1363 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
\r
1364 padapter->securitypriv.binstallBIPkey = _TRUE;
\r
1365 DBG_871X(" ~~~~set sta key:IGKT\n");
\r
1367 #endif //CONFIG_IEEE80211W
\r
1370 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1372 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
\r
1374 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
\r
1377 #endif //CONFIG_P2P
\r
1382 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1383 if(pbcmc_sta==NULL)
\r
1385 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
\r
1389 //Jeff: don't disable ieee8021x_blocked while clearing key
\r
1390 if (strcmp(param->u.crypt.alg, "none") != 0)
\r
1391 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1393 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
\r
1394 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
\r
1396 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
\r
1400 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
\r
1405 #ifdef CONFIG_WAPI_SUPPORT
\r
1406 if (strcmp(param->u.crypt.alg, "SMS4") == 0)
\r
1408 PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
\r
1409 PRT_WAPI_STA_INFO pWapiSta;
\r
1410 u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1411 u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1412 u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1414 if(param->u.crypt.set_tx == 1)
\r
1416 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
\r
1417 if(_rtw_memcmp(pWapiSta->PeerMacAddr,param->sta_addr,6))
\r
1419 _rtw_memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
\r
1421 pWapiSta->wapiUsk.bSet = true;
\r
1422 _rtw_memcpy(pWapiSta->wapiUsk.dataKey,param->u.crypt.key,16);
\r
1423 _rtw_memcpy(pWapiSta->wapiUsk.micKey,param->u.crypt.key+16,16);
\r
1424 pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
\r
1425 pWapiSta->wapiUsk.bTxEnable = true;
\r
1427 _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16);
\r
1428 _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16);
\r
1429 _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16);
\r
1430 _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16);
\r
1431 _rtw_memcpy(pWapiSta->lastRxUnicastPN,WapiAEPNInitialValueSrc,16);
\r
1432 pWapiSta->wapiUskUpdate.bTxEnable = false;
\r
1433 pWapiSta->wapiUskUpdate.bSet = false;
\r
1435 if (psecuritypriv->sw_encrypt== false || psecuritypriv->sw_decrypt == false)
\r
1437 //set unicast key for ASUE
\r
1438 rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
\r
1445 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
\r
1446 if(_rtw_memcmp(pWapiSta->PeerMacAddr,get_bssid(pmlmepriv),6))
\r
1448 pWapiSta->wapiMsk.bSet = true;
\r
1449 _rtw_memcpy(pWapiSta->wapiMsk.dataKey,param->u.crypt.key,16);
\r
1450 _rtw_memcpy(pWapiSta->wapiMsk.micKey,param->u.crypt.key+16,16);
\r
1451 pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
\r
1452 pWapiSta->wapiMsk.bTxEnable = false;
\r
1453 if(!pWapiSta->bSetkeyOk)
\r
1454 pWapiSta->bSetkeyOk = true;
\r
1455 pWapiSta->bAuthenticateInProgress = false;
\r
1457 _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
\r
1459 if (psecuritypriv->sw_decrypt == false)
\r
1461 //set rx broadcast key for ASUE
\r
1462 rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
\r
1474 DBG_8192C("%s, ret=%d\n", __func__, ret);
\r
1481 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1482 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1483 u8 key_index, bool pairwise, const u8 *mac_addr,
\r
1484 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1485 u8 key_index, const u8 *mac_addr,
\r
1486 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1487 struct key_params *params)
\r
1491 struct ieee_param *param = NULL;
\r
1493 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1494 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
1495 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1497 DBG_871X(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
\r
1498 DBG_871X("cipher=0x%x\n", params->cipher);
\r
1499 DBG_871X("key_len=0x%x\n", params->key_len);
\r
1500 DBG_871X("seq_len=0x%x\n", params->seq_len);
\r
1501 DBG_871X("key_index=%d\n", key_index);
\r
1502 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1503 DBG_871X("pairwise=%d\n", pairwise);
\r
1504 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1506 param_len = sizeof(struct ieee_param) + params->key_len;
\r
1507 param = (struct ieee_param *)rtw_malloc(param_len);
\r
1508 if (param == NULL)
\r
1511 _rtw_memset(param, 0, param_len);
\r
1513 param->cmd = IEEE_CMD_SET_ENCRYPTION;
\r
1514 _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
\r
1516 switch (params->cipher) {
\r
1517 case IW_AUTH_CIPHER_NONE:
\r
1518 //todo: remove key
\r
1520 alg_name = "none";
\r
1522 case WLAN_CIPHER_SUITE_WEP40:
\r
1523 case WLAN_CIPHER_SUITE_WEP104:
\r
1526 case WLAN_CIPHER_SUITE_TKIP:
\r
1527 alg_name = "TKIP";
\r
1529 case WLAN_CIPHER_SUITE_CCMP:
\r
1530 alg_name = "CCMP";
\r
1532 #ifdef CONFIG_IEEE80211W
\r
1533 case WLAN_CIPHER_SUITE_AES_CMAC:
\r
1536 #endif //CONFIG_IEEE80211W
\r
1537 #ifdef CONFIG_WAPI_SUPPORT
\r
1538 case WLAN_CIPHER_SUITE_SMS4:
\r
1540 if(pairwise == NL80211_KEYTYPE_PAIRWISE) {
\r
1541 if (key_index != 0 && key_index != 1) {
\r
1545 _rtw_memcpy((void*)param->sta_addr, (void*)mac_addr, ETH_ALEN);
\r
1547 DBG_871X("mac_addr is null \n");
\r
1549 DBG_871X("rtw_wx_set_enc_ext: SMS4 case \n");
\r
1558 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
\r
1561 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
\r
1563 param->u.crypt.set_tx = 0; //for wpa/wpa2 group key
\r
1565 param->u.crypt.set_tx = 1; //for wpa/wpa2 pairwise key
\r
1569 //param->u.crypt.idx = key_index - 1;
\r
1570 param->u.crypt.idx = key_index;
\r
1572 if (params->seq_len && params->seq)
\r
1574 _rtw_memcpy(param->u.crypt.seq, (u8 *)params->seq, params->seq_len);
\r
1577 if(params->key_len && params->key)
\r
1579 param->u.crypt.key_len = params->key_len;
\r
1580 _rtw_memcpy(param->u.crypt.key, (u8 *)params->key, params->key_len);
\r
1583 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
\r
1585 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
\r
1587 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
1589 #ifdef CONFIG_AP_MODE
\r
1591 _rtw_memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN);
\r
1593 ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
\r
1596 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE
\r
1597 || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)
\r
1599 //DBG_8192C("@@@@@@@@@@ fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
\r
1600 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
\r
1604 DBG_8192C("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
\r
1611 rtw_mfree((u8*)param, param_len);
\r
1618 static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1619 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1620 u8 key_index, bool pairwise, const u8 *mac_addr,
\r
1621 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1622 u8 key_index, const u8 *mac_addr,
\r
1623 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1625 void (*callback)(void *cookie,
\r
1626 struct key_params*))
\r
1629 struct iwm_priv *iwm = ndev_to_iwm(ndev);
\r
1630 struct iwm_key *key = &iwm->keys[key_index];
\r
1631 struct key_params params;
\r
1633 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
\r
1635 memset(¶ms, 0, sizeof(params));
\r
1637 params.cipher = key->cipher;
\r
1638 params.key_len = key->key_len;
\r
1639 params.seq_len = key->seq_len;
\r
1640 params.seq = key->seq;
\r
1641 params.key = key->key;
\r
1643 callback(cookie, ¶ms);
\r
1645 return key->key_len ? 0 : -ENOENT;
\r
1647 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
1651 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1652 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1653 u8 key_index, bool pairwise, const u8 *mac_addr)
\r
1654 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1655 u8 key_index, const u8 *mac_addr)
\r
1656 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1658 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1659 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1661 DBG_871X(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index);
\r
1663 if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
\r
1665 //clear the flag of wep default key set.
\r
1666 psecuritypriv->bWepDefaultKeyIdxSet = 0;
\r
1672 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
\r
1673 struct net_device *ndev, u8 key_index
\r
1674 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1675 , bool unicast, bool multicast
\r
1679 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1680 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1682 DBG_871X(FUNC_NDEV_FMT" key_index=%d"
\r
1683 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1684 ", unicast=%d, multicast=%d"
\r
1686 ".\n", FUNC_NDEV_ARG(ndev), key_index
\r
1687 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1688 , unicast, multicast
\r
1692 if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) //set wep default key
\r
1694 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1696 psecuritypriv->dot11PrivacyKeyIndex = key_index;
\r
1698 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
\r
1699 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1700 if (psecuritypriv->dot11DefKeylen[key_index] == 13)
\r
1702 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
\r
1703 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1706 psecuritypriv->bWepDefaultKeyIdxSet = 1; //set the flag to represent that wep default key has been set
\r
1713 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
\r
1714 struct net_device *ndev,
\r
1715 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
1720 struct station_info *sinfo)
\r
1723 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1724 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1725 struct sta_info *psta = NULL;
\r
1726 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1728 sinfo->filled = 0;
\r
1731 DBG_871X(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
\r
1736 psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
\r
1737 if (psta == NULL) {
\r
1738 DBG_8192C("%s, sta_info is null\n", __func__);
\r
1743 #ifdef CONFIG_DEBUG_CFG80211
\r
1744 DBG_871X(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
\r
1747 //for infra./P2PClient mode
\r
1748 if( check_fwstate(pmlmepriv, WIFI_STATION_STATE)
\r
1749 && check_fwstate(pmlmepriv, _FW_LINKED)
\r
1752 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
1754 if (_rtw_memcmp((u8 *)mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) {
\r
1755 DBG_871X("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
\r
1760 sinfo->filled |= STATION_INFO_SIGNAL;
\r
1761 sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
\r
1763 sinfo->filled |= STATION_INFO_TX_BITRATE;
\r
1764 sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
\r
1766 sinfo->filled |= STATION_INFO_RX_PACKETS;
\r
1767 sinfo->rx_packets = sta_rx_data_pkts(psta);
\r
1769 sinfo->filled |= STATION_INFO_TX_PACKETS;
\r
1770 sinfo->tx_packets = psta->sta_stats.tx_pkts;
\r
1774 //for Ad-Hoc/AP mode
\r
1775 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
\r
1776 ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
\r
1777 ||check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
1778 && check_fwstate(pmlmepriv, _FW_LINKED)
\r
1781 //TODO: should acquire station info...
\r
1788 extern int netdev_open(struct net_device *pnetdev);
\r
1789 #ifdef CONFIG_CONCURRENT_MODE
\r
1790 extern int netdev_if2_open(struct net_device *pnetdev);
\r
1794 enum nl80211_iftype {
\r
1795 NL80211_IFTYPE_UNSPECIFIED,
\r
1796 NL80211_IFTYPE_ADHOC, //1
\r
1797 NL80211_IFTYPE_STATION, //2
\r
1798 NL80211_IFTYPE_AP, //3
\r
1799 NL80211_IFTYPE_AP_VLAN,
\r
1800 NL80211_IFTYPE_WDS,
\r
1801 NL80211_IFTYPE_MONITOR, //6
\r
1802 NL80211_IFTYPE_MESH_POINT,
\r
1803 NL80211_IFTYPE_P2P_CLIENT, //8
\r
1804 NL80211_IFTYPE_P2P_GO, //9
\r
1806 NUM_NL80211_IFTYPES,
\r
1807 NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
\r
1810 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
\r
1811 struct net_device *ndev,
\r
1812 enum nl80211_iftype type, u32 *flags,
\r
1813 struct vif_params *params)
\r
1815 enum nl80211_iftype old_type;
\r
1816 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
\r
1817 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1818 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
1819 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
1821 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
1824 u8 change = _FALSE;
\r
1826 DBG_871X(FUNC_NDEV_FMT" type=%d\n", FUNC_NDEV_ARG(ndev), type);
\r
1828 if(adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE)
\r
1834 #ifdef CONFIG_CONCURRENT_MODE
\r
1835 if(padapter->adapter_type == SECONDARY_ADAPTER)
\r
1837 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev));
\r
1838 if(netdev_if2_open(ndev) != 0) {
\r
1839 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open fail\n", FUNC_NDEV_ARG(ndev));
\r
1844 else if(padapter->adapter_type == PRIMARY_ADAPTER)
\r
1845 #endif //CONFIG_CONCURRENT_MODE
\r
1847 DBG_871X(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
\r
1848 if(netdev_open(ndev) != 0) {
\r
1849 DBG_871X(FUNC_NDEV_FMT" call netdev_open fail\n", FUNC_NDEV_ARG(ndev));
\r
1855 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
1856 DBG_871X(FUNC_NDEV_FMT" call rtw_pwr_wakeup fail\n", FUNC_NDEV_ARG(ndev));
\r
1861 old_type = rtw_wdev->iftype;
\r
1862 DBG_871X(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
\r
1863 FUNC_NDEV_ARG(ndev), old_type, type);
\r
1865 if(old_type != type)
\r
1868 pmlmeext->action_public_rxseq = 0xffff;
\r
1869 pmlmeext->action_public_dialog_token = 0xff;
\r
1873 case NL80211_IFTYPE_ADHOC:
\r
1874 networkType = Ndis802_11IBSS;
\r
1876 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1877 case NL80211_IFTYPE_P2P_CLIENT:
\r
1879 case NL80211_IFTYPE_STATION:
\r
1880 networkType = Ndis802_11Infrastructure;
\r
1882 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1884 if(change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
1886 //it means remove GO and change mode from AP(GO) to station(P2P DEVICE)
\r
1887 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
1888 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
1890 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
1893 #endif //CONFIG_P2P
\r
1895 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1896 case NL80211_IFTYPE_P2P_GO:
\r
1898 case NL80211_IFTYPE_AP:
\r
1899 networkType = Ndis802_11APMode;
\r
1901 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1903 if(change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
1905 //it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO)
\r
1906 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
\r
1909 #endif //CONFIG_P2P
\r
1912 ret = -EOPNOTSUPP;
\r
1916 rtw_wdev->iftype = type;
\r
1918 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE)
\r
1920 rtw_wdev->iftype = old_type;
\r
1925 rtw_setopmode_cmd(padapter, networkType,_TRUE);
\r
1929 DBG_871X(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret);
\r
1933 void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted)
\r
1935 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
1938 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
1939 if (pwdev_priv->scan_request != NULL) {
\r
1940 #ifdef CONFIG_DEBUG_CFG80211
\r
1941 DBG_871X("%s with scan req\n", __FUNCTION__);
\r
1944 /* avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); */
\r
1945 if(pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
\r
1947 DBG_8192C("error wiphy compare\n");
\r
1951 cfg80211_scan_done(pwdev_priv->scan_request, aborted);
\r
1954 pwdev_priv->scan_request = NULL;
\r
1956 #ifdef CONFIG_DEBUG_CFG80211
\r
1957 DBG_871X("%s without scan req\n", __FUNCTION__);
\r
1960 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
1963 void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork)
\r
1965 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
1966 struct wiphy *wiphy = pwdev->wiphy;
\r
1967 struct cfg80211_bss *bss = NULL;
\r
1968 WLAN_BSSID_EX select_network = pnetwork->network;
\r
1970 bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
\r
1971 select_network.MacAddress, select_network.Ssid.Ssid,
\r
1972 select_network.Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
\r
1973 0/*WLAN_CAPABILITY_ESS*/);
\r
1976 cfg80211_unlink_bss(wiphy, bss);
\r
1977 DBG_8192C("%s(): cfg80211_unlink %s!! () ",__func__,select_network.Ssid.Ssid );
\r
1978 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
1979 cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
\r
1981 cfg80211_put_bss(bss);
\r
1987 void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
\r
1990 _list *plist, *phead;
\r
1991 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
1992 _queue *queue = &(pmlmepriv->scanned_queue);
\r
1993 struct wlan_network *pnetwork = NULL;
\r
1995 u32 wait_for_surveydone;
\r
1998 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
\r
1999 #endif //CONFIG_P2P
\r
2000 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
2002 #ifdef CONFIG_DEBUG_CFG80211
\r
2003 DBG_8192C("%s\n", __func__);
\r
2006 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
2008 phead = get_list_head(queue);
\r
2009 plist = get_next(phead);
\r
2013 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
\r
2016 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
\r
2018 //report network only if the current channel set contains the channel to which this network belongs
\r
2019 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
\r
2020 && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
\r
2021 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
\r
2024 //ev=translate_scan(padapter, a, pnetwork, ev, stop);
\r
2025 rtw_cfg80211_inform_bss(padapter, pnetwork);
\r
2027 /* //check ralink testbed RSN IE length
\r
2029 if(_rtw_memcmp(pnetwork->network.Ssid.Ssid, "Ralink_11n_AP",13))
\r
2033 p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
\r
2034 DBG_871X("ie_len=%d\n", ie_len);
\r
2037 plist = get_next(plist);
\r
2041 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
2044 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
\r
2047 uint wps_ielen = 0;
\r
2049 u32 p2p_ielen = 0;
\r
2051 u32 wfd_ielen = 0;
\r
2053 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2055 #ifdef CONFIG_DEBUG_CFG80211
\r
2056 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
2061 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
2063 #ifdef CONFIG_DEBUG_CFG80211
\r
2064 DBG_8192C("probe_req_wps_ielen=%d\n", wps_ielen);
\r
2067 if(pmlmepriv->wps_probe_req_ie)
\r
2069 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
\r
2070 pmlmepriv->wps_probe_req_ie_len = 0;
\r
2071 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
\r
2072 pmlmepriv->wps_probe_req_ie = NULL;
\r
2075 pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
\r
2076 if ( pmlmepriv->wps_probe_req_ie == NULL) {
\r
2077 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2081 _rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
\r
2082 pmlmepriv->wps_probe_req_ie_len = wps_ielen;
\r
2085 //buf += wps_ielen;
\r
2086 //len -= wps_ielen;
\r
2089 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
2091 struct wifidirect_info *wdinfo = &padapter->wdinfo;
\r
2092 u32 attr_contentlen = 0;
\r
2093 u8 listen_ch_attr[5];
\r
2095 #ifdef CONFIG_DEBUG_CFG80211
\r
2096 DBG_8192C("probe_req_p2p_ielen=%d\n", p2p_ielen);
\r
2099 if(pmlmepriv->p2p_probe_req_ie)
\r
2101 u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
\r
2102 pmlmepriv->p2p_probe_req_ie_len = 0;
\r
2103 rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len);
\r
2104 pmlmepriv->p2p_probe_req_ie = NULL;
\r
2107 pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen);
\r
2108 if ( pmlmepriv->p2p_probe_req_ie == NULL) {
\r
2109 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2113 _rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
\r
2114 pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
\r
2116 if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8*)listen_ch_attr, (uint*) &attr_contentlen)
\r
2117 && attr_contentlen == 5)
\r
2119 if (wdinfo->listen_channel != listen_ch_attr[4]) {
\r
2120 DBG_871X(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n",
\r
2121 FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2],
\r
2122 listen_ch_attr[3], listen_ch_attr[4]);
\r
2123 wdinfo->listen_channel = listen_ch_attr[4];
\r
2127 #endif //CONFIG_P2P
\r
2129 //buf += p2p_ielen;
\r
2130 //len -= p2p_ielen;
\r
2133 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
2135 #ifdef CONFIG_DEBUG_CFG80211
\r
2136 DBG_8192C("probe_req_wfd_ielen=%d\n", wfd_ielen);
\r
2139 if(pmlmepriv->wfd_probe_req_ie)
\r
2141 u32 free_len = pmlmepriv->wfd_probe_req_ie_len;
\r
2142 pmlmepriv->wfd_probe_req_ie_len = 0;
\r
2143 rtw_mfree(pmlmepriv->wfd_probe_req_ie, free_len);
\r
2144 pmlmepriv->wfd_probe_req_ie = NULL;
\r
2147 pmlmepriv->wfd_probe_req_ie = rtw_malloc(wfd_ielen);
\r
2148 if ( pmlmepriv->wfd_probe_req_ie == NULL) {
\r
2149 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2153 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
\r
2155 #endif //CONFIG_WFD
\r
2163 static int cfg80211_rtw_scan(struct wiphy *wiphy
\r
2164 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
\r
2165 , struct net_device *ndev
\r
2167 , struct cfg80211_scan_request *request)
\r
2169 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
2170 struct net_device *ndev = wdev_to_ndev(request->wdev);
\r
2173 u8 _status = _FALSE;
\r
2175 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
\r
2176 struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
\r
2179 uint wps_ielen=0;
\r
2182 u8 survey_times=3;
\r
2183 u8 survey_times_for_one_ch=6;
\r
2184 struct cfg80211_ssid *ssids = request->ssids;
\r
2185 int social_channel = 0, j = 0;
\r
2186 bool need_indicate_scan_done = _FALSE;
\r
2188 _adapter *padapter;
\r
2189 struct rtw_wdev_priv *pwdev_priv;
\r
2190 struct mlme_priv *pmlmepriv;
\r
2192 struct wifidirect_info *pwdinfo;
\r
2193 #endif //CONFIG_P2P
\r
2194 #ifdef CONFIG_CONCURRENT_MODE
\r
2195 PADAPTER pbuddy_adapter = NULL;
\r
2196 struct mlme_priv *pbuddy_mlmepriv = NULL;
\r
2197 #endif //CONFIG_CONCURRENT_MODE
\r
2199 if (ndev == NULL) {
\r
2204 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2205 pwdev_priv = adapter_wdev_data(padapter);
\r
2206 pmlmepriv= &padapter->mlmepriv;
\r
2208 pwdinfo= &(padapter->wdinfo);
\r
2209 #endif //CONFIG_P2P
\r
2211 //#ifdef CONFIG_DEBUG_CFG80211
\r
2212 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
2215 #ifdef CONFIG_CONCURRENT_MODE
\r
2216 if (padapter->pbuddy_adapter) {
\r
2217 pbuddy_adapter = padapter->pbuddy_adapter;
\r
2218 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
\r
2220 #endif //CONFIG_CONCURRENT_MODE
\r
2222 #ifdef CONFIG_MP_INCLUDED
\r
2223 if (padapter->registrypriv.mp_mode == 1)
\r
2225 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter));
\r
2229 #ifdef CONFIG_CONCURRENT_MODE
\r
2230 if (padapter->pbuddy_adapter) {
\r
2231 if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1)
\r
2233 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter));
\r
2238 #endif //CONFIG_CONCURRENT_MODE
\r
2241 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2242 pwdev_priv->scan_request = request;
\r
2243 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2245 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
2247 #ifdef CONFIG_DEBUG_CFG80211
\r
2248 DBG_871X("%s under WIFI_AP_STATE\n", __FUNCTION__);
\r
2251 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
\r
2253 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2255 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
\r
2257 DBG_8192C("AP mode process WPS \n");
\r
2260 need_indicate_scan_done = _TRUE;
\r
2261 goto check_need_indicate_scan_done;
\r
2265 rtw_ps_deny(padapter, PS_DENY_SCAN);
\r
2266 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
2267 need_indicate_scan_done = _TRUE;
\r
2268 goto check_need_indicate_scan_done;
\r
2272 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
2274 if(ssids->ssid != NULL
\r
2275 && _rtw_memcmp(ssids->ssid, "DIRECT-", 7)
\r
2276 && rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
\r
2279 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2281 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
\r
2282 adapter_wdev_data(padapter)->p2p_enabled = _TRUE;
\r
2286 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
2287 #ifdef CONFIG_DEBUG_CFG80211
\r
2288 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
2291 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
\r
2293 if(request->n_channels == 3 &&
\r
2294 request->channels[0]->hw_value == 1 &&
\r
2295 request->channels[1]->hw_value == 6 &&
\r
2296 request->channels[2]->hw_value == 11
\r
2299 social_channel = 1;
\r
2303 #endif //CONFIG_P2P
\r
2305 if(request->ie && request->ie_len>0)
\r
2307 rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len );
\r
2310 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
\r
2311 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2312 need_indicate_scan_done = _TRUE;
\r
2313 goto check_need_indicate_scan_done;
\r
2314 } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
2315 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2317 goto check_need_indicate_scan_done;
\r
2320 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)
\r
2322 #if 1 // Miracast can't do AP scan
\r
2323 static u32 lastscantime = 0;
\r
2326 passtime = rtw_get_passing_time_ms(lastscantime);
\r
2327 lastscantime = rtw_get_current_time();
\r
2328 if (passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD)
\r
2331 DBG_871X("%s: bBusyTraffic == _TRUE\n", __FUNCTION__);
\r
2332 need_indicate_scan_done = _TRUE;
\r
2333 goto check_need_indicate_scan_done;
\r
2337 if (rtw_is_scan_deny(padapter)){
\r
2338 DBG_871X(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter));
\r
2339 need_indicate_scan_done = _TRUE;
\r
2340 goto check_need_indicate_scan_done;
\r
2343 #ifdef CONFIG_CONCURRENT_MODE
\r
2344 if(pbuddy_mlmepriv && (pbuddy_mlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))
\r
2346 #if 1 // Miracast can't do AP scan
\r
2347 static u32 buddylastscantime = 0;
\r
2350 passtime = rtw_get_passing_time_ms(buddylastscantime);
\r
2351 buddylastscantime = rtw_get_current_time();
\r
2352 if ((passtime > BUSY_TRAFFIC_SCAN_DENY_PERIOD)
\r
2353 //#ifdef CONFIG_P2P
\r
2354 // ||(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
\r
2355 //#endif //CONFIG_P2P
\r
2359 DBG_871X("%s: bBusyTraffic == _TRUE at buddy_intf\n", __FUNCTION__);
\r
2360 need_indicate_scan_done = _TRUE;
\r
2361 goto check_need_indicate_scan_done;
\r
2365 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE) {
\r
2366 DBG_871X("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv->fw_state);
\r
2367 need_indicate_scan_done = _TRUE;
\r
2368 goto check_need_indicate_scan_done;
\r
2370 } else if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY)) {
\r
2371 bool scan_via_buddy = _FALSE;
\r
2372 struct rtw_wdev_priv *buddy_wdev_priv = adapter_wdev_data(pbuddy_adapter);
\r
2374 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2375 _enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
\r
2376 if (buddy_wdev_priv->scan_request) {
\r
2377 DBG_871X("scan via buddy\n");
\r
2378 pmlmepriv->scanning_via_buddy_intf = _TRUE;
\r
2379 _enter_critical_bh(&pmlmepriv->lock, &irqL);
\r
2380 set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
\r
2381 _exit_critical_bh(&pmlmepriv->lock, &irqL);
\r
2382 scan_via_buddy = _TRUE;
\r
2384 _exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
\r
2385 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2387 if (scan_via_buddy == _FALSE)
\r
2388 need_indicate_scan_done = _TRUE;
\r
2390 goto check_need_indicate_scan_done;
\r
2392 #endif /* CONFIG_CONCURRENT_MODE */
\r
2395 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
\r
2397 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
\r
2398 rtw_free_network_queue(padapter, _TRUE);
\r
2400 if(social_channel == 0)
\r
2401 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
\r
2403 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
\r
2405 #endif //CONFIG_P2P
\r
2408 _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
\r
2409 //parsing request ssids, n_ssids
\r
2410 for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
\r
2411 #ifdef CONFIG_DEBUG_CFG80211
\r
2412 DBG_8192C("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
\r
2414 _rtw_memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
\r
2415 ssid[i].SsidLength = ssids[i].ssid_len;
\r
2418 /* parsing channels, n_channels */
\r
2419 _rtw_memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
\r
2420 for (i=0;i<request->n_channels && i<RTW_CHANNEL_SCAN_AMOUNT;i++) {
\r
2421 #ifdef CONFIG_DEBUG_CFG80211
\r
2422 DBG_871X(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
\r
2424 ch[i].hw_value = request->channels[i]->hw_value;
\r
2425 ch[i].flags = request->channels[i]->flags;
\r
2428 _enter_critical_bh(&pmlmepriv->lock, &irqL);
\r
2429 if (request->n_channels == 1) {
\r
2430 for(i=1;i<survey_times_for_one_ch;i++)
\r
2431 _rtw_memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
\r
2432 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times_for_one_ch);
\r
2433 } else if (request->n_channels <= 4) {
\r
2434 for(j=request->n_channels-1;j>=0;j--)
\r
2435 for(i=0;i<survey_times;i++)
\r
2437 _rtw_memcpy(&ch[j*survey_times+i], &ch[j], sizeof(struct rtw_ieee80211_channel));
\r
2439 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * request->n_channels);
\r
2441 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
\r
2443 _exit_critical_bh(&pmlmepriv->lock, &irqL);
\r
2446 if(_status == _FALSE)
\r
2451 check_need_indicate_scan_done:
\r
2452 if (_TRUE == need_indicate_scan_done)
\r
2454 rtw_cfg80211_surveydone_event_callback(padapter);
\r
2455 rtw_cfg80211_indicate_scan_done(padapter, _FALSE);
\r
2459 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
\r
2466 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
\r
2469 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
\r
2471 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
\r
2472 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
\r
2475 iwm->conf.rts_threshold = wiphy->rts_threshold;
\r
2477 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
\r
2478 CFG_RTS_THRESHOLD,
\r
2479 iwm->conf.rts_threshold);
\r
2484 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
\r
2485 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
\r
2488 iwm->conf.frag_threshold = wiphy->frag_threshold;
\r
2490 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
\r
2491 CFG_FRAG_THRESHOLD,
\r
2492 iwm->conf.frag_threshold);
\r
2497 DBG_8192C("%s\n", __func__);
\r
2503 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
\r
2505 DBG_8192C("%s, wpa_version=%d\n", __func__, wpa_version);
\r
2507 if (!wpa_version) {
\r
2508 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
2513 if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
\r
2515 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
\r
2519 if (wpa_version & NL80211_WPA_VERSION_2)
\r
2521 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
\r
2525 #ifdef CONFIG_WAPI_SUPPORT
\r
2526 if (wpa_version & NL80211_WAPI_VERSION_1)
\r
2528 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWAPI;
\r
2536 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
\r
2537 enum nl80211_auth_type sme_auth_type)
\r
2539 DBG_8192C("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
\r
2542 switch (sme_auth_type) {
\r
2543 case NL80211_AUTHTYPE_AUTOMATIC:
\r
2545 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
\r
2548 case NL80211_AUTHTYPE_OPEN_SYSTEM:
\r
2550 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
\r
2552 if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
\r
2553 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2555 #ifdef CONFIG_WAPI_SUPPORT
\r
2556 if(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI)
\r
2557 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2561 case NL80211_AUTHTYPE_SHARED_KEY:
\r
2563 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
\r
2565 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2570 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
\r
2571 //return -ENOTSUPP;
\r
2578 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
\r
2580 u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2582 u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
\r
2583 &psecuritypriv->dot118021XGrpPrivacy;
\r
2585 DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
\r
2589 *profile_cipher = _NO_PRIVACY_;
\r
2590 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
\r
2595 case IW_AUTH_CIPHER_NONE:
\r
2596 *profile_cipher = _NO_PRIVACY_;
\r
2597 ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2598 #ifdef CONFIG_WAPI_SUPPORT
\r
2599 if(psecuritypriv->dot11PrivacyAlgrthm ==_SMS4_ )
\r
2601 *profile_cipher = _SMS4_;
\r
2605 case WLAN_CIPHER_SUITE_WEP40:
\r
2606 *profile_cipher = _WEP40_;
\r
2607 ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2609 case WLAN_CIPHER_SUITE_WEP104:
\r
2610 *profile_cipher = _WEP104_;
\r
2611 ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2613 case WLAN_CIPHER_SUITE_TKIP:
\r
2614 *profile_cipher = _TKIP_;
\r
2615 ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2617 case WLAN_CIPHER_SUITE_CCMP:
\r
2618 *profile_cipher = _AES_;
\r
2619 ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2621 #ifdef CONFIG_WAPI_SUPPORT
\r
2622 case WLAN_CIPHER_SUITE_SMS4:
\r
2623 *profile_cipher = _SMS4_;
\r
2624 ndisencryptstatus = Ndis802_11_EncrypteionWAPI;
\r
2628 DBG_8192C("Unsupported cipher: 0x%x\n", cipher);
\r
2634 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
\r
2636 //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
\r
2637 // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
\r
2643 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
\r
2645 DBG_8192C("%s, key_mgt=0x%x\n", __func__, key_mgt);
\r
2647 if (key_mgt == WLAN_AKM_SUITE_8021X)
\r
2648 //*auth_type = UMAC_AUTH_TYPE_8021X;
\r
2649 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2650 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
\r
2651 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2653 #ifdef CONFIG_WAPI_SUPPORT
\r
2654 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_PSK){
\r
2655 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2657 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_CERT){
\r
2658 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2664 DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt);
\r
2671 static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
\r
2673 u8 *buf=NULL, *pos=NULL;
\r
2675 int group_cipher = 0, pairwise_cipher = 0;
\r
2680 u8 null_addr[]= {0,0,0,0,0,0};
\r
2682 if (pie == NULL || !ielen) {
\r
2683 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
\r
2684 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2688 if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
\r
2693 buf = rtw_zmalloc(ielen);
\r
2699 _rtw_memcpy(buf, pie , ielen);
\r
2704 DBG_8192C("set wpa_ie(length:%zu):\n", ielen);
\r
2705 for(i=0;i<ielen;i=i+8)
\r
2706 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
2710 if(ielen < RSN_HEADER_LEN){
\r
2711 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
\r
2716 pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
\r
2717 if(pwpa && wpa_ielen>0)
\r
2719 if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
2721 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
2722 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
\r
2723 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
\r
2725 DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
\r
2729 pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
\r
2730 if(pwpa2 && wpa2_ielen>0)
\r
2732 if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
2734 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
2735 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
\r
2736 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
\r
2738 DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
\r
2742 if (group_cipher == 0)
\r
2744 group_cipher = WPA_CIPHER_NONE;
\r
2746 if (pairwise_cipher == 0)
\r
2748 pairwise_cipher = WPA_CIPHER_NONE;
\r
2751 switch(group_cipher)
\r
2753 case WPA_CIPHER_NONE:
\r
2754 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
\r
2755 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
\r
2757 case WPA_CIPHER_WEP40:
\r
2758 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
\r
2759 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2761 case WPA_CIPHER_TKIP:
\r
2762 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
\r
2763 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2765 case WPA_CIPHER_CCMP:
\r
2766 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
\r
2767 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2769 case WPA_CIPHER_WEP104:
\r
2770 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
\r
2771 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2775 switch(pairwise_cipher)
\r
2777 case WPA_CIPHER_NONE:
\r
2778 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
\r
2779 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
\r
2781 case WPA_CIPHER_WEP40:
\r
2782 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
\r
2783 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2785 case WPA_CIPHER_TKIP:
\r
2786 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
\r
2787 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2789 case WPA_CIPHER_CCMP:
\r
2790 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
\r
2791 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2793 case WPA_CIPHER_WEP104:
\r
2794 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
\r
2795 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2799 {/* handle wps_ie */
\r
2803 wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
\r
2804 if (wps_ie && wps_ielen > 0) {
\r
2805 DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen);
\r
2806 padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
\r
2807 _rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
\r
2808 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2810 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2815 {//check p2p_ie for assoc req;
\r
2818 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2820 if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen)))
\r
2822 #ifdef CONFIG_DEBUG_CFG80211
\r
2823 DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
\r
2826 if(pmlmepriv->p2p_assoc_req_ie)
\r
2828 u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
\r
2829 pmlmepriv->p2p_assoc_req_ie_len = 0;
\r
2830 rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
\r
2831 pmlmepriv->p2p_assoc_req_ie = NULL;
\r
2834 pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
\r
2835 if ( pmlmepriv->p2p_assoc_req_ie == NULL) {
\r
2836 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2839 _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
\r
2840 pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
\r
2843 #endif //CONFIG_P2P
\r
2846 {//check wfd_ie for assoc req;
\r
2849 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2851 if(rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen))
\r
2853 #ifdef CONFIG_DEBUG_CFG80211
\r
2854 DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
\r
2857 if(pmlmepriv->wfd_assoc_req_ie)
\r
2859 u32 free_len = pmlmepriv->wfd_assoc_req_ie_len;
\r
2860 pmlmepriv->wfd_assoc_req_ie_len = 0;
\r
2861 rtw_mfree(pmlmepriv->wfd_assoc_req_ie, free_len);
\r
2862 pmlmepriv->wfd_assoc_req_ie = NULL;
\r
2865 pmlmepriv->wfd_assoc_req_ie = rtw_malloc(wfd_ielen);
\r
2866 if ( pmlmepriv->wfd_assoc_req_ie == NULL) {
\r
2867 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2870 rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
\r
2873 #endif //CONFIG_WFD
\r
2875 //TKIP and AES disallow multicast packets until installing group key
\r
2876 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
\r
2877 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
\r
2878 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
\r
2879 //WPS open need to enable multicast
\r
2880 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
\r
2881 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
\r
2883 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
\r
2884 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
\r
2885 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
\r
2889 rtw_mfree(buf, ielen);
\r
2891 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2895 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
\r
2896 struct cfg80211_ibss_params *params)
\r
2898 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2899 NDIS_802_11_SSID ndis_ssid;
\r
2900 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
2901 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2904 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
2909 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
\r
2914 #ifdef CONFIG_CONCURRENT_MODE
\r
2915 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
\r
2916 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
\r
2920 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
\r
2921 rtw_scan_abort(padapter->pbuddy_adapter);
\r
2923 #endif //CONFIG_CONCURRENT_MODE
\r
2925 if (!params->ssid || !params->ssid_len)
\r
2931 if (params->ssid_len > IW_ESSID_MAX_SIZE){
\r
2937 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
\r
2938 ndis_ssid.SsidLength = params->ssid_len;
\r
2939 _rtw_memcpy(ndis_ssid.Ssid, (u8 *)params->ssid, params->ssid_len);
\r
2941 //DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, params->ssid_len);
\r
2943 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2944 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
\r
2945 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
2946 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
\r
2947 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
2949 ret = rtw_cfg80211_set_auth_type(psecuritypriv, NL80211_AUTHTYPE_OPEN_SYSTEM);
\r
2950 rtw_set_802_11_authentication_mode(padapter, psecuritypriv->ndisauthtype);
\r
2952 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE)
\r
2962 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
\r
2964 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2965 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
2966 enum nl80211_iftype old_type;
\r
2969 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
2971 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
2973 old_type = rtw_wdev->iftype;
\r
2975 rtw_set_to_roam(padapter, 0);
\r
2977 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
2979 rtw_scan_abort(padapter);
\r
2980 LeaveAllPowerSaveMode(padapter);
\r
2982 rtw_wdev->iftype = NL80211_IFTYPE_STATION;
\r
2984 if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) ==_FALSE)
\r
2986 rtw_wdev->iftype = old_type;
\r
2990 rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure,_TRUE);
\r
2994 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
2999 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
\r
3000 struct cfg80211_connect_params *sme)
\r
3005 struct wlan_network *pnetwork = NULL;
\r
3006 NDIS_802_11_AUTHENTICATION_MODE authmode;
\r
3007 NDIS_802_11_SSID ndis_ssid;
\r
3008 u8 *dst_ssid, *src_ssid;
\r
3009 u8 *dst_bssid, *src_bssid;
\r
3010 //u8 matched_by_bssid=_FALSE;
\r
3011 //u8 matched_by_ssid=_FALSE;
\r
3012 u8 matched=_FALSE;
\r
3013 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3014 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
3015 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3016 _queue *queue = &pmlmepriv->scanned_queue;
\r
3018 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
3020 DBG_871X("=>"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3021 DBG_871X("privacy=%d, key=%p, key_len=%d, key_idx=%d\n",
\r
3022 sme->privacy, sme->key, sme->key_len, sme->key_idx);
\r
3025 if(adapter_wdev_data(padapter)->block == _TRUE)
\r
3028 DBG_871X("%s wdev_priv.block is set\n", __FUNCTION__);
\r
3032 #ifdef CONFIG_PLATFORM_MSTAR_SCAN_BEFORE_CONNECT
\r
3033 printk("MStar Android!\n");
\r
3034 if(adapter_wdev_data(padapter)->bandroid_scan == _FALSE)
\r
3037 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
3038 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
3039 #endif //CONFIG_P2P
\r
3042 printk("Android hasn't attached yet!\n");
\r
3048 rtw_ps_deny(padapter, PS_DENY_JOIN);
\r
3049 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
3054 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
\r
3059 #ifdef CONFIG_CONCURRENT_MODE
\r
3060 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
\r
3061 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
\r
3065 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
\r
3066 rtw_scan_abort(padapter->pbuddy_adapter);
\r
3070 if (!sme->ssid || !sme->ssid_len)
\r
3076 if (sme->ssid_len > IW_ESSID_MAX_SIZE){
\r
3082 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
\r
3083 ndis_ssid.SsidLength = sme->ssid_len;
\r
3084 _rtw_memcpy(ndis_ssid.Ssid, (u8 *)sme->ssid, sme->ssid_len);
\r
3086 DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
\r
3090 DBG_8192C("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
\r
3093 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
3095 DBG_8192C("%s, fw_state=0x%x, goto exit\n", __FUNCTION__, pmlmepriv->fw_state);
\r
3098 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
\r
3099 rtw_scan_abort(padapter);
\r
3102 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
3103 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
\r
3104 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
3105 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
\r
3106 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
3108 #ifdef CONFIG_WAPI_SUPPORT
\r
3109 padapter->wapiInfo.bWapiEnable = false;
\r
3112 ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
\r
3116 #ifdef CONFIG_WAPI_SUPPORT
\r
3117 if(sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1)
\r
3119 padapter->wapiInfo.bWapiEnable = true;
\r
3120 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
\r
3121 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
\r
3125 ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
\r
3127 #ifdef CONFIG_WAPI_SUPPORT
\r
3128 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI)
\r
3129 padapter->mlmeextpriv.mlmext_info.auth_algo = psecuritypriv->dot11AuthAlgrthm;
\r
3136 DBG_8192C("%s, ie_len=%zu\n", __func__, sme->ie_len);
\r
3138 ret = rtw_cfg80211_set_wpa_ie(padapter, (u8 *)sme->ie, sme->ie_len);
\r
3142 if (sme->crypto.n_ciphers_pairwise) {
\r
3143 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
\r
3148 //For WEP Shared auth
\r
3149 if((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared
\r
3150 || psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && sme->key
\r
3153 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
3154 NDIS_802_11_WEP *pwep = NULL;
\r
3155 DBG_871X("%s(): Shared/Auto WEP\n",__FUNCTION__);
\r
3157 wep_key_idx = sme->key_idx;
\r
3158 wep_key_len = sme->key_len;
\r
3160 if (sme->key_idx > WEP_KEYS) {
\r
3165 if (wep_key_len > 0)
\r
3167 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
3168 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
\r
3169 pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
\r
3171 DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
\r
3176 _rtw_memset(pwep, 0, wep_total_len);
\r
3178 pwep->KeyLength = wep_key_len;
\r
3179 pwep->Length = wep_total_len;
\r
3181 if(wep_key_len==13)
\r
3183 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
\r
3184 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
\r
3192 pwep->KeyIndex = wep_key_idx;
\r
3193 pwep->KeyIndex |= 0x80000000;
\r
3195 _rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
\r
3197 if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
\r
3199 ret = -EOPNOTSUPP ;
\r
3203 rtw_mfree((u8 *)pwep,wep_total_len);
\r
3210 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
\r
3214 if (sme->crypto.n_akm_suites) {
\r
3215 ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
\r
3220 #ifdef CONFIG_WAPI_SUPPORT
\r
3221 if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_PSK){
\r
3222 padapter->wapiInfo.bWapiPSK = true;
\r
3224 else if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_CERT){
\r
3225 padapter->wapiInfo.bWapiPSK = false;
\r
3229 authmode = psecuritypriv->ndisauthtype;
\r
3230 rtw_set_802_11_authentication_mode(padapter, authmode);
\r
3232 //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
\r
3234 if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid) == _FALSE) {
\r
3239 DBG_8192C("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy);
\r
3243 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
\r
3245 DBG_8192C("<=%s, ret %d\n",__FUNCTION__, ret);
\r
3247 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3252 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
\r
3255 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3257 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3259 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
3261 rtw_set_to_roam(padapter, 0);
\r
3263 //if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
3265 rtw_scan_abort(padapter);
\r
3266 LeaveAllPowerSaveMode(padapter);
\r
3267 rtw_disassoc_cmd(padapter, 500, _FALSE);
\r
3269 DBG_871X("%s...call rtw_indicate_disconnect\n", __FUNCTION__);
\r
3271 rtw_indicate_disconnect(padapter);
\r
3273 rtw_free_assoc_resources(padapter, 1);
\r
3274 rtw_pwr_wakeup(padapter);
\r
3277 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3279 DBG_871X(FUNC_NDEV_FMT" return 0\n", FUNC_NDEV_ARG(ndev));
\r
3283 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
\r
3284 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
\r
3285 struct wireless_dev *wdev,
\r
3287 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE)
\r
3288 enum nl80211_tx_power_setting type, int mbm)
\r
3290 enum tx_power_setting type, int dbm)
\r
3294 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
\r
3298 case NL80211_TX_POWER_AUTOMATIC:
\r
3300 case NL80211_TX_POWER_FIXED:
\r
3301 if (mbm < 0 || (mbm % 100))
\r
3302 return -EOPNOTSUPP;
\r
3304 if (!test_bit(IWM_STATUS_READY, &iwm->status))
\r
3307 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
\r
3308 CFG_TX_PWR_LIMIT_USR,
\r
3309 MBM_TO_DBM(mbm) * 2);
\r
3313 return iwm_tx_power_trigger(iwm);
\r
3315 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
\r
3316 return -EOPNOTSUPP;
\r
3319 DBG_8192C("%s\n", __func__);
\r
3323 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
\r
3324 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
\r
3325 struct wireless_dev *wdev,
\r
3329 DBG_8192C("%s\n", __func__);
\r
3336 inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
\r
3338 struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter);
\r
3339 return rtw_wdev_priv->power_mgmt;
\r
3342 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
\r
3343 struct net_device *ndev,
\r
3344 bool enabled, int timeout)
\r
3346 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3347 struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter);
\r
3349 DBG_871X(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
\r
3350 enabled, timeout);
\r
3352 rtw_wdev_priv->power_mgmt = enabled;
\r
3356 LPS_Leave(padapter, "CFG80211_PWRMGMT");
\r
3362 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
\r
3363 struct net_device *ndev,
\r
3364 struct cfg80211_pmksa *pmksa)
\r
3366 u8 index,blInserted = _FALSE;
\r
3367 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3368 struct mlme_priv *mlme = &padapter->mlmepriv;
\r
3369 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3370 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
\r
3372 DBG_871X(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
\r
3373 , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
\r
3375 if ( _rtw_memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
\r
3380 if (check_fwstate(mlme, _FW_LINKED) == _FALSE) {
\r
3381 DBG_871X(FUNC_NDEV_FMT" not set pmksa cause not in linked state\n", FUNC_NDEV_ARG(ndev));
\r
3385 blInserted = _FALSE;
\r
3388 for(index=0 ; index<NUM_PMKID_CACHE; index++)
\r
3390 if( _rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) ==_TRUE )
\r
3391 { // BSSID is matched, the same AP => rewrite with new PMKID.
\r
3392 DBG_871X(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(ndev));
\r
3394 _rtw_memcpy( psecuritypriv->PMKIDList[index].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
\r
3395 psecuritypriv->PMKIDList[index].bUsed = _TRUE;
\r
3396 psecuritypriv->PMKIDIndex = index+1;
\r
3397 blInserted = _TRUE;
\r
3404 // Find a new entry
\r
3405 DBG_871X(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
\r
3406 FUNC_NDEV_ARG(ndev), psecuritypriv->PMKIDIndex );
\r
3408 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, (u8 *)pmksa->bssid, ETH_ALEN);
\r
3409 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, (u8 *)pmksa->pmkid, WLAN_PMKID_LEN);
\r
3411 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
\r
3412 psecuritypriv->PMKIDIndex++ ;
\r
3413 if(psecuritypriv->PMKIDIndex==16)
\r
3415 psecuritypriv->PMKIDIndex =0;
\r
3422 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
\r
3423 struct net_device *ndev,
\r
3424 struct cfg80211_pmksa *pmksa)
\r
3426 u8 index, bMatched = _FALSE;
\r
3427 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3428 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3430 DBG_871X(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
\r
3431 , MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
\r
3433 for(index=0 ; index<NUM_PMKID_CACHE; index++)
\r
3435 if( _rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) ==_TRUE )
\r
3436 { // BSSID is matched, the same AP => Remove this PMKID information and reset it.
\r
3437 _rtw_memset(psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN );
\r
3438 _rtw_memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN );
\r
3439 psecuritypriv->PMKIDList[index].bUsed = _FALSE;
\r
3441 DBG_871X(FUNC_NDEV_FMT" clear id:%hhu\n", FUNC_NDEV_ARG(ndev), index);
\r
3446 if(_FALSE == bMatched)
\r
3448 DBG_871X(FUNC_NDEV_FMT" do not have matched BSSID\n"
\r
3449 , FUNC_NDEV_ARG(ndev));
\r
3456 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
\r
3457 struct net_device *ndev)
\r
3459 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3460 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3462 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3464 _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
\r
3465 psecuritypriv->PMKIDIndex = 0;
\r
3470 #ifdef CONFIG_AP_MODE
\r
3471 void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
3475 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
3476 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3477 struct net_device *ndev = padapter->pnetdev;
\r
3479 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
3481 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
\r
3483 struct station_info sinfo;
\r
3485 if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
\r
3486 ie_offset = _ASOCREQ_IE_OFFSET_;
\r
3487 else // WIFI_REASSOCREQ
\r
3488 ie_offset = _REASOCREQ_IE_OFFSET_;
\r
3491 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
\r
3492 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
\r
3493 sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
\r
3494 cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
\r
3496 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3497 channel = pmlmeext->cur_channel;
\r
3498 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
3499 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
3501 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
3503 #ifdef COMPAT_KERNEL_RELEASE
\r
3504 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3505 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
3506 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3507 #else //COMPAT_KERNEL_RELEASE
\r
3509 //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc()
\r
3510 #ifndef CONFIG_PLATFORM_MSTAR
\r
3511 pwdev->iftype = NL80211_IFTYPE_STATION;
\r
3512 #endif //CONFIG_PLATFORM_MSTAR
\r
3513 DBG_8192C("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
\r
3514 rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
\r
3515 DBG_8192C("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
\r
3516 pwdev->iftype = NL80211_IFTYPE_AP;
\r
3517 //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3519 #endif //COMPAT_KERNEL_RELEASE
\r
3520 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3524 void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason)
\r
3530 struct rtw_ieee80211_hdr *pwlanhdr;
\r
3531 unsigned short *fctrl;
\r
3532 u8 mgmt_buf[128] = {0};
\r
3533 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3534 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
3535 struct net_device *ndev = padapter->pnetdev;
\r
3537 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
3539 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
\r
3540 cfg80211_del_sta(ndev, da, GFP_ATOMIC);
\r
3541 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3542 channel = pmlmeext->cur_channel;
\r
3543 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
3544 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
3546 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
3548 pmgmt_frame = mgmt_buf;
\r
3549 pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
\r
3551 fctrl = &(pwlanhdr->frame_ctl);
\r
3554 //_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
\r
3555 //_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
3556 _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
3557 _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN);
\r
3558 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
3560 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
3561 pmlmeext->mgnt_seq++;
\r
3562 SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
\r
3564 pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
3565 frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
3567 reason = cpu_to_le16(reason);
\r
3568 pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
\r
3570 #ifdef COMPAT_KERNEL_RELEASE
\r
3571 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3572 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
3573 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3574 #else //COMPAT_KERNEL_RELEASE
\r
3575 cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len);
\r
3576 //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3577 #endif //COMPAT_KERNEL_RELEASE
\r
3578 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3581 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
\r
3585 DBG_8192C("%s\n", __func__);
\r
3590 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
\r
3594 DBG_8192C("%s\n", __func__);
\r
3599 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
\r
3604 int dot11_hdr_len = 24;
\r
3606 unsigned char *pdata;
\r
3608 unsigned char src_mac_addr[6];
\r
3609 unsigned char dst_mac_addr[6];
\r
3610 struct ieee80211_hdr *dot11_hdr;
\r
3611 struct ieee80211_radiotap_header *rtap_hdr;
\r
3612 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3614 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3617 rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
\r
3619 if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
\r
3622 rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
\r
3623 if (unlikely(rtap_hdr->it_version))
\r
3626 rtap_len = ieee80211_get_radiotap_len(skb->data);
\r
3627 if (unlikely(skb->len < rtap_len))
\r
3630 if(rtap_len != 14)
\r
3632 DBG_8192C("radiotap len (should be 14): %d\n", rtap_len);
\r
3636 /* Skip the ratio tap header */
\r
3637 skb_pull(skb, rtap_len);
\r
3639 dot11_hdr = (struct ieee80211_hdr *)skb->data;
\r
3640 frame_ctl = le16_to_cpu(dot11_hdr->frame_control);
\r
3641 /* Check if the QoS bit is set */
\r
3642 if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
\r
3643 /* Check if this ia a Wireless Distribution System (WDS) frame
\r
3644 * which has 4 MAC addresses
\r
3646 if (dot11_hdr->frame_control & 0x0080)
\r
3648 if ((dot11_hdr->frame_control & 0x0300) == 0x0300)
\r
3649 dot11_hdr_len += 6;
\r
3651 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
\r
3652 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
\r
3654 /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
\r
3655 * for two MAC addresses
\r
3657 skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
\r
3658 pdata = (unsigned char*)skb->data;
\r
3659 memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
\r
3660 memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
\r
3662 DBG_8192C("should be eapol packet\n");
\r
3664 /* Use the real net device to transmit the packet */
\r
3665 ret = _rtw_xmit_entry(skb, padapter->pnetdev);
\r
3670 else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE))
\r
3671 == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION)
\r
3674 //only for action frames
\r
3675 struct xmit_frame *pmgntframe;
\r
3676 struct pkt_attrib *pattrib;
\r
3677 unsigned char *pframe;
\r
3678 //u8 category, action, OUI_Subtype, dialogToken=0;
\r
3679 //unsigned char *frame_body;
\r
3680 struct rtw_ieee80211_hdr *pwlanhdr;
\r
3681 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
3682 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3683 u8 *buf = skb->data;
\r
3684 u32 len = skb->len;
\r
3685 u8 category, action;
\r
3688 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
\r
3689 DBG_8192C(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
\r
3690 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
\r
3694 DBG_8192C("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
\r
3695 MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
\r
3697 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0)
\r
3700 if (category == RTW_WLAN_CATEGORY_PUBLIC)
\r
3701 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
\r
3703 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
\r
3706 //starting alloc mgmt frame to dump it
\r
3707 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
3712 //update attribute
\r
3713 pattrib = &pmgntframe->attrib;
\r
3714 update_mgntframe_attrib(padapter, pattrib);
\r
3715 pattrib->retry_ctrl = _FALSE;
\r
3717 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
3719 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
3721 _rtw_memcpy(pframe, (void*)buf, len);
\r
3725 struct wifi_display_info *pwfd_info;
\r
3727 pwfd_info = padapter->wdinfo.wfd_info;
\r
3729 if ( _TRUE == pwfd_info->wfd_enable )
\r
3731 rtw_append_wfd_ie( padapter, pframe, &len );
\r
3734 #endif // CONFIG_WFD
\r
3735 pattrib->pktlen = len;
\r
3737 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
3738 //update seq number
\r
3739 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
\r
3740 pattrib->seqnum = pmlmeext->mgnt_seq;
\r
3741 pmlmeext->mgnt_seq++;
\r
3744 pattrib->last_txcmdsz = pattrib->pktlen;
\r
3746 dump_mgntframe(padapter, pmgntframe);
\r
3751 DBG_8192C("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE));
\r
3757 rtw_skb_free(skb);
\r
3763 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
\r
3765 DBG_8192C("%s\n", __func__);
\r
3768 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
\r
3772 DBG_8192C("%s\n", __func__);
\r
3777 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
\r
3778 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
\r
3779 .ndo_open = rtw_cfg80211_monitor_if_open,
\r
3780 .ndo_stop = rtw_cfg80211_monitor_if_close,
\r
3781 .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
\r
3782 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
\r
3783 .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
\r
3785 .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
\r
3789 static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
\r
3792 struct net_device* mon_ndev = NULL;
\r
3793 struct wireless_dev* mon_wdev = NULL;
\r
3794 struct rtw_netdev_priv_indicator *pnpi;
\r
3795 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
3798 DBG_871X(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
\r
3803 if (pwdev_priv->pmon_ndev) {
\r
3804 DBG_871X(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
\r
3805 FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
\r
3810 mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
\r
3812 DBG_871X(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
\r
3817 mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
\r
3818 strncpy(mon_ndev->name, name, IFNAMSIZ);
\r
3819 mon_ndev->name[IFNAMSIZ - 1] = 0;
\r
3820 mon_ndev->destructor = rtw_ndev_destructor;
\r
3822 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
\r
3823 mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
\r
3825 mon_ndev->open = rtw_cfg80211_monitor_if_open;
\r
3826 mon_ndev->stop = rtw_cfg80211_monitor_if_close;
\r
3827 mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry;
\r
3828 mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address;
\r
3831 pnpi = netdev_priv(mon_ndev);
\r
3832 pnpi->priv = padapter;
\r
3833 pnpi->sizeof_priv = sizeof(_adapter);
\r
3836 mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
\r
3838 DBG_871X(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
\r
3843 mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
\r
3844 mon_wdev->netdev = mon_ndev;
\r
3845 mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
\r
3846 mon_ndev->ieee80211_ptr = mon_wdev;
\r
3848 ret = register_netdevice(mon_ndev);
\r
3853 *ndev = pwdev_priv->pmon_ndev = mon_ndev;
\r
3854 _rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
\r
3857 if (ret && mon_wdev) {
\r
3858 rtw_mfree((u8*)mon_wdev, sizeof(struct wireless_dev));
\r
3862 if (ret && mon_ndev) {
\r
3863 free_netdev(mon_ndev);
\r
3864 *ndev = mon_ndev = NULL;
\r
3870 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3871 static struct wireless_dev *
\r
3872 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
3873 static struct net_device *
\r
3877 cfg80211_rtw_add_virtual_intf(
\r
3878 struct wiphy *wiphy,
\r
3879 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
\r
3884 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
\r
3887 struct net_device* ndev = NULL;
\r
3888 _adapter *padapter = wiphy_to_adapter(wiphy);
\r
3890 DBG_871X(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
\r
3891 FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
\r
3894 case NL80211_IFTYPE_ADHOC:
\r
3895 case NL80211_IFTYPE_AP_VLAN:
\r
3896 case NL80211_IFTYPE_WDS:
\r
3897 case NL80211_IFTYPE_MESH_POINT:
\r
3900 case NL80211_IFTYPE_MONITOR:
\r
3901 ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
\r
3904 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
3905 case NL80211_IFTYPE_P2P_CLIENT:
\r
3907 case NL80211_IFTYPE_STATION:
\r
3911 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
3912 case NL80211_IFTYPE_P2P_GO:
\r
3914 case NL80211_IFTYPE_AP:
\r
3919 DBG_871X("Unsupported interface type\n");
\r
3923 DBG_871X(FUNC_ADPT_FMT" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter), ndev, ret);
\r
3925 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3926 return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
\r
3927 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
3928 return ndev ? ndev : ERR_PTR(ret);
\r
3934 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
\r
3935 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3936 struct wireless_dev *wdev
\r
3938 struct net_device *ndev
\r
3942 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3943 struct net_device *ndev = wdev_to_ndev(wdev);
\r
3946 _adapter *adapter;
\r
3947 struct rtw_wdev_priv *pwdev_priv;
\r
3954 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3955 pwdev_priv = adapter_wdev_data(adapter);
\r
3957 unregister_netdevice(ndev);
\r
3959 if (ndev == pwdev_priv->pmon_ndev) {
\r
3960 pwdev_priv->pmon_ndev = NULL;
\r
3961 pwdev_priv->ifname_mon[0] = '\0';
\r
3962 DBG_871X(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev));
\r
3969 static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
\r
3973 uint len, wps_ielen=0;
\r
3976 u8 got_p2p_ie = _FALSE;
\r
3977 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
3978 //struct sta_priv *pstapriv = &padapter->stapriv;
\r
3981 DBG_8192C("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
\r
3984 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
\r
3991 pbuf = rtw_zmalloc(head_len+tail_len);
\r
3996 //_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
\r
3998 //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
\r
3999 // pstapriv->max_num_sta = NUM_STA;
\r
4002 _rtw_memcpy(pbuf, (void *)head+24, head_len-24);// 24=beacon header len.
\r
4003 _rtw_memcpy(pbuf+head_len-24, (void *)tail, tail_len);
\r
4005 len = head_len+tail_len-24;
\r
4007 //check wps ie if inclued
\r
4008 if(rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
\r
4009 DBG_8192C("add bcn, wps_ielen=%d\n", wps_ielen);
\r
4012 if( adapter->wdinfo.driver_interface == DRIVER_CFG80211 )
\r
4014 //check p2p if enable
\r
4015 if(rtw_get_p2p_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &p2p_ielen))
\r
4017 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
\r
4018 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
\r
4020 DBG_8192C("got p2p_ie, len=%d\n", p2p_ielen);
\r
4022 got_p2p_ie = _TRUE;
\r
4024 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4026 DBG_8192C("Enable P2P function for the first time\n");
\r
4027 rtw_p2p_enable(adapter, P2P_ROLE_GO);
\r
4028 adapter_wdev_data(adapter)->p2p_enabled = _TRUE;
\r
4030 adapter->stapriv.expire_to = 3; // 3x2 = 6 sec in p2p mode
\r
4034 DBG_8192C("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);
\r
4036 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
\r
4037 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
\r
4038 pwdinfo->intent = 15;
\r
4042 #endif // CONFIG_P2P
\r
4044 /* pbss_network->IEs will not include p2p_ie, wfd ie */
\r
4045 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
\r
4046 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
\r
4048 if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS)
\r
4050 #ifdef CONFIG_P2P
\r
4051 //check p2p if enable
\r
4052 if(got_p2p_ie == _TRUE)
\r
4054 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
\r
4055 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
\r
4056 pwdinfo->operating_channel = pmlmeext->cur_channel;
\r
4058 #endif //CONFIG_P2P
\r
4067 rtw_mfree(pbuf, head_len+tail_len);
\r
4072 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE)
\r
4073 static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4074 struct beacon_parameters *info)
\r
4077 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4079 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4080 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
\r
4085 static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4086 struct beacon_parameters *info)
\r
4088 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4089 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
4091 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4093 pmlmeext->bstart_bss = _TRUE;
\r
4095 cfg80211_rtw_add_beacon(wiphy, ndev, info);
\r
4100 static int cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
\r
4102 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4107 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
\r
4108 struct cfg80211_ap_settings *settings)
\r
4111 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4113 DBG_871X(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
\r
4114 settings->hidden_ssid, settings->auth_type);
\r
4116 ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
\r
4117 settings->beacon.tail, settings->beacon.tail_len);
\r
4119 adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
\r
4121 if (settings->ssid && settings->ssid_len) {
\r
4122 WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
\r
4123 WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
\r
4126 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%zu), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
\r
4127 settings->ssid, settings->ssid_len,
\r
4128 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
\r
4130 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
\r
4131 pbss_network->Ssid.SsidLength = settings->ssid_len;
\r
4132 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
\r
4133 pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
\r
4136 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
\r
4137 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
\r
4138 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
\r
4144 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4145 struct cfg80211_beacon_data *info)
\r
4148 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4150 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4152 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
\r
4157 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
\r
4159 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4163 #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
\r
4165 static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4166 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
4171 struct station_parameters *params)
\r
4173 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4178 static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4179 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
4188 _list *phead, *plist;
\r
4189 u8 updated = _FALSE;
\r
4190 struct sta_info *psta = NULL;
\r
4191 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4192 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
4193 struct sta_priv *pstapriv = &padapter->stapriv;
\r
4195 DBG_871X("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4197 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
\r
4199 DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
\r
4206 DBG_8192C("flush all sta, and cam_entry\n");
\r
4208 flush_all_cam_entry(padapter); //clear CAM
\r
4210 ret = rtw_sta_flush(padapter);
\r
4216 DBG_8192C("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
\r
4218 if (mac[0] == 0xff && mac[1] == 0xff &&
\r
4219 mac[2] == 0xff && mac[3] == 0xff &&
\r
4220 mac[4] == 0xff && mac[5] == 0xff)
\r
4226 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4228 phead = &pstapriv->asoc_list;
\r
4229 plist = get_next(phead);
\r
4231 //check asoc_queue
\r
4232 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
4234 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
4236 plist = get_next(plist);
\r
4238 if(_rtw_memcmp((u8 *)mac, psta->hwaddr, ETH_ALEN))
\r
4240 if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE)
\r
4242 DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
\r
4246 DBG_8192C("free psta=%p, aid=%d\n", psta, psta->aid);
\r
4248 rtw_list_delete(&psta->asoc_list);
\r
4249 pstapriv->asoc_list_cnt--;
\r
4251 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4252 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
\r
4253 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4264 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4266 associated_clients_update(padapter, updated);
\r
4268 DBG_871X("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4274 static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4275 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0))
\r
4280 struct station_parameters *params)
\r
4282 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4287 struct sta_info *rtw_sta_info_get_by_idx(const int idx, struct sta_priv *pstapriv)
\r
4290 _list *phead, *plist;
\r
4291 struct sta_info *psta = NULL;
\r
4294 phead = &pstapriv->asoc_list;
\r
4295 plist = get_next(phead);
\r
4297 //check asoc_queue
\r
4298 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
4300 if(idx == i) psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
4301 plist = get_next(plist);
\r
4307 static int cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4308 int idx, u8 *mac, struct station_info *sinfo)
\r
4313 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4314 struct sta_info *psta = NULL;
\r
4315 struct sta_priv *pstapriv = &padapter->stapriv;
\r
4316 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4318 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4319 psta = rtw_sta_info_get_by_idx(idx, pstapriv);
\r
4320 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4323 DBG_871X("Station is not found\n");
\r
4327 _rtw_memcpy(mac, psta->hwaddr, ETH_ALEN);
\r
4328 sinfo->filled = 0;
\r
4329 sinfo->filled |= STATION_INFO_SIGNAL;
\r
4330 sinfo->signal = psta->rssi;
\r
4336 static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
\r
4337 struct bss_parameters *params)
\r
4341 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4343 DBG_8192C("use_cts_prot=%d\n", params->use_cts_prot);
\r
4344 DBG_8192C("use_short_preamble=%d\n", params->use_short_preamble);
\r
4345 DBG_8192C("use_short_slot_time=%d\n", params->use_short_slot_time);
\r
4346 DBG_8192C("ap_isolate=%d\n", params->ap_isolate);
\r
4348 DBG_8192C("basic_rates_len=%d\n", params->basic_rates_len);
\r
4349 for(i=0; i<params->basic_rates_len; i++)
\r
4351 DBG_8192C("basic_rates=%d\n", params->basic_rates[i]);
\r
4359 static int cfg80211_rtw_set_channel(struct wiphy *wiphy
\r
4360 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
\r
4361 , struct net_device *ndev
\r
4363 , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
\r
4365 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
\r
4366 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4372 static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
\r
4373 struct cfg80211_auth_request *req)
\r
4375 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4380 static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
\r
4381 struct cfg80211_assoc_request *req)
\r
4383 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4387 #endif //CONFIG_AP_MODE
\r
4389 void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
4394 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4395 u8 category, action;
\r
4397 channel = rtw_get_oper_ch(padapter);
\r
4399 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4401 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
\r
4405 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
\r
4406 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4409 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4410 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4412 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4414 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4415 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4417 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4421 void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
4426 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4427 u8 category, action;
\r
4429 channel = rtw_get_oper_ch(padapter);
\r
4431 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4433 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
\r
4436 case P2P_GO_NEGO_CONF:
\r
4437 case P2P_PROVISION_DISC_RESP:
\r
4438 case P2P_INVIT_RESP:
\r
4439 rtw_set_scan_deny(padapter, 2000);
\r
4440 rtw_clear_scan_deny(padapter);
\r
4445 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
\r
4446 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4449 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4450 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4452 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4454 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4455 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4457 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4461 void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg)
\r
4465 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
4466 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
4467 u8 category, action;
\r
4469 channel = rtw_get_oper_ch(adapter);
\r
4471 rtw_action_frame_parse(frame, frame_len, &category, &action);
\r
4473 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4475 DBG_871X("RTW_Rx:%s\n", msg);
\r
4477 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4479 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4480 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4482 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4484 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4485 rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
\r
4487 cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
\r
4493 void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
\r
4495 u16 wps_devicepassword_id = 0x0000;
\r
4496 uint wps_devicepassword_id_len = 0;
\r
4497 u8 wpsie[ 255 ] = { 0x00 }, p2p_ie[ 255 ] = { 0x00 };
\r
4498 uint p2p_ielen = 0;
\r
4499 uint wpsielen = 0;
\r
4500 u32 devinfo_contentlen = 0;
\r
4501 u8 devinfo_content[64] = { 0x00 };
\r
4502 u16 capability = 0;
\r
4503 uint capability_len = 0;
\r
4505 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
\r
4506 u8 action = P2P_PUB_ACTION_ACTION;
\r
4507 u8 dialogToken = 1;
\r
4508 u32 p2poui = cpu_to_be32(P2POUI);
\r
4509 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
\r
4513 #endif //CONFIG_WFD
\r
4515 struct xmit_frame *pmgntframe;
\r
4516 struct pkt_attrib *pattrib;
\r
4517 unsigned char *pframe;
\r
4518 struct rtw_ieee80211_hdr *pwlanhdr;
\r
4519 unsigned short *fctrl;
\r
4520 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
4521 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4522 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
4524 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
\r
4525 u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
\r
4526 size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4529 DBG_871X( "[%s] In\n", __FUNCTION__ );
\r
4531 //prepare for building provision_request frame
\r
4532 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
\r
4533 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
\r
4535 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
\r
4537 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
\r
4538 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
\r
4539 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
\r
4541 switch(wps_devicepassword_id)
\r
4543 case WPS_DPID_PIN:
\r
4544 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
\r
4546 case WPS_DPID_USER_SPEC:
\r
4547 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
\r
4549 case WPS_DPID_MACHINE_SPEC:
\r
4551 case WPS_DPID_REKEY:
\r
4553 case WPS_DPID_PBC:
\r
4554 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
\r
4556 case WPS_DPID_REGISTRAR_SPEC:
\r
4557 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
\r
4564 if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) )
\r
4567 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);
\r
4568 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&capability, &capability_len);
\r
4573 //start to build provision_request frame
\r
4574 _rtw_memset(wpsie, 0, sizeof(wpsie));
\r
4575 _rtw_memset(p2p_ie, 0, sizeof(p2p_ie));
\r
4578 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
4584 //update attribute
\r
4585 pattrib = &pmgntframe->attrib;
\r
4586 update_mgntframe_attrib(padapter, pattrib);
\r
4588 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
4590 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
4591 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
4593 fctrl = &(pwlanhdr->frame_ctl);
\r
4596 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
\r
4597 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
4598 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
\r
4600 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
4601 pmlmeext->mgnt_seq++;
\r
4602 SetFrameSubType(pframe, WIFI_ACTION);
\r
4604 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4605 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4607 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
4608 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
4609 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
\r
4610 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
\r
4611 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
\r
4614 //build_prov_disc_request_p2p_ie
\r
4617 p2p_ie[ p2pielen++ ] = 0x50;
\r
4618 p2p_ie[ p2pielen++ ] = 0x6F;
\r
4619 p2p_ie[ p2pielen++ ] = 0x9A;
\r
4620 p2p_ie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
\r
4622 // Commented by Albert 20110301
\r
4623 // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
\r
4624 // 1. P2P Capability
\r
4626 // 3. Group ID ( When joining an operating P2P Group )
\r
4628 // P2P Capability ATTR
\r
4630 p2p_ie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
\r
4633 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
\r
4634 RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
\r
4638 // Device Capability Bitmap, 1 byte
\r
4639 // Group Capability Bitmap, 1 byte
\r
4640 _rtw_memcpy(p2p_ie + p2pielen, &capability, 2);
\r
4644 // Device Info ATTR
\r
4646 p2p_ie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
\r
4649 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
\r
4650 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
\r
4651 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
\r
4652 RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
\r
4656 _rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
\r
4657 p2pielen += devinfo_contentlen;
\r
4660 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);
\r
4661 //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr);
\r
4662 //pframe += p2pielen;
\r
4663 pattrib->pktlen += p2p_ielen;
\r
4667 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
\r
4672 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
\r
4676 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
\r
4680 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
\r
4684 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
\r
4688 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
\r
4692 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
\r
4695 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
\r
4699 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
\r
4700 pframe += wfdielen;
\r
4701 pattrib->pktlen += wfdielen;
\r
4702 #endif //CONFIG_WFD
\r
4704 pattrib->last_txcmdsz = pattrib->pktlen;
\r
4706 //dump_mgntframe(padapter, pmgntframe);
\r
4707 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
\r
4708 DBG_8192C("%s, ack to\n", __func__);
\r
4710 //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
\r
4712 // DBG_8192C("waiting for p2p peer key-in PIN CODE\n");
\r
4713 // rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req.
\r
4718 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
\r
4719 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4720 struct wireless_dev *wdev,
\r
4722 struct net_device *ndev,
\r
4724 struct ieee80211_channel * channel,
\r
4725 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
4726 enum nl80211_channel_type channel_type,
\r
4728 unsigned int duration, u64 *cookie)
\r
4730 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4731 struct net_device *ndev = wdev_to_ndev(wdev);
\r
4734 u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
\r
4735 u8 ready_on_channel = _FALSE;
\r
4736 _adapter *padapter;
\r
4737 struct rtw_wdev_priv *pwdev_priv;
\r
4738 struct mlme_ext_priv *pmlmeext;
\r
4739 struct wifidirect_info *pwdinfo;
\r
4740 struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
\r
4741 u8 is_p2p_find = _FALSE;
\r
4743 if (ndev == NULL) {
\r
4747 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4748 pwdev_priv = adapter_wdev_data(padapter);
\r
4749 pmlmeext = &padapter->mlmeextpriv;
\r
4750 pwdinfo = &padapter->wdinfo;
\r
4751 pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
4752 #ifdef CONFIG_CONCURRENT_MODE
\r
4753 is_p2p_find=(duration < (pwdinfo->ext_listen_interval))? _TRUE : _FALSE;
\r
4755 DBG_871X(FUNC_ADPT_FMT" ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter), remain_ch, duration);
\r
4757 if(pcfg80211_wdinfo->is_ro_ch == _TRUE)
\r
4759 pcfg80211_wdinfo->not_indic_ro_ch_exp = _TRUE;
\r
4760 DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
4761 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
4762 #ifdef CONFIG_CONCURRENT_MODE
\r
4763 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
4764 #endif //CONFIG_CONCURRENT_MODE
\r
4765 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
\r
4766 pcfg80211_wdinfo->not_indic_ro_ch_exp = _FALSE;
\r
4769 pcfg80211_wdinfo->is_ro_ch = _TRUE;
\r
4770 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
4772 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
4777 _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
\r
4778 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
4779 pcfg80211_wdinfo->remain_on_ch_type= channel_type;
\r
4781 pcfg80211_wdinfo->remain_on_ch_cookie= *cookie;
\r
4783 rtw_scan_abort(padapter);
\r
4784 #ifdef CONFIG_CONCURRENT_MODE
\r
4785 if ((rtw_buddy_adapter_up(padapter)) && is_p2p_find) //don't scan_abort during p2p_listen.
\r
4786 rtw_scan_abort(padapter->pbuddy_adapter);
\r
4787 #endif //CONFIG_CONCURRENT_MODE
\r
4789 if (check_fwstate(&padapter->mlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
\r
4791 DBG_871X("mlme state:0x%x\n", get_fwstate(&padapter->mlmepriv));
\r
4792 remain_ch = padapter->mlmeextpriv.cur_channel;
\r
4794 #ifdef CONFIG_CONCURRENT_MODE
\r
4795 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
\r
4797 DBG_871X("buddy_intf's mlme state:0x%x\n", get_fwstate(&(padapter->pbuddy_adapter->mlmepriv)));
\r
4798 remain_ch = padapter->pbuddy_adapter->mlmeextpriv.cur_channel;
\r
4800 #endif /* CONFIG_CONCURRENT_MODE */
\r
4802 //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
4803 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4805 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
\r
4806 adapter_wdev_data(padapter)->p2p_enabled = _TRUE;
\r
4807 padapter->wdinfo.listen_channel = remain_ch;
\r
4811 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
4812 #ifdef CONFIG_DEBUG_CFG80211
\r
4813 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
4818 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
\r
4821 if(duration < 400)
\r
4822 duration = duration*3;//extend from exper.
\r
4825 #ifdef CONFIG_CONCURRENT_MODE
\r
4826 if (check_buddy_fwstate(padapter, _FW_LINKED))
\r
4828 if (is_p2p_find) // p2p_find , duration<1000
\r
4829 duration = duration + pwdinfo->ext_listen_interval;
\r
4830 else // p2p_listen, duration=5000
\r
4831 duration = pwdinfo->ext_listen_interval
\r
4832 + (pwdinfo->ext_listen_interval/4);
\r
4836 pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter);
\r
4838 if(rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) >= 0) {
\r
4839 #ifdef CONFIG_CONCURRENT_MODE
\r
4840 if ( check_buddy_fwstate(padapter, _FW_LINKED) )
\r
4842 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
\r
4843 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
4845 if((remain_ch != pbuddy_mlmeext->cur_channel) && !check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
4847 if(ATOMIC_READ(&pwdev_priv->switch_ch_to)==1 ||
\r
4848 (remain_ch != pmlmeext->cur_channel))
\r
4850 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
\r
4851 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
\r
4853 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
\r
4855 DBG_8192C("%s, set switch ch timer, duration=%d\n", __func__, duration-pwdinfo->ext_listen_interval);
\r
4856 _set_timer(&pwdinfo->ap_p2p_switch_timer, duration-pwdinfo->ext_listen_interval);
\r
4860 ready_on_channel = _TRUE;
\r
4861 //pmlmeext->cur_channel = remain_ch;
\r
4862 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4864 #endif //CONFIG_CONCURRENT_MODE
\r
4865 if(remain_ch != rtw_get_oper_ch(padapter) )
\r
4867 ready_on_channel = _TRUE;
\r
4868 //pmlmeext->cur_channel = remain_ch;
\r
4869 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4872 DBG_871X("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__, remain_ch);
\r
4876 //call this after other things have been done
\r
4877 #ifdef CONFIG_CONCURRENT_MODE
\r
4878 if(ATOMIC_READ(&pwdev_priv->ro_ch_to)==1 ||
\r
4879 (remain_ch != rtw_get_oper_ch(padapter)))
\r
4881 u8 co_channel = 0xff;
\r
4882 ATOMIC_SET(&pwdev_priv->ro_ch_to, 0);
\r
4885 if(ready_on_channel == _TRUE)
\r
4887 if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) )
\r
4889 pmlmeext->cur_channel = remain_ch;
\r
4891 #ifdef CONFIG_CONCURRENT_MODE
\r
4892 co_channel = rtw_get_oper_ch(padapter);
\r
4894 if(co_channel !=remain_ch)
\r
4897 //if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic)
\r
4898 set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4902 DBG_8192C("%s, set ro ch timer, duration=%d\n", __func__, duration);
\r
4903 _set_timer( &pcfg80211_wdinfo->remain_on_ch_timer, duration);
\r
4905 #ifdef CONFIG_CONCURRENT_MODE
\r
4909 rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type, duration, GFP_KERNEL);
\r
4913 pcfg80211_wdinfo->is_ro_ch = _FALSE;
\r
4914 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
4920 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
\r
4921 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4922 struct wireless_dev *wdev,
\r
4924 struct net_device *ndev,
\r
4928 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4929 struct net_device *ndev = wdev_to_ndev(wdev);
\r
4932 _adapter *padapter;
\r
4933 struct rtw_wdev_priv *pwdev_priv;
\r
4934 struct wifidirect_info *pwdinfo;
\r
4935 struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
\r
4937 if (ndev == NULL) {
\r
4942 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4943 pwdev_priv = adapter_wdev_data(padapter);
\r
4944 pwdinfo = &padapter->wdinfo;
\r
4945 pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
4947 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
4949 if (pcfg80211_wdinfo->is_ro_ch == _TRUE) {
\r
4950 pcfg80211_wdinfo->not_indic_ro_ch_exp = _TRUE;
\r
4951 DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
4952 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
4953 #ifdef CONFIG_CONCURRENT_MODE
\r
4954 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
4956 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
\r
4957 pcfg80211_wdinfo->not_indic_ro_ch_exp = _FALSE;
\r
4961 // Disable P2P Listen State
\r
4962 if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
4964 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4966 rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
\r
4967 _rtw_memset(pwdinfo, 0x00, sizeof(struct wifidirect_info));
\r
4973 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
4974 #ifdef CONFIG_DEBUG_CFG80211
\r
4975 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
4979 pcfg80211_wdinfo->is_ro_ch = _FALSE;
\r
4980 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
4986 #endif //CONFIG_P2P
\r
4988 static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, const u8 *buf, size_t len)
\r
4990 struct xmit_frame *pmgntframe;
\r
4991 struct pkt_attrib *pattrib;
\r
4992 unsigned char *pframe;
\r
4995 struct rtw_ieee80211_hdr *pwlanhdr;
\r
4996 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
4997 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
4998 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
4999 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
5001 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
\r
5002 #endif //CONFIG_P2P
\r
5003 //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
5005 rtw_set_scan_deny(padapter, 1000);
\r
5007 rtw_scan_abort(padapter);
\r
5008 #ifdef CONFIG_CONCURRENT_MODE
\r
5009 if(rtw_buddy_adapter_up(padapter))
\r
5010 rtw_scan_abort(padapter->pbuddy_adapter);
\r
5011 #endif /* CONFIG_CONCURRENT_MODE */
\r
5013 if (padapter->cfg80211_wdinfo.is_ro_ch == _TRUE) {
\r
5014 //DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
5015 //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
5016 //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE;
\r
5017 #ifdef CONFIG_CONCURRENT_MODE
\r
5018 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5020 DBG_8192C("%s, extend ro ch time\n", __func__);
\r
5021 _set_timer( &padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
\r
5023 #endif //CONFIG_CONCURRENT_MODE
\r
5025 #endif //CONFIG_P2P
\r
5026 #ifdef CONFIG_CONCURRENT_MODE
\r
5027 if (check_buddy_fwstate(padapter, _FW_LINKED )) {
\r
5028 u8 co_channel=0xff;
\r
5029 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
\r
5030 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
5032 co_channel = rtw_get_oper_ch(padapter);
\r
5034 if (tx_ch != pbuddy_mlmeext->cur_channel) {
\r
5036 u16 ext_listen_period;
\r
5038 if (ATOMIC_READ(&pwdev_priv->switch_ch_to)==1) {
\r
5039 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
\r
5040 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
\r
5042 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
\r
5044 //DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
\r
5045 //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
\r
5048 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5050 ext_listen_period = 500;// 500ms
\r
5054 ext_listen_period = pwdinfo->ext_listen_period;
\r
5057 DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period);
\r
5058 _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period);
\r
5062 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5063 pmlmeext->cur_channel = tx_ch;
\r
5065 if (tx_ch != co_channel)
\r
5066 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5068 #endif //CONFIG_CONCURRENT_MODE
\r
5069 //if (tx_ch != pmlmeext->cur_channel) {
\r
5070 if(tx_ch != rtw_get_oper_ch(padapter)) {
\r
5071 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
5072 pmlmeext->cur_channel = tx_ch;
\r
5073 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
5076 //starting alloc mgmt frame to dump it
\r
5077 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
5084 //update attribute
\r
5085 pattrib = &pmgntframe->attrib;
\r
5086 update_mgntframe_attrib(padapter, pattrib);
\r
5087 pattrib->retry_ctrl = _FALSE;
\r
5089 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
5091 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
5093 _rtw_memcpy(pframe, (void*)buf, len);
\r
5094 pattrib->pktlen = len;
\r
5096 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
5097 //update seq number
\r
5098 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
\r
5099 pattrib->seqnum = pmlmeext->mgnt_seq;
\r
5100 pmlmeext->mgnt_seq++;
\r
5104 struct wifi_display_info *pwfd_info;
\r
5106 pwfd_info = padapter->wdinfo.wfd_info;
\r
5108 if ( _TRUE == pwfd_info->wfd_enable )
\r
5110 rtw_append_wfd_ie( padapter, pframe, &pattrib->pktlen );
\r
5113 #endif // CONFIG_WFD
\r
5115 pattrib->last_txcmdsz = pattrib->pktlen;
\r
5117 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
\r
5122 #ifdef CONFIG_DEBUG_CFG80211
\r
5123 DBG_8192C("%s, ack == _FAIL\n", __func__);
\r
5129 #ifdef CONFIG_XMIT_ACK
\r
5130 rtw_msleep_os(50);
\r
5132 #ifdef CONFIG_DEBUG_CFG80211
\r
5133 DBG_8192C("%s, ack=%d, ok!\n", __func__, ack);
\r
5140 #ifdef CONFIG_DEBUG_CFG80211
\r
5141 DBG_8192C("%s, ret=%d\n", __func__, ret);
\r
5148 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
\r
5149 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5150 struct wireless_dev *wdev,
\r
5152 struct net_device *ndev,
\r
5154 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0)) || defined(COMPAT_KERNEL_RELEASE)
\r
5155 struct ieee80211_channel *chan,
\r
5156 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
5159 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5160 enum nl80211_channel_type channel_type,
\r
5161 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5162 bool channel_type_valid,
\r
5165 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
5166 unsigned int wait,
\r
5168 const u8 *buf, size_t len,
\r
5169 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5172 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
\r
5173 bool dont_wait_for_ack,
\r
5176 struct cfg80211_mgmt_tx_params *params,
\r
5180 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5181 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5183 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)) || defined(COMPAT_KERNEL_RELEASE)
\r
5184 struct ieee80211_channel *chan = params->chan;
\r
5185 bool offchan = params->offchan;
\r
5186 unsigned int wait = params->wait;
\r
5187 const u8 *buf = params->buf;
\r
5188 size_t len = params->len;
\r
5189 bool no_cck = params->no_cck;
\r
5190 bool dont_wait_for_ack = params->dont_wait_for_ack;
\r
5194 u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
\r
5197 u8 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
\r
5198 u8 category, action;
\r
5200 u32 start = rtw_get_current_time();
\r
5201 _adapter *padapter;
\r
5202 struct rtw_wdev_priv *pwdev_priv;
\r
5204 if (ndev == NULL) {
\r
5209 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5210 pwdev_priv = adapter_wdev_data(padapter);
\r
5212 /* cookie generation */
\r
5213 *cookie = (unsigned long) buf;
\r
5215 #ifdef CONFIG_DEBUG_CFG80211
\r
5216 DBG_871X(FUNC_ADPT_FMT" len=%zu, ch=%d"
\r
5217 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5219 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5220 ", channel_type_valid=%d"
\r
5223 "\n", FUNC_ADPT_ARG(padapter),
\r
5225 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5227 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5228 , channel_type_valid
\r
5232 #endif /* CONFIG_DEBUG_CFG80211 */
\r
5234 /* indicate ack before issue frame to avoid racing with rsp frame */
\r
5235 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5236 rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL);
\r
5237 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
\r
5238 cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
\r
5241 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
\r
5242 DBG_8192C(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
\r
5243 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
\r
5247 DBG_8192C("RTW_Tx:tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
\r
5249 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0) {
\r
5253 if (category == RTW_WLAN_CATEGORY_PUBLIC)
\r
5254 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
\r
5256 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
\r
5260 rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
\r
5261 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
5263 goto cancel_ps_deny;
\r
5268 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
\r
5269 } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
\r
5271 if (tx_ret != _SUCCESS || dump_cnt > 1) {
\r
5272 DBG_871X(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
\r
5273 tx_ret==_SUCCESS?"OK":"FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
\r
5277 case P2P_GO_NEGO_CONF:
\r
5278 rtw_clear_scan_deny(padapter);
\r
5280 case P2P_INVIT_RESP:
\r
5281 if (pwdev_priv->invit_info.flags & BIT(0)
\r
5282 && pwdev_priv->invit_info.status == 0)
\r
5284 DBG_871X(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
\r
5285 FUNC_ADPT_ARG(padapter));
\r
5286 rtw_set_scan_deny(padapter, 5000);
\r
5287 rtw_pwr_wakeup_ex(padapter, 5000);
\r
5288 rtw_clear_scan_deny(padapter);
\r
5294 rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
\r
5299 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
\r
5300 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
\r
5301 struct wireless_dev *wdev,
\r
5303 struct net_device *ndev,
\r
5305 u16 frame_type, bool reg)
\r
5307 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5308 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5310 _adapter *adapter;
\r
5315 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5317 #ifdef CONFIG_DEBUG_CFG80211
\r
5318 DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
\r
5322 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
\r
5328 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5329 static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy,
\r
5330 struct net_device *ndev,
\r
5338 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5340 struct tdls_txmgmt txmgmt;
\r
5342 //TDLS: discard wpa_supplicant's frame mgmt
\r
5343 DBG_871X("%s %d\n", __FUNCTION__, __LINE__);
\r
5346 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
5347 _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
\r
5348 txmgmt.action_code = action_code;
\r
5349 txmgmt.dialog_token= dialog_token;
\r
5350 txmgmt.status_code = status_code;
\r
5352 txmgmt.buf = (u8 *)rtw_malloc(txmgmt.len);
\r
5353 if (txmgmt.buf == NULL)
\r
5358 _rtw_memcpy(txmgmt.buf, (void*)buf, txmgmt.len);
\r
5359 txmgmt.external_support = _TRUE;
\r
5361 //TDLS: Debug purpose
\r
5363 DBG_871X("%s %d\n", __FUNCTION__, __LINE__);
\r
5364 DBG_871X("peer:"MAC_FMT" ", MAC_ARG(txmgmt.peer));
\r
5365 DBG_871X("action code:%d ", txmgmt.action_code);
\r
5366 DBG_871X("dialog:%d ", txmgmt.dialog_token);
\r
5367 DBG_871X("status code:%d\n", txmgmt.status_code);
\r
5368 if( txmgmt.len > 0 )
\r
5371 for(;i < len; i++)
\r
5372 DBG_871X("%02x ", *(txmgmt.buf+i));
\r
5373 DBG_871X("\n len:%d\n", txmgmt.len);
\r
5377 switch(txmgmt.action_code) {
\r
5378 case TDLS_SETUP_REQUEST:
\r
5379 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5381 case TDLS_SETUP_RESPONSE:
\r
5382 issue_tdls_setup_rsp(padapter, &txmgmt);
\r
5384 case TDLS_SETUP_CONFIRM:
\r
5385 issue_tdls_setup_cfm(padapter, &txmgmt);
\r
5387 case TDLS_TEARDOWN:
\r
5389 case TDLS_DISCOVERY_REQUEST:
\r
5390 issue_tdls_dis_req(padapter, &txmgmt);
\r
5397 rtw_mfree(txmgmt.buf, txmgmt.len);
\r
5403 static int cfg80211_rtw_tdls_oper(struct wiphy *wiphy,
\r
5404 struct net_device *ndev,
\r
5406 enum nl80211_tdls_operation oper)
\r
5408 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5409 struct tdls_txmgmt txmgmt;
\r
5410 struct sta_info *ptdls_sta = NULL;
\r
5412 DBG_871X(FUNC_NDEV_FMT", nl80211_tdls_operation:%d\n", FUNC_NDEV_ARG(ndev), oper);
\r
5415 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1);
\r
5416 #endif //CONFIG_LPS
\r
5418 _rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
\r
5420 _rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
\r
5422 CFG80211_TDLS_DISCOVERY_REQ,
\r
5423 CFG80211_TDLS_SETUP,
\r
5424 CFG80211_TDLS_TEARDOWN,
\r
5425 CFG80211_TDLS_ENABLE_LINK,
\r
5426 CFG80211_TDLS_DISABLE_LINK,
\r
5427 CFG80211_TDLS_ENABLE,
\r
5428 CFG80211_TDLS_DISABLE
\r
5431 case NL80211_TDLS_DISCOVERY_REQ:
\r
5432 issue_tdls_dis_req(padapter, &txmgmt);
\r
5434 case NL80211_TDLS_SETUP:
\r
5436 if ( _AES_ != padapter->securitypriv.dot11PrivacyAlgrthm )
\r
5438 if ( padapter->wdinfo.wfd_tdls_weaksec == _TRUE)
\r
5439 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5441 DBG_871X( "[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__ );
\r
5444 #endif // CONFIG_WFD
\r
5446 issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
\r
5449 case NL80211_TDLS_TEARDOWN:
\r
5450 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), txmgmt.peer);
\r
5451 if(ptdls_sta != NULL)
\r
5453 txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
\r
5454 issue_tdls_teardown(padapter, &txmgmt, _FALSE);
\r
5457 DBG_871X( "TDLS peer not found\n");
\r
5459 case NL80211_TDLS_ENABLE_LINK:
\r
5461 case NL80211_TDLS_DISABLE_LINK:
\r
5466 #endif /* CONFIG_TDLS */
\r
5468 #if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
5469 static int cfg80211_rtw_sched_scan_start(struct wiphy *wiphy,
\r
5470 struct net_device *dev,
\r
5471 struct cfg80211_sched_scan_request *request) {
\r
5473 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
5474 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5477 if (padapter->bup == _FALSE) {
\r
5478 DBG_871X("%s: net device is down.\n", __func__);
\r
5482 if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE ||
\r
5483 check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ||
\r
5484 check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
5485 DBG_871X("%s: device is busy.\n", __func__);
\r
5486 rtw_scan_abort(padapter);
\r
5489 if (request == NULL) {
\r
5490 DBG_871X("%s: invalid cfg80211_requests parameters.\n", __func__);
\r
5494 ret = rtw_android_cfg80211_pno_setup(dev, request->ssids,
\r
5495 request->n_ssids, request->interval);
\r
5498 DBG_871X("%s ret: %d\n", __func__, ret);
\r
5502 ret = rtw_android_pno_enable(dev, _TRUE);
\r
5504 DBG_871X("%s ret: %d\n", __func__, ret);
\r
5511 static int cfg80211_rtw_sched_scan_stop(struct wiphy *wiphy,
\r
5512 struct net_device *dev) {
\r
5513 return rtw_android_pno_enable(dev, _FALSE);
\r
5515 #endif /* CONFIG_PNO_SUPPORT */
\r
5517 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
\r
5520 uint wps_ielen = 0;
\r
5522 u32 p2p_ielen = 0;
\r
5523 u8 wps_oui[8]={0x0,0x50,0xf2,0x04};
\r
5525 u32 wfd_ielen = 0;
\r
5527 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5528 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5529 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
5531 DBG_871X(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
\r
5535 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
5537 #ifdef CONFIG_DEBUG_CFG80211
\r
5538 DBG_8192C("bcn_wps_ielen=%d\n", wps_ielen);
\r
5541 if(pmlmepriv->wps_beacon_ie)
\r
5543 u32 free_len = pmlmepriv->wps_beacon_ie_len;
\r
5544 pmlmepriv->wps_beacon_ie_len = 0;
\r
5545 rtw_mfree(pmlmepriv->wps_beacon_ie, free_len);
\r
5546 pmlmepriv->wps_beacon_ie = NULL;
\r
5549 pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen);
\r
5550 if ( pmlmepriv->wps_beacon_ie == NULL) {
\r
5551 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5556 _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
\r
5557 pmlmepriv->wps_beacon_ie_len = wps_ielen;
\r
5559 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
\r
5563 //buf += wps_ielen;
\r
5564 //len -= wps_ielen;
\r
5567 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
5569 #ifdef CONFIG_DEBUG_CFG80211
\r
5570 DBG_8192C("bcn_p2p_ielen=%d\n", p2p_ielen);
\r
5573 if(pmlmepriv->p2p_beacon_ie)
\r
5575 u32 free_len = pmlmepriv->p2p_beacon_ie_len;
\r
5576 pmlmepriv->p2p_beacon_ie_len = 0;
\r
5577 rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len);
\r
5578 pmlmepriv->p2p_beacon_ie = NULL;
\r
5581 pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen);
\r
5582 if ( pmlmepriv->p2p_beacon_ie == NULL) {
\r
5583 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5588 _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
\r
5589 pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
\r
5592 #endif //CONFIG_P2P
\r
5594 //buf += p2p_ielen;
\r
5595 //len -= p2p_ielen;
\r
5598 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
5600 #ifdef CONFIG_DEBUG_CFG80211
\r
5601 DBG_8192C("bcn_wfd_ielen=%d\n", wfd_ielen);
\r
5604 if(pmlmepriv->wfd_beacon_ie)
\r
5606 u32 free_len = pmlmepriv->wfd_beacon_ie_len;
\r
5607 pmlmepriv->wfd_beacon_ie_len = 0;
\r
5608 rtw_mfree(pmlmepriv->wfd_beacon_ie, free_len);
\r
5609 pmlmepriv->wfd_beacon_ie = NULL;
\r
5612 pmlmepriv->wfd_beacon_ie = rtw_malloc(wfd_ielen);
\r
5613 if ( pmlmepriv->wfd_beacon_ie == NULL) {
\r
5614 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5618 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
\r
5620 #endif //CONFIG_WFD
\r
5622 pmlmeext->bstart_bss = _TRUE;
\r
5630 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
\r
5633 uint wps_ielen = 0;
\r
5635 u32 p2p_ielen = 0;
\r
5637 u32 wfd_ielen = 0;
\r
5639 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
\r
5640 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5642 #ifdef CONFIG_DEBUG_CFG80211
\r
5643 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5648 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
5650 uint attr_contentlen = 0;
\r
5651 u16 uconfig_method, *puconfig_method = NULL;
\r
5653 #ifdef CONFIG_DEBUG_CFG80211
\r
5654 DBG_8192C("probe_resp_wps_ielen=%d\n", wps_ielen);
\r
5657 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
\r
5660 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
\r
5664 DBG_871X("%s, got sr\n", __func__);
\r
5668 DBG_8192C("GO mode process WPS under site-survey, sr no set\n");
\r
5673 if(pmlmepriv->wps_probe_resp_ie)
\r
5675 u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
\r
5676 pmlmepriv->wps_probe_resp_ie_len = 0;
\r
5677 rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len);
\r
5678 pmlmepriv->wps_probe_resp_ie = NULL;
\r
5681 pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen);
\r
5682 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
\r
5683 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5688 //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode
\r
5689 if ( (puconfig_method = (u16*)rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen)) != NULL )
\r
5691 //struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
5692 struct wireless_dev *wdev = padapter->rtw_wdev;
\r
5694 #ifdef CONFIG_DEBUG_CFG80211
\r
5695 //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method));
\r
5698 //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
\r
5699 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5700 if(wdev->iftype != NL80211_IFTYPE_P2P_GO) //for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags
\r
5702 uconfig_method = WPS_CM_PUSH_BUTTON;
\r
5703 uconfig_method = cpu_to_be16( uconfig_method );
\r
5705 *puconfig_method |= uconfig_method;
\r
5710 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
\r
5711 pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
\r
5715 //buf += wps_ielen;
\r
5716 //len -= wps_ielen;
\r
5719 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
5721 u8 is_GO = _FALSE;
\r
5722 u32 attr_contentlen = 0;
\r
5725 #ifdef CONFIG_DEBUG_CFG80211
\r
5726 DBG_8192C("probe_resp_p2p_ielen=%d\n", p2p_ielen);
\r
5729 //Check P2P Capability ATTR
\r
5730 if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) )
\r
5733 //DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
\r
5734 cap_attr = le16_to_cpu(cap_attr);
\r
5735 grp_cap = (u8)((cap_attr >> 8)&0xff);
\r
5737 is_GO = (grp_cap&BIT(0)) ? _TRUE:_FALSE;
\r
5740 DBG_8192C("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
\r
5744 if(is_GO == _FALSE)
\r
5746 if(pmlmepriv->p2p_probe_resp_ie)
\r
5748 u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
\r
5749 pmlmepriv->p2p_probe_resp_ie_len = 0;
\r
5750 rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len);
\r
5751 pmlmepriv->p2p_probe_resp_ie = NULL;
\r
5754 pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen);
\r
5755 if ( pmlmepriv->p2p_probe_resp_ie == NULL) {
\r
5756 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5760 _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
\r
5761 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
\r
5765 if(pmlmepriv->p2p_go_probe_resp_ie)
\r
5767 u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
\r
5768 pmlmepriv->p2p_go_probe_resp_ie_len = 0;
\r
5769 rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len);
\r
5770 pmlmepriv->p2p_go_probe_resp_ie = NULL;
\r
5773 pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen);
\r
5774 if ( pmlmepriv->p2p_go_probe_resp_ie == NULL) {
\r
5775 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5779 _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
\r
5780 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
\r
5784 #endif //CONFIG_P2P
\r
5786 //buf += p2p_ielen;
\r
5787 //len -= p2p_ielen;
\r
5790 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
5792 #ifdef CONFIG_DEBUG_CFG80211
\r
5793 DBG_8192C("probe_resp_wfd_ielen=%d\n", wfd_ielen);
\r
5796 if(pmlmepriv->wfd_probe_resp_ie)
\r
5798 u32 free_len = pmlmepriv->wfd_probe_resp_ie_len;
\r
5799 pmlmepriv->wfd_probe_resp_ie_len = 0;
\r
5800 rtw_mfree(pmlmepriv->wfd_probe_resp_ie, free_len);
\r
5801 pmlmepriv->wfd_probe_resp_ie = NULL;
\r
5804 pmlmepriv->wfd_probe_resp_ie = rtw_malloc(wfd_ielen);
\r
5805 if ( pmlmepriv->wfd_probe_resp_ie == NULL) {
\r
5806 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5810 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
\r
5812 #endif //CONFIG_WFD
\r
5820 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
\r
5823 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
\r
5824 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5826 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5830 if(pmlmepriv->wps_assoc_resp_ie)
\r
5832 u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
\r
5833 pmlmepriv->wps_assoc_resp_ie_len = 0;
\r
5834 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len);
\r
5835 pmlmepriv->wps_assoc_resp_ie = NULL;
\r
5838 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(len);
\r
5839 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
\r
5840 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5844 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len);
\r
5845 pmlmepriv->wps_assoc_resp_ie_len = len;
\r
5852 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
\r
5856 uint wps_ielen = 0;
\r
5857 u32 p2p_ielen = 0;
\r
5859 #ifdef CONFIG_DEBUG_CFG80211
\r
5860 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5863 if( (rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen>0))
\r
5865 || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen>0))
\r
5873 case 0x1: //BEACON
\r
5874 ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
\r
5876 case 0x2: //PROBE_RESP
\r
5877 ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
\r
5879 case 0x4: //ASSOC_RESP
\r
5880 ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
\r
5890 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
\r
5893 #define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
\r
5894 #define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
\r
5896 ht_cap->ht_supported = _TRUE;
\r
5898 ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
\r
5899 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
\r
5900 IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
\r
5903 *Maximum length of AMPDU that the STA can receive.
\r
5904 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
\r
5906 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
\r
5908 /*Minimum MPDU start spacing , */
\r
5909 ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
\r
5911 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
\r
5914 *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
\r
5917 *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
\r
5918 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
\r
5919 *if rx_ant >=3 rx_mask[2]=0xff;
\r
5920 *if BW_40 rx_mask[4]=0x01;
\r
5921 *highest supported RX rate
\r
5923 if(rf_type == RF_1T1R)
\r
5925 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
5926 ht_cap->mcs.rx_mask[1] = 0x00;
\r
5927 ht_cap->mcs.rx_mask[4] = 0x01;
\r
5929 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
\r
5931 else if((rf_type == RF_1T2R) || (rf_type==RF_2T2R))
\r
5933 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
5934 ht_cap->mcs.rx_mask[1] = 0xFF;
\r
5935 ht_cap->mcs.rx_mask[4] = 0x01;
\r
5937 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
\r
5941 DBG_8192C("%s, error rf_type=%d\n", __func__, rf_type);
\r
5946 void rtw_cfg80211_init_wiphy(_adapter *padapter)
\r
5949 struct ieee80211_supported_band *bands;
\r
5950 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
5951 struct wiphy *wiphy = pwdev->wiphy;
\r
5953 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
\r
5955 DBG_8192C("%s:rf_type=%d\n", __func__, rf_type);
\r
5957 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
\r
5959 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
\r
5961 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type);
\r
5964 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
\r
5966 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
\r
5968 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type);
\r
5971 /* init regulary domain */
\r
5972 rtw_regd_init(padapter);
\r
5974 /* copy mac_addr to wiphy */
\r
5975 _rtw_memcpy(wiphy->perm_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
\r
5980 struct ieee80211_iface_limit rtw_limits[] = {
\r
5981 { .max = 1, .types = BIT(NL80211_IFTYPE_STATION)
\r
5982 | BIT(NL80211_IFTYPE_ADHOC)
\r
5983 #ifdef CONFIG_AP_MODE
\r
5984 | BIT(NL80211_IFTYPE_AP)
\r
5986 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
5987 | BIT(NL80211_IFTYPE_P2P_CLIENT)
\r
5988 | BIT(NL80211_IFTYPE_P2P_GO)
\r
5991 {.max = 1, .types = BIT(NL80211_IFTYPE_MONITOR)},
\r
5994 struct ieee80211_iface_combination rtw_combinations = {
\r
5995 .limits = rtw_limits,
\r
5996 .n_limits = ARRAY_SIZE(rtw_limits),
\r
5997 .max_interfaces = 2,
\r
5998 .num_different_channels = 1,
\r
6002 static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy)
\r
6005 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
\r
6007 wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
\r
6008 wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
\r
6009 wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
\r
6011 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
6012 wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
\r
6015 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
\r
6016 | BIT(NL80211_IFTYPE_ADHOC)
\r
6017 #ifdef CONFIG_AP_MODE
\r
6018 | BIT(NL80211_IFTYPE_AP)
\r
6019 | BIT(NL80211_IFTYPE_MONITOR)
\r
6021 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
6022 | BIT(NL80211_IFTYPE_P2P_CLIENT)
\r
6023 | BIT(NL80211_IFTYPE_P2P_GO)
\r
6027 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
6028 #ifdef CONFIG_AP_MODE
\r
6029 wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
\r
6030 #endif //CONFIG_AP_MODE
\r
6033 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
6034 wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
\r
6038 wiphy->iface_combinations = &rtw_combinations;
\r
6039 wiphy->n_iface_combinations = 1;
\r
6042 wiphy->cipher_suites = rtw_cipher_suites;
\r
6043 wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
\r
6045 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
\r
6046 wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
\r
6047 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
\r
6048 wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
\r
6050 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
\r
6051 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
\r
6054 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
\r
6055 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
\r
6056 wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
\r
6059 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
6060 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
\r
6061 #ifdef CONFIG_PNO_SUPPORT
\r
6062 wiphy->max_sched_scan_ssids = MAX_PNO_LIST_COUNT;
\r
6066 #if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
\r
6067 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,11,0))
\r
6068 wiphy->wowlan = wowlan_stub;
\r
6070 wiphy->wowlan = &wowlan_stub;
\r
6074 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
6075 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
\r
6076 //wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
\r
6077 #endif /* CONFIG_TDLS */
\r
6079 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
\r
6080 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
\r
6082 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
\r
6084 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
6085 //wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
\r
6088 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
\r
6089 rtw_cfgvendor_attach(wiphy);
\r
6093 static struct cfg80211_ops rtw_cfg80211_ops = {
\r
6094 .change_virtual_intf = cfg80211_rtw_change_iface,
\r
6095 .add_key = cfg80211_rtw_add_key,
\r
6096 .get_key = cfg80211_rtw_get_key,
\r
6097 .del_key = cfg80211_rtw_del_key,
\r
6098 .set_default_key = cfg80211_rtw_set_default_key,
\r
6099 .get_station = cfg80211_rtw_get_station,
\r
6100 .scan = cfg80211_rtw_scan,
\r
6101 .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
\r
6102 .connect = cfg80211_rtw_connect,
\r
6103 .disconnect = cfg80211_rtw_disconnect,
\r
6104 .join_ibss = cfg80211_rtw_join_ibss,
\r
6105 .leave_ibss = cfg80211_rtw_leave_ibss,
\r
6106 .set_tx_power = cfg80211_rtw_set_txpower,
\r
6107 .get_tx_power = cfg80211_rtw_get_txpower,
\r
6108 .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
\r
6109 .set_pmksa = cfg80211_rtw_set_pmksa,
\r
6110 .del_pmksa = cfg80211_rtw_del_pmksa,
\r
6111 .flush_pmksa = cfg80211_rtw_flush_pmksa,
\r
6113 #ifdef CONFIG_AP_MODE
\r
6114 .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
\r
6115 .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
\r
6117 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
\r
6118 .add_beacon = cfg80211_rtw_add_beacon,
\r
6119 .set_beacon = cfg80211_rtw_set_beacon,
\r
6120 .del_beacon = cfg80211_rtw_del_beacon,
\r
6122 .start_ap = cfg80211_rtw_start_ap,
\r
6123 .change_beacon = cfg80211_rtw_change_beacon,
\r
6124 .stop_ap = cfg80211_rtw_stop_ap,
\r
6127 .add_station = cfg80211_rtw_add_station,
\r
6128 .del_station = cfg80211_rtw_del_station,
\r
6129 .change_station = cfg80211_rtw_change_station,
\r
6130 .dump_station = cfg80211_rtw_dump_station,
\r
6131 .change_bss = cfg80211_rtw_change_bss,
\r
6132 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
\r
6133 .set_channel = cfg80211_rtw_set_channel,
\r
6135 //.auth = cfg80211_rtw_auth,
\r
6136 //.assoc = cfg80211_rtw_assoc,
\r
6137 #endif //CONFIG_AP_MODE
\r
6140 .remain_on_channel = cfg80211_rtw_remain_on_channel,
\r
6141 .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
\r
6144 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
6145 .mgmt_tx = cfg80211_rtw_mgmt_tx,
\r
6146 .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
\r
6147 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
\r
6148 .action = cfg80211_rtw_mgmt_tx,
\r
6151 #if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
6152 .tdls_mgmt = cfg80211_rtw_tdls_mgmt,
\r
6153 .tdls_oper = cfg80211_rtw_tdls_oper,
\r
6154 #endif /* CONFIG_TDLS */
\r
6156 #if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
6157 .sched_scan_start = cfg80211_rtw_sched_scan_start,
\r
6158 .sched_scan_stop = cfg80211_rtw_sched_scan_stop,
\r
6159 #endif /* CONFIG_PNO_SUPPORT */
\r
6162 int rtw_wdev_alloc(_adapter *padapter, struct device *dev)
\r
6165 struct wiphy *wiphy;
\r
6166 struct wireless_dev *wdev;
\r
6167 struct rtw_wdev_priv *pwdev_priv;
\r
6168 struct net_device *pnetdev = padapter->pnetdev;
\r
6170 DBG_8192C("%s(padapter=%p)\n", __func__, padapter);
\r
6173 wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(_adapter*));
\r
6175 DBG_8192C("Couldn't allocate wiphy device\n");
\r
6179 set_wiphy_dev(wiphy, dev);
\r
6180 *((_adapter**)wiphy_priv(wiphy)) = padapter;
\r
6181 rtw_cfg80211_preinit_wiphy(padapter, wiphy);
\r
6183 ret = wiphy_register(wiphy);
\r
6185 DBG_8192C("Couldn't register wiphy device\n");
\r
6190 wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
\r
6192 DBG_8192C("Couldn't allocate wireless device\n");
\r
6194 goto unregister_wiphy;
\r
6196 wdev->wiphy = wiphy;
\r
6197 wdev->netdev = pnetdev;
\r
6199 wdev->iftype = NL80211_IFTYPE_STATION; // will be init in rtw_hal_init()
\r
6200 // Must sync with _rtw_init_mlme_priv()
\r
6201 // pmlmepriv->fw_state = WIFI_STATION_STATE
\r
6202 //wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
\r
6203 padapter->rtw_wdev = wdev;
\r
6204 pnetdev->ieee80211_ptr = wdev;
\r
6207 pwdev_priv = adapter_wdev_data(padapter);
\r
6208 pwdev_priv->rtw_wdev = wdev;
\r
6209 pwdev_priv->pmon_ndev = NULL;
\r
6210 pwdev_priv->ifname_mon[0] = '\0';
\r
6211 pwdev_priv->padapter = padapter;
\r
6212 pwdev_priv->scan_request = NULL;
\r
6213 _rtw_spinlock_init(&pwdev_priv->scan_req_lock);
\r
6215 pwdev_priv->p2p_enabled = _FALSE;
\r
6216 pwdev_priv->provdisc_req_issued = _FALSE;
\r
6217 rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
\r
6218 rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
\r
6220 pwdev_priv->bandroid_scan = _FALSE;
\r
6222 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
\r
6223 pwdev_priv->power_mgmt = _TRUE;
\r
6225 pwdev_priv->power_mgmt = _FALSE;
\r
6227 #ifdef CONFIG_CONCURRENT_MODE
\r
6228 ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
\r
6229 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
6234 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
\r
6236 wiphy_unregister(wiphy);
\r
6238 wiphy_free(wiphy);
\r
6244 void rtw_wdev_free(struct wireless_dev *wdev)
\r
6246 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
\r
6251 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
\r
6252 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
\r
6254 wiphy_free(wdev->wiphy);
\r
6256 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
\r
6259 void rtw_wdev_unregister(struct wireless_dev *wdev)
\r
6261 struct net_device *ndev;
\r
6262 _adapter *adapter;
\r
6263 struct rtw_wdev_priv *pwdev_priv;
\r
6265 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
\r
6270 if(!(ndev = wdev_to_ndev(wdev)))
\r
6273 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
6274 pwdev_priv = adapter_wdev_data(adapter);
\r
6276 rtw_cfg80211_indicate_scan_done(adapter, _TRUE);
\r
6278 if (pwdev_priv->pmon_ndev) {
\r
6279 DBG_8192C("%s, unregister monitor interface\n", __func__);
\r
6280 unregister_netdev(pwdev_priv->pmon_ndev);
\r
6283 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
\r
6284 rtw_cfgvendor_detach(wdev->wiphy);
\r
6287 wiphy_unregister(wdev->wiphy);
\r
6290 #endif //CONFIG_IOCTL_CFG80211
\r