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 65535 //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 static const u32 rtw_cipher_suites[] = {
\r
57 WLAN_CIPHER_SUITE_WEP40,
\r
58 WLAN_CIPHER_SUITE_WEP104,
\r
59 WLAN_CIPHER_SUITE_TKIP,
\r
60 WLAN_CIPHER_SUITE_CCMP,
\r
61 #ifdef CONFIG_WAPI_SUPPORT
\r
62 WLAN_CIPHER_SUITE_SMS4,
\r
63 #endif // CONFIG_WAPI_SUPPORT
\r
64 #ifdef CONFIG_IEEE80211W
\r
65 WLAN_CIPHER_SUITE_AES_CMAC,
\r
66 #endif //CONFIG_IEEE80211W
\r
69 #define RATETAB_ENT(_rate, _rateid, _flags) \
\r
71 .bitrate = (_rate), \
\r
72 .hw_value = (_rateid), \
\r
73 .flags = (_flags), \
\r
76 #define CHAN2G(_channel, _freq, _flags) { \
\r
77 .band = IEEE80211_BAND_2GHZ, \
\r
78 .center_freq = (_freq), \
\r
79 .hw_value = (_channel), \
\r
80 .flags = (_flags), \
\r
81 .max_antenna_gain = 0, \
\r
85 #define CHAN5G(_channel, _flags) { \
\r
86 .band = IEEE80211_BAND_5GHZ, \
\r
87 .center_freq = 5000 + (5 * (_channel)), \
\r
88 .hw_value = (_channel), \
\r
89 .flags = (_flags), \
\r
90 .max_antenna_gain = 0, \
\r
94 static struct ieee80211_rate rtw_rates[] = {
\r
95 RATETAB_ENT(10, 0x1, 0),
\r
96 RATETAB_ENT(20, 0x2, 0),
\r
97 RATETAB_ENT(55, 0x4, 0),
\r
98 RATETAB_ENT(110, 0x8, 0),
\r
99 RATETAB_ENT(60, 0x10, 0),
\r
100 RATETAB_ENT(90, 0x20, 0),
\r
101 RATETAB_ENT(120, 0x40, 0),
\r
102 RATETAB_ENT(180, 0x80, 0),
\r
103 RATETAB_ENT(240, 0x100, 0),
\r
104 RATETAB_ENT(360, 0x200, 0),
\r
105 RATETAB_ENT(480, 0x400, 0),
\r
106 RATETAB_ENT(540, 0x800, 0),
\r
109 #define rtw_a_rates (rtw_rates + 4)
\r
110 #define RTW_A_RATES_NUM 8
\r
111 #define rtw_g_rates (rtw_rates + 0)
\r
112 #define RTW_G_RATES_NUM 12
\r
114 #define RTW_2G_CHANNELS_NUM 14
\r
115 #define RTW_5G_CHANNELS_NUM 37
\r
117 static struct ieee80211_channel rtw_2ghz_channels[] = {
\r
118 CHAN2G(1, 2412, 0),
\r
119 CHAN2G(2, 2417, 0),
\r
120 CHAN2G(3, 2422, 0),
\r
121 CHAN2G(4, 2427, 0),
\r
122 CHAN2G(5, 2432, 0),
\r
123 CHAN2G(6, 2437, 0),
\r
124 CHAN2G(7, 2442, 0),
\r
125 CHAN2G(8, 2447, 0),
\r
126 CHAN2G(9, 2452, 0),
\r
127 CHAN2G(10, 2457, 0),
\r
128 CHAN2G(11, 2462, 0),
\r
129 CHAN2G(12, 2467, 0),
\r
130 CHAN2G(13, 2472, 0),
\r
131 CHAN2G(14, 2484, 0),
\r
134 static struct ieee80211_channel rtw_5ghz_a_channels[] = {
\r
135 CHAN5G(34, 0), CHAN5G(36, 0),
\r
136 CHAN5G(38, 0), CHAN5G(40, 0),
\r
137 CHAN5G(42, 0), CHAN5G(44, 0),
\r
138 CHAN5G(46, 0), CHAN5G(48, 0),
\r
139 CHAN5G(52, 0), CHAN5G(56, 0),
\r
140 CHAN5G(60, 0), CHAN5G(64, 0),
\r
141 CHAN5G(100, 0), CHAN5G(104, 0),
\r
142 CHAN5G(108, 0), CHAN5G(112, 0),
\r
143 CHAN5G(116, 0), CHAN5G(120, 0),
\r
144 CHAN5G(124, 0), CHAN5G(128, 0),
\r
145 CHAN5G(132, 0), CHAN5G(136, 0),
\r
146 CHAN5G(140, 0), CHAN5G(149, 0),
\r
147 CHAN5G(153, 0), CHAN5G(157, 0),
\r
148 CHAN5G(161, 0), CHAN5G(165, 0),
\r
149 CHAN5G(184, 0), CHAN5G(188, 0),
\r
150 CHAN5G(192, 0), CHAN5G(196, 0),
\r
151 CHAN5G(200, 0), CHAN5G(204, 0),
\r
152 CHAN5G(208, 0), CHAN5G(212, 0),
\r
157 void rtw_2g_channels_init(struct ieee80211_channel *channels)
\r
159 _rtw_memcpy((void*)channels, (void*)rtw_2ghz_channels,
\r
160 sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
\r
164 void rtw_5g_channels_init(struct ieee80211_channel *channels)
\r
166 _rtw_memcpy((void*)channels, (void*)rtw_5ghz_a_channels,
\r
167 sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
\r
171 void rtw_2g_rates_init(struct ieee80211_rate *rates)
\r
173 _rtw_memcpy(rates, rtw_g_rates,
\r
174 sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
\r
178 void rtw_5g_rates_init(struct ieee80211_rate *rates)
\r
180 _rtw_memcpy(rates, rtw_a_rates,
\r
181 sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM
\r
185 struct ieee80211_supported_band *rtw_spt_band_alloc(
\r
186 enum ieee80211_band band
\r
189 struct ieee80211_supported_band *spt_band = NULL;
\r
190 int n_channels, n_bitrates;
\r
192 if(band == IEEE80211_BAND_2GHZ)
\r
194 n_channels = RTW_2G_CHANNELS_NUM;
\r
195 n_bitrates = RTW_G_RATES_NUM;
\r
197 else if(band == IEEE80211_BAND_5GHZ)
\r
199 n_channels = RTW_5G_CHANNELS_NUM;
\r
200 n_bitrates = RTW_A_RATES_NUM;
\r
207 spt_band = (struct ieee80211_supported_band *)rtw_zmalloc(
\r
208 sizeof(struct ieee80211_supported_band)
\r
209 + sizeof(struct ieee80211_channel)*n_channels
\r
210 + sizeof(struct ieee80211_rate)*n_bitrates
\r
215 spt_band->channels = (struct ieee80211_channel*)(((u8*)spt_band)+sizeof(struct ieee80211_supported_band));
\r
216 spt_band->bitrates= (struct ieee80211_rate*)(((u8*)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
\r
217 spt_band->band = band;
\r
218 spt_band->n_channels = n_channels;
\r
219 spt_band->n_bitrates = n_bitrates;
\r
221 if(band == IEEE80211_BAND_2GHZ)
\r
223 rtw_2g_channels_init(spt_band->channels);
\r
224 rtw_2g_rates_init(spt_band->bitrates);
\r
226 else if(band == IEEE80211_BAND_5GHZ)
\r
228 rtw_5g_channels_init(spt_band->channels);
\r
229 rtw_5g_rates_init(spt_band->bitrates);
\r
239 void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
\r
246 if(spt_band->band == IEEE80211_BAND_2GHZ)
\r
248 size = sizeof(struct ieee80211_supported_band)
\r
249 + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
\r
250 + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM;
\r
252 else if(spt_band->band == IEEE80211_BAND_5GHZ)
\r
254 size = sizeof(struct ieee80211_supported_band)
\r
255 + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
\r
256 + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM;
\r
262 rtw_mfree((u8*)spt_band, size);
\r
265 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
266 static const struct ieee80211_txrx_stypes
\r
267 rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
\r
268 [NL80211_IFTYPE_ADHOC] = {
\r
270 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
\r
272 [NL80211_IFTYPE_STATION] = {
\r
274 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
\r
275 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
\r
277 [NL80211_IFTYPE_AP] = {
\r
279 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
280 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
281 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
282 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
283 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
284 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
285 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
287 [NL80211_IFTYPE_AP_VLAN] = {
\r
290 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
291 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
292 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
293 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
294 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
295 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
296 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
298 [NL80211_IFTYPE_P2P_CLIENT] = {
\r
300 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
\r
301 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
\r
303 [NL80211_IFTYPE_P2P_GO] = {
\r
305 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
\r
306 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
\r
307 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
\r
308 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
\r
309 BIT(IEEE80211_STYPE_AUTH >> 4) |
\r
310 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
\r
311 BIT(IEEE80211_STYPE_ACTION >> 4)
\r
316 static int rtw_ieee80211_channel_to_frequency(int chan, int band)
\r
318 /* see 802.11 17.3.8.3.2 and Annex J
\r
319 * there are overlapping channel numbers in 5GHz and 2GHz bands */
\r
321 if (band == IEEE80211_BAND_5GHZ) {
\r
322 if (chan >= 182 && chan <= 196)
\r
323 return 4000 + chan * 5;
\r
325 return 5000 + chan * 5;
\r
326 } else { /* IEEE80211_BAND_2GHZ */
\r
329 else if (chan < 14)
\r
330 return 2407 + chan * 5;
\r
332 return 0; /* not supported */
\r
336 #define MAX_BSSINFO_LEN 1000
\r
337 struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork)
\r
339 struct ieee80211_channel *notify_channel;
\r
340 struct cfg80211_bss *bss = NULL;
\r
341 //struct ieee80211_supported_band *band;
\r
344 u64 notify_timestamp;
\r
345 u16 notify_capability;
\r
346 u16 notify_interval;
\r
348 size_t notify_ielen;
\r
350 u8 buf[MAX_BSSINFO_LEN], *pbuf;
\r
351 size_t len,bssinf_len=0;
\r
352 struct rtw_ieee80211_hdr *pwlanhdr;
\r
353 unsigned short *fctrl;
\r
354 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
\r
356 struct wireless_dev *wdev = padapter->rtw_wdev;
\r
357 struct wiphy *wiphy = wdev->wiphy;
\r
358 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
361 //DBG_8192C("%s\n", __func__);
\r
363 bssinf_len = pnetwork->network.IELength+sizeof (struct rtw_ieee80211_hdr_3addr);
\r
364 if(bssinf_len > MAX_BSSINFO_LEN){
\r
365 DBG_871X("%s IE Length too long > %d byte \n",__FUNCTION__,MAX_BSSINFO_LEN);
\r
369 #ifndef CONFIG_WAPI_SUPPORT
\r
373 if(rtw_get_wapi_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &wapi_len)>0)
\r
377 DBG_871X("%s, no support wapi!\n",__FUNCTION__);
\r
382 #endif //!CONFIG_WAPI_SUPPORT
\r
384 //To reduce PBC Overlap rate
\r
385 //_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
386 if(adapter_wdev_data(padapter)->scan_request != NULL)
\r
388 u8 *psr=NULL, sr = 0;
\r
389 NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid;
\r
390 struct cfg80211_scan_request *request = adapter_wdev_data(padapter)->scan_request;
\r
391 struct cfg80211_ssid *ssids = request->ssids;
\r
395 wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
\r
397 if(wpsie && wpsielen>0)
\r
398 psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
\r
402 if(request->n_ssids == 1 && request->n_channels == 1) // it means under processing WPS
\r
404 DBG_8192C("ssid=%s, len=%d\n", pssid->Ssid, pssid->SsidLength);
\r
406 if (ssids[0].ssid_len == 0) {
\r
408 else if(pssid->SsidLength == ssids[0].ssid_len &&
\r
409 _rtw_memcmp(pssid->Ssid, ssids[0].ssid, ssids[0].ssid_len))
\r
411 DBG_871X("%s, got sr and ssid match!\n", __func__);
\r
416 *psr = 0; //clear sr
\r
419 WLAN_BSSID_EX *pselect_network = &pnetwork->network;
\r
420 struct cfg80211_bss *pselect_bss = NULL;
\r
421 struct ieee80211_channel *notify_channel = NULL;
\r
424 DBG_871X("%s, got sr, but ssid mismatch, to remove this bss\n", __func__);
\r
426 if (pselect_network->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
\r
427 freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
\r
429 freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
\r
431 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
432 pselect_bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
\r
433 pselect_network->MacAddress, pselect_network->Ssid.Ssid,
\r
434 pselect_network->Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
\r
435 0/*WLAN_CAPABILITY_ESS*/);
\r
439 DBG_871X("%s, got bss for cfg80211 for unlinking bss\n", __func__);
\r
441 cfg80211_unlink_bss(wiphy, pselect_bss);
\r
442 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
443 cfg80211_put_bss(wiphy, pselect_bss);
\r
445 cfg80211_put_bss(pselect_bss);
\r
456 //_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
459 channel = pnetwork->network.Configuration.DSConfig;
\r
460 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
461 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
463 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
465 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
467 //rtw_get_timestampe_from_ie()
\r
468 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
\r
470 notify_interval = le16_to_cpu(*(u16*)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
\r
471 notify_capability = le16_to_cpu(*(u16*)rtw_get_capability_from_ie(pnetwork->network.IEs));
\r
474 notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_;
\r
475 notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_;
\r
477 //We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm)
\r
478 if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
\r
479 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) {
\r
480 notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);//dbm
\r
482 notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);//dbm
\r
486 DBG_8192C("bssid: "MAC_FMT"\n", MAC_ARG(pnetwork->network.MacAddress));
\r
487 DBG_8192C("Channel: %d(%d)\n", channel, freq);
\r
488 DBG_8192C("Capability: %X\n", notify_capability);
\r
489 DBG_8192C("Beacon interval: %d\n", notify_interval);
\r
490 DBG_8192C("Signal: %d\n", notify_signal);
\r
491 DBG_8192C("notify_timestamp: %#018llx\n", notify_timestamp);
\r
496 pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;
\r
497 fctrl = &(pwlanhdr->frame_ctl);
\r
500 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
\r
501 //pmlmeext->mgnt_seq++;
\r
503 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
\r
504 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
\r
505 SetFrameSubType(pbuf, WIFI_BEACON);
\r
507 _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
508 SetFrameSubType(pbuf, WIFI_PROBERSP);
\r
511 _rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
\r
512 _rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
\r
515 pbuf += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
516 len = sizeof (struct rtw_ieee80211_hdr_3addr);
\r
518 _rtw_memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength);
\r
519 len += pnetwork->network.IELength;
\r
521 //#ifdef CONFIG_P2P
\r
522 //if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
\r
524 // DBG_8192C("%s, got p2p_ie\n", __func__);
\r
530 bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)buf,
\r
531 len, notify_signal, GFP_ATOMIC);
\r
534 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress,
\r
535 notify_timestamp, notify_capability, notify_interval, notify_ie,
\r
536 notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/);
\r
539 if (unlikely(!bss)) {
\r
540 DBG_8192C(FUNC_ADPT_FMT" bss NULL\n", FUNC_ADPT_ARG(padapter));
\r
544 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
\r
545 #ifndef COMPAT_KERNEL_RELEASE
\r
546 //patch for cfg80211, update beacon ies to information_elements
\r
547 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
\r
549 if(bss->len_information_elements != bss->len_beacon_ies)
\r
551 bss->information_elements = bss->beacon_ies;
\r
552 bss->len_information_elements = bss->len_beacon_ies;
\r
555 #endif //COMPAT_KERNEL_RELEASE
\r
556 #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
\r
560 if( bss->information_elements == bss->proberesp_ies)
\r
562 if( bss->len_information_elements != bss->len_proberesp_ies)
\r
564 DBG_8192C("error!, len_information_elements != bss->len_proberesp_ies\n");
\r
568 else if(bss->len_information_elements < bss->len_beacon_ies)
\r
570 bss->information_elements = bss->beacon_ies;
\r
571 bss->len_information_elements = bss->len_beacon_ies;
\r
575 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
\r
576 cfg80211_put_bss(wiphy, bss);
\r
578 cfg80211_put_bss(bss);
\r
587 Check the given bss is valid by kernel API cfg80211_get_bss()
\r
588 @padapter : the given adapter
\r
590 return _TRUE if bss is valid, _FALSE for not found.
\r
592 int rtw_cfg80211_check_bss(_adapter *padapter)
\r
594 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
595 struct cfg80211_bss *bss = NULL;
\r
596 struct ieee80211_channel *notify_channel = NULL;
\r
599 if (!(pnetwork) || !(padapter->rtw_wdev))
\r
602 if (pnetwork->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
\r
603 freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
\r
605 freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
\r
607 notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
\r
608 bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
\r
609 pnetwork->MacAddress, pnetwork->Ssid.Ssid,
\r
610 pnetwork->Ssid.SsidLength,
\r
611 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
\r
613 return (bss!=NULL);
\r
616 void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter)
\r
618 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
619 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
620 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
621 struct cfg80211_bss *bss = NULL;
\r
623 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
624 if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
\r
629 if (!rtw_cfg80211_check_bss(padapter)) {
\r
630 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
631 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
\r
633 if(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)==_TRUE)
\r
636 _rtw_memcpy(&cur_network->network, pnetwork, sizeof(WLAN_BSSID_EX));
\r
639 if (!rtw_cfg80211_inform_bss(padapter,cur_network))
\r
640 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
642 DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
646 DBG_871X("cur_network is not exist!!!\n");
\r
652 if(scanned == NULL)
\r
655 if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
\r
656 && _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
\r
658 if (!rtw_cfg80211_inform_bss(padapter,scanned)) {
\r
659 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
661 //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
664 DBG_871X("scanned & pnetwork compare fail\n");
\r
669 if (!rtw_cfg80211_check_bss(padapter))
\r
670 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
\r
672 //notify cfg80211 that device joined an IBSS
\r
673 cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, GFP_ATOMIC);
\r
676 void rtw_cfg80211_indicate_connect(_adapter *padapter)
\r
678 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
679 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
680 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
682 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
684 struct cfg80211_bss *bss = NULL;
\r
686 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
687 if (pwdev->iftype != NL80211_IFTYPE_STATION
\r
688 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
689 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
\r
695 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
699 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
701 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
703 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
704 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
\r
705 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
\r
706 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
709 #endif //CONFIG_P2P
\r
712 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
\r
713 struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
\r
715 //DBG_871X(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter));
\r
717 if(scanned == NULL) {
\r
722 if (_rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
\r
723 && _rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
\r
725 if (!rtw_cfg80211_inform_bss(padapter,scanned)) {
\r
726 DBG_871X(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
\r
728 //DBG_871X(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
\r
731 DBG_871X("scanned: %s("MAC_FMT"), cur: %s("MAC_FMT")\n",
\r
732 scanned->network.Ssid.Ssid, MAC_ARG(scanned->network.MacAddress),
\r
733 pnetwork->Ssid.Ssid, MAC_ARG(pnetwork->MacAddress)
\r
740 if (!rtw_cfg80211_check_bss(padapter))
\r
741 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
\r
743 if (rtw_to_roam(padapter) > 0) {
\r
744 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
\r
745 struct wiphy *wiphy = pwdev->wiphy;
\r
746 struct ieee80211_channel *notify_channel;
\r
748 u16 channel = cur_network->network.Configuration.DSConfig;
\r
750 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
751 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
753 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
755 notify_channel = ieee80211_get_channel(wiphy, freq);
\r
758 DBG_871X(FUNC_ADPT_FMT" call cfg80211_roamed\n", FUNC_ADPT_ARG(padapter));
\r
759 cfg80211_roamed(padapter->pnetdev
\r
760 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
\r
763 , cur_network->network.MacAddress
\r
764 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
\r
765 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
\r
766 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
\r
767 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
\r
772 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
\r
773 cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
\r
774 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
\r
775 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
\r
776 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
\r
777 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
\r
778 , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
\r
779 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
\r
783 void rtw_cfg80211_indicate_disconnect(_adapter *padapter)
\r
785 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
786 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
788 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
791 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
793 if (pwdev->iftype != NL80211_IFTYPE_STATION
\r
794 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
795 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
\r
801 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
805 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
807 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
809 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
810 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
812 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
815 #endif //CONFIG_P2P
\r
817 if (!padapter->mlmepriv.not_indic_disco) {
\r
818 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
\r
820 if(pwdev->sme_state==CFG80211_SME_CONNECTING)
\r
821 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
\r
822 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
\r
823 else if(pwdev->sme_state==CFG80211_SME_CONNECTED)
\r
824 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
\r
826 //DBG_8192C("pwdev->sme_state=%d\n", pwdev->sme_state);
\r
828 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
\r
833 #ifdef CONFIG_AP_MODE
\r
834 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
\r
837 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
838 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
\r
839 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
840 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
841 struct security_priv* psecuritypriv=&(padapter->securitypriv);
\r
842 struct sta_priv *pstapriv = &padapter->stapriv;
\r
844 DBG_8192C("%s\n", __FUNCTION__);
\r
846 param->u.crypt.err = 0;
\r
847 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
\r
849 //sizeof(struct ieee_param) = 64 bytes;
\r
850 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
\r
851 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
\r
857 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
\r
858 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
\r
859 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
\r
861 if (param->u.crypt.idx >= WEP_KEYS)
\r
869 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
\r
873 DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n");
\r
878 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
\r
880 //todo:clear default encryption keys
\r
882 DBG_8192C("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
\r
888 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
\r
890 DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
\r
892 wep_key_idx = param->u.crypt.idx;
\r
893 wep_key_len = param->u.crypt.key_len;
\r
895 DBG_8192C("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
\r
897 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
\r
903 if (wep_key_len > 0)
\r
905 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
908 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
\r
910 //wep default key has not been set, so use this key index as default key.
\r
912 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
\r
913 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
914 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
\r
915 psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
\r
917 if(wep_key_len == 13)
\r
919 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
\r
920 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
\r
923 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
\r
926 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
\r
928 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
\r
930 rtw_ap_set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx, 1);
\r
937 if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
\r
939 if(param->u.crypt.set_tx == 0) //group key
\r
941 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
943 DBG_8192C("%s, set group_key, WEP\n", __FUNCTION__);
\r
945 _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
947 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
948 if(param->u.crypt.key_len==13)
\r
950 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
954 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
956 DBG_8192C("%s, set group_key, TKIP\n", __FUNCTION__);
\r
958 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
\r
960 _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
962 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
964 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
\r
965 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
\r
967 psecuritypriv->busetkipkey = _TRUE;
\r
970 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
972 DBG_8192C("%s, set group_key, CCMP\n", __FUNCTION__);
\r
974 psecuritypriv->dot118021XGrpPrivacy = _AES_;
\r
976 _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
980 DBG_8192C("%s, set group_key, none\n", __FUNCTION__);
\r
982 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
985 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
\r
987 psecuritypriv->binstallGrpkey = _TRUE;
\r
989 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
\r
991 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
\r
993 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
996 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
997 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
\r
1006 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
\r
1008 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
1010 if(param->u.crypt.set_tx ==1) //pairwise key
\r
1012 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1014 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1016 DBG_8192C("%s, set pairwise key, WEP\n", __FUNCTION__);
\r
1018 psta->dot118021XPrivacy = _WEP40_;
\r
1019 if(param->u.crypt.key_len==13)
\r
1021 psta->dot118021XPrivacy = _WEP104_;
\r
1024 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1026 DBG_8192C("%s, set pairwise key, TKIP\n", __FUNCTION__);
\r
1028 psta->dot118021XPrivacy = _TKIP_;
\r
1030 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1032 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
\r
1033 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
\r
1035 psecuritypriv->busetkipkey = _TRUE;
\r
1038 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1041 DBG_8192C("%s, set pairwise key, CCMP\n", __FUNCTION__);
\r
1043 psta->dot118021XPrivacy = _AES_;
\r
1047 DBG_8192C("%s, set pairwise key, none\n", __FUNCTION__);
\r
1049 psta->dot118021XPrivacy = _NO_PRIVACY_;
\r
1052 rtw_ap_set_pairwise_key(padapter, psta);
\r
1054 psta->ieee8021x_blocked = _FALSE;
\r
1056 psta->bpairwise_key_installed = _TRUE;
\r
1059 else//group key???
\r
1061 if(strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1063 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1065 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1066 if(param->u.crypt.key_len==13)
\r
1068 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1071 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
\r
1073 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
\r
1075 _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
1077 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
\r
1079 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
\r
1080 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
\r
1082 psecuritypriv->busetkipkey = _TRUE;
\r
1085 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1087 psecuritypriv->dot118021XGrpPrivacy = _AES_;
\r
1089 _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
1093 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
1096 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
\r
1098 psecuritypriv->binstallGrpkey = _TRUE;
\r
1100 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
\r
1102 rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
\r
1104 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1107 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1108 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
\r
1124 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
\r
1127 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
1128 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
\r
1129 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1130 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1132 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
\r
1133 #endif //CONFIG_P2P
\r
1137 DBG_8192C("%s\n", __func__);
\r
1139 param->u.crypt.err = 0;
\r
1140 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
\r
1142 if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
\r
1148 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
\r
1149 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
\r
1150 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
\r
1152 if (param->u.crypt.idx >= WEP_KEYS
\r
1153 #ifdef CONFIG_IEEE80211W
\r
1154 && param->u.crypt.idx > BIP_MAX_KEYID
\r
1155 #endif //CONFIG_IEEE80211W
\r
1162 #ifdef CONFIG_WAPI_SUPPORT
\r
1163 if (strcmp(param->u.crypt.alg, "SMS4"))
\r
1171 if (strcmp(param->u.crypt.alg, "WEP") == 0)
\r
1173 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
\r
1174 DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n");
\r
1176 wep_key_idx = param->u.crypt.idx;
\r
1177 wep_key_len = param->u.crypt.key_len;
\r
1179 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0))
\r
1185 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
\r
1187 //wep default key has not been set, so use this key index as default key.
\r
1189 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
1191 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1192 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
\r
1193 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1195 if(wep_key_len==13)
\r
1197 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
\r
1198 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1201 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
\r
1204 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
\r
1206 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
\r
1208 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, _TRUE);
\r
1213 if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
\r
1215 struct sta_info * psta,*pbcmc_sta;
\r
1216 struct sta_priv * pstapriv = &padapter->stapriv;
\r
1218 //DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__);
\r
1220 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
\r
1222 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
\r
1223 if (psta == NULL) {
\r
1224 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
\r
1225 DBG_8192C("%s, : Obtain Sta_info fail \n", __func__);
\r
1229 //Jeff: don't disable ieee8021x_blocked while clearing key
\r
1230 if (strcmp(param->u.crypt.alg, "none") != 0)
\r
1231 psta->ieee8021x_blocked = _FALSE;
\r
1234 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
\r
1235 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
\r
1237 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
\r
1240 if(param->u.crypt.set_tx ==1)//pairwise key
\r
1243 DBG_8192C("%s, : param->u.crypt.set_tx ==1 \n", __func__);
\r
1245 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
\r
1247 if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
\r
1249 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
\r
1250 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
\r
1251 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
\r
1253 padapter->securitypriv.busetkipkey=_FALSE;
\r
1254 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
\r
1257 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
\r
1258 DBG_871X(" ~~~~set sta key:unicastkey\n");
\r
1260 rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE, _TRUE);
\r
1264 if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
\r
1266 _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
1267 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
\r
1268 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
\r
1269 padapter->securitypriv.binstallGrpkey = _TRUE;
\r
1270 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
\r
1271 DBG_871X(" ~~~~set sta key:groupkey\n");
\r
1273 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
\r
1274 #ifdef CONFIG_CONCURRENT_MODE
\r
1275 if (padapter->adapter_type == PRIMARY_ADAPTER)
\r
1276 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1, _TRUE);
\r
1278 DBG_871X_LEVEL(_drv_always_, "second interface do not set cam.\n");
\r
1280 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1, _TRUE);
\r
1283 #ifdef CONFIG_IEEE80211W
\r
1284 else if(strcmp(param->u.crypt.alg, "BIP") == 0)
\r
1287 //DBG_871X("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx);
\r
1288 //save the IGTK key, length 16 bytes
\r
1289 _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
1290 /*DBG_871X("IGTK key below:\n");
\r
1291 for(no=0;no<16;no++)
\r
1292 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
\r
1294 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
\r
1295 padapter->securitypriv.binstallBIPkey = _TRUE;
\r
1296 DBG_871X(" ~~~~set sta key:IGKT\n");
\r
1298 #endif //CONFIG_IEEE80211W
\r
1301 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1303 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
\r
1305 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
\r
1308 #endif //CONFIG_P2P
\r
1313 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
\r
1314 if(pbcmc_sta==NULL)
\r
1316 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
\r
1320 //Jeff: don't disable ieee8021x_blocked while clearing key
\r
1321 if (strcmp(param->u.crypt.alg, "none") != 0)
\r
1322 pbcmc_sta->ieee8021x_blocked = _FALSE;
\r
1324 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
\r
1325 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
\r
1327 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
\r
1331 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
\r
1336 #ifdef CONFIG_WAPI_SUPPORT
\r
1337 if (strcmp(param->u.crypt.alg, "SMS4") == 0)
\r
1339 PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
\r
1340 PRT_WAPI_STA_INFO pWapiSta;
\r
1341 u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1342 u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1343 u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
\r
1345 if(param->u.crypt.set_tx == 1)
\r
1347 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
\r
1348 if(_rtw_memcmp(pWapiSta->PeerMacAddr,param->sta_addr,6))
\r
1350 _rtw_memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
\r
1352 pWapiSta->wapiUsk.bSet = true;
\r
1353 _rtw_memcpy(pWapiSta->wapiUsk.dataKey,param->u.crypt.key,16);
\r
1354 _rtw_memcpy(pWapiSta->wapiUsk.micKey,param->u.crypt.key+16,16);
\r
1355 pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
\r
1356 pWapiSta->wapiUsk.bTxEnable = true;
\r
1358 _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16);
\r
1359 _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16);
\r
1360 _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16);
\r
1361 _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16);
\r
1362 _rtw_memcpy(pWapiSta->lastRxUnicastPN,WapiAEPNInitialValueSrc,16);
\r
1363 pWapiSta->wapiUskUpdate.bTxEnable = false;
\r
1364 pWapiSta->wapiUskUpdate.bSet = false;
\r
1366 if (psecuritypriv->sw_encrypt== false || psecuritypriv->sw_decrypt == false)
\r
1368 //set unicast key for ASUE
\r
1369 rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
\r
1376 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
\r
1377 if(_rtw_memcmp(pWapiSta->PeerMacAddr,get_bssid(pmlmepriv),6))
\r
1379 pWapiSta->wapiMsk.bSet = true;
\r
1380 _rtw_memcpy(pWapiSta->wapiMsk.dataKey,param->u.crypt.key,16);
\r
1381 _rtw_memcpy(pWapiSta->wapiMsk.micKey,param->u.crypt.key+16,16);
\r
1382 pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
\r
1383 pWapiSta->wapiMsk.bTxEnable = false;
\r
1384 if(!pWapiSta->bSetkeyOk)
\r
1385 pWapiSta->bSetkeyOk = true;
\r
1386 pWapiSta->bAuthenticateInProgress = false;
\r
1388 _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
\r
1390 if (psecuritypriv->sw_decrypt == false)
\r
1392 //set rx broadcast key for ASUE
\r
1393 rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
\r
1405 DBG_8192C("%s, ret=%d\n", __func__, ret);
\r
1412 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1413 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1414 u8 key_index, bool pairwise, const u8 *mac_addr,
\r
1415 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1416 u8 key_index, const u8 *mac_addr,
\r
1417 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1418 struct key_params *params)
\r
1422 struct ieee_param *param = NULL;
\r
1424 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1425 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
1426 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1428 DBG_871X(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
\r
1429 DBG_871X("cipher=0x%x\n", params->cipher);
\r
1430 DBG_871X("key_len=0x%x\n", params->key_len);
\r
1431 DBG_871X("seq_len=0x%x\n", params->seq_len);
\r
1432 DBG_871X("key_index=%d\n", key_index);
\r
1433 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1434 DBG_871X("pairwise=%d\n", pairwise);
\r
1435 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1437 param_len = sizeof(struct ieee_param) + params->key_len;
\r
1438 param = (struct ieee_param *)rtw_malloc(param_len);
\r
1439 if (param == NULL)
\r
1442 _rtw_memset(param, 0, param_len);
\r
1444 param->cmd = IEEE_CMD_SET_ENCRYPTION;
\r
1445 _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
\r
1447 switch (params->cipher) {
\r
1448 case IW_AUTH_CIPHER_NONE:
\r
1449 //todo: remove key
\r
1451 alg_name = "none";
\r
1453 case WLAN_CIPHER_SUITE_WEP40:
\r
1454 case WLAN_CIPHER_SUITE_WEP104:
\r
1457 case WLAN_CIPHER_SUITE_TKIP:
\r
1458 alg_name = "TKIP";
\r
1460 case WLAN_CIPHER_SUITE_CCMP:
\r
1461 alg_name = "CCMP";
\r
1463 #ifdef CONFIG_IEEE80211W
\r
1464 case WLAN_CIPHER_SUITE_AES_CMAC:
\r
1467 #endif //CONFIG_IEEE80211W
\r
1468 #ifdef CONFIG_WAPI_SUPPORT
\r
1469 case WLAN_CIPHER_SUITE_SMS4:
\r
1471 if(pairwise == NL80211_KEYTYPE_PAIRWISE) {
\r
1472 if (key_index != 0 && key_index != 1) {
\r
1476 _rtw_memcpy((void*)param->sta_addr, (void*)mac_addr, ETH_ALEN);
\r
1478 DBG_871X("mac_addr is null \n");
\r
1480 DBG_871X("rtw_wx_set_enc_ext: SMS4 case \n");
\r
1489 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
\r
1492 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
\r
1494 param->u.crypt.set_tx = 0; //for wpa/wpa2 group key
\r
1496 param->u.crypt.set_tx = 1; //for wpa/wpa2 pairwise key
\r
1500 //param->u.crypt.idx = key_index - 1;
\r
1501 param->u.crypt.idx = key_index;
\r
1503 if (params->seq_len && params->seq)
\r
1505 _rtw_memcpy(param->u.crypt.seq, params->seq, params->seq_len);
\r
1508 if(params->key_len && params->key)
\r
1510 param->u.crypt.key_len = params->key_len;
\r
1511 _rtw_memcpy(param->u.crypt.key, params->key, params->key_len);
\r
1514 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
\r
1516 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
\r
1518 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
1520 #ifdef CONFIG_AP_MODE
\r
1522 _rtw_memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN);
\r
1524 ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
\r
1529 DBG_8192C("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
\r
1536 rtw_mfree((u8*)param, param_len);
\r
1543 static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1544 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1545 u8 key_index, bool pairwise, const u8 *mac_addr,
\r
1546 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1547 u8 key_index, const u8 *mac_addr,
\r
1548 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1550 void (*callback)(void *cookie,
\r
1551 struct key_params*))
\r
1554 struct iwm_priv *iwm = ndev_to_iwm(ndev);
\r
1555 struct iwm_key *key = &iwm->keys[key_index];
\r
1556 struct key_params params;
\r
1558 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
\r
1560 memset(¶ms, 0, sizeof(params));
\r
1562 params.cipher = key->cipher;
\r
1563 params.key_len = key->key_len;
\r
1564 params.seq_len = key->seq_len;
\r
1565 params.seq = key->seq;
\r
1566 params.key = key->key;
\r
1568 callback(cookie, ¶ms);
\r
1570 return key->key_len ? 0 : -ENOENT;
\r
1572 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
1576 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
\r
1577 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
1578 u8 key_index, bool pairwise, const u8 *mac_addr)
\r
1579 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1580 u8 key_index, const u8 *mac_addr)
\r
1581 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
\r
1583 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1584 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1586 DBG_871X(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index);
\r
1588 if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
\r
1590 //clear the flag of wep default key set.
\r
1591 psecuritypriv->bWepDefaultKeyIdxSet = 0;
\r
1597 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
\r
1598 struct net_device *ndev, u8 key_index
\r
1599 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1600 , bool unicast, bool multicast
\r
1604 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1605 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
1607 DBG_871X(FUNC_NDEV_FMT" key_index=%d"
\r
1608 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1609 ", unicast=%d, multicast=%d"
\r
1611 ".\n", FUNC_NDEV_ARG(ndev), key_index
\r
1612 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
1613 , unicast, multicast
\r
1617 if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) //set wep default key
\r
1619 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
1621 psecuritypriv->dot11PrivacyKeyIndex = key_index;
\r
1623 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
\r
1624 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
\r
1625 if (psecuritypriv->dot11DefKeylen[key_index] == 13)
\r
1627 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
\r
1628 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
\r
1631 psecuritypriv->bWepDefaultKeyIdxSet = 1; //set the flag to represent that wep default key has been set
\r
1638 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
\r
1639 struct net_device *ndev,
\r
1640 u8 *mac, struct station_info *sinfo)
\r
1643 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1644 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
1645 struct sta_info *psta = NULL;
\r
1646 struct sta_priv *pstapriv = &padapter->stapriv;
\r
1648 sinfo->filled = 0;
\r
1651 DBG_871X(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
\r
1656 psta = rtw_get_stainfo(pstapriv, mac);
\r
1657 if (psta == NULL) {
\r
1658 DBG_8192C("%s, sta_info is null\n", __func__);
\r
1663 #ifdef CONFIG_DEBUG_CFG80211
\r
1664 DBG_871X(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
\r
1667 //for infra./P2PClient mode
\r
1668 if( check_fwstate(pmlmepriv, WIFI_STATION_STATE)
\r
1669 && check_fwstate(pmlmepriv, _FW_LINKED)
\r
1672 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
\r
1674 if (_rtw_memcmp(mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) {
\r
1675 DBG_871X("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
\r
1680 sinfo->filled |= STATION_INFO_SIGNAL;
\r
1681 sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
\r
1683 sinfo->filled |= STATION_INFO_TX_BITRATE;
\r
1684 sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
\r
1686 sinfo->filled |= STATION_INFO_RX_PACKETS;
\r
1687 sinfo->rx_packets = sta_rx_data_pkts(psta);
\r
1689 sinfo->filled |= STATION_INFO_TX_PACKETS;
\r
1690 sinfo->tx_packets = psta->sta_stats.tx_pkts;
\r
1694 //for Ad-Hoc/AP mode
\r
1695 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
\r
1696 ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
\r
1697 ||check_fwstate(pmlmepriv, WIFI_AP_STATE))
\r
1698 && check_fwstate(pmlmepriv, _FW_LINKED)
\r
1701 //TODO: should acquire station info...
\r
1708 extern int netdev_open(struct net_device *pnetdev);
\r
1709 #ifdef CONFIG_CONCURRENT_MODE
\r
1710 extern int netdev_if2_open(struct net_device *pnetdev);
\r
1714 enum nl80211_iftype {
\r
1715 NL80211_IFTYPE_UNSPECIFIED,
\r
1716 NL80211_IFTYPE_ADHOC, //1
\r
1717 NL80211_IFTYPE_STATION, //2
\r
1718 NL80211_IFTYPE_AP, //3
\r
1719 NL80211_IFTYPE_AP_VLAN,
\r
1720 NL80211_IFTYPE_WDS,
\r
1721 NL80211_IFTYPE_MONITOR, //6
\r
1722 NL80211_IFTYPE_MESH_POINT,
\r
1723 NL80211_IFTYPE_P2P_CLIENT, //8
\r
1724 NL80211_IFTYPE_P2P_GO, //9
\r
1726 NUM_NL80211_IFTYPES,
\r
1727 NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
\r
1730 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
\r
1731 struct net_device *ndev,
\r
1732 enum nl80211_iftype type, u32 *flags,
\r
1733 struct vif_params *params)
\r
1735 enum nl80211_iftype old_type;
\r
1736 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
\r
1737 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
1738 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
1739 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
1741 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
1744 u8 change = _FALSE;
\r
1746 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
1748 if(adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE)
\r
1754 #ifdef CONFIG_CONCURRENT_MODE
\r
1755 if(padapter->adapter_type == SECONDARY_ADAPTER)
\r
1757 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev));
\r
1758 if(netdev_if2_open(ndev) != 0) {
\r
1763 else if(padapter->adapter_type == PRIMARY_ADAPTER)
\r
1764 #endif //CONFIG_CONCURRENT_MODE
\r
1766 DBG_871X(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
\r
1767 if(netdev_open(ndev) != 0) {
\r
1773 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
1778 old_type = rtw_wdev->iftype;
\r
1779 DBG_871X(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
\r
1780 FUNC_NDEV_ARG(ndev), old_type, type);
\r
1782 if(old_type != type)
\r
1785 pmlmeext->action_public_rxseq = 0xffff;
\r
1786 pmlmeext->action_public_dialog_token = 0xff;
\r
1790 case NL80211_IFTYPE_ADHOC:
\r
1791 networkType = Ndis802_11IBSS;
\r
1793 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1794 case NL80211_IFTYPE_P2P_CLIENT:
\r
1796 case NL80211_IFTYPE_STATION:
\r
1797 networkType = Ndis802_11Infrastructure;
\r
1799 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1801 if(change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
1803 //it means remove GO and change mode from AP(GO) to station(P2P DEVICE)
\r
1804 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
\r
1805 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
1807 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
1810 #endif //CONFIG_P2P
\r
1812 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
1813 case NL80211_IFTYPE_P2P_GO:
\r
1815 case NL80211_IFTYPE_AP:
\r
1816 networkType = Ndis802_11APMode;
\r
1818 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
1820 if(change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
1822 //it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO)
\r
1823 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
\r
1826 #endif //CONFIG_P2P
\r
1829 return -EOPNOTSUPP;
\r
1832 rtw_wdev->iftype = type;
\r
1834 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE)
\r
1836 rtw_wdev->iftype = old_type;
\r
1841 rtw_setopmode_cmd(padapter, networkType,_TRUE);
\r
1848 void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted)
\r
1850 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
1853 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
1854 if (pwdev_priv->scan_request != NULL) {
\r
1855 #ifdef CONFIG_DEBUG_CFG80211
\r
1856 DBG_871X("%s with scan req\n", __FUNCTION__);
\r
1859 /* avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); */
\r
1860 if(pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
\r
1862 DBG_8192C("error wiphy compare\n");
\r
1866 cfg80211_scan_done(pwdev_priv->scan_request, aborted);
\r
1869 pwdev_priv->scan_request = NULL;
\r
1871 #ifdef CONFIG_DEBUG_CFG80211
\r
1872 DBG_871X("%s without scan req\n", __FUNCTION__);
\r
1875 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
1878 void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
\r
1881 _list *plist, *phead;
\r
1882 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
1883 _queue *queue = &(pmlmepriv->scanned_queue);
\r
1884 struct wlan_network *pnetwork = NULL;
\r
1886 u32 wait_for_surveydone;
\r
1889 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
\r
1890 #endif //CONFIG_P2P
\r
1891 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
1893 #ifdef CONFIG_DEBUG_CFG80211
\r
1894 DBG_8192C("%s\n", __func__);
\r
1897 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
1899 phead = get_list_head(queue);
\r
1900 plist = get_next(phead);
\r
1904 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
\r
1907 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
\r
1909 //report network only if the current channel set contains the channel to which this network belongs
\r
1910 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
\r
1911 && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
\r
1912 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
\r
1915 //ev=translate_scan(padapter, a, pnetwork, ev, stop);
\r
1916 rtw_cfg80211_inform_bss(padapter, pnetwork);
\r
1919 plist = get_next(plist);
\r
1923 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
\r
1926 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
\r
1929 uint wps_ielen = 0;
\r
1931 u32 p2p_ielen = 0;
\r
1933 u32 wfd_ielen = 0;
\r
1935 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
1937 #ifdef CONFIG_DEBUG_CFG80211
\r
1938 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
1943 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
1945 #ifdef CONFIG_DEBUG_CFG80211
\r
1946 DBG_8192C("probe_req_wps_ielen=%d\n", wps_ielen);
\r
1949 if(pmlmepriv->wps_probe_req_ie)
\r
1951 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
\r
1952 pmlmepriv->wps_probe_req_ie_len = 0;
\r
1953 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
\r
1954 pmlmepriv->wps_probe_req_ie = NULL;
\r
1957 pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
\r
1958 if ( pmlmepriv->wps_probe_req_ie == NULL) {
\r
1959 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
1963 _rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
\r
1964 pmlmepriv->wps_probe_req_ie_len = wps_ielen;
\r
1967 //buf += wps_ielen;
\r
1968 //len -= wps_ielen;
\r
1971 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
1973 struct wifidirect_info *wdinfo = &padapter->wdinfo;
\r
1974 u32 attr_contentlen = 0;
\r
1975 u8 listen_ch_attr[5];
\r
1977 #ifdef CONFIG_DEBUG_CFG80211
\r
1978 DBG_8192C("probe_req_p2p_ielen=%d\n", p2p_ielen);
\r
1981 if(pmlmepriv->p2p_probe_req_ie)
\r
1983 u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
\r
1984 pmlmepriv->p2p_probe_req_ie_len = 0;
\r
1985 rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len);
\r
1986 pmlmepriv->p2p_probe_req_ie = NULL;
\r
1989 pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen);
\r
1990 if ( pmlmepriv->p2p_probe_req_ie == NULL) {
\r
1991 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
1995 _rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
\r
1996 pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
\r
1998 if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8*)listen_ch_attr, (uint*) &attr_contentlen)
\r
1999 && attr_contentlen == 5)
\r
2001 if (wdinfo->listen_channel != listen_ch_attr[4]) {
\r
2002 DBG_871X(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n",
\r
2003 FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2],
\r
2004 listen_ch_attr[3], listen_ch_attr[4]);
\r
2005 wdinfo->listen_channel = listen_ch_attr[4];
\r
2009 #endif //CONFIG_P2P
\r
2011 //buf += p2p_ielen;
\r
2012 //len -= p2p_ielen;
\r
2015 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
2017 #ifdef CONFIG_DEBUG_CFG80211
\r
2018 DBG_8192C("probe_req_wfd_ielen=%d\n", wfd_ielen);
\r
2021 if(pmlmepriv->wfd_probe_req_ie)
\r
2023 u32 free_len = pmlmepriv->wfd_probe_req_ie_len;
\r
2024 pmlmepriv->wfd_probe_req_ie_len = 0;
\r
2025 rtw_mfree(pmlmepriv->wfd_probe_req_ie, free_len);
\r
2026 pmlmepriv->wfd_probe_req_ie = NULL;
\r
2029 pmlmepriv->wfd_probe_req_ie = rtw_malloc(wfd_ielen);
\r
2030 if ( pmlmepriv->wfd_probe_req_ie == NULL) {
\r
2031 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2035 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
\r
2037 #endif //CONFIG_WFD
\r
2045 static int cfg80211_rtw_scan(struct wiphy *wiphy
\r
2046 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
\r
2047 , struct net_device *ndev
\r
2049 , struct cfg80211_scan_request *request)
\r
2051 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
2052 struct net_device *ndev = wdev_to_ndev(request->wdev);
\r
2055 u8 _status = _FALSE;
\r
2057 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
\r
2058 struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
\r
2061 uint wps_ielen=0;
\r
2064 u8 survey_times=3;
\r
2065 u8 survey_times_for_one_ch=6;
\r
2066 struct cfg80211_ssid *ssids = request->ssids;
\r
2067 int social_channel = 0, j = 0;
\r
2068 bool need_indicate_scan_done = _FALSE;
\r
2070 _adapter *padapter;
\r
2071 struct rtw_wdev_priv *pwdev_priv;
\r
2072 struct mlme_priv *pmlmepriv;
\r
2074 struct wifidirect_info *pwdinfo;
\r
2075 #endif //CONFIG_P2P
\r
2076 #ifdef CONFIG_CONCURRENT_MODE
\r
2077 PADAPTER pbuddy_adapter = NULL;
\r
2078 struct mlme_priv *pbuddy_mlmepriv = NULL;
\r
2079 #endif //CONFIG_CONCURRENT_MODE
\r
2081 if (ndev == NULL) {
\r
2086 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2087 pwdev_priv = adapter_wdev_data(padapter);
\r
2088 pmlmepriv= &padapter->mlmepriv;
\r
2090 pwdinfo= &(padapter->wdinfo);
\r
2091 #endif //CONFIG_P2P
\r
2093 //#ifdef CONFIG_DEBUG_CFG80211
\r
2094 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
2097 #ifdef CONFIG_CONCURRENT_MODE
\r
2098 if (padapter->pbuddy_adapter) {
\r
2099 pbuddy_adapter = padapter->pbuddy_adapter;
\r
2100 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
\r
2102 #endif //CONFIG_CONCURRENT_MODE
\r
2104 #ifdef CONFIG_MP_INCLUDED
\r
2105 if (padapter->registrypriv.mp_mode == 1)
\r
2107 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter));
\r
2111 #ifdef CONFIG_CONCURRENT_MODE
\r
2112 if (padapter->pbuddy_adapter) {
\r
2113 if (padapter->pbuddy_adapter->registrypriv.mp_mode == 1)
\r
2115 DBG_871X(FUNC_ADPT_FMT ": MP mode block Scan request\n", FUNC_ADPT_ARG(padapter->pbuddy_adapter));
\r
2120 #endif //CONFIG_CONCURRENT_MODE
\r
2123 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2124 pwdev_priv->scan_request = request;
\r
2125 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
\r
2127 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
\r
2129 #ifdef CONFIG_DEBUG_CFG80211
\r
2130 DBG_871X("%s under WIFI_AP_STATE\n", __FUNCTION__);
\r
2133 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
\r
2135 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2137 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
\r
2139 DBG_8192C("AP mode process WPS \n");
\r
2142 need_indicate_scan_done = _TRUE;
\r
2143 goto check_need_indicate_scan_done;
\r
2147 rtw_ps_deny(padapter, PS_DENY_SCAN);
\r
2148 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
2149 need_indicate_scan_done = _TRUE;
\r
2150 goto check_need_indicate_scan_done;
\r
2154 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
2156 if(ssids->ssid != NULL
\r
2157 && _rtw_memcmp(ssids->ssid, "DIRECT-", 7)
\r
2158 && rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
\r
2161 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2163 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
\r
2164 adapter_wdev_data(padapter)->p2p_enabled = _TRUE;
\r
2168 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
2169 #ifdef CONFIG_DEBUG_CFG80211
\r
2170 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
2173 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
\r
2175 if(request->n_channels == 3 &&
\r
2176 request->channels[0]->hw_value == 1 &&
\r
2177 request->channels[1]->hw_value == 6 &&
\r
2178 request->channels[2]->hw_value == 11
\r
2181 social_channel = 1;
\r
2185 #endif //CONFIG_P2P
\r
2187 if(request->ie && request->ie_len>0)
\r
2189 rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len );
\r
2192 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
\r
2193 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2194 need_indicate_scan_done = _TRUE;
\r
2195 goto check_need_indicate_scan_done;
\r
2196 } else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
2197 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
\r
2199 goto check_need_indicate_scan_done;
\r
2202 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)
\r
2204 #if 1 // Miracast can't do AP scan
\r
2205 static u32 lastscantime = 0;
\r
2208 passtime = rtw_get_passing_time_ms(lastscantime);
\r
2209 lastscantime = rtw_get_current_time();
\r
2210 if (passtime > 12000)
\r
2213 DBG_871X("%s: bBusyTraffic == _TRUE\n", __FUNCTION__);
\r
2214 need_indicate_scan_done = _TRUE;
\r
2215 goto check_need_indicate_scan_done;
\r
2219 if (rtw_is_scan_deny(padapter)){
\r
2220 DBG_871X(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter));
\r
2221 need_indicate_scan_done = _TRUE;
\r
2222 goto check_need_indicate_scan_done;
\r
2225 #ifdef CONFIG_CONCURRENT_MODE
\r
2226 if(pbuddy_mlmepriv && (pbuddy_mlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))
\r
2228 #if 1 // Miracast can't do AP scan
\r
2229 static u32 buddylastscantime = 0;
\r
2232 passtime = rtw_get_passing_time_ms(buddylastscantime);
\r
2233 buddylastscantime = rtw_get_current_time();
\r
2234 if ((passtime > 12000)
\r
2236 ||(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
\r
2237 #endif //CONFIG_P2P
\r
2241 DBG_871X("%s: bBusyTraffic == _TRUE at buddy_intf\n", __FUNCTION__);
\r
2242 need_indicate_scan_done = _TRUE;
\r
2243 goto check_need_indicate_scan_done;
\r
2247 if (check_buddy_fwstate(padapter,
\r
2248 _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
\r
2250 if(check_buddy_fwstate(padapter, _FW_UNDER_SURVEY))
\r
2252 DBG_8192C("scanning_via_buddy_intf\n");
\r
2253 pmlmepriv->scanning_via_buddy_intf = _TRUE;
\r
2256 DBG_8192C("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv->fw_state);
\r
2258 need_indicate_scan_done = _TRUE;
\r
2259 goto check_need_indicate_scan_done;
\r
2265 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
\r
2267 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
\r
2269 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
\r
2270 rtw_free_network_queue(padapter, _TRUE);
\r
2272 if(social_channel == 0)
\r
2273 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
\r
2275 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
\r
2278 #endif //CONFIG_P2P
\r
2281 _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
\r
2282 //parsing request ssids, n_ssids
\r
2283 for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
\r
2284 #ifdef CONFIG_DEBUG_CFG80211
\r
2285 DBG_8192C("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
\r
2287 _rtw_memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
\r
2288 ssid[i].SsidLength = ssids[i].ssid_len;
\r
2291 /* parsing channels, n_channels */
\r
2292 _rtw_memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
\r
2293 for (i=0;i<request->n_channels && i<RTW_CHANNEL_SCAN_AMOUNT;i++) {
\r
2294 #ifdef CONFIG_DEBUG_CFG80211
\r
2295 DBG_871X(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
\r
2297 ch[i].hw_value = request->channels[i]->hw_value;
\r
2298 ch[i].flags = request->channels[i]->flags;
\r
2301 _enter_critical_bh(&pmlmepriv->lock, &irqL);
\r
2302 if (request->n_channels == 1) {
\r
2303 for(i=1;i<survey_times_for_one_ch;i++)
\r
2304 _rtw_memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
\r
2305 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times_for_one_ch);
\r
2306 } else if (request->n_channels <= 4) {
\r
2307 for(j=request->n_channels-1;j>=0;j--)
\r
2308 for(i=0;i<survey_times;i++)
\r
2310 _rtw_memcpy(&ch[j*survey_times+i], &ch[j], sizeof(struct rtw_ieee80211_channel));
\r
2312 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * request->n_channels);
\r
2314 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
\r
2316 _exit_critical_bh(&pmlmepriv->lock, &irqL);
\r
2319 if(_status == _FALSE)
\r
2324 check_need_indicate_scan_done:
\r
2325 if (_TRUE == need_indicate_scan_done)
\r
2327 rtw_cfg80211_surveydone_event_callback(padapter);
\r
2328 rtw_cfg80211_indicate_scan_done(padapter, _FALSE);
\r
2332 rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
\r
2339 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
\r
2342 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
\r
2344 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
\r
2345 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
\r
2348 iwm->conf.rts_threshold = wiphy->rts_threshold;
\r
2350 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
\r
2351 CFG_RTS_THRESHOLD,
\r
2352 iwm->conf.rts_threshold);
\r
2357 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
\r
2358 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
\r
2361 iwm->conf.frag_threshold = wiphy->frag_threshold;
\r
2363 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
\r
2364 CFG_FRAG_THRESHOLD,
\r
2365 iwm->conf.frag_threshold);
\r
2370 DBG_8192C("%s\n", __func__);
\r
2376 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
\r
2378 DBG_8192C("%s, wpa_version=%d\n", __func__, wpa_version);
\r
2380 if (!wpa_version) {
\r
2381 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
2386 if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
\r
2388 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
\r
2392 if (wpa_version & NL80211_WPA_VERSION_2)
\r
2394 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
\r
2398 #ifdef CONFIG_WAPI_SUPPORT
\r
2399 if (wpa_version & NL80211_WAPI_VERSION_1)
\r
2401 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWAPI;
\r
2409 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
\r
2410 enum nl80211_auth_type sme_auth_type)
\r
2412 DBG_8192C("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
\r
2415 switch (sme_auth_type) {
\r
2416 case NL80211_AUTHTYPE_AUTOMATIC:
\r
2418 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
\r
2421 case NL80211_AUTHTYPE_OPEN_SYSTEM:
\r
2423 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
\r
2425 if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
\r
2426 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2428 #ifdef CONFIG_WAPI_SUPPORT
\r
2429 if(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI)
\r
2430 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2434 case NL80211_AUTHTYPE_SHARED_KEY:
\r
2436 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
\r
2438 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2443 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
\r
2444 //return -ENOTSUPP;
\r
2451 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
\r
2453 u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2455 u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
\r
2456 &psecuritypriv->dot118021XGrpPrivacy;
\r
2458 DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
\r
2462 *profile_cipher = _NO_PRIVACY_;
\r
2463 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
\r
2468 case IW_AUTH_CIPHER_NONE:
\r
2469 *profile_cipher = _NO_PRIVACY_;
\r
2470 ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2471 #ifdef CONFIG_WAPI_SUPPORT
\r
2472 if(psecuritypriv->dot11PrivacyAlgrthm ==_SMS4_ )
\r
2474 *profile_cipher = _SMS4_;
\r
2478 case WLAN_CIPHER_SUITE_WEP40:
\r
2479 *profile_cipher = _WEP40_;
\r
2480 ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2482 case WLAN_CIPHER_SUITE_WEP104:
\r
2483 *profile_cipher = _WEP104_;
\r
2484 ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2486 case WLAN_CIPHER_SUITE_TKIP:
\r
2487 *profile_cipher = _TKIP_;
\r
2488 ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2490 case WLAN_CIPHER_SUITE_CCMP:
\r
2491 *profile_cipher = _AES_;
\r
2492 ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2494 #ifdef CONFIG_WAPI_SUPPORT
\r
2495 case WLAN_CIPHER_SUITE_SMS4:
\r
2496 *profile_cipher = _SMS4_;
\r
2497 ndisencryptstatus = Ndis802_11_EncrypteionWAPI;
\r
2501 DBG_8192C("Unsupported cipher: 0x%x\n", cipher);
\r
2507 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
\r
2509 //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
\r
2510 // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
\r
2516 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
\r
2518 DBG_8192C("%s, key_mgt=0x%x\n", __func__, key_mgt);
\r
2520 if (key_mgt == WLAN_AKM_SUITE_8021X)
\r
2521 //*auth_type = UMAC_AUTH_TYPE_8021X;
\r
2522 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2523 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
\r
2524 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
\r
2526 #ifdef CONFIG_WAPI_SUPPORT
\r
2527 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_PSK){
\r
2528 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2530 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_CERT){
\r
2531 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
\r
2537 DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt);
\r
2544 static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
\r
2546 u8 *buf=NULL, *pos=NULL;
\r
2548 int group_cipher = 0, pairwise_cipher = 0;
\r
2553 u8 null_addr[]= {0,0,0,0,0,0};
\r
2555 if (pie == NULL || !ielen) {
\r
2556 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
\r
2557 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2561 if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
\r
2566 buf = rtw_zmalloc(ielen);
\r
2572 _rtw_memcpy(buf, pie , ielen);
\r
2577 DBG_8192C("set wpa_ie(length:%zu):\n", ielen);
\r
2578 for(i=0;i<ielen;i=i+8)
\r
2579 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
2583 if(ielen < RSN_HEADER_LEN){
\r
2584 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
\r
2589 pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
\r
2590 if(pwpa && wpa_ielen>0)
\r
2592 if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
2594 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
2595 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
\r
2596 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
\r
2598 DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
\r
2602 pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
\r
2603 if(pwpa2 && wpa2_ielen>0)
\r
2605 if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
\r
2607 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
\r
2608 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
\r
2609 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
\r
2611 DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
\r
2615 if (group_cipher == 0)
\r
2617 group_cipher = WPA_CIPHER_NONE;
\r
2619 if (pairwise_cipher == 0)
\r
2621 pairwise_cipher = WPA_CIPHER_NONE;
\r
2624 switch(group_cipher)
\r
2626 case WPA_CIPHER_NONE:
\r
2627 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
\r
2628 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
\r
2630 case WPA_CIPHER_WEP40:
\r
2631 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
\r
2632 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2634 case WPA_CIPHER_TKIP:
\r
2635 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
\r
2636 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2638 case WPA_CIPHER_CCMP:
\r
2639 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
\r
2640 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2642 case WPA_CIPHER_WEP104:
\r
2643 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
\r
2644 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2648 switch(pairwise_cipher)
\r
2650 case WPA_CIPHER_NONE:
\r
2651 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
\r
2652 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
\r
2654 case WPA_CIPHER_WEP40:
\r
2655 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
\r
2656 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2658 case WPA_CIPHER_TKIP:
\r
2659 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
\r
2660 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
\r
2662 case WPA_CIPHER_CCMP:
\r
2663 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
\r
2664 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
\r
2666 case WPA_CIPHER_WEP104:
\r
2667 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
\r
2668 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
\r
2672 {/* handle wps_ie */
\r
2676 wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
\r
2677 if (wps_ie && wps_ielen > 0) {
\r
2678 DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen);
\r
2679 padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
\r
2680 _rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
\r
2681 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2683 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2688 {//check p2p_ie for assoc req;
\r
2691 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2693 if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen)))
\r
2695 #ifdef CONFIG_DEBUG_CFG80211
\r
2696 DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
\r
2699 if(pmlmepriv->p2p_assoc_req_ie)
\r
2701 u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
\r
2702 pmlmepriv->p2p_assoc_req_ie_len = 0;
\r
2703 rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
\r
2704 pmlmepriv->p2p_assoc_req_ie = NULL;
\r
2707 pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
\r
2708 if ( pmlmepriv->p2p_assoc_req_ie == NULL) {
\r
2709 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2712 _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
\r
2713 pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
\r
2716 #endif //CONFIG_P2P
\r
2719 {//check wfd_ie for assoc req;
\r
2722 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
2724 if(rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen))
\r
2726 #ifdef CONFIG_DEBUG_CFG80211
\r
2727 DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
\r
2730 if(pmlmepriv->wfd_assoc_req_ie)
\r
2732 u32 free_len = pmlmepriv->wfd_assoc_req_ie_len;
\r
2733 pmlmepriv->wfd_assoc_req_ie_len = 0;
\r
2734 rtw_mfree(pmlmepriv->wfd_assoc_req_ie, free_len);
\r
2735 pmlmepriv->wfd_assoc_req_ie = NULL;
\r
2738 pmlmepriv->wfd_assoc_req_ie = rtw_malloc(wfd_ielen);
\r
2739 if ( pmlmepriv->wfd_assoc_req_ie == NULL) {
\r
2740 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
2743 rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
\r
2746 #endif //CONFIG_WFD
\r
2748 //TKIP and AES disallow multicast packets until installing group key
\r
2749 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
\r
2750 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
\r
2751 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
\r
2752 //WPS open need to enable multicast
\r
2753 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
\r
2754 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
\r
2756 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
\r
2757 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
\r
2758 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
\r
2762 rtw_mfree(buf, ielen);
\r
2764 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
\r
2768 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
\r
2769 struct cfg80211_ibss_params *params)
\r
2771 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2772 NDIS_802_11_SSID ndis_ssid;
\r
2773 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
2774 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2777 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
2782 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
\r
2787 #ifdef CONFIG_CONCURRENT_MODE
\r
2788 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
\r
2789 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
\r
2793 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
\r
2794 rtw_scan_abort(padapter->pbuddy_adapter);
\r
2796 #endif //CONFIG_CONCURRENT_MODE
\r
2798 if (!params->ssid || !params->ssid_len)
\r
2804 if (params->ssid_len > IW_ESSID_MAX_SIZE){
\r
2810 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
\r
2811 ndis_ssid.SsidLength = params->ssid_len;
\r
2812 _rtw_memcpy(ndis_ssid.Ssid, params->ssid, params->ssid_len);
\r
2814 //DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, params->ssid_len);
\r
2816 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2817 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
\r
2818 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
2819 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
\r
2820 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
2822 ret = rtw_cfg80211_set_auth_type(psecuritypriv, NL80211_AUTHTYPE_OPEN_SYSTEM);
\r
2823 rtw_set_802_11_authentication_mode(padapter, psecuritypriv->ndisauthtype);
\r
2825 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE)
\r
2835 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
\r
2837 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2838 struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
\r
2839 enum nl80211_iftype old_type;
\r
2842 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
2844 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
2846 old_type = rtw_wdev->iftype;
\r
2848 rtw_set_to_roam(padapter, 0);
\r
2850 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
2852 rtw_scan_abort(padapter);
\r
2853 LeaveAllPowerSaveMode(padapter);
\r
2855 rtw_wdev->iftype = NL80211_IFTYPE_STATION;
\r
2857 if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure) ==_FALSE)
\r
2859 rtw_wdev->iftype = old_type;
\r
2863 rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure,_TRUE);
\r
2867 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
2872 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
\r
2873 struct cfg80211_connect_params *sme)
\r
2878 struct wlan_network *pnetwork = NULL;
\r
2879 NDIS_802_11_AUTHENTICATION_MODE authmode;
\r
2880 NDIS_802_11_SSID ndis_ssid;
\r
2881 u8 *dst_ssid, *src_ssid;
\r
2882 u8 *dst_bssid, *src_bssid;
\r
2883 //u8 matched_by_bssid=_FALSE;
\r
2884 //u8 matched_by_ssid=_FALSE;
\r
2885 u8 matched=_FALSE;
\r
2886 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
2887 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
\r
2888 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
2889 _queue *queue = &pmlmepriv->scanned_queue;
\r
2891 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
2893 DBG_871X("=>"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
2894 DBG_871X("privacy=%d, key=%p, key_len=%d, key_idx=%d\n",
\r
2895 sme->privacy, sme->key, sme->key_len, sme->key_idx);
\r
2898 if(adapter_wdev_data(padapter)->block == _TRUE)
\r
2901 DBG_871X("%s wdev_priv.block is set\n", __FUNCTION__);
\r
2905 #ifdef CONFIG_PLATFORM_MSTAR
\r
2906 printk("MStar Android!\n");
\r
2907 if(adapter_wdev_data(padapter)->bandroid_scan == _FALSE)
\r
2910 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
\r
2911 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
2912 #endif //CONFIG_P2P
\r
2915 printk("Android hasn't attached yet!\n");
\r
2921 rtw_ps_deny(padapter, PS_DENY_JOIN);
\r
2922 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
2927 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
\r
2932 #ifdef CONFIG_CONCURRENT_MODE
\r
2933 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
\r
2934 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
\r
2938 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
\r
2939 rtw_scan_abort(padapter->pbuddy_adapter);
\r
2943 if (!sme->ssid || !sme->ssid_len)
\r
2949 if (sme->ssid_len > IW_ESSID_MAX_SIZE){
\r
2955 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
\r
2956 ndis_ssid.SsidLength = sme->ssid_len;
\r
2957 _rtw_memcpy(ndis_ssid.Ssid, sme->ssid, sme->ssid_len);
\r
2959 DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
\r
2963 DBG_8192C("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
\r
2966 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
\r
2968 DBG_8192C("%s, fw_state=0x%x, goto exit\n", __FUNCTION__, pmlmepriv->fw_state);
\r
2971 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
\r
2972 rtw_scan_abort(padapter);
\r
2975 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
\r
2976 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
\r
2977 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
\r
2978 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
\r
2979 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
\r
2981 #ifdef CONFIG_WAPI_SUPPORT
\r
2982 padapter->wapiInfo.bWapiEnable = false;
\r
2985 ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
\r
2989 #ifdef CONFIG_WAPI_SUPPORT
\r
2990 if(sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1)
\r
2992 padapter->wapiInfo.bWapiEnable = true;
\r
2993 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
\r
2994 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
\r
2998 ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
\r
3000 #ifdef CONFIG_WAPI_SUPPORT
\r
3001 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI)
\r
3002 padapter->mlmeextpriv.mlmext_info.auth_algo = psecuritypriv->dot11AuthAlgrthm;
\r
3009 DBG_8192C("%s, ie_len=%zu\n", __func__, sme->ie_len);
\r
3011 ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len);
\r
3015 if (sme->crypto.n_ciphers_pairwise) {
\r
3016 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
\r
3021 //For WEP Shared auth
\r
3022 if((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared
\r
3023 || psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && sme->key
\r
3026 u32 wep_key_idx, wep_key_len,wep_total_len;
\r
3027 NDIS_802_11_WEP *pwep = NULL;
\r
3028 DBG_871X("%s(): Shared/Auto WEP\n",__FUNCTION__);
\r
3030 wep_key_idx = sme->key_idx;
\r
3031 wep_key_len = sme->key_len;
\r
3033 if (sme->key_idx > WEP_KEYS) {
\r
3038 if (wep_key_len > 0)
\r
3040 wep_key_len = wep_key_len <= 5 ? 5 : 13;
\r
3041 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
\r
3042 pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
\r
3044 DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
\r
3049 _rtw_memset(pwep, 0, wep_total_len);
\r
3051 pwep->KeyLength = wep_key_len;
\r
3052 pwep->Length = wep_total_len;
\r
3054 if(wep_key_len==13)
\r
3056 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
\r
3057 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
\r
3065 pwep->KeyIndex = wep_key_idx;
\r
3066 pwep->KeyIndex |= 0x80000000;
\r
3068 _rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
\r
3070 if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
\r
3072 ret = -EOPNOTSUPP ;
\r
3076 rtw_mfree((u8 *)pwep,wep_total_len);
\r
3083 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
\r
3087 if (sme->crypto.n_akm_suites) {
\r
3088 ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
\r
3093 #ifdef CONFIG_WAPI_SUPPORT
\r
3094 if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_PSK){
\r
3095 padapter->wapiInfo.bWapiPSK = true;
\r
3097 else if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_CERT){
\r
3098 padapter->wapiInfo.bWapiPSK = false;
\r
3102 authmode = psecuritypriv->ndisauthtype;
\r
3103 rtw_set_802_11_authentication_mode(padapter, authmode);
\r
3105 //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
\r
3107 if (rtw_set_802_11_connect(padapter, sme->bssid, &ndis_ssid) == _FALSE) {
\r
3112 DBG_8192C("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy);
\r
3116 rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
\r
3118 DBG_8192C("<=%s, ret %d\n",__FUNCTION__, ret);
\r
3120 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3125 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
\r
3128 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3130 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3132 padapter->mlmepriv.not_indic_disco = _TRUE;
\r
3134 rtw_set_to_roam(padapter, 0);
\r
3136 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
3138 rtw_scan_abort(padapter);
\r
3139 LeaveAllPowerSaveMode(padapter);
\r
3140 rtw_disassoc_cmd(padapter, 500, _FALSE);
\r
3142 DBG_871X("%s...call rtw_indicate_disconnect\n", __FUNCTION__);
\r
3144 rtw_indicate_disconnect(padapter);
\r
3146 rtw_free_assoc_resources(padapter, 1);
\r
3147 rtw_pwr_wakeup(padapter);
\r
3150 padapter->mlmepriv.not_indic_disco = _FALSE;
\r
3155 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
\r
3156 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
\r
3157 struct wireless_dev *wdev,
\r
3159 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE)
\r
3160 enum nl80211_tx_power_setting type, int mbm)
\r
3162 enum tx_power_setting type, int dbm)
\r
3166 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
\r
3170 case NL80211_TX_POWER_AUTOMATIC:
\r
3172 case NL80211_TX_POWER_FIXED:
\r
3173 if (mbm < 0 || (mbm % 100))
\r
3174 return -EOPNOTSUPP;
\r
3176 if (!test_bit(IWM_STATUS_READY, &iwm->status))
\r
3179 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
\r
3180 CFG_TX_PWR_LIMIT_USR,
\r
3181 MBM_TO_DBM(mbm) * 2);
\r
3185 return iwm_tx_power_trigger(iwm);
\r
3187 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
\r
3188 return -EOPNOTSUPP;
\r
3191 DBG_8192C("%s\n", __func__);
\r
3195 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
\r
3196 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
\r
3197 struct wireless_dev *wdev,
\r
3201 DBG_8192C("%s\n", __func__);
\r
3208 inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
\r
3210 struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter);
\r
3211 return rtw_wdev_priv->power_mgmt;
\r
3214 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
\r
3215 struct net_device *ndev,
\r
3216 bool enabled, int timeout)
\r
3218 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3219 struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter);
\r
3221 DBG_871X(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
\r
3222 enabled, timeout);
\r
3224 rtw_wdev_priv->power_mgmt = enabled;
\r
3228 LPS_Leave(padapter, "CFG80211_PWRMGMT");
\r
3234 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
\r
3235 struct net_device *ndev,
\r
3236 struct cfg80211_pmksa *pmksa)
\r
3238 u8 index,blInserted = _FALSE;
\r
3239 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3240 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3241 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
\r
3243 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3245 if ( _rtw_memcmp( pmksa->bssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
\r
3250 blInserted = _FALSE;
\r
3253 for(index=0 ; index<NUM_PMKID_CACHE; index++)
\r
3255 if( _rtw_memcmp( psecuritypriv->PMKIDList[index].Bssid, pmksa->bssid, ETH_ALEN) ==_TRUE )
\r
3256 { // BSSID is matched, the same AP => rewrite with new PMKID.
\r
3257 DBG_871X(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(ndev));
\r
3259 _rtw_memcpy( psecuritypriv->PMKIDList[index].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
\r
3260 psecuritypriv->PMKIDList[index].bUsed = _TRUE;
\r
3261 psecuritypriv->PMKIDIndex = index+1;
\r
3262 blInserted = _TRUE;
\r
3269 // Find a new entry
\r
3270 DBG_871X(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
\r
3271 FUNC_NDEV_ARG(ndev), psecuritypriv->PMKIDIndex );
\r
3273 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, pmksa->bssid, ETH_ALEN);
\r
3274 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
\r
3276 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
\r
3277 psecuritypriv->PMKIDIndex++ ;
\r
3278 if(psecuritypriv->PMKIDIndex==16)
\r
3280 psecuritypriv->PMKIDIndex =0;
\r
3287 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
\r
3288 struct net_device *ndev,
\r
3289 struct cfg80211_pmksa *pmksa)
\r
3291 u8 index, bMatched = _FALSE;
\r
3292 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3293 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3295 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3297 for(index=0 ; index<NUM_PMKID_CACHE; index++)
\r
3299 if( _rtw_memcmp( psecuritypriv->PMKIDList[index].Bssid, pmksa->bssid, ETH_ALEN) ==_TRUE )
\r
3300 { // BSSID is matched, the same AP => Remove this PMKID information and reset it.
\r
3301 _rtw_memset( psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN );
\r
3302 _rtw_memset( psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN );
\r
3303 psecuritypriv->PMKIDList[index].bUsed = _FALSE;
\r
3309 if(_FALSE == bMatched)
\r
3311 DBG_871X(FUNC_NDEV_FMT" do not have matched BSSID\n"
\r
3312 , FUNC_NDEV_ARG(ndev));
\r
3319 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
\r
3320 struct net_device *ndev)
\r
3322 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3323 struct security_priv *psecuritypriv = &padapter->securitypriv;
\r
3325 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3327 _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
\r
3328 psecuritypriv->PMKIDIndex = 0;
\r
3333 #ifdef CONFIG_AP_MODE
\r
3334 void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
3338 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
3339 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3340 struct net_device *ndev = padapter->pnetdev;
\r
3342 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
3344 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
\r
3346 struct station_info sinfo;
\r
3348 if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
\r
3349 ie_offset = _ASOCREQ_IE_OFFSET_;
\r
3350 else // WIFI_REASSOCREQ
\r
3351 ie_offset = _REASOCREQ_IE_OFFSET_;
\r
3354 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
\r
3355 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
\r
3356 sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
\r
3357 cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
\r
3359 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3360 channel = pmlmeext->cur_channel;
\r
3361 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
3362 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
3364 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
3366 #ifdef COMPAT_KERNEL_RELEASE
\r
3367 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3368 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
3369 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3370 #else //COMPAT_KERNEL_RELEASE
\r
3372 //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc()
\r
3373 #ifndef CONFIG_PLATFORM_MSTAR
\r
3374 pwdev->iftype = NL80211_IFTYPE_STATION;
\r
3375 #endif //CONFIG_PLATFORM_MSTAR
\r
3376 DBG_8192C("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
\r
3377 rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
\r
3378 DBG_8192C("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
\r
3379 pwdev->iftype = NL80211_IFTYPE_AP;
\r
3380 //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
3382 #endif //COMPAT_KERNEL_RELEASE
\r
3383 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3387 void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason)
\r
3393 struct rtw_ieee80211_hdr *pwlanhdr;
\r
3394 unsigned short *fctrl;
\r
3395 u8 mgmt_buf[128] = {0};
\r
3396 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3397 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
3398 struct net_device *ndev = padapter->pnetdev;
\r
3400 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
3402 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
\r
3403 cfg80211_del_sta(ndev, da, GFP_ATOMIC);
\r
3404 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3405 channel = pmlmeext->cur_channel;
\r
3406 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
3407 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
3409 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
3411 pmgmt_frame = mgmt_buf;
\r
3412 pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
\r
3414 fctrl = &(pwlanhdr->frame_ctl);
\r
3417 //_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
\r
3418 //_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
3419 _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
3420 _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN);
\r
3421 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
\r
3423 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
3424 pmlmeext->mgnt_seq++;
\r
3425 SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
\r
3427 pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
3428 frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
3430 reason = cpu_to_le16(reason);
\r
3431 pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
\r
3433 #ifdef COMPAT_KERNEL_RELEASE
\r
3434 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3435 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
\r
3436 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3437 #else //COMPAT_KERNEL_RELEASE
\r
3438 cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len);
\r
3439 //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC);
\r
3440 #endif //COMPAT_KERNEL_RELEASE
\r
3441 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
\r
3444 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
\r
3448 DBG_8192C("%s\n", __func__);
\r
3453 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
\r
3457 DBG_8192C("%s\n", __func__);
\r
3462 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
\r
3467 int dot11_hdr_len = 24;
\r
3469 unsigned char *pdata;
\r
3471 unsigned char src_mac_addr[6];
\r
3472 unsigned char dst_mac_addr[6];
\r
3473 struct ieee80211_hdr *dot11_hdr;
\r
3474 struct ieee80211_radiotap_header *rtap_hdr;
\r
3475 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3477 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3480 rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
\r
3482 if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
\r
3485 rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
\r
3486 if (unlikely(rtap_hdr->it_version))
\r
3489 rtap_len = ieee80211_get_radiotap_len(skb->data);
\r
3490 if (unlikely(skb->len < rtap_len))
\r
3493 if(rtap_len != 14)
\r
3495 DBG_8192C("radiotap len (should be 14): %d\n", rtap_len);
\r
3499 /* Skip the ratio tap header */
\r
3500 skb_pull(skb, rtap_len);
\r
3502 dot11_hdr = (struct ieee80211_hdr *)skb->data;
\r
3503 frame_ctl = le16_to_cpu(dot11_hdr->frame_control);
\r
3504 /* Check if the QoS bit is set */
\r
3505 if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
\r
3506 /* Check if this ia a Wireless Distribution System (WDS) frame
\r
3507 * which has 4 MAC addresses
\r
3509 if (dot11_hdr->frame_control & 0x0080)
\r
3511 if ((dot11_hdr->frame_control & 0x0300) == 0x0300)
\r
3512 dot11_hdr_len += 6;
\r
3514 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
\r
3515 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
\r
3517 /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
\r
3518 * for two MAC addresses
\r
3520 skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
\r
3521 pdata = (unsigned char*)skb->data;
\r
3522 memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
\r
3523 memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
\r
3525 DBG_8192C("should be eapol packet\n");
\r
3527 /* Use the real net device to transmit the packet */
\r
3528 ret = _rtw_xmit_entry(skb, padapter->pnetdev);
\r
3533 else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE))
\r
3534 == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION)
\r
3537 //only for action frames
\r
3538 struct xmit_frame *pmgntframe;
\r
3539 struct pkt_attrib *pattrib;
\r
3540 unsigned char *pframe;
\r
3541 //u8 category, action, OUI_Subtype, dialogToken=0;
\r
3542 //unsigned char *frame_body;
\r
3543 struct rtw_ieee80211_hdr *pwlanhdr;
\r
3544 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
3545 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
3546 u8 *buf = skb->data;
\r
3547 u32 len = skb->len;
\r
3548 u8 category, action;
\r
3551 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
\r
3552 DBG_8192C(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
\r
3553 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
\r
3557 DBG_8192C("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
\r
3558 MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
\r
3560 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0)
\r
3563 if (category == RTW_WLAN_CATEGORY_PUBLIC)
\r
3564 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
\r
3566 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
\r
3569 //starting alloc mgmt frame to dump it
\r
3570 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
3575 //update attribute
\r
3576 pattrib = &pmgntframe->attrib;
\r
3577 update_mgntframe_attrib(padapter, pattrib);
\r
3578 pattrib->retry_ctrl = _FALSE;
\r
3580 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
3582 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
3584 _rtw_memcpy(pframe, (void*)buf, len);
\r
3588 struct wifi_display_info *pwfd_info;
\r
3590 pwfd_info = padapter->wdinfo.wfd_info;
\r
3592 if ( _TRUE == pwfd_info->wfd_enable )
\r
3594 rtw_append_wfd_ie( padapter, pframe, &len );
\r
3597 #endif // CONFIG_WFD
\r
3598 pattrib->pktlen = len;
\r
3600 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
3601 //update seq number
\r
3602 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
\r
3603 pattrib->seqnum = pmlmeext->mgnt_seq;
\r
3604 pmlmeext->mgnt_seq++;
\r
3607 pattrib->last_txcmdsz = pattrib->pktlen;
\r
3609 dump_mgntframe(padapter, pmgntframe);
\r
3614 DBG_8192C("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE));
\r
3620 rtw_skb_free(skb);
\r
3626 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
\r
3628 DBG_8192C("%s\n", __func__);
\r
3631 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
\r
3635 DBG_8192C("%s\n", __func__);
\r
3640 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
\r
3641 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
\r
3642 .ndo_open = rtw_cfg80211_monitor_if_open,
\r
3643 .ndo_stop = rtw_cfg80211_monitor_if_close,
\r
3644 .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
\r
3645 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
\r
3646 .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
\r
3648 .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
\r
3652 static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
\r
3655 struct net_device* mon_ndev = NULL;
\r
3656 struct wireless_dev* mon_wdev = NULL;
\r
3657 struct rtw_netdev_priv_indicator *pnpi;
\r
3658 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
3661 DBG_871X(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
\r
3666 if (pwdev_priv->pmon_ndev) {
\r
3667 DBG_871X(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
\r
3668 FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
\r
3673 mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
\r
3675 DBG_871X(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
\r
3680 mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
\r
3681 strncpy(mon_ndev->name, name, IFNAMSIZ);
\r
3682 mon_ndev->name[IFNAMSIZ - 1] = 0;
\r
3683 mon_ndev->destructor = rtw_ndev_destructor;
\r
3685 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
\r
3686 mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
\r
3688 mon_ndev->open = rtw_cfg80211_monitor_if_open;
\r
3689 mon_ndev->stop = rtw_cfg80211_monitor_if_close;
\r
3690 mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry;
\r
3691 mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address;
\r
3694 pnpi = netdev_priv(mon_ndev);
\r
3695 pnpi->priv = padapter;
\r
3696 pnpi->sizeof_priv = sizeof(_adapter);
\r
3699 mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
\r
3701 DBG_871X(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
\r
3706 mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
\r
3707 mon_wdev->netdev = mon_ndev;
\r
3708 mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
\r
3709 mon_ndev->ieee80211_ptr = mon_wdev;
\r
3711 ret = register_netdevice(mon_ndev);
\r
3716 *ndev = pwdev_priv->pmon_ndev = mon_ndev;
\r
3717 _rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
\r
3720 if (ret && mon_wdev) {
\r
3721 rtw_mfree((u8*)mon_wdev, sizeof(struct wireless_dev));
\r
3725 if (ret && mon_ndev) {
\r
3726 free_netdev(mon_ndev);
\r
3727 *ndev = mon_ndev = NULL;
\r
3733 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3734 static struct wireless_dev *
\r
3735 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
3736 static struct net_device *
\r
3740 cfg80211_rtw_add_virtual_intf(
\r
3741 struct wiphy *wiphy,
\r
3742 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
\r
3747 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
\r
3750 struct net_device* ndev = NULL;
\r
3751 _adapter *padapter = wiphy_to_adapter(wiphy);
\r
3753 DBG_871X(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
\r
3754 FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
\r
3757 case NL80211_IFTYPE_ADHOC:
\r
3758 case NL80211_IFTYPE_AP_VLAN:
\r
3759 case NL80211_IFTYPE_WDS:
\r
3760 case NL80211_IFTYPE_MESH_POINT:
\r
3763 case NL80211_IFTYPE_MONITOR:
\r
3764 ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
\r
3767 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
3768 case NL80211_IFTYPE_P2P_CLIENT:
\r
3770 case NL80211_IFTYPE_STATION:
\r
3774 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
3775 case NL80211_IFTYPE_P2P_GO:
\r
3777 case NL80211_IFTYPE_AP:
\r
3782 DBG_871X("Unsupported interface type\n");
\r
3786 DBG_871X(FUNC_ADPT_FMT" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter), ndev, ret);
\r
3788 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3789 return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
\r
3790 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
3791 return ndev ? ndev : ERR_PTR(ret);
\r
3797 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
\r
3798 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3799 struct wireless_dev *wdev
\r
3801 struct net_device *ndev
\r
3805 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
3806 struct net_device *ndev = wdev_to_ndev(wdev);
\r
3809 _adapter *adapter;
\r
3810 struct rtw_wdev_priv *pwdev_priv;
\r
3817 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3818 pwdev_priv = adapter_wdev_data(adapter);
\r
3820 unregister_netdevice(ndev);
\r
3822 if (ndev == pwdev_priv->pmon_ndev) {
\r
3823 pwdev_priv->pmon_ndev = NULL;
\r
3824 pwdev_priv->ifname_mon[0] = '\0';
\r
3825 DBG_871X(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev));
\r
3832 static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
\r
3836 uint len, wps_ielen=0;
\r
3839 u8 got_p2p_ie = _FALSE;
\r
3840 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
\r
3841 //struct sta_priv *pstapriv = &padapter->stapriv;
\r
3844 DBG_8192C("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
\r
3847 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
\r
3854 pbuf = rtw_zmalloc(head_len+tail_len);
\r
3859 //_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
\r
3861 //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
\r
3862 // pstapriv->max_num_sta = NUM_STA;
\r
3865 _rtw_memcpy(pbuf, (void *)head+24, head_len-24);// 24=beacon header len.
\r
3866 _rtw_memcpy(pbuf+head_len-24, (void *)tail, tail_len);
\r
3868 len = head_len+tail_len-24;
\r
3870 //check wps ie if inclued
\r
3871 if(rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
\r
3872 DBG_8192C("add bcn, wps_ielen=%d\n", wps_ielen);
\r
3875 if( adapter->wdinfo.driver_interface == DRIVER_CFG80211 )
\r
3877 //check p2p if enable
\r
3878 if(rtw_get_p2p_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &p2p_ielen))
\r
3880 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
\r
3881 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
\r
3883 DBG_8192C("got p2p_ie, len=%d\n", p2p_ielen);
\r
3885 got_p2p_ie = _TRUE;
\r
3887 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
3889 DBG_8192C("Enable P2P function for the first time\n");
\r
3890 rtw_p2p_enable(adapter, P2P_ROLE_GO);
\r
3891 adapter_wdev_data(adapter)->p2p_enabled = _TRUE;
\r
3893 adapter->stapriv.expire_to = 3; // 3x2 = 6 sec in p2p mode
\r
3897 DBG_8192C("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);
\r
3899 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
\r
3900 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
\r
3901 pwdinfo->intent = 15;
\r
3905 #endif // CONFIG_P2P
\r
3907 /* pbss_network->IEs will not include p2p_ie, wfd ie */
\r
3908 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
\r
3909 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
\r
3911 if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS)
\r
3913 #ifdef CONFIG_P2P
\r
3914 //check p2p if enable
\r
3915 if(got_p2p_ie == _TRUE)
\r
3917 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
\r
3918 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
\r
3919 pwdinfo->operating_channel = pmlmeext->cur_channel;
\r
3921 #endif //CONFIG_P2P
\r
3930 rtw_mfree(pbuf, head_len+tail_len);
\r
3935 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE)
\r
3936 static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
3937 struct beacon_parameters *info)
\r
3940 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3942 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3943 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
\r
3948 static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
3949 struct beacon_parameters *info)
\r
3951 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3952 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
3954 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3956 pmlmeext->bstart_bss = _TRUE;
\r
3958 cfg80211_rtw_add_beacon(wiphy, ndev, info);
\r
3963 static int cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
\r
3965 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
3970 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
\r
3971 struct cfg80211_ap_settings *settings)
\r
3974 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
3976 DBG_871X(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
\r
3977 settings->hidden_ssid, settings->auth_type);
\r
3979 ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
\r
3980 settings->beacon.tail, settings->beacon.tail_len);
\r
3982 adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
\r
3984 if (settings->ssid && settings->ssid_len) {
\r
3985 WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
\r
3986 WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
\r
3989 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
\r
3990 settings->ssid, settings->ssid_len,
\r
3991 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
\r
3993 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
\r
3994 pbss_network->Ssid.SsidLength = settings->ssid_len;
\r
3995 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
\r
3996 pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
\r
3999 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
\r
4000 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
\r
4001 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
\r
4007 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
\r
4008 struct cfg80211_beacon_data *info)
\r
4011 _adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4013 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4015 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
\r
4020 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
\r
4022 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4026 #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
\r
4028 static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4029 u8 *mac, struct station_parameters *params)
\r
4031 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4036 static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4041 _list *phead, *plist;
\r
4042 u8 updated = _FALSE;
\r
4043 struct sta_info *psta = NULL;
\r
4044 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4045 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
4046 struct sta_priv *pstapriv = &padapter->stapriv;
\r
4048 DBG_871X("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4050 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
\r
4052 DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
\r
4059 DBG_8192C("flush all sta, and cam_entry\n");
\r
4061 flush_all_cam_entry(padapter); //clear CAM
\r
4063 ret = rtw_sta_flush(padapter);
\r
4069 DBG_8192C("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
\r
4071 if (mac[0] == 0xff && mac[1] == 0xff &&
\r
4072 mac[2] == 0xff && mac[3] == 0xff &&
\r
4073 mac[4] == 0xff && mac[5] == 0xff)
\r
4079 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4081 phead = &pstapriv->asoc_list;
\r
4082 plist = get_next(phead);
\r
4084 //check asoc_queue
\r
4085 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
\r
4087 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
\r
4089 plist = get_next(plist);
\r
4091 if(_rtw_memcmp(mac, psta->hwaddr, ETH_ALEN))
\r
4093 if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE)
\r
4095 DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
\r
4099 DBG_8192C("free psta=%p, aid=%d\n", psta, psta->aid);
\r
4101 rtw_list_delete(&psta->asoc_list);
\r
4102 pstapriv->asoc_list_cnt--;
\r
4104 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4105 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
\r
4106 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4117 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
\r
4119 associated_clients_update(padapter, updated);
\r
4121 DBG_871X("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4127 static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4128 u8 *mac, struct station_parameters *params)
\r
4130 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4135 static int cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
\r
4136 int idx, u8 *mac, struct station_info *sinfo)
\r
4138 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4140 //TODO: dump scanned queue
\r
4145 static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
\r
4146 struct bss_parameters *params)
\r
4150 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4152 DBG_8192C("use_cts_prot=%d\n", params->use_cts_prot);
\r
4153 DBG_8192C("use_short_preamble=%d\n", params->use_short_preamble);
\r
4154 DBG_8192C("use_short_slot_time=%d\n", params->use_short_slot_time);
\r
4155 DBG_8192C("ap_isolate=%d\n", params->ap_isolate);
\r
4157 DBG_8192C("basic_rates_len=%d\n", params->basic_rates_len);
\r
4158 for(i=0; i<params->basic_rates_len; i++)
\r
4160 DBG_8192C("basic_rates=%d\n", params->basic_rates[i]);
\r
4168 static int cfg80211_rtw_set_channel(struct wiphy *wiphy
\r
4169 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
\r
4170 , struct net_device *ndev
\r
4172 , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
\r
4174 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
\r
4175 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4181 static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
\r
4182 struct cfg80211_auth_request *req)
\r
4184 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4189 static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
\r
4190 struct cfg80211_assoc_request *req)
\r
4192 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
\r
4196 #endif //CONFIG_AP_MODE
\r
4198 void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
4203 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4204 u8 category, action;
\r
4206 channel = rtw_get_oper_ch(padapter);
\r
4208 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4210 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
\r
4214 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
\r
4215 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4218 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4219 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4221 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4223 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4224 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4226 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4230 void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
\r
4235 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4236 u8 category, action;
\r
4238 channel = rtw_get_oper_ch(padapter);
\r
4240 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4242 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
\r
4245 case P2P_GO_NEGO_CONF:
\r
4246 case P2P_PROVISION_DISC_RESP:
\r
4247 case P2P_INVIT_RESP:
\r
4248 rtw_set_scan_deny(padapter, 2000);
\r
4249 rtw_clear_scan_deny(padapter);
\r
4254 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
\r
4255 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4258 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4259 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4261 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4263 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4264 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4266 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
\r
4270 void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg)
\r
4274 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
\r
4275 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
\r
4276 u8 category, action;
\r
4278 channel = rtw_get_oper_ch(adapter);
\r
4280 rtw_action_frame_parse(frame, frame_len, &category, &action);
\r
4282 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
\r
4284 DBG_871X("RTW_Rx:%s\n", msg);
\r
4286 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
\r
4288 if (channel <= RTW_CH_MAX_2G_CHANNEL)
\r
4289 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
\r
4291 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
\r
4293 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4294 rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
\r
4296 cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
\r
4302 void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
\r
4304 u16 wps_devicepassword_id = 0x0000;
\r
4305 uint wps_devicepassword_id_len = 0;
\r
4306 u8 wpsie[ 255 ] = { 0x00 }, p2p_ie[ 255 ] = { 0x00 };
\r
4307 uint p2p_ielen = 0;
\r
4308 uint wpsielen = 0;
\r
4309 u32 devinfo_contentlen = 0;
\r
4310 u8 devinfo_content[64] = { 0x00 };
\r
4311 u16 capability = 0;
\r
4312 uint capability_len = 0;
\r
4314 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
\r
4315 u8 action = P2P_PUB_ACTION_ACTION;
\r
4316 u8 dialogToken = 1;
\r
4317 u32 p2poui = cpu_to_be32(P2POUI);
\r
4318 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
\r
4322 #endif //CONFIG_WFD
\r
4324 struct xmit_frame *pmgntframe;
\r
4325 struct pkt_attrib *pattrib;
\r
4326 unsigned char *pframe;
\r
4327 struct rtw_ieee80211_hdr *pwlanhdr;
\r
4328 unsigned short *fctrl;
\r
4329 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
4330 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4331 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
\r
4333 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
\r
4334 u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
\r
4335 size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4338 DBG_871X( "[%s] In\n", __FUNCTION__ );
\r
4340 //prepare for building provision_request frame
\r
4341 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
\r
4342 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
\r
4344 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
\r
4346 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
\r
4347 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
\r
4348 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
\r
4350 switch(wps_devicepassword_id)
\r
4352 case WPS_DPID_PIN:
\r
4353 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
\r
4355 case WPS_DPID_USER_SPEC:
\r
4356 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
\r
4358 case WPS_DPID_MACHINE_SPEC:
\r
4360 case WPS_DPID_REKEY:
\r
4362 case WPS_DPID_PBC:
\r
4363 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
\r
4365 case WPS_DPID_REGISTRAR_SPEC:
\r
4366 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
\r
4373 if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) )
\r
4376 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);
\r
4377 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&capability, &capability_len);
\r
4382 //start to build provision_request frame
\r
4383 _rtw_memset(wpsie, 0, sizeof(wpsie));
\r
4384 _rtw_memset(p2p_ie, 0, sizeof(p2p_ie));
\r
4387 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
4393 //update attribute
\r
4394 pattrib = &pmgntframe->attrib;
\r
4395 update_mgntframe_attrib(padapter, pattrib);
\r
4397 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
4399 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
4400 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
4402 fctrl = &(pwlanhdr->frame_ctl);
\r
4405 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
\r
4406 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
\r
4407 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
\r
4409 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
\r
4410 pmlmeext->mgnt_seq++;
\r
4411 SetFrameSubType(pframe, WIFI_ACTION);
\r
4413 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4414 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
\r
4416 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
\r
4417 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
\r
4418 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
\r
4419 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
\r
4420 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
\r
4423 //build_prov_disc_request_p2p_ie
\r
4426 p2p_ie[ p2pielen++ ] = 0x50;
\r
4427 p2p_ie[ p2pielen++ ] = 0x6F;
\r
4428 p2p_ie[ p2pielen++ ] = 0x9A;
\r
4429 p2p_ie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
\r
4431 // Commented by Albert 20110301
\r
4432 // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
\r
4433 // 1. P2P Capability
\r
4435 // 3. Group ID ( When joining an operating P2P Group )
\r
4437 // P2P Capability ATTR
\r
4439 p2p_ie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
\r
4442 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
\r
4443 RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
\r
4447 // Device Capability Bitmap, 1 byte
\r
4448 // Group Capability Bitmap, 1 byte
\r
4449 _rtw_memcpy(p2p_ie + p2pielen, &capability, 2);
\r
4453 // Device Info ATTR
\r
4455 p2p_ie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
\r
4458 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
\r
4459 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
\r
4460 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
\r
4461 RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
\r
4465 _rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
\r
4466 p2pielen += devinfo_contentlen;
\r
4469 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);
\r
4470 //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr);
\r
4471 //pframe += p2pielen;
\r
4472 pattrib->pktlen += p2p_ielen;
\r
4476 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
\r
4481 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
\r
4485 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
\r
4489 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
\r
4493 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
\r
4497 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
\r
4501 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
\r
4504 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
\r
4508 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
\r
4509 pframe += wfdielen;
\r
4510 pattrib->pktlen += wfdielen;
\r
4511 #endif //CONFIG_WFD
\r
4513 pattrib->last_txcmdsz = pattrib->pktlen;
\r
4515 //dump_mgntframe(padapter, pmgntframe);
\r
4516 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
\r
4517 DBG_8192C("%s, ack to\n", __func__);
\r
4519 //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
\r
4521 // DBG_8192C("waiting for p2p peer key-in PIN CODE\n");
\r
4522 // rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req.
\r
4527 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
\r
4528 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4529 struct wireless_dev *wdev,
\r
4531 struct net_device *ndev,
\r
4533 struct ieee80211_channel * channel,
\r
4534 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
4535 enum nl80211_channel_type channel_type,
\r
4537 unsigned int duration, u64 *cookie)
\r
4539 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4540 struct net_device *ndev = wdev_to_ndev(wdev);
\r
4543 u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
\r
4544 u8 ready_on_channel = _FALSE;
\r
4545 _adapter *padapter;
\r
4546 struct rtw_wdev_priv *pwdev_priv;
\r
4547 struct mlme_ext_priv *pmlmeext;
\r
4548 struct wifidirect_info *pwdinfo;
\r
4549 struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
\r
4551 if (ndev == NULL) {
\r
4555 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4556 pwdev_priv = adapter_wdev_data(padapter);
\r
4557 pmlmeext = &padapter->mlmeextpriv;
\r
4558 pwdinfo = &padapter->wdinfo;
\r
4559 pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
4561 DBG_871X(FUNC_ADPT_FMT" ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter), remain_ch, duration);
\r
4563 if(pcfg80211_wdinfo->is_ro_ch == _TRUE)
\r
4565 DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
4567 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
4569 #ifdef CONFIG_CONCURRENT_MODE
\r
4570 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
4571 #endif //CONFIG_CONCURRENT_MODE
\r
4573 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
\r
4576 pcfg80211_wdinfo->is_ro_ch = _TRUE;
\r
4577 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
4579 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
4584 _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
\r
4585 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
4586 pcfg80211_wdinfo->remain_on_ch_type= channel_type;
\r
4588 pcfg80211_wdinfo->remain_on_ch_cookie= *cookie;
\r
4590 rtw_scan_abort(padapter);
\r
4591 #ifdef CONFIG_CONCURRENT_MODE
\r
4592 if(rtw_buddy_adapter_up(padapter))
\r
4593 rtw_scan_abort(padapter->pbuddy_adapter);
\r
4594 #endif //CONFIG_CONCURRENT_MODE
\r
4596 //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
4597 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4599 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
\r
4600 adapter_wdev_data(padapter)->p2p_enabled = _TRUE;
\r
4601 padapter->wdinfo.listen_channel = remain_ch;
\r
4605 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
\r
4606 #ifdef CONFIG_DEBUG_CFG80211
\r
4607 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
4612 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
\r
4615 if(duration < 400)
\r
4616 duration = duration*3;//extend from exper.
\r
4619 #ifdef CONFIG_CONCURRENT_MODE
\r
4620 if(check_buddy_fwstate(padapter, _FW_LINKED) &&
\r
4621 (duration<pwdinfo->ext_listen_interval))
\r
4623 duration = duration + pwdinfo->ext_listen_interval;
\r
4627 pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter);
\r
4629 if(rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) >= 0) {
\r
4630 #ifdef CONFIG_CONCURRENT_MODE
\r
4631 if ( check_buddy_fwstate(padapter, _FW_LINKED) )
\r
4633 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
\r
4634 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
4636 if((remain_ch != pbuddy_mlmeext->cur_channel) && !check_fwstate(&padapter->mlmepriv, _FW_LINKED))
\r
4638 if(ATOMIC_READ(&pwdev_priv->switch_ch_to)==1 ||
\r
4639 (remain_ch != pmlmeext->cur_channel))
\r
4641 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
\r
4642 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
\r
4644 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
\r
4646 DBG_8192C("%s, set switch ch timer, duration=%d\n", __func__, duration-pwdinfo->ext_listen_interval);
\r
4647 _set_timer(&pwdinfo->ap_p2p_switch_timer, duration-pwdinfo->ext_listen_interval);
\r
4651 ready_on_channel = _TRUE;
\r
4652 //pmlmeext->cur_channel = remain_ch;
\r
4653 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4655 #endif //CONFIG_CONCURRENT_MODE
\r
4656 if(remain_ch != rtw_get_oper_ch(padapter) )
\r
4658 ready_on_channel = _TRUE;
\r
4659 //pmlmeext->cur_channel = remain_ch;
\r
4660 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4663 DBG_871X("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__, remain_ch);
\r
4667 //call this after other things have been done
\r
4668 #ifdef CONFIG_CONCURRENT_MODE
\r
4669 if(ATOMIC_READ(&pwdev_priv->ro_ch_to)==1 ||
\r
4670 (remain_ch != rtw_get_oper_ch(padapter)))
\r
4672 u8 co_channel = 0xff;
\r
4673 ATOMIC_SET(&pwdev_priv->ro_ch_to, 0);
\r
4676 if(ready_on_channel == _TRUE)
\r
4678 if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) )
\r
4680 pmlmeext->cur_channel = remain_ch;
\r
4682 #ifdef CONFIG_CONCURRENT_MODE
\r
4683 co_channel = rtw_get_oper_ch(padapter);
\r
4685 if(co_channel !=remain_ch)
\r
4688 //if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic)
\r
4689 set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4693 DBG_8192C("%s, set ro ch timer, duration=%d\n", __func__, duration);
\r
4694 _set_timer( &pcfg80211_wdinfo->remain_on_ch_timer, duration);
\r
4696 #ifdef CONFIG_CONCURRENT_MODE
\r
4700 rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type, duration, GFP_KERNEL);
\r
4704 pcfg80211_wdinfo->is_ro_ch = _FALSE;
\r
4705 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
4711 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
\r
4712 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4713 struct wireless_dev *wdev,
\r
4715 struct net_device *ndev,
\r
4719 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4720 struct net_device *ndev = wdev_to_ndev(wdev);
\r
4723 _adapter *padapter;
\r
4724 struct rtw_wdev_priv *pwdev_priv;
\r
4725 struct wifidirect_info *pwdinfo;
\r
4726 struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
\r
4728 if (ndev == NULL) {
\r
4733 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4734 pwdev_priv = adapter_wdev_data(padapter);
\r
4735 pwdinfo = &padapter->wdinfo;
\r
4736 pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
4738 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
\r
4740 if (pcfg80211_wdinfo->is_ro_ch == _TRUE) {
\r
4741 DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
4742 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
4743 #ifdef CONFIG_CONCURRENT_MODE
\r
4744 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
4746 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
\r
4750 // Disable P2P Listen State
\r
4751 if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
\r
4753 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
\r
4755 rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
\r
4756 _rtw_memset(pwdinfo, 0x00, sizeof(struct wifidirect_info));
\r
4762 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
\r
4763 #ifdef CONFIG_DEBUG_CFG80211
\r
4764 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
\r
4768 pcfg80211_wdinfo->is_ro_ch = _FALSE;
\r
4769 pcfg80211_wdinfo->last_ro_ch_time = rtw_get_current_time();
\r
4775 #endif //CONFIG_P2P
\r
4777 static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, const u8 *buf, size_t len)
\r
4779 struct xmit_frame *pmgntframe;
\r
4780 struct pkt_attrib *pattrib;
\r
4781 unsigned char *pframe;
\r
4784 struct rtw_ieee80211_hdr *pwlanhdr;
\r
4785 struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
\r
4786 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
\r
4787 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
4788 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
4790 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
\r
4791 #endif //CONFIG_P2P
\r
4792 //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
\r
4794 rtw_set_scan_deny(padapter, 1000);
\r
4796 rtw_scan_abort(padapter);
\r
4797 #ifdef CONFIG_CONCURRENT_MODE
\r
4798 if(rtw_buddy_adapter_up(padapter))
\r
4799 rtw_scan_abort(padapter->pbuddy_adapter);
\r
4800 #endif /* CONFIG_CONCURRENT_MODE */
\r
4802 if (padapter->cfg80211_wdinfo.is_ro_ch == _TRUE) {
\r
4803 //DBG_8192C("%s, cancel ro ch timer\n", __func__);
\r
4804 //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
\r
4805 //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE;
\r
4806 #ifdef CONFIG_CONCURRENT_MODE
\r
4807 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
4809 DBG_8192C("%s, extend ro ch time\n", __func__);
\r
4810 _set_timer( &padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
\r
4812 #endif //CONFIG_CONCURRENT_MODE
\r
4814 #endif //CONFIG_P2P
\r
4815 #ifdef CONFIG_CONCURRENT_MODE
\r
4816 if (check_buddy_fwstate(padapter, _FW_LINKED )) {
\r
4817 u8 co_channel=0xff;
\r
4818 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
\r
4819 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
\r
4821 co_channel = rtw_get_oper_ch(padapter);
\r
4823 if (tx_ch != pbuddy_mlmeext->cur_channel) {
\r
4825 u16 ext_listen_period;
\r
4827 if (ATOMIC_READ(&pwdev_priv->switch_ch_to)==1) {
\r
4828 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
\r
4829 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
\r
4831 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
\r
4833 //DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
\r
4834 //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
\r
4837 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
4839 ext_listen_period = 500;// 500ms
\r
4843 ext_listen_period = pwdinfo->ext_listen_period;
\r
4846 DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period);
\r
4847 _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period);
\r
4851 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
4852 pmlmeext->cur_channel = tx_ch;
\r
4854 if (tx_ch != co_channel)
\r
4855 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4857 #endif //CONFIG_CONCURRENT_MODE
\r
4858 //if (tx_ch != pmlmeext->cur_channel) {
\r
4859 if(tx_ch != rtw_get_oper_ch(padapter)) {
\r
4860 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
\r
4861 pmlmeext->cur_channel = tx_ch;
\r
4862 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
\r
4865 //starting alloc mgmt frame to dump it
\r
4866 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
\r
4873 //update attribute
\r
4874 pattrib = &pmgntframe->attrib;
\r
4875 update_mgntframe_attrib(padapter, pattrib);
\r
4876 pattrib->retry_ctrl = _FALSE;
\r
4878 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
\r
4880 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
\r
4882 _rtw_memcpy(pframe, (void*)buf, len);
\r
4883 pattrib->pktlen = len;
\r
4885 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
\r
4886 //update seq number
\r
4887 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
\r
4888 pattrib->seqnum = pmlmeext->mgnt_seq;
\r
4889 pmlmeext->mgnt_seq++;
\r
4893 struct wifi_display_info *pwfd_info;
\r
4895 pwfd_info = padapter->wdinfo.wfd_info;
\r
4897 if ( _TRUE == pwfd_info->wfd_enable )
\r
4899 rtw_append_wfd_ie( padapter, pframe, &pattrib->pktlen );
\r
4902 #endif // CONFIG_WFD
\r
4904 pattrib->last_txcmdsz = pattrib->pktlen;
\r
4906 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
\r
4911 #ifdef CONFIG_DEBUG_CFG80211
\r
4912 DBG_8192C("%s, ack == _FAIL\n", __func__);
\r
4918 #ifdef CONFIG_XMIT_ACK
\r
4919 rtw_msleep_os(50);
\r
4921 #ifdef CONFIG_DEBUG_CFG80211
\r
4922 DBG_8192C("%s, ack=%d, ok!\n", __func__, ack);
\r
4929 #ifdef CONFIG_DEBUG_CFG80211
\r
4930 DBG_8192C("%s, ret=%d\n", __func__, ret);
\r
4937 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
\r
4938 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4939 struct wireless_dev *wdev,
\r
4941 struct net_device *ndev,
\r
4943 struct ieee80211_channel *chan,
\r
4944 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
4947 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
4948 enum nl80211_channel_type channel_type,
\r
4949 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4950 bool channel_type_valid,
\r
4953 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
4954 unsigned int wait,
\r
4956 const u8 *buf, size_t len,
\r
4957 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
4960 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
\r
4961 bool dont_wait_for_ack,
\r
4965 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
4966 struct net_device *ndev = wdev_to_ndev(wdev);
\r
4970 u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
\r
4973 u8 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
\r
4974 u8 category, action;
\r
4976 u32 start = rtw_get_current_time();
\r
4977 _adapter *padapter;
\r
4978 struct rtw_wdev_priv *pwdev_priv;
\r
4980 if (ndev == NULL) {
\r
4985 padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
4986 pwdev_priv = adapter_wdev_data(padapter);
\r
4988 /* cookie generation */
\r
4989 *cookie = (unsigned long) buf;
\r
4991 #ifdef CONFIG_DEBUG_CFG80211
\r
4992 DBG_871X(FUNC_ADPT_FMT" len=%zu, ch=%d"
\r
4993 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
4995 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
4996 ", channel_type_valid=%d"
\r
4999 "\n", FUNC_ADPT_ARG(padapter),
\r
5001 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
\r
5003 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5004 , channel_type_valid
\r
5008 #endif /* CONFIG_DEBUG_CFG80211 */
\r
5010 /* indicate ack before issue frame to avoid racing with rsp frame */
\r
5011 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5012 rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL);
\r
5013 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
\r
5014 cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
\r
5017 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
\r
5018 DBG_8192C(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
\r
5019 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
\r
5023 DBG_8192C("RTW_Tx:tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
\r
5025 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0) {
\r
5029 if (category == RTW_WLAN_CATEGORY_PUBLIC)
\r
5030 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
\r
5032 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
\r
5036 rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
\r
5037 if(_FAIL == rtw_pwr_wakeup(padapter)) {
\r
5039 goto cancel_ps_deny;
\r
5044 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
\r
5045 } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
\r
5047 if (tx_ret != _SUCCESS || dump_cnt > 1) {
\r
5048 DBG_871X(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
\r
5049 tx_ret==_SUCCESS?"OK":"FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
\r
5053 case P2P_GO_NEGO_CONF:
\r
5054 rtw_clear_scan_deny(padapter);
\r
5056 case P2P_INVIT_RESP:
\r
5057 if (pwdev_priv->invit_info.flags & BIT(0)
\r
5058 && pwdev_priv->invit_info.status == 0)
\r
5060 DBG_871X(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
\r
5061 FUNC_ADPT_ARG(padapter));
\r
5062 rtw_set_scan_deny(padapter, 5000);
\r
5063 rtw_pwr_wakeup_ex(padapter, 5000);
\r
5064 rtw_clear_scan_deny(padapter);
\r
5070 rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
\r
5075 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
\r
5076 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
\r
5077 struct wireless_dev *wdev,
\r
5079 struct net_device *ndev,
\r
5081 u16 frame_type, bool reg)
\r
5083 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
\r
5084 struct net_device *ndev = wdev_to_ndev(wdev);
\r
5086 _adapter *adapter;
\r
5091 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5093 #ifdef CONFIG_DEBUG_CFG80211
\r
5094 DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
\r
5098 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
\r
5104 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
\r
5107 uint wps_ielen = 0;
\r
5109 u32 p2p_ielen = 0;
\r
5110 u8 wps_oui[8]={0x0,0x50,0xf2,0x04};
\r
5112 u32 wfd_ielen = 0;
\r
5114 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5115 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5116 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
\r
5118 DBG_871X(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
\r
5122 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
5124 #ifdef CONFIG_DEBUG_CFG80211
\r
5125 DBG_8192C("bcn_wps_ielen=%d\n", wps_ielen);
\r
5128 if(pmlmepriv->wps_beacon_ie)
\r
5130 u32 free_len = pmlmepriv->wps_beacon_ie_len;
\r
5131 pmlmepriv->wps_beacon_ie_len = 0;
\r
5132 rtw_mfree(pmlmepriv->wps_beacon_ie, free_len);
\r
5133 pmlmepriv->wps_beacon_ie = NULL;
\r
5136 pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen);
\r
5137 if ( pmlmepriv->wps_beacon_ie == NULL) {
\r
5138 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5143 _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
\r
5144 pmlmepriv->wps_beacon_ie_len = wps_ielen;
\r
5146 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
\r
5150 //buf += wps_ielen;
\r
5151 //len -= wps_ielen;
\r
5154 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
5156 #ifdef CONFIG_DEBUG_CFG80211
\r
5157 DBG_8192C("bcn_p2p_ielen=%d\n", p2p_ielen);
\r
5160 if(pmlmepriv->p2p_beacon_ie)
\r
5162 u32 free_len = pmlmepriv->p2p_beacon_ie_len;
\r
5163 pmlmepriv->p2p_beacon_ie_len = 0;
\r
5164 rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len);
\r
5165 pmlmepriv->p2p_beacon_ie = NULL;
\r
5168 pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen);
\r
5169 if ( pmlmepriv->p2p_beacon_ie == NULL) {
\r
5170 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5175 _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
\r
5176 pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
\r
5179 #endif //CONFIG_P2P
\r
5181 //buf += p2p_ielen;
\r
5182 //len -= p2p_ielen;
\r
5185 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
5187 #ifdef CONFIG_DEBUG_CFG80211
\r
5188 DBG_8192C("bcn_wfd_ielen=%d\n", wfd_ielen);
\r
5191 if(pmlmepriv->wfd_beacon_ie)
\r
5193 u32 free_len = pmlmepriv->wfd_beacon_ie_len;
\r
5194 pmlmepriv->wfd_beacon_ie_len = 0;
\r
5195 rtw_mfree(pmlmepriv->wfd_beacon_ie, free_len);
\r
5196 pmlmepriv->wfd_beacon_ie = NULL;
\r
5199 pmlmepriv->wfd_beacon_ie = rtw_malloc(wfd_ielen);
\r
5200 if ( pmlmepriv->wfd_beacon_ie == NULL) {
\r
5201 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5205 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
\r
5207 #endif //CONFIG_WFD
\r
5209 pmlmeext->bstart_bss = _TRUE;
\r
5217 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
\r
5220 uint wps_ielen = 0;
\r
5222 u32 p2p_ielen = 0;
\r
5224 u32 wfd_ielen = 0;
\r
5226 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
\r
5227 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5229 #ifdef CONFIG_DEBUG_CFG80211
\r
5230 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5235 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
\r
5237 uint attr_contentlen = 0;
\r
5238 u16 uconfig_method, *puconfig_method = NULL;
\r
5240 #ifdef CONFIG_DEBUG_CFG80211
\r
5241 DBG_8192C("probe_resp_wps_ielen=%d\n", wps_ielen);
\r
5244 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
\r
5247 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
\r
5251 DBG_871X("%s, got sr\n", __func__);
\r
5255 DBG_8192C("GO mode process WPS under site-survey, sr no set\n");
\r
5260 if(pmlmepriv->wps_probe_resp_ie)
\r
5262 u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
\r
5263 pmlmepriv->wps_probe_resp_ie_len = 0;
\r
5264 rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len);
\r
5265 pmlmepriv->wps_probe_resp_ie = NULL;
\r
5268 pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen);
\r
5269 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
\r
5270 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5275 //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode
\r
5276 if ( (puconfig_method = (u16*)rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen)) != NULL )
\r
5278 //struct registry_priv *pregistrypriv = &padapter->registrypriv;
\r
5279 struct wireless_dev *wdev = padapter->rtw_wdev;
\r
5281 #ifdef CONFIG_DEBUG_CFG80211
\r
5282 //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method));
\r
5285 //if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
\r
5286 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5287 if(wdev->iftype != NL80211_IFTYPE_P2P_GO) //for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags
\r
5289 uconfig_method = WPS_CM_PUSH_BUTTON;
\r
5290 uconfig_method = cpu_to_be16( uconfig_method );
\r
5292 *puconfig_method |= uconfig_method;
\r
5297 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
\r
5298 pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
\r
5302 //buf += wps_ielen;
\r
5303 //len -= wps_ielen;
\r
5306 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
\r
5308 u8 is_GO = _FALSE;
\r
5309 u32 attr_contentlen = 0;
\r
5312 #ifdef CONFIG_DEBUG_CFG80211
\r
5313 DBG_8192C("probe_resp_p2p_ielen=%d\n", p2p_ielen);
\r
5316 //Check P2P Capability ATTR
\r
5317 if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) )
\r
5320 //DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
\r
5321 cap_attr = le16_to_cpu(cap_attr);
\r
5322 grp_cap = (u8)((cap_attr >> 8)&0xff);
\r
5324 is_GO = (grp_cap&BIT(0)) ? _TRUE:_FALSE;
\r
5327 DBG_8192C("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
\r
5331 if(is_GO == _FALSE)
\r
5333 if(pmlmepriv->p2p_probe_resp_ie)
\r
5335 u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
\r
5336 pmlmepriv->p2p_probe_resp_ie_len = 0;
\r
5337 rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len);
\r
5338 pmlmepriv->p2p_probe_resp_ie = NULL;
\r
5341 pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen);
\r
5342 if ( pmlmepriv->p2p_probe_resp_ie == NULL) {
\r
5343 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5347 _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
\r
5348 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
\r
5352 if(pmlmepriv->p2p_go_probe_resp_ie)
\r
5354 u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
\r
5355 pmlmepriv->p2p_go_probe_resp_ie_len = 0;
\r
5356 rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len);
\r
5357 pmlmepriv->p2p_go_probe_resp_ie = NULL;
\r
5360 pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen);
\r
5361 if ( pmlmepriv->p2p_go_probe_resp_ie == NULL) {
\r
5362 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5366 _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
\r
5367 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
\r
5371 #endif //CONFIG_P2P
\r
5373 //buf += p2p_ielen;
\r
5374 //len -= p2p_ielen;
\r
5377 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
\r
5379 #ifdef CONFIG_DEBUG_CFG80211
\r
5380 DBG_8192C("probe_resp_wfd_ielen=%d\n", wfd_ielen);
\r
5383 if(pmlmepriv->wfd_probe_resp_ie)
\r
5385 u32 free_len = pmlmepriv->wfd_probe_resp_ie_len;
\r
5386 pmlmepriv->wfd_probe_resp_ie_len = 0;
\r
5387 rtw_mfree(pmlmepriv->wfd_probe_resp_ie, free_len);
\r
5388 pmlmepriv->wfd_probe_resp_ie = NULL;
\r
5391 pmlmepriv->wfd_probe_resp_ie = rtw_malloc(wfd_ielen);
\r
5392 if ( pmlmepriv->wfd_probe_resp_ie == NULL) {
\r
5393 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5397 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
\r
5399 #endif //CONFIG_WFD
\r
5407 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
\r
5410 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
\r
5411 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
\r
5413 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5417 if(pmlmepriv->wps_assoc_resp_ie)
\r
5419 u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
\r
5420 pmlmepriv->wps_assoc_resp_ie_len = 0;
\r
5421 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len);
\r
5422 pmlmepriv->wps_assoc_resp_ie = NULL;
\r
5425 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(len);
\r
5426 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
\r
5427 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
\r
5431 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len);
\r
5432 pmlmepriv->wps_assoc_resp_ie_len = len;
\r
5439 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
\r
5443 uint wps_ielen = 0;
\r
5444 u32 p2p_ielen = 0;
\r
5446 #ifdef CONFIG_DEBUG_CFG80211
\r
5447 DBG_8192C("%s, ielen=%d\n", __func__, len);
\r
5450 if( (rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen>0))
\r
5452 || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen>0))
\r
5460 case 0x1: //BEACON
\r
5461 ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
\r
5463 case 0x2: //PROBE_RESP
\r
5464 ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
\r
5466 case 0x4: //ASSOC_RESP
\r
5467 ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
\r
5477 static struct cfg80211_ops rtw_cfg80211_ops = {
\r
5478 .change_virtual_intf = cfg80211_rtw_change_iface,
\r
5479 .add_key = cfg80211_rtw_add_key,
\r
5480 .get_key = cfg80211_rtw_get_key,
\r
5481 .del_key = cfg80211_rtw_del_key,
\r
5482 .set_default_key = cfg80211_rtw_set_default_key,
\r
5483 .get_station = cfg80211_rtw_get_station,
\r
5484 .scan = cfg80211_rtw_scan,
\r
5485 .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
\r
5486 .connect = cfg80211_rtw_connect,
\r
5487 .disconnect = cfg80211_rtw_disconnect,
\r
5488 .join_ibss = cfg80211_rtw_join_ibss,
\r
5489 .leave_ibss = cfg80211_rtw_leave_ibss,
\r
5490 .set_tx_power = cfg80211_rtw_set_txpower,
\r
5491 .get_tx_power = cfg80211_rtw_get_txpower,
\r
5492 .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
\r
5493 .set_pmksa = cfg80211_rtw_set_pmksa,
\r
5494 .del_pmksa = cfg80211_rtw_del_pmksa,
\r
5495 .flush_pmksa = cfg80211_rtw_flush_pmksa,
\r
5497 #ifdef CONFIG_AP_MODE
\r
5498 .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
\r
5499 .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
\r
5501 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
\r
5502 .add_beacon = cfg80211_rtw_add_beacon,
\r
5503 .set_beacon = cfg80211_rtw_set_beacon,
\r
5504 .del_beacon = cfg80211_rtw_del_beacon,
\r
5506 .start_ap = cfg80211_rtw_start_ap,
\r
5507 .change_beacon = cfg80211_rtw_change_beacon,
\r
5508 .stop_ap = cfg80211_rtw_stop_ap,
\r
5511 .add_station = cfg80211_rtw_add_station,
\r
5512 .del_station = cfg80211_rtw_del_station,
\r
5513 .change_station = cfg80211_rtw_change_station,
\r
5514 .dump_station = cfg80211_rtw_dump_station,
\r
5515 .change_bss = cfg80211_rtw_change_bss,
\r
5516 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
\r
5517 .set_channel = cfg80211_rtw_set_channel,
\r
5519 //.auth = cfg80211_rtw_auth,
\r
5520 //.assoc = cfg80211_rtw_assoc,
\r
5521 #endif //CONFIG_AP_MODE
\r
5524 .remain_on_channel = cfg80211_rtw_remain_on_channel,
\r
5525 .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
\r
5528 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5529 .mgmt_tx = cfg80211_rtw_mgmt_tx,
\r
5530 .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
\r
5531 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
\r
5532 .action = cfg80211_rtw_mgmt_tx,
\r
5536 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
\r
5539 #define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
\r
5540 #define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
\r
5542 ht_cap->ht_supported = _TRUE;
\r
5544 ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
\r
5545 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
\r
5546 IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
\r
5549 *Maximum length of AMPDU that the STA can receive.
\r
5550 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
\r
5552 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
\r
5554 /*Minimum MPDU start spacing , */
\r
5555 ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
\r
5557 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
\r
5560 *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
\r
5563 *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
\r
5564 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
\r
5565 *if rx_ant >=3 rx_mask[2]=0xff;
\r
5566 *if BW_40 rx_mask[4]=0x01;
\r
5567 *highest supported RX rate
\r
5569 if(rf_type == RF_1T1R)
\r
5571 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
5572 ht_cap->mcs.rx_mask[1] = 0x00;
\r
5573 ht_cap->mcs.rx_mask[4] = 0x01;
\r
5575 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
\r
5577 else if((rf_type == RF_1T2R) || (rf_type==RF_2T2R))
\r
5579 ht_cap->mcs.rx_mask[0] = 0xFF;
\r
5580 ht_cap->mcs.rx_mask[1] = 0xFF;
\r
5581 ht_cap->mcs.rx_mask[4] = 0x01;
\r
5583 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
\r
5587 DBG_8192C("%s, error rf_type=%d\n", __func__, rf_type);
\r
5592 void rtw_cfg80211_init_wiphy(_adapter *padapter)
\r
5595 struct ieee80211_supported_band *bands;
\r
5596 struct wireless_dev *pwdev = padapter->rtw_wdev;
\r
5597 struct wiphy *wiphy = pwdev->wiphy;
\r
5599 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
\r
5601 DBG_8192C("%s:rf_type=%d\n", __func__, rf_type);
\r
5603 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
\r
5605 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
\r
5607 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type);
\r
5610 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
\r
5612 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
\r
5614 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type);
\r
5617 /* init regulary domain */
\r
5618 rtw_regd_init(padapter, rtw_reg_notifier);
\r
5620 /* copy mac_addr to wiphy */
\r
5621 _rtw_memcpy(wiphy->perm_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
\r
5626 struct ieee80211_iface_limit rtw_limits[] = {
\r
5627 { .max = 1, .types = BIT(NL80211_IFTYPE_STATION)
\r
5628 | BIT(NL80211_IFTYPE_ADHOC)
\r
5629 #ifdef CONFIG_AP_MODE
\r
5630 | BIT(NL80211_IFTYPE_AP)
\r
5632 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
5633 | BIT(NL80211_IFTYPE_P2P_CLIENT)
\r
5634 | BIT(NL80211_IFTYPE_P2P_GO)
\r
5637 {.max = 1, .types = BIT(NL80211_IFTYPE_MONITOR)},
\r
5640 struct ieee80211_iface_combination rtw_combinations = {
\r
5641 .limits = rtw_limits,
\r
5642 .n_limits = ARRAY_SIZE(rtw_limits),
\r
5643 .max_interfaces = 2,
\r
5644 .num_different_channels = 1,
\r
5648 static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy)
\r
5651 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
\r
5653 wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
\r
5654 wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
\r
5655 wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
\r
5657 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
\r
5658 wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
\r
5661 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
\r
5662 | BIT(NL80211_IFTYPE_ADHOC)
\r
5663 #ifdef CONFIG_AP_MODE
\r
5664 | BIT(NL80211_IFTYPE_AP)
\r
5665 | BIT(NL80211_IFTYPE_MONITOR)
\r
5667 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
\r
5668 | BIT(NL80211_IFTYPE_P2P_CLIENT)
\r
5669 | BIT(NL80211_IFTYPE_P2P_GO)
\r
5673 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
\r
5674 #ifdef CONFIG_AP_MODE
\r
5675 wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
\r
5676 #endif //CONFIG_AP_MODE
\r
5679 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
\r
5680 wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
\r
5684 wiphy->iface_combinations = &rtw_combinations;
\r
5685 wiphy->n_iface_combinations = 1;
\r
5688 wiphy->cipher_suites = rtw_cipher_suites;
\r
5689 wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
\r
5691 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
\r
5692 wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
\r
5693 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
\r
5694 wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
\r
5696 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
\r
5697 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
\r
5700 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
\r
5701 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
\r
5702 wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
\r
5705 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
\r
5706 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
\r
5708 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
\r
5710 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
\r
5711 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
\r
5715 int rtw_wdev_alloc(_adapter *padapter, struct device *dev)
\r
5718 struct wiphy *wiphy;
\r
5719 struct wireless_dev *wdev;
\r
5720 struct rtw_wdev_priv *pwdev_priv;
\r
5721 struct net_device *pnetdev = padapter->pnetdev;
\r
5723 DBG_8192C("%s(padapter=%p)\n", __func__, padapter);
\r
5726 wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(_adapter*));
\r
5728 DBG_8192C("Couldn't allocate wiphy device\n");
\r
5732 set_wiphy_dev(wiphy, dev);
\r
5733 *((_adapter**)wiphy_priv(wiphy)) = padapter;
\r
5734 rtw_cfg80211_preinit_wiphy(padapter, wiphy);
\r
5736 ret = wiphy_register(wiphy);
\r
5738 DBG_8192C("Couldn't register wiphy device\n");
\r
5743 wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
\r
5745 DBG_8192C("Couldn't allocate wireless device\n");
\r
5747 goto unregister_wiphy;
\r
5749 wdev->wiphy = wiphy;
\r
5750 wdev->netdev = pnetdev;
\r
5752 wdev->iftype = NL80211_IFTYPE_STATION; // will be init in rtw_hal_init()
\r
5753 // Must sync with _rtw_init_mlme_priv()
\r
5754 // pmlmepriv->fw_state = WIFI_STATION_STATE
\r
5755 //wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
\r
5756 padapter->rtw_wdev = wdev;
\r
5757 pnetdev->ieee80211_ptr = wdev;
\r
5760 pwdev_priv = adapter_wdev_data(padapter);
\r
5761 pwdev_priv->rtw_wdev = wdev;
\r
5762 pwdev_priv->pmon_ndev = NULL;
\r
5763 pwdev_priv->ifname_mon[0] = '\0';
\r
5764 pwdev_priv->padapter = padapter;
\r
5765 pwdev_priv->scan_request = NULL;
\r
5766 _rtw_spinlock_init(&pwdev_priv->scan_req_lock);
\r
5768 pwdev_priv->p2p_enabled = _FALSE;
\r
5769 pwdev_priv->provdisc_req_issued = _FALSE;
\r
5770 rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
\r
5771 rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
\r
5773 pwdev_priv->bandroid_scan = _FALSE;
\r
5775 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
\r
5776 pwdev_priv->power_mgmt = _TRUE;
\r
5778 pwdev_priv->power_mgmt = _FALSE;
\r
5780 #ifdef CONFIG_CONCURRENT_MODE
\r
5781 ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
\r
5782 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
\r
5787 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
\r
5789 wiphy_unregister(wiphy);
\r
5791 wiphy_free(wiphy);
\r
5797 void rtw_wdev_free(struct wireless_dev *wdev)
\r
5799 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
\r
5804 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
\r
5805 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
\r
5807 wiphy_free(wdev->wiphy);
\r
5809 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
\r
5812 void rtw_wdev_unregister(struct wireless_dev *wdev)
\r
5814 struct net_device *ndev;
\r
5815 _adapter *adapter;
\r
5816 struct rtw_wdev_priv *pwdev_priv;
\r
5818 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
\r
5823 if(!(ndev = wdev_to_ndev(wdev)))
\r
5826 adapter = (_adapter *)rtw_netdev_priv(ndev);
\r
5827 pwdev_priv = adapter_wdev_data(adapter);
\r
5829 rtw_cfg80211_indicate_scan_done(adapter, _TRUE);
\r
5831 if (pwdev_priv->pmon_ndev) {
\r
5832 DBG_8192C("%s, unregister monitor interface\n", __func__);
\r
5833 unregister_netdev(pwdev_priv->pmon_ndev);
\r
5836 wiphy_unregister(wdev->wiphy);
\r
5839 #endif //CONFIG_IOCTL_CFG80211
\r