1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
20 #define _IOCTL_CFG80211_C_
23 #include <osdep_service.h>
24 #include <drv_types.h>
25 #include <rtw_ioctl.h>
26 #include <rtw_ioctl_set.h>
27 #include <rtw_ioctl_query.h>
28 #include <xmit_osdep.h>
30 #ifdef CONFIG_IOCTL_CFG80211
32 #include "ioctl_cfg80211.h"
34 #define RTW_MAX_MGMT_TX_CNT (8)
36 #define RTW_SCAN_IE_LEN_MAX 2304
37 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535 //ms
38 #define RTW_MAX_NUM_PMKIDS 4
40 #define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
42 static const u32 rtw_cipher_suites[] = {
43 WLAN_CIPHER_SUITE_WEP40,
44 WLAN_CIPHER_SUITE_WEP104,
45 WLAN_CIPHER_SUITE_TKIP,
46 WLAN_CIPHER_SUITE_CCMP,
47 #ifdef CONFIG_IEEE80211W
48 WLAN_CIPHER_SUITE_AES_CMAC,
49 #endif //CONFIG_IEEE80211W
52 #define RATETAB_ENT(_rate, _rateid, _flags) \
55 .hw_value = (_rateid), \
59 #define CHAN2G(_channel, _freq, _flags) { \
60 .band = IEEE80211_BAND_2GHZ, \
61 .center_freq = (_freq), \
62 .hw_value = (_channel), \
64 .max_antenna_gain = 0, \
68 #define CHAN5G(_channel, _flags) { \
69 .band = IEEE80211_BAND_5GHZ, \
70 .center_freq = 5000 + (5 * (_channel)), \
71 .hw_value = (_channel), \
73 .max_antenna_gain = 0, \
77 static struct ieee80211_rate rtw_rates[] = {
78 RATETAB_ENT(10, 0x1, 0),
79 RATETAB_ENT(20, 0x2, 0),
80 RATETAB_ENT(55, 0x4, 0),
81 RATETAB_ENT(110, 0x8, 0),
82 RATETAB_ENT(60, 0x10, 0),
83 RATETAB_ENT(90, 0x20, 0),
84 RATETAB_ENT(120, 0x40, 0),
85 RATETAB_ENT(180, 0x80, 0),
86 RATETAB_ENT(240, 0x100, 0),
87 RATETAB_ENT(360, 0x200, 0),
88 RATETAB_ENT(480, 0x400, 0),
89 RATETAB_ENT(540, 0x800, 0),
92 #define rtw_a_rates (rtw_rates + 4)
93 #define RTW_A_RATES_NUM 8
94 #define rtw_g_rates (rtw_rates + 0)
95 #define RTW_G_RATES_NUM 12
97 #define RTW_2G_CHANNELS_NUM 14
98 #define RTW_5G_CHANNELS_NUM 37
100 static struct ieee80211_channel rtw_2ghz_channels[] = {
117 static struct ieee80211_channel rtw_5ghz_a_channels[] = {
118 CHAN5G(34, 0), CHAN5G(36, 0),
119 CHAN5G(38, 0), CHAN5G(40, 0),
120 CHAN5G(42, 0), CHAN5G(44, 0),
121 CHAN5G(46, 0), CHAN5G(48, 0),
122 CHAN5G(52, 0), CHAN5G(56, 0),
123 CHAN5G(60, 0), CHAN5G(64, 0),
124 CHAN5G(100, 0), CHAN5G(104, 0),
125 CHAN5G(108, 0), CHAN5G(112, 0),
126 CHAN5G(116, 0), CHAN5G(120, 0),
127 CHAN5G(124, 0), CHAN5G(128, 0),
128 CHAN5G(132, 0), CHAN5G(136, 0),
129 CHAN5G(140, 0), CHAN5G(149, 0),
130 CHAN5G(153, 0), CHAN5G(157, 0),
131 CHAN5G(161, 0), CHAN5G(165, 0),
132 CHAN5G(184, 0), CHAN5G(188, 0),
133 CHAN5G(192, 0), CHAN5G(196, 0),
134 CHAN5G(200, 0), CHAN5G(204, 0),
135 CHAN5G(208, 0), CHAN5G(212, 0),
140 void rtw_2g_channels_init(struct ieee80211_channel *channels)
142 _rtw_memcpy((void*)channels, (void*)rtw_2ghz_channels,
143 sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
147 void rtw_5g_channels_init(struct ieee80211_channel *channels)
149 _rtw_memcpy((void*)channels, (void*)rtw_5ghz_a_channels,
150 sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
154 void rtw_2g_rates_init(struct ieee80211_rate *rates)
156 _rtw_memcpy(rates, rtw_g_rates,
157 sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
161 void rtw_5g_rates_init(struct ieee80211_rate *rates)
163 _rtw_memcpy(rates, rtw_a_rates,
164 sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM
168 struct ieee80211_supported_band *rtw_spt_band_alloc(
169 enum ieee80211_band band
172 struct ieee80211_supported_band *spt_band = NULL;
173 int n_channels, n_bitrates;
175 if(band == IEEE80211_BAND_2GHZ)
177 n_channels = RTW_2G_CHANNELS_NUM;
178 n_bitrates = RTW_G_RATES_NUM;
180 else if(band == IEEE80211_BAND_5GHZ)
182 n_channels = RTW_5G_CHANNELS_NUM;
183 n_bitrates = RTW_A_RATES_NUM;
190 spt_band = (struct ieee80211_supported_band *)rtw_zmalloc(
191 sizeof(struct ieee80211_supported_band)
192 + sizeof(struct ieee80211_channel)*n_channels
193 + sizeof(struct ieee80211_rate)*n_bitrates
198 spt_band->channels = (struct ieee80211_channel*)(((u8*)spt_band)+sizeof(struct ieee80211_supported_band));
199 spt_band->bitrates= (struct ieee80211_rate*)(((u8*)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
200 spt_band->band = band;
201 spt_band->n_channels = n_channels;
202 spt_band->n_bitrates = n_bitrates;
204 if(band == IEEE80211_BAND_2GHZ)
206 rtw_2g_channels_init(spt_band->channels);
207 rtw_2g_rates_init(spt_band->bitrates);
209 else if(band == IEEE80211_BAND_5GHZ)
211 rtw_5g_channels_init(spt_band->channels);
212 rtw_5g_rates_init(spt_band->bitrates);
222 void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
229 if(spt_band->band == IEEE80211_BAND_2GHZ)
231 size = sizeof(struct ieee80211_supported_band)
232 + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
233 + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM;
235 else if(spt_band->band == IEEE80211_BAND_5GHZ)
237 size = sizeof(struct ieee80211_supported_band)
238 + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
239 + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM;
245 rtw_mfree((u8*)spt_band, size);
248 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
249 static const struct ieee80211_txrx_stypes
250 rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
251 [NL80211_IFTYPE_ADHOC] = {
253 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
255 [NL80211_IFTYPE_STATION] = {
257 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
258 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
260 [NL80211_IFTYPE_AP] = {
262 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
263 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
264 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
265 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
266 BIT(IEEE80211_STYPE_AUTH >> 4) |
267 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
268 BIT(IEEE80211_STYPE_ACTION >> 4)
270 [NL80211_IFTYPE_AP_VLAN] = {
273 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
274 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
275 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
276 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
277 BIT(IEEE80211_STYPE_AUTH >> 4) |
278 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
279 BIT(IEEE80211_STYPE_ACTION >> 4)
281 [NL80211_IFTYPE_P2P_CLIENT] = {
283 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
284 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
286 [NL80211_IFTYPE_P2P_GO] = {
288 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
289 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
290 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
291 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
292 BIT(IEEE80211_STYPE_AUTH >> 4) |
293 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
294 BIT(IEEE80211_STYPE_ACTION >> 4)
299 static int rtw_ieee80211_channel_to_frequency(int chan, int band)
301 /* see 802.11 17.3.8.3.2 and Annex J
302 * there are overlapping channel numbers in 5GHz and 2GHz bands */
304 if (band == IEEE80211_BAND_5GHZ) {
305 if (chan >= 182 && chan <= 196)
306 return 4000 + chan * 5;
308 return 5000 + chan * 5;
309 } else { /* IEEE80211_BAND_2GHZ */
313 return 2407 + chan * 5;
315 return 0; /* not supported */
319 #define MAX_BSSINFO_LEN 1000
320 static int rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork)
323 struct ieee80211_channel *notify_channel;
324 struct cfg80211_bss *bss;
325 //struct ieee80211_supported_band *band;
328 u64 notify_timestamp;
329 u16 notify_capability;
334 u8 buf[MAX_BSSINFO_LEN], *pbuf;
335 size_t len,bssinf_len=0;
336 struct rtw_ieee80211_hdr *pwlanhdr;
337 unsigned short *fctrl;
338 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
340 struct wireless_dev *wdev = padapter->rtw_wdev;
341 struct wiphy *wiphy = wdev->wiphy;
342 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
345 //DBG_8192C("%s\n", __func__);
347 bssinf_len = pnetwork->network.IELength+sizeof (struct rtw_ieee80211_hdr_3addr);
348 if(bssinf_len > MAX_BSSINFO_LEN){
349 DBG_871X("%s IE Length too long > %d byte \n",__FUNCTION__,MAX_BSSINFO_LEN);
353 //To reduce PBC Overlap rate
354 //_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
355 if(wdev_to_priv(wdev)->scan_request != NULL)
357 u8 *psr=NULL, sr = 0;
358 NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid;
359 struct cfg80211_scan_request *request = wdev_to_priv(wdev)->scan_request;
360 struct cfg80211_ssid *ssids = request->ssids;
364 wpsie = rtw_get_wps_ie(pnetwork->network.IEs+_FIXED_IE_LENGTH_, pnetwork->network.IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
366 if(wpsie && wpsielen>0)
367 psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
371 if(request->n_ssids == 1 && request->n_channels == 1) // it means under processing WPS
373 DBG_8192C("ssid=%s, len=%d\n", pssid->Ssid, pssid->SsidLength);
375 if(pssid->SsidLength == ssids[0].ssid_len &&
376 _rtw_memcmp(pssid->Ssid, ssids[0].ssid, ssids[0].ssid_len))
378 DBG_871X("%s, got sr and ssid match!\n", __func__);
386 WLAN_BSSID_EX *pselect_network = &pnetwork->network;
387 struct cfg80211_bss *pselect_bss = NULL;
388 struct ieee80211_channel *notify_channel = NULL;
391 DBG_871X("%s, got sr, but ssid mismatch, to remove this bss\n", __func__);
393 if (pselect_network->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
394 freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
396 freq = rtw_ieee80211_channel_to_frequency(pselect_network->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
398 notify_channel = ieee80211_get_channel(wiphy, freq);
399 pselect_bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
400 pselect_network->MacAddress, pselect_network->Ssid.Ssid,
401 pselect_network->Ssid.SsidLength, 0/*WLAN_CAPABILITY_ESS*/,
402 0/*WLAN_CAPABILITY_ESS*/);
406 DBG_871X("%s, got bss for cfg80211 for unlinking bss\n", __func__);
408 cfg80211_unlink_bss(wiphy, pselect_bss);
409 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
410 cfg80211_put_bss(wiphy, pselect_bss);
412 cfg80211_put_bss(pselect_bss);
423 //_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
425 channel = pnetwork->network.Configuration.DSConfig;
426 if (channel <= RTW_CH_MAX_2G_CHANNEL)
427 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
429 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
431 notify_channel = ieee80211_get_channel(wiphy, freq);
433 //rtw_get_timestampe_from_ie()
434 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
436 notify_interval = le16_to_cpu(*(u16*)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
437 notify_capability = le16_to_cpu(*(u16*)rtw_get_capability_from_ie(pnetwork->network.IEs));
440 notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_;
441 notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_;
443 //We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm)
444 if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
445 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) {
446 notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);//dbm
448 notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);//dbm
452 DBG_8192C("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
453 pnetwork->network.MacAddress[0], pnetwork->network.MacAddress[1], pnetwork->network.MacAddress[2],
454 pnetwork->network.MacAddress[3], pnetwork->network.MacAddress[4], pnetwork->network.MacAddress[5]);
455 DBG_8192C("Channel: %d(%d)\n", channel, freq);
456 DBG_8192C("Capability: %X\n", notify_capability);
457 DBG_8192C("Beacon interval: %d\n", notify_interval);
458 DBG_8192C("Signal: %d\n", notify_signal);
459 DBG_8192C("notify_timestamp: %#018llx\n", notify_timestamp);
464 pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;
465 fctrl = &(pwlanhdr->frame_ctl);
468 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
469 //pmlmeext->mgnt_seq++;
471 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
472 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
473 SetFrameSubType(pbuf, WIFI_BEACON);
475 _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
476 SetFrameSubType(pbuf, WIFI_PROBERSP);
479 _rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
480 _rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
483 pbuf += sizeof(struct rtw_ieee80211_hdr_3addr);
484 len = sizeof (struct rtw_ieee80211_hdr_3addr);
486 _rtw_memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength);
487 len += pnetwork->network.IELength;
490 //if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
492 // DBG_8192C("%s, got p2p_ie\n", __func__);
498 bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)buf,
499 len, notify_signal, GFP_ATOMIC);
502 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress,
503 notify_timestamp, notify_capability, notify_interval, notify_ie,
504 notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/);
507 if (unlikely(!bss)) {
508 DBG_8192C("rtw_cfg80211_inform_bss error\n");
512 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
513 #ifndef COMPAT_KERNEL_RELEASE
514 //patch for cfg80211, update beacon ies to information_elements
515 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
517 if(bss->len_information_elements != bss->len_beacon_ies)
519 bss->information_elements = bss->beacon_ies;
520 bss->len_information_elements = bss->len_beacon_ies;
523 #endif //COMPAT_KERNEL_RELEASE
524 #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
528 if( bss->information_elements == bss->proberesp_ies)
530 if( bss->len_information_elements != bss->len_proberesp_ies)
532 DBG_8192C("error!, len_information_elements != bss->len_proberesp_ies\n");
536 else if(bss->len_information_elements < bss->len_beacon_ies)
538 bss->information_elements = bss->beacon_ies;
539 bss->len_information_elements = bss->len_beacon_ies;
544 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
545 cfg80211_put_bss(wiphy, bss);
547 cfg80211_put_bss(bss);
556 Check the given bss is valid by kernel API cfg80211_get_bss()
557 @padapter : the given adapter
559 return _TRUE if bss is valid, _FALSE for not found.
561 int rtw_cfg80211_check_bss(_adapter *padapter)
563 WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
564 struct cfg80211_bss *bss = NULL;
565 struct ieee80211_channel *notify_channel = NULL;
568 if (!(pnetwork) || !(padapter->rtw_wdev))
571 if (pnetwork->Configuration.DSConfig <= RTW_CH_MAX_2G_CHANNEL)
572 freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_2GHZ);
574 freq = rtw_ieee80211_channel_to_frequency(pnetwork->Configuration.DSConfig, IEEE80211_BAND_5GHZ);
576 notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
577 bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
578 pnetwork->MacAddress, pnetwork->Ssid.Ssid,
579 pnetwork->Ssid.SsidLength,
580 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
585 void rtw_cfg80211_indicate_connect(_adapter *padapter)
587 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
588 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
589 struct wireless_dev *pwdev = padapter->rtw_wdev;
591 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
593 struct cfg80211_bss *bss = NULL;
595 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
596 if (pwdev->iftype != NL80211_IFTYPE_STATION
597 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
598 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
604 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
608 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
610 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
612 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
613 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
614 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
615 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));
620 #ifdef CONFIG_LAYER2_ROAMING
621 if (rtw_to_roaming(padapter) > 0) {
622 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
623 struct wiphy *wiphy = pwdev->wiphy;
624 struct ieee80211_channel *notify_channel;
626 u16 channel = cur_network->network.Configuration.DSConfig;
628 if (channel <= RTW_CH_MAX_2G_CHANNEL)
629 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
631 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
633 notify_channel = ieee80211_get_channel(wiphy, freq);
636 DBG_871X("%s call cfg80211_roamed\n", __FUNCTION__);
637 cfg80211_roamed(padapter->pnetdev
638 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
641 , cur_network->network.MacAddress
642 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
643 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
644 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
645 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
651 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
652 cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
653 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
654 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
655 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
656 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
657 , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
658 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
662 void rtw_cfg80211_indicate_disconnect(_adapter *padapter)
664 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
665 struct wireless_dev *pwdev = padapter->rtw_wdev;
667 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
670 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
672 if (pwdev->iftype != NL80211_IFTYPE_STATION
673 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
674 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
680 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
684 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
686 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
688 _cancel_timer_ex( &pwdinfo->find_phase_timer );
689 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
690 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
692 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
693 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
695 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));
700 if (!padapter->mlmepriv.not_indic_disco) {
701 DBG_8192C("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
703 if(pwdev->sme_state==CFG80211_SME_CONNECTING)
704 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
705 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
706 else if(pwdev->sme_state==CFG80211_SME_CONNECTED)
707 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
709 //DBG_8192C("pwdev->sme_state=%d\n", pwdev->sme_state);
711 DBG_8192C("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
716 #ifdef CONFIG_AP_MODE
717 static u8 set_pairwise_key(_adapter *padapter, struct sta_info *psta)
719 struct cmd_obj* ph2c;
720 struct set_stakey_parm *psetstakey_para;
721 struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
724 ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
730 psetstakey_para = (struct set_stakey_parm*)rtw_zmalloc(sizeof(struct set_stakey_parm));
731 if(psetstakey_para==NULL){
732 rtw_mfree((u8 *) ph2c, sizeof(struct cmd_obj));
737 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
740 psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy;
742 _rtw_memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);
744 _rtw_memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
747 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
755 static int set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid)
758 struct cmd_obj* pcmd;
759 struct setkey_parm *psetkeyparm;
760 struct cmd_priv *pcmdpriv=&(padapter->cmdpriv);
763 DBG_8192C("%s\n", __FUNCTION__);
765 pcmd = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
770 psetkeyparm=(struct setkey_parm*)rtw_zmalloc(sizeof(struct setkey_parm));
771 if(psetkeyparm==NULL){
772 rtw_mfree((unsigned char *)pcmd, sizeof(struct cmd_obj));
777 _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
779 psetkeyparm->keyid=(u8)keyid;
781 padapter->securitypriv.key_mask |= BIT(psetkeyparm->keyid);
783 psetkeyparm->algorithm = alg;
785 psetkeyparm->set_tx = 1;
803 _rtw_memcpy(&(psetkeyparm->key[0]), key, keylen);
805 pcmd->cmdcode = _SetKey_CMD_;
806 pcmd->parmbuf = (u8 *)psetkeyparm;
807 pcmd->cmdsz = (sizeof(struct setkey_parm));
812 _rtw_init_listhead(&pcmd->list);
814 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
823 static int set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid)
839 return set_group_key(padapter, key, alg, keyid);
843 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
846 u32 wep_key_idx, wep_key_len,wep_total_len;
847 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
848 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
849 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
850 struct security_priv* psecuritypriv=&(padapter->securitypriv);
851 struct sta_priv *pstapriv = &padapter->stapriv;
853 DBG_8192C("%s\n", __FUNCTION__);
855 param->u.crypt.err = 0;
856 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
858 //sizeof(struct ieee_param) = 64 bytes;
859 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
860 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
866 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
867 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
868 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
870 if (param->u.crypt.idx >= WEP_KEYS)
878 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
882 DBG_8192C("rtw_set_encryption(), sta has already been removed or never been added\n");
887 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
889 //todo:clear default encryption keys
891 DBG_8192C("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
897 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
899 DBG_8192C("r871x_set_encryption, crypt.alg = WEP\n");
901 wep_key_idx = param->u.crypt.idx;
902 wep_key_len = param->u.crypt.key_len;
904 DBG_8192C("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
906 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
914 wep_key_len = wep_key_len <= 5 ? 5 : 13;
917 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
919 //wep default key has not been set, so use this key index as default key.
921 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
922 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
923 psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
925 if(wep_key_len == 13)
927 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
928 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
931 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
934 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
936 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
938 set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx);
945 if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
947 if(param->u.crypt.set_tx == 0) //group key
949 if(strcmp(param->u.crypt.alg, "WEP") == 0)
951 DBG_8192C("%s, set group_key, WEP\n", __FUNCTION__);
953 _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));
955 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
956 if(param->u.crypt.key_len==13)
958 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
962 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
964 DBG_8192C("%s, set group_key, TKIP\n", __FUNCTION__);
966 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
968 _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));
970 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
972 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
973 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
975 psecuritypriv->busetkipkey = _TRUE;
978 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
980 DBG_8192C("%s, set group_key, CCMP\n", __FUNCTION__);
982 psecuritypriv->dot118021XGrpPrivacy = _AES_;
984 _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));
988 DBG_8192C("%s, set group_key, none\n", __FUNCTION__);
990 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
993 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
995 psecuritypriv->binstallGrpkey = _TRUE;
997 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
999 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
1001 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1004 pbcmc_sta->ieee8021x_blocked = _FALSE;
1005 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
1014 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
1016 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
1018 if(param->u.crypt.set_tx ==1) //pairwise key
1020 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1022 if(strcmp(param->u.crypt.alg, "WEP") == 0)
1024 DBG_8192C("%s, set pairwise key, WEP\n", __FUNCTION__);
1026 psta->dot118021XPrivacy = _WEP40_;
1027 if(param->u.crypt.key_len==13)
1029 psta->dot118021XPrivacy = _WEP104_;
1032 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
1034 DBG_8192C("%s, set pairwise key, TKIP\n", __FUNCTION__);
1036 psta->dot118021XPrivacy = _TKIP_;
1038 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
1040 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1041 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1043 psecuritypriv->busetkipkey = _TRUE;
1046 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
1049 DBG_8192C("%s, set pairwise key, CCMP\n", __FUNCTION__);
1051 psta->dot118021XPrivacy = _AES_;
1055 DBG_8192C("%s, set pairwise key, none\n", __FUNCTION__);
1057 psta->dot118021XPrivacy = _NO_PRIVACY_;
1060 set_pairwise_key(padapter, psta);
1062 psta->ieee8021x_blocked = _FALSE;
1064 psta->bpairwise_key_installed = _TRUE;
1069 if(strcmp(param->u.crypt.alg, "WEP") == 0)
1071 _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));
1073 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1074 if(param->u.crypt.key_len==13)
1076 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1079 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
1081 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
1083 _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));
1085 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
1087 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
1088 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
1090 psecuritypriv->busetkipkey = _TRUE;
1093 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
1095 psecuritypriv->dot118021XGrpPrivacy = _AES_;
1097 _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));
1101 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
1104 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
1106 psecuritypriv->binstallGrpkey = _TRUE;
1108 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
1110 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
1112 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1115 pbcmc_sta->ieee8021x_blocked = _FALSE;
1116 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
1132 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
1135 u32 wep_key_idx, wep_key_len,wep_total_len;
1136 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1137 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1138 struct security_priv *psecuritypriv = &padapter->securitypriv;
1140 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
1145 DBG_8192C("%s\n", __func__);
1147 param->u.crypt.err = 0;
1148 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
1150 if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
1156 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
1157 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
1158 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
1160 if (param->u.crypt.idx >= WEP_KEYS
1161 #ifdef CONFIG_IEEE80211W
1162 && param->u.crypt.idx > BIP_MAX_KEYID
1163 #endif //CONFIG_IEEE80211W
1174 if (strcmp(param->u.crypt.alg, "WEP") == 0)
1176 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
1177 DBG_8192C("wpa_set_encryption, crypt.alg = WEP\n");
1179 wep_key_idx = param->u.crypt.idx;
1180 wep_key_len = param->u.crypt.key_len;
1182 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0))
1188 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
1190 //wep default key has not been set, so use this key index as default key.
1192 wep_key_len = wep_key_len <= 5 ? 5 : 13;
1194 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1195 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1196 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1200 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1201 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1204 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
1207 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
1209 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
1211 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
1216 if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
1218 struct sta_info * psta,*pbcmc_sta;
1219 struct sta_priv * pstapriv = &padapter->stapriv;
1221 //DBG_8192C("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__);
1223 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
1225 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
1227 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
1228 DBG_8192C("%s, : Obtain Sta_info fail \n", __func__);
1232 //Jeff: don't disable ieee8021x_blocked while clearing key
1233 if (strcmp(param->u.crypt.alg, "none") != 0)
1234 psta->ieee8021x_blocked = _FALSE;
1237 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1238 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1240 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1243 if(param->u.crypt.set_tx ==1)//pairwise key
1246 DBG_8192C("%s, : param->u.crypt.set_tx ==1 \n", __func__);
1248 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1250 if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
1252 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1253 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1254 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1256 padapter->securitypriv.busetkipkey=_FALSE;
1257 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
1260 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
1261 DBG_871X(" ~~~~set sta key:unicastkey\n");
1263 rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE);
1267 if(strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0)
1269 _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));
1270 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
1271 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
1272 padapter->securitypriv.binstallGrpkey = _TRUE;
1273 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1274 DBG_871X(" ~~~~set sta key:groupkey\n");
1276 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1278 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1);
1280 #ifdef CONFIG_IEEE80211W
1281 else if(strcmp(param->u.crypt.alg, "BIP") == 0)
1284 //DBG_871X("BIP key_len=%d , index=%d @@@@@@@@@@@@@@@@@@\n", param->u.crypt.key_len, param->u.crypt.idx);
1285 //save the IGTK key, length 16 bytes
1286 _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));
1287 /*DBG_871X("IGTK key below:\n");
1288 for(no=0;no<16;no++)
1289 printk(" %02x ", padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey[no]);
1291 padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
1292 padapter->securitypriv.binstallBIPkey = _TRUE;
1293 DBG_871X(" ~~~~set sta key:IGKT\n");
1295 #endif //CONFIG_IEEE80211W
1298 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
1300 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
1302 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
1310 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1313 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
1317 //Jeff: don't disable ieee8021x_blocked while clearing key
1318 if (strcmp(param->u.crypt.alg, "none") != 0)
1319 pbcmc_sta->ieee8021x_blocked = _FALSE;
1321 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1322 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1324 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1328 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
1335 DBG_8192C("%s, ret=%d\n", __func__, ret);
1342 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
1343 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1344 u8 key_index, bool pairwise, const u8 *mac_addr,
1345 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1346 u8 key_index, const u8 *mac_addr,
1347 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1348 struct key_params *params)
1352 struct ieee_param *param = NULL;
1354 struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
1355 _adapter *padapter = wiphy_to_adapter(wiphy);
1356 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1358 DBG_871X(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
1359 DBG_871X("cipher=0x%x\n", params->cipher);
1360 DBG_871X("key_len=0x%x\n", params->key_len);
1361 DBG_871X("seq_len=0x%x\n", params->seq_len);
1362 DBG_871X("key_index=%d\n", key_index);
1363 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1364 DBG_871X("pairwise=%d\n", pairwise);
1365 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1367 param_len = sizeof(struct ieee_param) + params->key_len;
1368 param = (struct ieee_param *)rtw_malloc(param_len);
1372 _rtw_memset(param, 0, param_len);
1374 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1375 _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
1377 switch (params->cipher) {
1378 case IW_AUTH_CIPHER_NONE:
1383 case WLAN_CIPHER_SUITE_WEP40:
1384 case WLAN_CIPHER_SUITE_WEP104:
1387 case WLAN_CIPHER_SUITE_TKIP:
1390 case WLAN_CIPHER_SUITE_CCMP:
1393 #ifdef CONFIG_IEEE80211W
1394 case WLAN_CIPHER_SUITE_AES_CMAC:
1397 #endif //CONFIG_IEEE80211W
1402 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1405 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1407 param->u.crypt.set_tx = 0; //for wpa/wpa2 group key
1409 param->u.crypt.set_tx = 1; //for wpa/wpa2 pairwise key
1413 //param->u.crypt.idx = key_index - 1;
1414 param->u.crypt.idx = key_index;
1416 if (params->seq_len && params->seq)
1418 _rtw_memcpy(param->u.crypt.seq, params->seq, params->seq_len);
1421 if(params->key_len && params->key)
1423 param->u.crypt.key_len = params->key_len;
1424 _rtw_memcpy(param->u.crypt.key, params->key, params->key_len);
1427 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1429 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
1431 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1433 #ifdef CONFIG_AP_MODE
1435 _rtw_memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN);
1437 ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
1442 DBG_8192C("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
1448 rtw_mfree((u8*)param, param_len);
1455 static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
1456 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1457 u8 key_index, bool pairwise, const u8 *mac_addr,
1458 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1459 u8 key_index, const u8 *mac_addr,
1460 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1462 void (*callback)(void *cookie,
1463 struct key_params*))
1466 struct iwm_priv *iwm = ndev_to_iwm(ndev);
1467 struct iwm_key *key = &iwm->keys[key_index];
1468 struct key_params params;
1470 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
1472 memset(¶ms, 0, sizeof(params));
1474 params.cipher = key->cipher;
1475 params.key_len = key->key_len;
1476 params.seq_len = key->seq_len;
1477 params.seq = key->seq;
1478 params.key = key->key;
1480 callback(cookie, ¶ms);
1482 return key->key_len ? 0 : -ENOENT;
1484 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
1488 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
1489 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1490 u8 key_index, bool pairwise, const u8 *mac_addr)
1491 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1492 u8 key_index, const u8 *mac_addr)
1493 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1495 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1496 struct security_priv *psecuritypriv = &padapter->securitypriv;
1498 DBG_871X(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index);
1500 if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
1502 //clear the flag of wep default key set.
1503 psecuritypriv->bWepDefaultKeyIdxSet = 0;
1509 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
1510 struct net_device *ndev, u8 key_index
1511 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1512 , bool unicast, bool multicast
1516 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1517 struct security_priv *psecuritypriv = &padapter->securitypriv;
1519 DBG_871X(FUNC_NDEV_FMT" key_index=%d"
1520 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1521 ", unicast=%d, multicast=%d"
1523 ".\n", FUNC_NDEV_ARG(ndev), key_index
1524 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1525 , unicast, multicast
1529 if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) //set wep default key
1531 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1533 psecuritypriv->dot11PrivacyKeyIndex = key_index;
1535 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1536 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1537 if (psecuritypriv->dot11DefKeylen[key_index] == 13)
1539 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1540 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1543 psecuritypriv->bWepDefaultKeyIdxSet = 1; //set the flag to represent that wep default key has been set
1550 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
1551 struct net_device *ndev,
1552 u8 *mac, struct station_info *sinfo)
1555 _adapter *padapter = wiphy_to_adapter(wiphy);
1556 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1557 struct sta_info *psta = NULL;
1558 struct sta_priv *pstapriv = &padapter->stapriv;
1563 DBG_871X(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
1568 psta = rtw_get_stainfo(pstapriv, mac);
1570 DBG_8192C("%s, sta_info is null\n", __func__);
1575 #ifdef CONFIG_DEBUG_CFG80211
1576 DBG_871X(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
1579 //for infra./P2PClient mode
1580 if( check_fwstate(pmlmepriv, WIFI_STATION_STATE)
1581 && check_fwstate(pmlmepriv, _FW_LINKED)
1584 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
1586 if (_rtw_memcmp(mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) {
1587 DBG_871X("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
1592 sinfo->filled |= STATION_INFO_SIGNAL;
1593 sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
1595 sinfo->filled |= STATION_INFO_TX_BITRATE;
1596 sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
1598 sinfo->filled |= STATION_INFO_RX_PACKETS;
1599 sinfo->rx_packets = sta_rx_data_pkts(psta);
1601 sinfo->filled |= STATION_INFO_TX_PACKETS;
1602 sinfo->tx_packets = psta->sta_stats.tx_pkts;
1606 //for Ad-Hoc/AP mode
1607 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
1608 ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
1609 ||check_fwstate(pmlmepriv, WIFI_AP_STATE))
1610 && check_fwstate(pmlmepriv, _FW_LINKED)
1613 //TODO: should acquire station info...
1620 extern int netdev_open(struct net_device *pnetdev);
1621 #ifdef CONFIG_CONCURRENT_MODE
1622 extern int netdev_if2_open(struct net_device *pnetdev);
1626 enum nl80211_iftype {
1627 NL80211_IFTYPE_UNSPECIFIED,
1628 NL80211_IFTYPE_ADHOC, //1
1629 NL80211_IFTYPE_STATION, //2
1630 NL80211_IFTYPE_AP, //3
1631 NL80211_IFTYPE_AP_VLAN,
1633 NL80211_IFTYPE_MONITOR, //6
1634 NL80211_IFTYPE_MESH_POINT,
1635 NL80211_IFTYPE_P2P_CLIENT, //8
1636 NL80211_IFTYPE_P2P_GO, //9
1638 NUM_NL80211_IFTYPES,
1639 NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
1642 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
1643 struct net_device *ndev,
1644 enum nl80211_iftype type, u32 *flags,
1645 struct vif_params *params)
1647 enum nl80211_iftype old_type;
1648 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
1649 _adapter *padapter = wiphy_to_adapter(wiphy);
1650 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1651 struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
1652 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1654 _queue *queue = &pmlmepriv->scanned_queue;
1656 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
1661 if (adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE) {
1666 #ifdef CONFIG_CONCURRENT_MODE
1667 if(padapter->adapter_type == SECONDARY_ADAPTER)
1669 DBG_871X(FUNC_NDEV_FMT" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev));
1670 if(netdev_if2_open(ndev) != 0) {
1675 else if(padapter->adapter_type == PRIMARY_ADAPTER)
1676 #endif //CONFIG_CONCURRENT_MODE
1678 DBG_871X(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
1679 if(netdev_open(ndev) != 0) {
1685 if(_FAIL == rtw_pwr_wakeup(padapter)) {
1690 old_type = rtw_wdev->iftype;
1691 DBG_871X(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
1692 FUNC_NDEV_ARG(ndev), old_type, type);
1694 if(old_type != type)
1697 pmlmeext->action_public_rxseq = 0xffff;
1698 pmlmeext->action_public_dialog_token = 0xff;
1702 case NL80211_IFTYPE_ADHOC:
1703 networkType = Ndis802_11IBSS;
1705 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
1706 case NL80211_IFTYPE_P2P_CLIENT:
1708 case NL80211_IFTYPE_STATION:
1709 networkType = Ndis802_11Infrastructure;
1711 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
1713 if(change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1715 _cancel_timer_ex( &pwdinfo->find_phase_timer );
1716 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
1717 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
1719 //it means remove GO and change mode from AP(GO) to station(P2P DEVICE)
1720 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1721 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
1723 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));
1728 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
1729 case NL80211_IFTYPE_P2P_GO:
1731 case NL80211_IFTYPE_AP:
1732 networkType = Ndis802_11APMode;
1734 if(pwdinfo->driver_interface == DRIVER_CFG80211 )
1736 if(change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1738 //it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO)
1739 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1748 rtw_wdev->iftype = type;
1750 _enter_critical_bh(&pmlmepriv->lock, &irqL);
1751 _enter_critical_bh(&queue->lock, &irqL);
1753 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE)
1755 rtw_wdev->iftype = old_type;
1757 _exit_critical_bh(&queue->lock, &irqL);
1758 _exit_critical_bh(&pmlmepriv->lock, &irqL);
1761 _exit_critical_bh(&queue->lock, &irqL);
1762 _exit_critical_bh(&pmlmepriv->lock, &irqL);
1764 rtw_setopmode_cmd(padapter, networkType);
1771 void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv, bool aborted)
1775 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
1776 if(pwdev_priv->scan_request != NULL)
1778 //struct cfg80211_scan_request *scan_request = pwdev_priv->scan_request;
1780 #ifdef CONFIG_DEBUG_CFG80211
1781 DBG_871X("%s with scan req\n", __FUNCTION__);
1784 //avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
1785 //if(scan_request == wiphy_to_dev(scan_request->wiphy)->scan_req)
1786 if(pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
1788 DBG_8192C("error wiphy compare\n");
1792 cfg80211_scan_done(pwdev_priv->scan_request, aborted);
1795 pwdev_priv->scan_request = NULL;
1798 #ifdef CONFIG_DEBUG_CFG80211
1799 DBG_871X("%s without scan req\n", __FUNCTION__);
1802 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
1805 void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
1808 _list *plist, *phead;
1809 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1810 _queue *queue = &(pmlmepriv->scanned_queue);
1811 struct wlan_network *pnetwork = NULL;
1813 u32 wait_for_surveydone;
1816 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
1818 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
1819 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
1821 #ifdef CONFIG_DEBUG_CFG80211
1822 DBG_8192C("%s\n", __func__);
1825 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1827 phead = get_list_head(queue);
1828 plist = get_next(phead);
1832 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
1835 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1837 //report network only if the current channel set contains the channel to which this network belongs
1838 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
1839 && rtw_mlme_band_check(padapter, pnetwork->network.Configuration.DSConfig) == _TRUE
\r
1840 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
1843 //ev=translate_scan(padapter, a, pnetwork, ev, stop);
1844 rtw_cfg80211_inform_bss(padapter, pnetwork);
1847 plist = get_next(plist);
1851 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1853 //call this after other things have been done
1854 rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev), _FALSE);
1857 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
1866 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1868 #ifdef CONFIG_DEBUG_CFG80211
1869 DBG_8192C("%s, ielen=%d\n", __func__, len);
1874 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
1876 #ifdef CONFIG_DEBUG_CFG80211
1877 DBG_8192C("probe_req_wps_ielen=%d\n", wps_ielen);
1880 if(pmlmepriv->wps_probe_req_ie)
1882 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
1883 pmlmepriv->wps_probe_req_ie_len = 0;
1884 rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
1885 pmlmepriv->wps_probe_req_ie = NULL;
1888 pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
1889 if ( pmlmepriv->wps_probe_req_ie == NULL) {
1890 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
1894 _rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
1895 pmlmepriv->wps_probe_req_ie_len = wps_ielen;
1902 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
1904 struct wifidirect_info *wdinfo = &padapter->wdinfo;
1905 u32 attr_contentlen = 0;
1906 u8 listen_ch_attr[5];
1908 #ifdef CONFIG_DEBUG_CFG80211
1909 DBG_8192C("probe_req_p2p_ielen=%d\n", p2p_ielen);
1912 if(pmlmepriv->p2p_probe_req_ie)
1914 u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
1915 pmlmepriv->p2p_probe_req_ie_len = 0;
1916 rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len);
1917 pmlmepriv->p2p_probe_req_ie = NULL;
1920 pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen);
1921 if ( pmlmepriv->p2p_probe_req_ie == NULL) {
1922 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
1926 _rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
1927 pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
1929 if(rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8*)listen_ch_attr, (uint*) &attr_contentlen)
1930 && attr_contentlen == 5)
1932 if (wdinfo->listen_channel != listen_ch_attr[4]) {
1933 DBG_871X(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n",
1934 FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2],
1935 listen_ch_attr[3], listen_ch_attr[4]);
1936 wdinfo->listen_channel = listen_ch_attr[4];
1946 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
1948 #ifdef CONFIG_DEBUG_CFG80211
1949 DBG_8192C("probe_req_wfd_ielen=%d\n", wfd_ielen);
1952 if(pmlmepriv->wfd_probe_req_ie)
1954 u32 free_len = pmlmepriv->wfd_probe_req_ie_len;
1955 pmlmepriv->wfd_probe_req_ie_len = 0;
1956 rtw_mfree(pmlmepriv->wfd_probe_req_ie, free_len);
1957 pmlmepriv->wfd_probe_req_ie = NULL;
1960 pmlmepriv->wfd_probe_req_ie = rtw_malloc(wfd_ielen);
1961 if ( pmlmepriv->wfd_probe_req_ie == NULL) {
1962 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
1966 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
1976 static int cfg80211_rtw_scan(struct wiphy *wiphy
1977 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
1978 , struct net_device *ndev
1980 , struct cfg80211_scan_request *request)
1983 u8 _status = _FALSE;
1985 _adapter *padapter = wiphy_to_adapter(wiphy);
1986 struct mlme_priv *pmlmepriv= &padapter->mlmepriv;
1987 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
1988 struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
1995 u8 survey_times_for_one_ch=6;
1997 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
1999 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
2000 struct cfg80211_ssid *ssids = request->ssids;
2001 int social_channel = 0, j = 0;
2002 bool need_indicate_scan_done = _FALSE;
2003 #ifdef CONFIG_CONCURRENT_MODE
2004 PADAPTER pbuddy_adapter = NULL;
2005 struct mlme_priv *pbuddy_mlmepriv = NULL;
2006 #endif //CONFIG_CONCURRENT_MODE
2008 //#ifdef CONFIG_DEBUG_CFG80211
2009 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
2012 #ifdef CONFIG_CONCURRENT_MODE
2013 if (padapter->pbuddy_adapter) {
2014 pbuddy_adapter = padapter->pbuddy_adapter;
2015 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
2017 #endif //CONFIG_CONCURRENT_MODE
2019 #ifdef CONFIG_MP_INCLUDED
2020 if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
2027 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2028 pwdev_priv->scan_request = request;
2029 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2031 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2033 #ifdef CONFIG_DEBUG_CFG80211
2034 DBG_871X("%s under WIFI_AP_STATE\n", __FUNCTION__);
2037 if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS|_FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2039 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
2041 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
2043 DBG_8192C("AP mode process WPS \n");
2046 need_indicate_scan_done = _TRUE;
2047 goto check_need_indicate_scan_done;
2051 if(_FAIL == rtw_pwr_wakeup(padapter)) {
2052 need_indicate_scan_done = _TRUE;
2053 goto check_need_indicate_scan_done;
2057 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
2059 if(ssids->ssid != NULL
2060 && _rtw_memcmp(ssids->ssid, "DIRECT-", 7)
2061 && rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
2064 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2066 u32 initialgain = 0x30;
2067 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
2068 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = _TRUE;
2069 padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_INITIAL_GAIN, (u8 *)&(initialgain));
2070 padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_INITIAL_GAIN, (u8 *)&(initialgain));
2074 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
2075 #ifdef CONFIG_DEBUG_CFG80211
2076 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
2079 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
2081 if(request->n_channels == 3 &&
2082 request->channels[0]->hw_value == 1 &&
2083 request->channels[1]->hw_value == 6 &&
2084 request->channels[2]->hw_value == 11
2093 if(request->ie && request->ie_len>0)
2095 rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len );
2098 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)
2100 DBG_8192C("%s, bBusyTraffic == _TRUE\n", __func__);
2101 need_indicate_scan_done = _TRUE;
2102 goto check_need_indicate_scan_done;
2104 if (rtw_is_scan_deny(padapter)){
2105 DBG_871X(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter));
2106 need_indicate_scan_done = _TRUE;
2107 goto check_need_indicate_scan_done;
2110 #ifdef CONFIG_CONCURRENT_MODE
2111 if(pbuddy_mlmepriv && (pbuddy_mlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))
2113 DBG_8192C("%s, bBusyTraffic == _TRUE at buddy_intf\n", __func__);
2114 need_indicate_scan_done = _TRUE;
2115 goto check_need_indicate_scan_done;
2117 #endif //CONFIG_CONCURRENT_MODE
2119 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2121 DBG_8192C("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
2122 need_indicate_scan_done = _TRUE;
2123 goto check_need_indicate_scan_done;
2126 #ifdef CONFIG_CONCURRENT_MODE
2127 if (check_buddy_fwstate(padapter,
2128 _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
2130 if(check_buddy_fwstate(padapter, _FW_UNDER_SURVEY))
2132 DBG_8192C("scanning_via_buddy_intf\n");
2133 pmlmepriv->scanning_via_buddy_intf = _TRUE;
2136 DBG_8192C("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv->fw_state);
2138 need_indicate_scan_done = _TRUE;
2139 goto check_need_indicate_scan_done;
2145 if( pwdinfo->driver_interface == DRIVER_CFG80211 )
2147 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
2149 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
2150 rtw_free_network_queue(padapter, _TRUE);
2152 if(social_channel == 0)
2153 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
2155 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
2161 _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
2162 //parsing request ssids, n_ssids
2163 for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
2164 #ifdef CONFIG_DEBUG_CFG80211
2165 DBG_8192C("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
2167 _rtw_memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
2168 ssid[i].SsidLength = ssids[i].ssid_len;
2172 /* parsing channels, n_channels */
2173 _rtw_memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
2174 for (i=0;i<request->n_channels && i<RTW_CHANNEL_SCAN_AMOUNT;i++) {
2175 #ifdef CONFIG_DEBUG_CFG80211
2176 DBG_871X(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
2178 ch[i].hw_value = request->channels[i]->hw_value;
2179 ch[i].flags = request->channels[i]->flags;
2182 _enter_critical_bh(&pmlmepriv->lock, &irqL);
2183 if (request->n_channels == 1) {
2184 for(i=1;i<survey_times_for_one_ch;i++)
2185 _rtw_memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
2186 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times_for_one_ch);
2187 } else if (request->n_channels == 2) {
2188 _rtw_memcpy(&ch[3], &ch[1], sizeof(struct rtw_ieee80211_channel));
2189 for(i=1;i<survey_times;i++) {
2190 _rtw_memcpy(&ch[i], &ch[0], sizeof(struct rtw_ieee80211_channel));
2191 _rtw_memcpy(&ch[i+3], &ch[3], sizeof(struct rtw_ieee80211_channel));
2193 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, survey_times * 2);
2195 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
2197 _exit_critical_bh(&pmlmepriv->lock, &irqL);
2200 if(_status == _FALSE)
2205 check_need_indicate_scan_done:
2206 if(need_indicate_scan_done)
2207 rtw_cfg80211_surveydone_event_callback(padapter);
2215 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
2218 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2220 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
2221 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
2224 iwm->conf.rts_threshold = wiphy->rts_threshold;
2226 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
2228 iwm->conf.rts_threshold);
2233 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
2234 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
2237 iwm->conf.frag_threshold = wiphy->frag_threshold;
2239 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
2241 iwm->conf.frag_threshold);
2246 DBG_8192C("%s\n", __func__);
2250 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
2251 struct cfg80211_ibss_params *params)
2254 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2255 struct ieee80211_channel *chan = params->channel;
2257 if (!test_bit(IWM_STATUS_READY, &iwm->status))
2260 /* UMAC doesn't support creating or joining an IBSS network
2261 * with specified bssid. */
2265 iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
2266 iwm->umac_profile->ibss.band = chan->band;
2267 iwm->umac_profile->ibss.channel = iwm->channel;
2268 iwm->umac_profile->ssid.ssid_len = params->ssid_len;
2269 memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
2271 return iwm_send_mlme_profile(iwm);
2273 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2277 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
2280 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2282 if (iwm->umac_profile_active)
2283 return iwm_invalidate_mlme_profile(iwm);
2285 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2289 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
2291 DBG_8192C("%s, wpa_version=%d\n", __func__, wpa_version);
2294 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2299 if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
2301 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
2305 if (wpa_version & NL80211_WPA_VERSION_2)
2307 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2315 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
2316 enum nl80211_auth_type sme_auth_type)
2318 DBG_8192C("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
2321 switch (sme_auth_type) {
2322 case NL80211_AUTHTYPE_AUTOMATIC:
2324 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2327 case NL80211_AUTHTYPE_OPEN_SYSTEM:
2329 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2331 if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
2332 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2335 case NL80211_AUTHTYPE_SHARED_KEY:
2337 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
2339 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
2344 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2352 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
2354 u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
2356 u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
2357 &psecuritypriv->dot118021XGrpPrivacy;
2359 DBG_8192C("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
2363 *profile_cipher = _NO_PRIVACY_;
2364 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
2369 case IW_AUTH_CIPHER_NONE:
2370 *profile_cipher = _NO_PRIVACY_;
2371 ndisencryptstatus = Ndis802_11EncryptionDisabled;
2373 case WLAN_CIPHER_SUITE_WEP40:
2374 *profile_cipher = _WEP40_;
2375 ndisencryptstatus = Ndis802_11Encryption1Enabled;
2377 case WLAN_CIPHER_SUITE_WEP104:
2378 *profile_cipher = _WEP104_;
2379 ndisencryptstatus = Ndis802_11Encryption1Enabled;
2381 case WLAN_CIPHER_SUITE_TKIP:
2382 *profile_cipher = _TKIP_;
2383 ndisencryptstatus = Ndis802_11Encryption2Enabled;
2385 case WLAN_CIPHER_SUITE_CCMP:
2386 *profile_cipher = _AES_;
2387 ndisencryptstatus = Ndis802_11Encryption3Enabled;
2390 DBG_8192C("Unsupported cipher: 0x%x\n", cipher);
2396 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
2398 //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
2399 // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2405 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
2407 DBG_8192C("%s, key_mgt=0x%x\n", __func__, key_mgt);
2409 if (key_mgt == WLAN_AKM_SUITE_8021X)
2410 //*auth_type = UMAC_AUTH_TYPE_8021X;
2411 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2412 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
2413 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2415 DBG_8192C("Invalid key mgt: 0x%x\n", key_mgt);
2422 static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
2424 u8 *buf=NULL, *pos=NULL;
2426 int group_cipher = 0, pairwise_cipher = 0;
2431 u8 null_addr[]= {0,0,0,0,0,0};
2433 if (pie == NULL || !ielen) {
2434 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
2435 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2439 if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
2444 buf = rtw_zmalloc(ielen);
2450 _rtw_memcpy(buf, pie , ielen);
2455 DBG_8192C("set wpa_ie(length:%zu):\n", ielen);
2456 for(i=0;i<ielen;i=i+8)
2457 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]);
2461 if(ielen < RSN_HEADER_LEN){
2462 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
2467 pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
2468 if(pwpa && wpa_ielen>0)
2470 if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher) == _SUCCESS)
2472 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
2473 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
2474 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
2476 DBG_8192C("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
2480 pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
2481 if(pwpa2 && wpa2_ielen>0)
2483 if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher) == _SUCCESS)
2485 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
2486 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
2487 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
2489 DBG_8192C("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
2493 if (group_cipher == 0)
2495 group_cipher = WPA_CIPHER_NONE;
2497 if (pairwise_cipher == 0)
2499 pairwise_cipher = WPA_CIPHER_NONE;
2502 switch(group_cipher)
2504 case WPA_CIPHER_NONE:
2505 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
2506 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
2508 case WPA_CIPHER_WEP40:
2509 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
2510 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2512 case WPA_CIPHER_TKIP:
2513 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
2514 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
2516 case WPA_CIPHER_CCMP:
2517 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
2518 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
2520 case WPA_CIPHER_WEP104:
2521 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
2522 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2526 switch(pairwise_cipher)
2528 case WPA_CIPHER_NONE:
2529 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
2530 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
2532 case WPA_CIPHER_WEP40:
2533 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
2534 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2536 case WPA_CIPHER_TKIP:
2537 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
2538 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
2540 case WPA_CIPHER_CCMP:
2541 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
2542 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
2544 case WPA_CIPHER_WEP104:
2545 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
2546 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2550 {/* handle wps_ie */
2554 wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
2555 if (wps_ie && wps_ielen > 0) {
2556 DBG_8192C("got wps_ie, wps_ielen:%u\n", wps_ielen);
2557 padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
2558 _rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
2559 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
2561 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2566 {//check p2p_ie for assoc req;
2569 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2571 if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen)))
2573 #ifdef CONFIG_DEBUG_CFG80211
2574 DBG_8192C("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
2577 if(pmlmepriv->p2p_assoc_req_ie)
2579 u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
2580 pmlmepriv->p2p_assoc_req_ie_len = 0;
2581 rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
2582 pmlmepriv->p2p_assoc_req_ie = NULL;
2585 pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
2586 if ( pmlmepriv->p2p_assoc_req_ie == NULL) {
2587 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
2590 _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
2591 pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
2597 {//check wfd_ie for assoc req;
2600 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2602 if(rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen))
2604 #ifdef CONFIG_DEBUG_CFG80211
2605 DBG_8192C("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
2608 if(pmlmepriv->wfd_assoc_req_ie)
2610 u32 free_len = pmlmepriv->wfd_assoc_req_ie_len;
2611 pmlmepriv->wfd_assoc_req_ie_len = 0;
2612 rtw_mfree(pmlmepriv->wfd_assoc_req_ie, free_len);
2613 pmlmepriv->wfd_assoc_req_ie = NULL;
2616 pmlmepriv->wfd_assoc_req_ie = rtw_malloc(wfd_ielen);
2617 if ( pmlmepriv->wfd_assoc_req_ie == NULL) {
2618 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
2621 rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
2626 //TKIP and AES disallow multicast packets until installing group key
2627 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
2628 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
2629 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
2630 //WPS open need to enable multicast
2631 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
2632 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
2634 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2635 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
2636 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
2640 rtw_mfree(buf, ielen);
2642 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2646 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
2647 struct cfg80211_connect_params *sme)
2652 struct wlan_network *pnetwork = NULL;
2653 NDIS_802_11_AUTHENTICATION_MODE authmode;
2654 NDIS_802_11_SSID ndis_ssid;
2655 u8 *dst_ssid, *src_ssid;
2656 u8 *dst_bssid, *src_bssid;
2657 //u8 matched_by_bssid=_FALSE;
2658 //u8 matched_by_ssid=_FALSE;
2660 _adapter *padapter = wiphy_to_adapter(wiphy);
2661 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2662 struct security_priv *psecuritypriv = &padapter->securitypriv;
2663 _queue *queue = &pmlmepriv->scanned_queue;
2665 DBG_871X("=>"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2666 DBG_871X("privacy=%d, key=%p, key_len=%d, key_idx=%d\n",
2667 sme->privacy, sme->key, sme->key_len, sme->key_idx);
2670 if(wdev_to_priv(padapter->rtw_wdev)->block == _TRUE)
2673 DBG_871X("%s wdev_priv.block is set\n", __FUNCTION__);
2677 #ifdef CONFIG_PLATFORM_MSTAR
2678 printk("MStar Android!\n");
2679 if((wdev_to_priv(padapter->rtw_wdev))->bandroid_scan == _FALSE)
2682 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
2683 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2687 printk("Android hasn't attached yet!\n");
2693 if(_FAIL == rtw_pwr_wakeup(padapter)) {
2698 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2703 #ifdef CONFIG_CONCURRENT_MODE
2704 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
2705 DBG_8192C("%s, but buddy_intf is under linking\n", __FUNCTION__);
2709 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
2710 rtw_scan_abort(padapter->pbuddy_adapter);
2714 if (!sme->ssid || !sme->ssid_len)
2720 if (sme->ssid_len > IW_ESSID_MAX_SIZE){
2726 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
2727 ndis_ssid.SsidLength = sme->ssid_len;
2728 _rtw_memcpy(ndis_ssid.Ssid, sme->ssid, sme->ssid_len);
2730 DBG_8192C("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
2734 DBG_8192C("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
2737 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
2739 DBG_8192C("%s, fw_state=0x%x, goto exit\n", __FUNCTION__, pmlmepriv->fw_state);
2742 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
2743 rtw_scan_abort(padapter);
2746 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
2747 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
2748 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2749 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
2750 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2753 ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
2757 ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
2761 DBG_8192C("%s, ie_len=%zu\n", __func__, sme->ie_len);
2763 ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len);
2767 if (sme->crypto.n_ciphers_pairwise) {
2768 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
2773 //For WEP Shared auth
2774 if((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared
2775 || psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && sme->key
2778 u32 wep_key_idx, wep_key_len,wep_total_len;
2779 NDIS_802_11_WEP *pwep = NULL;
2780 DBG_871X("%s(): Shared/Auto WEP\n",__FUNCTION__);
2782 wep_key_idx = sme->key_idx;
2783 wep_key_len = sme->key_len;
2785 if (sme->key_idx > WEP_KEYS) {
2790 if (wep_key_len > 0)
2792 wep_key_len = wep_key_len <= 5 ? 5 : 13;
2793 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
2794 pwep =(NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
2796 DBG_871X(" wpa_set_encryption: pwep allocate fail !!!\n");
2801 _rtw_memset(pwep, 0, wep_total_len);
2803 pwep->KeyLength = wep_key_len;
2804 pwep->Length = wep_total_len;
2808 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
2809 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
2817 pwep->KeyIndex = wep_key_idx;
2818 pwep->KeyIndex |= 0x80000000;
2820 _rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
2822 if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
2828 rtw_mfree((u8 *)pwep,wep_total_len);
2835 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
2839 if (sme->crypto.n_akm_suites) {
2840 ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
2845 authmode = psecuritypriv->ndisauthtype;
2846 rtw_set_802_11_authentication_mode(padapter, authmode);
2848 //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
2850 if (rtw_set_802_11_connect(padapter, sme->bssid, &ndis_ssid) == _FALSE) {
\r
2855 DBG_8192C("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy);
2859 DBG_8192C("<=%s, ret %d\n",__FUNCTION__, ret);
2864 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2867 _adapter *padapter = wiphy_to_adapter(wiphy);
2869 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2871 rtw_set_roaming(padapter, 0);
2873 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
2875 rtw_scan_abort(padapter);
2876 LeaveAllPowerSaveMode(padapter);
2877 rtw_disassoc_cmd(padapter, 500, _FALSE);
2879 DBG_871X("%s...call rtw_indicate_disconnect\n", __FUNCTION__);
2881 padapter->mlmepriv.not_indic_disco = _TRUE;
2882 rtw_indicate_disconnect(padapter);
2883 padapter->mlmepriv.not_indic_disco = _FALSE;
2885 rtw_free_assoc_resources(padapter, 1);
2891 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
2892 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
2893 struct wireless_dev *wdev,
2895 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE)
2896 enum nl80211_tx_power_setting type, int mbm)
2898 enum tx_power_setting type, int dbm)
2902 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2906 case NL80211_TX_POWER_AUTOMATIC:
2908 case NL80211_TX_POWER_FIXED:
2909 if (mbm < 0 || (mbm % 100))
2912 if (!test_bit(IWM_STATUS_READY, &iwm->status))
2915 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
2916 CFG_TX_PWR_LIMIT_USR,
2917 MBM_TO_DBM(mbm) * 2);
2921 return iwm_tx_power_trigger(iwm);
2923 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
2927 DBG_8192C("%s\n", __func__);
2931 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
2932 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
2933 struct wireless_dev *wdev,
2937 //_adapter *padapter = wiphy_to_adapter(wiphy);
2939 DBG_8192C("%s\n", __func__);
2946 inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
2948 struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(adapter->rtw_wdev);
2949 return rtw_wdev_priv->power_mgmt;
2952 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
2953 struct net_device *ndev,
2954 bool enabled, int timeout)
2956 _adapter *padapter = wiphy_to_adapter(wiphy);
2957 struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(padapter->rtw_wdev);
2959 DBG_871X(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
2962 rtw_wdev_priv->power_mgmt = enabled;
2966 LPS_Leave(padapter);
2972 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
2973 struct net_device *netdev,
2974 struct cfg80211_pmksa *pmksa)
2976 u8 index,blInserted = _FALSE;
2977 _adapter *padapter = wiphy_to_adapter(wiphy);
2978 struct security_priv *psecuritypriv = &padapter->securitypriv;
2979 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
2981 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev));
2983 if ( _rtw_memcmp( pmksa->bssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
2988 blInserted = _FALSE;
2991 for(index=0 ; index<NUM_PMKID_CACHE; index++)
2993 if( _rtw_memcmp( psecuritypriv->PMKIDList[index].Bssid, pmksa->bssid, ETH_ALEN) ==_TRUE )
2994 { // BSSID is matched, the same AP => rewrite with new PMKID.
2995 DBG_871X(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(netdev));
2997 _rtw_memcpy( psecuritypriv->PMKIDList[index].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2998 psecuritypriv->PMKIDList[index].bUsed = _TRUE;
2999 psecuritypriv->PMKIDIndex = index+1;
3008 DBG_871X(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
3009 FUNC_NDEV_ARG(netdev), psecuritypriv->PMKIDIndex );
3011 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, pmksa->bssid, ETH_ALEN);
3012 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3014 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
3015 psecuritypriv->PMKIDIndex++ ;
3016 if(psecuritypriv->PMKIDIndex==16)
3018 psecuritypriv->PMKIDIndex =0;
3025 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
3026 struct net_device *netdev,
3027 struct cfg80211_pmksa *pmksa)
3029 u8 index, bMatched = _FALSE;
3030 _adapter *padapter = wiphy_to_adapter(wiphy);
3031 struct security_priv *psecuritypriv = &padapter->securitypriv;
3033 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev));
3035 for(index=0 ; index<NUM_PMKID_CACHE; index++)
3037 if( _rtw_memcmp( psecuritypriv->PMKIDList[index].Bssid, pmksa->bssid, ETH_ALEN) ==_TRUE )
3038 { // BSSID is matched, the same AP => Remove this PMKID information and reset it.
3039 _rtw_memset( psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN );
3040 _rtw_memset( psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN );
3041 psecuritypriv->PMKIDList[index].bUsed = _FALSE;
3047 if(_FALSE == bMatched)
3049 DBG_871X(FUNC_NDEV_FMT" do not have matched BSSID\n"
3050 , FUNC_NDEV_ARG(netdev));
3057 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
3058 struct net_device *netdev)
3060 _adapter *padapter = wiphy_to_adapter(wiphy);
3061 struct security_priv *psecuritypriv = &padapter->securitypriv;
3063 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev));
3065 _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
3066 psecuritypriv->PMKIDIndex = 0;
3071 #ifdef CONFIG_AP_MODE
3072 void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
3076 struct wireless_dev *pwdev = padapter->rtw_wdev;
3077 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3078 struct net_device *ndev = padapter->pnetdev;
3080 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
3082 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
3084 struct station_info sinfo;
3086 if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
3087 ie_offset = _ASOCREQ_IE_OFFSET_;
3088 else // WIFI_REASSOCREQ
3089 ie_offset = _REASOCREQ_IE_OFFSET_;
3092 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
3093 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
3094 sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
3095 cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
3097 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
3098 channel = pmlmeext->cur_channel;
3099 if (channel <= RTW_CH_MAX_2G_CHANNEL)
3100 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3102 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3104 #ifdef COMPAT_KERNEL_RELEASE
3105 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3106 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3107 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3108 #else //COMPAT_KERNEL_RELEASE
3110 //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc()
3111 #ifndef CONFIG_PLATFORM_MSTAR
3112 pwdev->iftype = NL80211_IFTYPE_STATION;
3113 #endif //CONFIG_PLATFORM_MSTAR
3114 DBG_8192C("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
3115 rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
3116 DBG_8192C("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
3117 pwdev->iftype = NL80211_IFTYPE_AP;
3118 //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
3120 #endif //COMPAT_KERNEL_RELEASE
3121 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
3125 void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason)
3131 struct rtw_ieee80211_hdr *pwlanhdr;
3132 unsigned short *fctrl;
3133 u8 mgmt_buf[128] = {0};
3134 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3135 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3136 struct net_device *ndev = padapter->pnetdev;
3138 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
3140 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
3141 cfg80211_del_sta(ndev, da, GFP_ATOMIC);
3142 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
3143 channel = pmlmeext->cur_channel;
3144 if (channel <= RTW_CH_MAX_2G_CHANNEL)
3145 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3147 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3149 pmgmt_frame = mgmt_buf;
3150 pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
3152 fctrl = &(pwlanhdr->frame_ctl);
3155 //_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3156 //_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3157 _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
3158 _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN);
3159 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3161 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3162 pmlmeext->mgnt_seq++;
3163 SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
3165 pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
3166 frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
3168 reason = cpu_to_le16(reason);
3169 pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
3171 #ifdef COMPAT_KERNEL_RELEASE
3172 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
3173 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3174 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
3175 #else //COMPAT_KERNEL_RELEASE
3176 cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len);
3177 //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC);
3178 #endif //COMPAT_KERNEL_RELEASE
3179 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
3182 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
3186 DBG_8192C("%s\n", __func__);
3191 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
3195 DBG_8192C("%s\n", __func__);
3200 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
3205 int dot11_hdr_len = 24;
3207 unsigned char *pdata;
3209 unsigned char src_mac_addr[6];
3210 unsigned char dst_mac_addr[6];
3211 struct ieee80211_hdr *dot11_hdr;
3212 struct ieee80211_radiotap_header *rtap_hdr;
3213 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3215 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3218 rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
3220 if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
3223 rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
3224 if (unlikely(rtap_hdr->it_version))
3227 rtap_len = ieee80211_get_radiotap_len(skb->data);
3228 if (unlikely(skb->len < rtap_len))
3233 DBG_8192C("radiotap len (should be 14): %d\n", rtap_len);
3237 /* Skip the ratio tap header */
3238 skb_pull(skb, rtap_len);
3240 dot11_hdr = (struct ieee80211_hdr *)skb->data;
3241 frame_ctl = le16_to_cpu(dot11_hdr->frame_control);
3242 /* Check if the QoS bit is set */
3243 if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
3244 /* Check if this ia a Wireless Distribution System (WDS) frame
3245 * which has 4 MAC addresses
3247 if (dot11_hdr->frame_control & 0x0080)
3249 if ((dot11_hdr->frame_control & 0x0300) == 0x0300)
3252 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
3253 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
3255 /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
3256 * for two MAC addresses
3258 skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
3259 pdata = (unsigned char*)skb->data;
3260 memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
3261 memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
3263 DBG_8192C("should be eapol packet\n");
3265 /* Use the real net device to transmit the packet */
3266 ret = _rtw_xmit_entry(skb, padapter->pnetdev);
3271 else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE))
3272 == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION)
3275 //only for action frames
3276 struct xmit_frame *pmgntframe;
3277 struct pkt_attrib *pattrib;
3278 unsigned char *pframe;
3279 //u8 category, action, OUI_Subtype, dialogToken=0;
3280 //unsigned char *frame_body;
3281 struct rtw_ieee80211_hdr *pwlanhdr;
3282 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3283 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3284 u8 *buf = skb->data;
3286 u8 category, action;
3289 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
3290 DBG_8192C(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
3291 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
3295 DBG_8192C("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
3296 MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
3298 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0)
3301 if (category == RTW_WLAN_CATEGORY_PUBLIC)
3302 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
3304 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
3307 //starting alloc mgmt frame to dump it
3308 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3314 pattrib = &pmgntframe->attrib;
3315 update_mgntframe_attrib(padapter, pattrib);
3316 pattrib->retry_ctrl = _FALSE;
3318 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3320 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3322 _rtw_memcpy(pframe, (void*)buf, len);
3326 struct wifi_display_info *pwfd_info;
3328 pwfd_info = padapter->wdinfo.wfd_info;
3330 if ( _TRUE == pwfd_info->wfd_enable )
3332 rtw_append_wfd_ie( padapter, pframe, &len );
3335 #endif // CONFIG_WFD
3336 pattrib->pktlen = len;
3338 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3340 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
3341 pattrib->seqnum = pmlmeext->mgnt_seq;
3342 pmlmeext->mgnt_seq++;
3345 pattrib->last_txcmdsz = pattrib->pktlen;
3347 dump_mgntframe(padapter, pmgntframe);
3352 DBG_8192C("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE));
3364 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
3366 DBG_8192C("%s\n", __func__);
3369 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
3373 DBG_8192C("%s\n", __func__);
3378 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
3379 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
3380 .ndo_open = rtw_cfg80211_monitor_if_open,
3381 .ndo_stop = rtw_cfg80211_monitor_if_close,
3382 .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
3383 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
3384 .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
3386 .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
3390 static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
3393 struct net_device* mon_ndev = NULL;
3394 struct wireless_dev* mon_wdev = NULL;
3395 struct rtw_netdev_priv_indicator *pnpi;
3396 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
3399 DBG_871X(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
3404 if (pwdev_priv->pmon_ndev) {
3405 DBG_871X(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
3406 FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
3411 mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
3413 DBG_871X(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
3418 mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
3419 strncpy(mon_ndev->name, name, IFNAMSIZ);
3420 mon_ndev->name[IFNAMSIZ - 1] = 0;
3421 mon_ndev->destructor = rtw_ndev_destructor;
3423 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
3424 mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
3426 mon_ndev->open = rtw_cfg80211_monitor_if_open;
3427 mon_ndev->stop = rtw_cfg80211_monitor_if_close;
3428 mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry;
3429 mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address;
3432 pnpi = netdev_priv(mon_ndev);
3433 pnpi->priv = padapter;
3434 pnpi->sizeof_priv = sizeof(_adapter);
3437 mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
3439 DBG_871X(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
3444 mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
3445 mon_wdev->netdev = mon_ndev;
3446 mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
3447 mon_ndev->ieee80211_ptr = mon_wdev;
3449 ret = register_netdevice(mon_ndev);
3454 *ndev = pwdev_priv->pmon_ndev = mon_ndev;
3455 _rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
3458 if (ret && mon_wdev) {
3459 rtw_mfree((u8*)mon_wdev, sizeof(struct wireless_dev));
3463 if (ret && mon_ndev) {
3464 free_netdev(mon_ndev);
3465 *ndev = mon_ndev = NULL;
3471 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3472 static struct wireless_dev *
3473 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
3474 static struct net_device *
3478 cfg80211_rtw_add_virtual_intf(
3479 struct wiphy *wiphy,
3480 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
3485 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
3488 struct net_device* ndev = NULL;
3489 _adapter *padapter = wiphy_to_adapter(wiphy);
3491 DBG_871X(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
3492 FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
3495 case NL80211_IFTYPE_ADHOC:
3496 case NL80211_IFTYPE_AP_VLAN:
3497 case NL80211_IFTYPE_WDS:
3498 case NL80211_IFTYPE_MESH_POINT:
3501 case NL80211_IFTYPE_MONITOR:
3502 ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
3505 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3506 case NL80211_IFTYPE_P2P_CLIENT:
3508 case NL80211_IFTYPE_STATION:
3512 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3513 case NL80211_IFTYPE_P2P_GO:
3515 case NL80211_IFTYPE_AP:
3520 DBG_871X("Unsupported interface type\n");
3524 DBG_871X(FUNC_ADPT_FMT" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter), ndev, ret);
3526 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3527 return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
3528 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
3529 return ndev ? ndev : ERR_PTR(ret);
3535 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
3536 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3537 struct wireless_dev *wdev
3539 struct net_device *ndev
3543 struct rtw_wdev_priv *pwdev_priv = (struct rtw_wdev_priv *)wiphy_priv(wiphy);
3544 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3545 struct net_device *ndev;
3546 ndev = wdev ? wdev->netdev : NULL;
3552 unregister_netdevice(ndev);
3554 if (ndev == pwdev_priv->pmon_ndev) {
3555 pwdev_priv->pmon_ndev = NULL;
3556 pwdev_priv->ifname_mon[0] = '\0';
3557 DBG_871X(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev));
3564 static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
3568 uint len, wps_ielen=0;
3571 u8 got_p2p_ie = _FALSE;
3572 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
3573 //struct sta_priv *pstapriv = &padapter->stapriv;
3576 DBG_8192C("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
3579 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
3586 pbuf = rtw_zmalloc(head_len+tail_len);
3591 //_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
3593 //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
3594 // pstapriv->max_num_sta = NUM_STA;
3597 _rtw_memcpy(pbuf, (void *)head+24, head_len-24);// 24=beacon header len.
3598 _rtw_memcpy(pbuf+head_len-24, (void *)tail, tail_len);
3600 len = head_len+tail_len-24;
3602 //check wps ie if inclued
3603 if(rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
3604 DBG_8192C("add bcn, wps_ielen=%d\n", wps_ielen);
3607 //check p2p ie if inclued
3608 if( adapter->wdinfo.driver_interface == DRIVER_CFG80211 )
3610 //check p2p if enable
3611 if(rtw_get_p2p_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &p2p_ielen))
3613 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3614 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
3616 DBG_8192C("got p2p_ie, len=%d\n", p2p_ielen);
3619 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3621 DBG_8192C("Enable P2P function for the first time\n");
3622 rtw_p2p_enable(adapter, P2P_ROLE_GO);
3623 wdev_to_priv(adapter->rtw_wdev)->p2p_enabled = _TRUE;
3627 _cancel_timer_ex( &pwdinfo->find_phase_timer );
3628 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
3629 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
3631 DBG_8192C("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);
3633 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
3634 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
3635 pwdinfo->intent = 15;
3639 #endif // CONFIG_P2P
3641 /* pbss_network->IEs will not include p2p_ie, wfd ie */
3642 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
3643 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
3645 if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS)
3648 //check p2p if enable
3649 if(got_p2p_ie == _TRUE)
3651 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3652 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
3653 pwdinfo->operating_channel = pmlmeext->cur_channel;
3664 rtw_mfree(pbuf, head_len+tail_len);
3669 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE)
3670 static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
3671 struct beacon_parameters *info)
3674 _adapter *adapter = wiphy_to_adapter(wiphy);
3676 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3677 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
3682 static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
3683 struct beacon_parameters *info)
3685 _adapter *padapter = wiphy_to_adapter(wiphy);
3686 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3688 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3690 pmlmeext->bstart_bss = _TRUE;
3692 cfg80211_rtw_add_beacon(wiphy, ndev, info);
3697 static int cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
3699 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3704 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3705 struct cfg80211_ap_settings *settings)
3708 _adapter *adapter = wiphy_to_adapter(wiphy);
3710 DBG_871X(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
3711 settings->hidden_ssid, settings->auth_type);
3713 ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
3714 settings->beacon.tail, settings->beacon.tail_len);
3716 adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
3718 if (settings->ssid && settings->ssid_len) {
3719 WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
3720 WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
3723 DBG_871X(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
3724 settings->ssid, settings->ssid_len,
3725 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
3727 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
3728 pbss_network->Ssid.SsidLength = settings->ssid_len;
3729 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
3730 pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
3733 DBG_871X(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
3734 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
3735 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
3741 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3742 struct cfg80211_beacon_data *info)
3745 _adapter *adapter = wiphy_to_adapter(wiphy);
3747 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3749 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
3754 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3756 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3760 #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
3762 static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
3763 u8 *mac, struct station_parameters *params)
3765 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3770 static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
3775 _list *phead, *plist;
3777 struct sta_info *psta = NULL;
3778 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3779 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3780 struct sta_priv *pstapriv = &padapter->stapriv;
3782 DBG_871X("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3784 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
3786 DBG_8192C("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
3793 DBG_8192C("flush all sta, and cam_entry\n");
3795 flush_all_cam_entry(padapter); //clear CAM
3797 ret = rtw_sta_flush(padapter);
3803 DBG_8192C("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
3805 if (mac[0] == 0xff && mac[1] == 0xff &&
3806 mac[2] == 0xff && mac[3] == 0xff &&
3807 mac[4] == 0xff && mac[5] == 0xff)
3813 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3815 phead = &pstapriv->asoc_list;
3816 plist = get_next(phead);
3819 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
3821 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3823 plist = get_next(plist);
3825 if(_rtw_memcmp(mac, psta->hwaddr, ETH_ALEN))
3827 if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE)
3829 DBG_8192C("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
3833 DBG_8192C("free psta=%p, aid=%d\n", psta, psta->aid);
3835 rtw_list_delete(&psta->asoc_list);
3836 pstapriv->asoc_list_cnt--;
3838 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3839 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
3840 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3851 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3853 associated_clients_update(padapter, updated);
3855 DBG_871X("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3861 static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
3862 u8 *mac, struct station_parameters *params)
3864 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3869 static int cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
3870 int idx, u8 *mac, struct station_info *sinfo)
3872 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3874 //TODO: dump scanned queue
3879 static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
3880 struct bss_parameters *params)
3884 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3886 DBG_8192C("use_cts_prot=%d\n", params->use_cts_prot);
3887 DBG_8192C("use_short_preamble=%d\n", params->use_short_preamble);
3888 DBG_8192C("use_short_slot_time=%d\n", params->use_short_slot_time);
3889 DBG_8192C("ap_isolate=%d\n", params->ap_isolate);
3891 DBG_8192C("basic_rates_len=%d\n", params->basic_rates_len);
3892 for(i=0; i<params->basic_rates_len; i++)
3894 DBG_8192C("basic_rates=%d\n", params->basic_rates[i]);
3902 static int cfg80211_rtw_set_channel(struct wiphy *wiphy
3903 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
3904 , struct net_device *ndev
3906 , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
3908 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
3909 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3915 static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
3916 struct cfg80211_auth_request *req)
3918 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3923 static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
3924 struct cfg80211_assoc_request *req)
3926 DBG_871X(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3930 #endif //CONFIG_AP_MODE
3932 void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
3937 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3938 u8 category, action;
3940 channel = rtw_get_oper_ch(padapter);
3942 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
3944 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
3948 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
3949 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
3952 if (channel <= RTW_CH_MAX_2G_CHANNEL)
3953 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3955 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3957 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3958 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3960 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
3964 void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
3969 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3970 u8 category, action;
3972 channel = rtw_get_oper_ch(padapter);
3974 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
3976 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
3979 case P2P_GO_NEGO_CONF:
3980 case P2P_PROVISION_DISC_RESP:
3981 case P2P_INVIT_RESP:
3982 rtw_set_scan_deny(padapter, 2000);
3983 rtw_clear_scan_deny(padapter);
3988 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
3989 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
3992 if (channel <= RTW_CH_MAX_2G_CHANNEL)
3993 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3995 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3997 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3998 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
4000 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
4004 void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg)
4008 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
4009 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(adapter->rtw_wdev);
4010 u8 category, action;
4012 channel = rtw_get_oper_ch(adapter);
4014 rtw_action_frame_parse(frame, frame_len, &category, &action);
4016 DBG_8192C("RTW_Rx:cur_ch=%d\n", channel);
4018 DBG_871X("RTW_Rx:%s\n", msg);
4020 DBG_871X("RTW_Rx:category(%u), action(%u)\n", category, action);
4022 if (channel <= RTW_CH_MAX_2G_CHANNEL)
4023 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
4025 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
4027 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4028 rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
4030 cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
4036 void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
4038 u16 wps_devicepassword_id = 0x0000;
4039 uint wps_devicepassword_id_len = 0;
4040 u8 wpsie[ 255 ] = { 0x00 }, p2p_ie[ 255 ] = { 0x00 };
4043 u32 devinfo_contentlen = 0;
4044 u8 devinfo_content[64] = { 0x00 };
4046 uint capability_len = 0;
4048 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4049 u8 action = P2P_PUB_ACTION_ACTION;
4051 u32 p2poui = cpu_to_be32(P2POUI);
4052 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
4058 struct xmit_frame *pmgntframe;
4059 struct pkt_attrib *pattrib;
4060 unsigned char *pframe;
4061 struct rtw_ieee80211_hdr *pwlanhdr;
4062 unsigned short *fctrl;
4063 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4064 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4065 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4067 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4068 u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
4069 size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
4072 DBG_871X( "[%s] In\n", __FUNCTION__ );
4074 //prepare for building provision_request frame
4075 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
4076 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
4078 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
4080 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
4081 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
4082 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
4084 switch(wps_devicepassword_id)
4087 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
4089 case WPS_DPID_USER_SPEC:
4090 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
4092 case WPS_DPID_MACHINE_SPEC:
4094 case WPS_DPID_REKEY:
4097 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
4099 case WPS_DPID_REGISTRAR_SPEC:
4100 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
4107 if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) )
4110 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);
4111 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&capability, &capability_len);
4116 //start to build provision_request frame
4117 _rtw_memset(wpsie, 0, sizeof(wpsie));
4118 _rtw_memset(p2p_ie, 0, sizeof(p2p_ie));
4121 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4128 pattrib = &pmgntframe->attrib;
4129 update_mgntframe_attrib(padapter, pattrib);
4131 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4133 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4134 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4136 fctrl = &(pwlanhdr->frame_ctl);
4139 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
4140 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
4141 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
4143 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4144 pmlmeext->mgnt_seq++;
4145 SetFrameSubType(pframe, WIFI_ACTION);
4147 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4148 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4150 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4151 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4152 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4153 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4154 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
4157 //build_prov_disc_request_p2p_ie
4160 p2p_ie[ p2pielen++ ] = 0x50;
4161 p2p_ie[ p2pielen++ ] = 0x6F;
4162 p2p_ie[ p2pielen++ ] = 0x9A;
4163 p2p_ie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4165 // Commented by Albert 20110301
4166 // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
4167 // 1. P2P Capability
4169 // 3. Group ID ( When joining an operating P2P Group )
4171 // P2P Capability ATTR
4173 p2p_ie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4176 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4177 RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
4181 // Device Capability Bitmap, 1 byte
4182 // Group Capability Bitmap, 1 byte
4183 _rtw_memcpy(p2p_ie + p2pielen, &capability, 2);
4189 p2p_ie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4192 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4193 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4194 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4195 RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
4199 _rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
4200 p2pielen += devinfo_contentlen;
4203 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);
4204 //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr);
4205 //pframe += p2pielen;
4206 pattrib->pktlen += p2p_ielen;
4210 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4215 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4219 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4223 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
4227 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
4231 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4235 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
4238 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4242 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
4244 pattrib->pktlen += wfdielen;
4247 pattrib->last_txcmdsz = pattrib->pktlen;
4249 //dump_mgntframe(padapter, pmgntframe);
4250 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
4251 DBG_8192C("%s, ack to\n", __func__);
4253 //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
4255 // DBG_8192C("waiting for p2p peer key-in PIN CODE\n");
4256 // rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req.
4261 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
4262 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4263 struct wireless_dev *wdev,
4265 struct net_device *ndev,
4267 struct ieee80211_channel * channel,
4268 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4269 enum nl80211_channel_type channel_type,
4271 unsigned int duration, u64 *cookie)
4274 _adapter *padapter = wiphy_to_adapter(wiphy);
4275 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4276 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4277 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4278 struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4279 u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
4280 u8 ready_on_channel = _FALSE;
4282 DBG_871X(FUNC_ADPT_FMT" ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter), remain_ch, duration);
4284 if(pcfg80211_wdinfo->is_ro_ch == _TRUE)
4286 DBG_8192C("%s, cancel ro ch timer\n", __func__);
4288 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4290 #ifdef CONFIG_CONCURRENT_MODE
4291 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
4292 #endif //CONFIG_CONCURRENT_MODE
4294 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
4297 pcfg80211_wdinfo->is_ro_ch = _TRUE;
4299 if(_FAIL == rtw_pwr_wakeup(padapter)) {
4304 _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
4305 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4306 pcfg80211_wdinfo->remain_on_ch_type= channel_type;
4308 pcfg80211_wdinfo->remain_on_ch_cookie= *cookie;
4310 rtw_scan_abort(padapter);
4311 #ifdef CONFIG_CONCURRENT_MODE
4312 if(rtw_buddy_adapter_up(padapter))
4313 rtw_scan_abort(padapter->pbuddy_adapter);
4314 #endif //CONFIG_CONCURRENT_MODE
4316 //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
4317 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4319 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
4320 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = _TRUE;
4324 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4325 #ifdef CONFIG_DEBUG_CFG80211
4326 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
4331 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
4335 duration = duration*3;//extend from exper.
4338 #ifdef CONFIG_CONCURRENT_MODE
4339 if(check_buddy_fwstate(padapter, _FW_LINKED) &&
4340 (duration<pwdinfo->ext_listen_interval))
4342 duration = duration + pwdinfo->ext_listen_interval;
4346 pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter);
4348 if(rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) >= 0) {
4349 #ifdef CONFIG_CONCURRENT_MODE
4350 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4352 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
4353 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4355 if(remain_ch != pbuddy_mlmeext->cur_channel)
4357 if(ATOMIC_READ(&pwdev_priv->switch_ch_to)==1 ||
4358 (remain_ch != pmlmeext->cur_channel))
4360 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
4361 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
4363 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
4365 DBG_8192C("%s, set switch ch timer, duration=%d\n", __func__, duration-pwdinfo->ext_listen_interval);
4366 _set_timer(&pwdinfo->ap_p2p_switch_timer, duration-pwdinfo->ext_listen_interval);
4370 ready_on_channel = _TRUE;
4371 //pmlmeext->cur_channel = remain_ch;
4372 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4374 #endif //CONFIG_CONCURRENT_MODE
4375 if(remain_ch != pmlmeext->cur_channel )
4377 ready_on_channel = _TRUE;
4378 //pmlmeext->cur_channel = remain_ch;
4379 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4382 DBG_871X("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__, remain_ch);
4386 //call this after other things have been done
4387 #ifdef CONFIG_CONCURRENT_MODE
4388 if(ATOMIC_READ(&pwdev_priv->ro_ch_to)==1 ||
4389 (remain_ch != pmlmeext->cur_channel))
4391 u8 co_channel = 0xff;
4392 ATOMIC_SET(&pwdev_priv->ro_ch_to, 0);
4395 if(ready_on_channel == _TRUE)
4397 if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) )
4398 pmlmeext->cur_channel = remain_ch;
4400 #ifdef CONFIG_CONCURRENT_MODE
4401 co_channel = rtw_get_oper_ch(padapter);
4403 if(co_channel !=remain_ch)
4406 if (!padapter->mlmepriv.LinkDetectInfo.bBusyTraffic)
4407 set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4410 DBG_8192C("%s, set ro ch timer, duration=%d\n", __func__, duration);
4411 _set_timer( &pcfg80211_wdinfo->remain_on_ch_timer, duration);
4413 #ifdef CONFIG_CONCURRENT_MODE
4417 rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type, duration, GFP_KERNEL);
4421 pcfg80211_wdinfo->is_ro_ch = _FALSE;
4426 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
4427 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4428 struct wireless_dev *wdev,
4430 struct net_device *ndev,
4435 _adapter *padapter = wiphy_to_adapter(wiphy);
4436 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4437 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4438 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
4439 struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4441 DBG_871X(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
4443 if (pcfg80211_wdinfo->is_ro_ch == _TRUE) {
4444 DBG_8192C("%s, cancel ro ch timer\n", __func__);
4445 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4446 #ifdef CONFIG_CONCURRENT_MODE
4447 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
4449 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
4453 // Disable P2P Listen State
4454 if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
4456 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4458 _cancel_timer_ex( &pwdinfo->find_phase_timer );
4459 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
4460 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
4462 rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
4463 _rtw_memset(pwdinfo, 0x00, sizeof(struct wifidirect_info));
4469 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
4470 #ifdef CONFIG_DEBUG_CFG80211
4471 DBG_8192C("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
4474 pcfg80211_wdinfo->is_ro_ch = _FALSE;
4481 static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, const u8 *buf, size_t len)
4483 struct xmit_frame *pmgntframe;
4484 struct pkt_attrib *pattrib;
4485 unsigned char *pframe;
4488 struct rtw_ieee80211_hdr *pwlanhdr;
4489 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4490 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4491 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4492 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4493 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4494 //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4496 if(_FAIL == rtw_pwr_wakeup(padapter)) {
4501 rtw_set_scan_deny(padapter, 1000);
4503 rtw_scan_abort(padapter);
4504 #ifdef CONFIG_CONCURRENT_MODE
4505 if(rtw_buddy_adapter_up(padapter))
4506 rtw_scan_abort(padapter->pbuddy_adapter);
4507 #endif /* CONFIG_CONCURRENT_MODE */
4509 if (padapter->cfg80211_wdinfo.is_ro_ch == _TRUE) {
4510 //DBG_8192C("%s, cancel ro ch timer\n", __func__);
4511 //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4512 //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE;
4513 #ifdef CONFIG_CONCURRENT_MODE
4514 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
4516 DBG_8192C("%s, extend ro ch time\n", __func__);
4517 _set_timer( &padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
4519 #endif //CONFIG_CONCURRENT_MODE
4522 #ifdef CONFIG_CONCURRENT_MODE
4523 if (check_buddy_fwstate(padapter, _FW_LINKED )) {
4525 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
4526 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4528 co_channel = rtw_get_oper_ch(padapter);
4530 if (tx_ch != pbuddy_mlmeext->cur_channel) {
4532 u16 ext_listen_period;
4534 if (ATOMIC_READ(&pwdev_priv->switch_ch_to)==1) {
4535 DBG_8192C("%s, issue nulldata pwrbit=1\n", __func__);
4536 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
4538 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
4540 //DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
4541 //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
4544 if (check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
4546 ext_listen_period = 500;// 500ms
4550 ext_listen_period = pwdinfo->ext_listen_period;
4553 DBG_8192C("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period);
4554 _set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period);
4558 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
4559 pmlmeext->cur_channel = tx_ch;
4561 if (tx_ch != co_channel)
4562 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4564 #endif //CONFIG_CONCURRENT_MODE
4565 //if (tx_ch != pmlmeext->cur_channel) {
4566 if(tx_ch != rtw_get_oper_ch(padapter)) {
4567 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
4568 pmlmeext->cur_channel = tx_ch;
4569 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4572 //starting alloc mgmt frame to dump it
4573 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4581 pattrib = &pmgntframe->attrib;
4582 update_mgntframe_attrib(padapter, pattrib);
4583 pattrib->retry_ctrl = _FALSE;
4585 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4587 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4589 _rtw_memcpy(pframe, (void*)buf, len);
4590 pattrib->pktlen = len;
4592 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4594 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
4595 pattrib->seqnum = pmlmeext->mgnt_seq;
4596 pmlmeext->mgnt_seq++;
4600 struct wifi_display_info *pwfd_info;
4602 pwfd_info = padapter->wdinfo.wfd_info;
4604 if ( _TRUE == pwfd_info->wfd_enable )
4606 rtw_append_wfd_ie( padapter, pframe, &pattrib->pktlen );
4609 #endif // CONFIG_WFD
4611 pattrib->last_txcmdsz = pattrib->pktlen;
4613 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
4618 #ifdef CONFIG_DEBUG_CFG80211
4619 DBG_8192C("%s, ack == _FAIL\n", __func__);
4624 #ifdef CONFIG_DEBUG_CFG80211
4625 DBG_8192C("%s, ack=%d, ok!\n", __func__, ack);
4632 #ifdef CONFIG_DEBUG_CFG80211
4633 DBG_8192C("%s, ret=%d\n", __func__, ret);
4640 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
4641 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4642 struct wireless_dev *wdev,
4644 struct net_device *ndev,
4646 struct ieee80211_channel *chan,
4647 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
4650 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4651 enum nl80211_channel_type channel_type,
4652 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4653 bool channel_type_valid,
4656 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
4659 const u8 *buf, size_t len,
4660 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
4663 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
4664 bool dont_wait_for_ack,
4668 _adapter *padapter = (_adapter *)wiphy_to_adapter(wiphy);
4669 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4672 u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
4675 u8 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
4676 u8 category, action;
4678 u32 start = rtw_get_current_time();
4680 /* cookie generation */
4681 *cookie = (unsigned long) buf;
4683 #ifdef CONFIG_DEBUG_CFG80211
4684 DBG_871X(FUNC_ADPT_FMT" len=%zu, ch=%d"
4685 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4687 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4688 ", channel_type_valid=%d"
4691 "\n", FUNC_ADPT_ARG(padapter),
4693 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4695 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4696 , channel_type_valid
4700 #endif /* CONFIG_DEBUG_CFG80211 */
4702 /* indicate ack before issue frame to avoid racing with rsp frame */
4703 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4704 rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL);
4705 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
4706 cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
4709 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
4710 DBG_8192C(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
4711 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
4715 DBG_8192C("RTW_Tx:tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
4717 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0) {
4721 if (category == RTW_WLAN_CATEGORY_PUBLIC)
4722 DBG_871X("RTW_Tx:%s\n", action_public_str(action));
4724 DBG_871X("RTW_Tx:category(%u), action(%u)\n", category, action);
4729 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
4730 } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
4732 if (tx_ret != _SUCCESS || dump_cnt > 1) {
4733 DBG_871X(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
4734 tx_ret==_SUCCESS?"OK":"FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
4738 case P2P_GO_NEGO_CONF:
4739 rtw_clear_scan_deny(padapter);
4741 case P2P_INVIT_RESP:
4742 if (pwdev_priv->invit_info.flags & BIT(0)
4743 && pwdev_priv->invit_info.status == 0)
4745 DBG_871X(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
4746 FUNC_ADPT_ARG(padapter));
4747 rtw_set_scan_deny(padapter, 5000);
4748 rtw_pwr_wakeup_ex(padapter, 5000);
4749 rtw_clear_scan_deny(padapter);
4758 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
4759 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
4760 struct wireless_dev *wdev,
4762 struct net_device *ndev,
4764 u16 frame_type, bool reg)
4766 _adapter *adapter = wiphy_to_adapter(wiphy);
4768 #ifdef CONFIG_DEBUG_CFG80211
4769 DBG_871X(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
4773 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
4779 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
4785 u8 wps_oui[8]={0x0,0x50,0xf2,0x04};
4789 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4790 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4791 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4793 DBG_871X(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
4797 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
4799 #ifdef CONFIG_DEBUG_CFG80211
4800 DBG_8192C("bcn_wps_ielen=%d\n", wps_ielen);
4803 if(pmlmepriv->wps_beacon_ie)
4805 u32 free_len = pmlmepriv->wps_beacon_ie_len;
4806 pmlmepriv->wps_beacon_ie_len = 0;
4807 rtw_mfree(pmlmepriv->wps_beacon_ie, free_len);
4808 pmlmepriv->wps_beacon_ie = NULL;
4811 pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen);
4812 if ( pmlmepriv->wps_beacon_ie == NULL) {
4813 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
4818 _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
4819 pmlmepriv->wps_beacon_ie_len = wps_ielen;
4821 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
4829 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
4831 #ifdef CONFIG_DEBUG_CFG80211
4832 DBG_8192C("bcn_p2p_ielen=%d\n", p2p_ielen);
4835 if(pmlmepriv->p2p_beacon_ie)
4837 u32 free_len = pmlmepriv->p2p_beacon_ie_len;
4838 pmlmepriv->p2p_beacon_ie_len = 0;
4839 rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len);
4840 pmlmepriv->p2p_beacon_ie = NULL;
4843 pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen);
4844 if ( pmlmepriv->p2p_beacon_ie == NULL) {
4845 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
4850 _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
4851 pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
4860 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
4862 #ifdef CONFIG_DEBUG_CFG80211
4863 DBG_8192C("bcn_wfd_ielen=%d\n", wfd_ielen);
4866 if(pmlmepriv->wfd_beacon_ie)
4868 u32 free_len = pmlmepriv->wfd_beacon_ie_len;
4869 pmlmepriv->wfd_beacon_ie_len = 0;
4870 rtw_mfree(pmlmepriv->wfd_beacon_ie, free_len);
4871 pmlmepriv->wfd_beacon_ie = NULL;
4874 pmlmepriv->wfd_beacon_ie = rtw_malloc(wfd_ielen);
4875 if ( pmlmepriv->wfd_beacon_ie == NULL) {
4876 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
4880 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
4884 pmlmeext->bstart_bss = _TRUE;
4892 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
4901 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
4902 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4904 #ifdef CONFIG_DEBUG_CFG80211
4905 DBG_8192C("%s, ielen=%d\n", __func__, len);
4910 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
4912 uint attr_contentlen = 0;
4913 u16 uconfig_method, *puconfig_method = NULL;
4915 #ifdef CONFIG_DEBUG_CFG80211
4916 DBG_8192C("probe_resp_wps_ielen=%d\n", wps_ielen);
4919 if(check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
4922 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
4926 DBG_871X("%s, got sr\n", __func__);
4930 DBG_8192C("GO mode process WPS under site-survey, sr no set\n");
4935 if(pmlmepriv->wps_probe_resp_ie)
4937 u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
4938 pmlmepriv->wps_probe_resp_ie_len = 0;
4939 rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len);
4940 pmlmepriv->wps_probe_resp_ie = NULL;
4943 pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen);
4944 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
4945 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
4950 //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode
4951 if ( (puconfig_method = (u16*)rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen)) != NULL )
4953 #ifdef CONFIG_DEBUG_CFG80211
4954 //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method));
4957 uconfig_method = WPS_CM_PUSH_BUTTON;
4958 uconfig_method = cpu_to_be16( uconfig_method );
4960 *puconfig_method |= uconfig_method;
4963 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
4964 pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
4972 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
4975 u32 attr_contentlen = 0;
4978 #ifdef CONFIG_DEBUG_CFG80211
4979 DBG_8192C("probe_resp_p2p_ielen=%d\n", p2p_ielen);
4982 //Check P2P Capability ATTR
4983 if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) )
4986 //DBG_8192C( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
4987 cap_attr = le16_to_cpu(cap_attr);
4988 grp_cap = (u8)((cap_attr >> 8)&0xff);
4990 is_GO = (grp_cap&BIT(0)) ? _TRUE:_FALSE;
4993 DBG_8192C("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
4999 if(pmlmepriv->p2p_probe_resp_ie)
5001 u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
5002 pmlmepriv->p2p_probe_resp_ie_len = 0;
5003 rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len);
5004 pmlmepriv->p2p_probe_resp_ie = NULL;
5007 pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen);
5008 if ( pmlmepriv->p2p_probe_resp_ie == NULL) {
5009 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
5013 _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
5014 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
5018 if(pmlmepriv->p2p_go_probe_resp_ie)
5020 u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
5021 pmlmepriv->p2p_go_probe_resp_ie_len = 0;
5022 rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len);
5023 pmlmepriv->p2p_go_probe_resp_ie = NULL;
5026 pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen);
5027 if ( pmlmepriv->p2p_go_probe_resp_ie == NULL) {
5028 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
5032 _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
5033 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
5043 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
5045 #ifdef CONFIG_DEBUG_CFG80211
5046 DBG_8192C("probe_resp_wfd_ielen=%d\n", wfd_ielen);
5049 if(pmlmepriv->wfd_probe_resp_ie)
5051 u32 free_len = pmlmepriv->wfd_probe_resp_ie_len;
5052 pmlmepriv->wfd_probe_resp_ie_len = 0;
5053 rtw_mfree(pmlmepriv->wfd_probe_resp_ie, free_len);
5054 pmlmepriv->wfd_probe_resp_ie = NULL;
5057 pmlmepriv->wfd_probe_resp_ie = rtw_malloc(wfd_ielen);
5058 if ( pmlmepriv->wfd_probe_resp_ie == NULL) {
5059 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
5063 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
5073 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
5076 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
5077 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5079 DBG_8192C("%s, ielen=%d\n", __func__, len);
5083 if(pmlmepriv->wps_assoc_resp_ie)
5085 u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
5086 pmlmepriv->wps_assoc_resp_ie_len = 0;
5087 rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len);
5088 pmlmepriv->wps_assoc_resp_ie = NULL;
5091 pmlmepriv->wps_assoc_resp_ie = rtw_malloc(len);
5092 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
5093 DBG_8192C("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
5097 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len);
5098 pmlmepriv->wps_assoc_resp_ie_len = len;
5105 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
5112 #ifdef CONFIG_DEBUG_CFG80211
5113 DBG_8192C("%s, ielen=%d\n", __func__, len);
5116 if( (rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen>0))
5118 || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen>0))
5127 ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
5129 case 0x2: //PROBE_RESP
5130 ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
5132 case 0x4: //ASSOC_RESP
5133 ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
5143 static struct cfg80211_ops rtw_cfg80211_ops = {
5144 .change_virtual_intf = cfg80211_rtw_change_iface,
5145 .add_key = cfg80211_rtw_add_key,
5146 .get_key = cfg80211_rtw_get_key,
5147 .del_key = cfg80211_rtw_del_key,
5148 .set_default_key = cfg80211_rtw_set_default_key,
5149 .get_station = cfg80211_rtw_get_station,
5150 .scan = cfg80211_rtw_scan,
5151 .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
5152 .connect = cfg80211_rtw_connect,
5153 .disconnect = cfg80211_rtw_disconnect,
5154 .join_ibss = cfg80211_rtw_join_ibss,
5155 .leave_ibss = cfg80211_rtw_leave_ibss,
5156 .set_tx_power = cfg80211_rtw_set_txpower,
5157 .get_tx_power = cfg80211_rtw_get_txpower,
5158 .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
5159 .set_pmksa = cfg80211_rtw_set_pmksa,
5160 .del_pmksa = cfg80211_rtw_del_pmksa,
5161 .flush_pmksa = cfg80211_rtw_flush_pmksa,
5163 #ifdef CONFIG_AP_MODE
5164 .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
5165 .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
5167 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
5168 .add_beacon = cfg80211_rtw_add_beacon,
5169 .set_beacon = cfg80211_rtw_set_beacon,
5170 .del_beacon = cfg80211_rtw_del_beacon,
5172 .start_ap = cfg80211_rtw_start_ap,
5173 .change_beacon = cfg80211_rtw_change_beacon,
5174 .stop_ap = cfg80211_rtw_stop_ap,
5177 .add_station = cfg80211_rtw_add_station,
5178 .del_station = cfg80211_rtw_del_station,
5179 .change_station = cfg80211_rtw_change_station,
5180 .dump_station = cfg80211_rtw_dump_station,
5181 .change_bss = cfg80211_rtw_change_bss,
5182 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
5183 .set_channel = cfg80211_rtw_set_channel,
5185 //.auth = cfg80211_rtw_auth,
5186 //.assoc = cfg80211_rtw_assoc,
5187 #endif //CONFIG_AP_MODE
5190 .remain_on_channel = cfg80211_rtw_remain_on_channel,
5191 .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
5194 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
5195 .mgmt_tx = cfg80211_rtw_mgmt_tx,
5196 .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
5197 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
5198 .action = cfg80211_rtw_mgmt_tx,
5202 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
5205 #define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
5206 #define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
5208 ht_cap->ht_supported = _TRUE;
5210 ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
5211 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
5212 IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
5215 *Maximum length of AMPDU that the STA can receive.
5216 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
5218 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5220 /*Minimum MPDU start spacing , */
5221 ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5223 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5226 *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
5229 *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
5230 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
5231 *if rx_ant >=3 rx_mask[2]=0xff;
5232 *if BW_40 rx_mask[4]=0x01;
5233 *highest supported RX rate
5235 if(rf_type == RF_1T1R)
5237 ht_cap->mcs.rx_mask[0] = 0xFF;
5238 ht_cap->mcs.rx_mask[1] = 0x00;
5239 ht_cap->mcs.rx_mask[4] = 0x01;
5241 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
5243 else if((rf_type == RF_1T2R) || (rf_type==RF_2T2R))
5245 ht_cap->mcs.rx_mask[0] = 0xFF;
5246 ht_cap->mcs.rx_mask[1] = 0xFF;
5247 ht_cap->mcs.rx_mask[4] = 0x01;
5249 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
5253 DBG_8192C("%s, error rf_type=%d\n", __func__, rf_type);
5258 void rtw_cfg80211_init_wiphy(_adapter *padapter)
5261 struct ieee80211_supported_band *bands;
5262 struct wireless_dev *pwdev = padapter->rtw_wdev;
5263 struct wiphy *wiphy = pwdev->wiphy;
5265 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
5267 DBG_8192C("%s:rf_type=%d\n", __func__, rf_type);
5269 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
5271 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
5273 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type);
5276 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
5278 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
5280 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type);
5285 struct ieee80211_iface_limit rtw_limits[] = {
5286 { .max = 1, .types = BIT(NL80211_IFTYPE_STATION)
5287 | BIT(NL80211_IFTYPE_ADHOC)
5288 #ifdef CONFIG_AP_MODE
5289 | BIT(NL80211_IFTYPE_AP)
5291 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
5292 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5293 | BIT(NL80211_IFTYPE_P2P_GO)
5296 {.max = 1, .types = BIT(NL80211_IFTYPE_MONITOR)},
5299 struct ieee80211_iface_combination rtw_combinations = {
5300 .limits = rtw_limits,
5301 .n_limits = ARRAY_SIZE(rtw_limits),
5302 .max_interfaces = 2,
5303 .num_different_channels = 1,
5307 static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy)
5310 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5312 wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
5313 wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
5314 wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
5316 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
5317 wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
5320 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
5321 | BIT(NL80211_IFTYPE_ADHOC)
5322 #ifdef CONFIG_AP_MODE
5323 | BIT(NL80211_IFTYPE_AP)
5324 | BIT(NL80211_IFTYPE_MONITOR)
5326 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
5327 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5328 | BIT(NL80211_IFTYPE_P2P_GO)
5332 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
5333 #ifdef CONFIG_AP_MODE
5334 wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
5335 #endif //CONFIG_AP_MODE
5338 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
5339 wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
5343 wiphy->iface_combinations = &rtw_combinations;
5344 wiphy->n_iface_combinations = 1;
5347 wiphy->cipher_suites = rtw_cipher_suites;
5348 wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
5350 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
5351 wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
5352 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
5353 wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
5355 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
5356 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
5359 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
5360 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
5361 wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
5364 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
5365 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
5367 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
5370 int rtw_wdev_alloc(_adapter *padapter, struct device *dev)
5373 struct wiphy *wiphy;
5374 struct wireless_dev *wdev;
5375 struct rtw_wdev_priv *pwdev_priv;
5376 struct net_device *pnetdev = padapter->pnetdev;
5378 DBG_8192C("%s(padapter=%p)\n", __func__, padapter);
5381 wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wdev_priv));
5383 DBG_8192C("Couldn't allocate wiphy device\n");
5387 set_wiphy_dev(wiphy, dev);
5388 rtw_cfg80211_preinit_wiphy(padapter, wiphy);
5390 ret = wiphy_register(wiphy);
5392 DBG_8192C("Couldn't register wiphy device\n");
5397 wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
5399 DBG_8192C("Couldn't allocate wireless device\n");
5401 goto unregister_wiphy;
5403 wdev->wiphy = wiphy;
5404 wdev->netdev = pnetdev;
5405 //wdev->iftype = NL80211_IFTYPE_STATION;
5406 wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
5407 padapter->rtw_wdev = wdev;
5408 pnetdev->ieee80211_ptr = wdev;
5411 pwdev_priv = wdev_to_priv(wdev);
5412 pwdev_priv->rtw_wdev = wdev;
5413 pwdev_priv->pmon_ndev = NULL;
5414 pwdev_priv->ifname_mon[0] = '\0';
5415 pwdev_priv->padapter = padapter;
5416 pwdev_priv->scan_request = NULL;
5417 _rtw_spinlock_init(&pwdev_priv->scan_req_lock);
5419 pwdev_priv->p2p_enabled = _FALSE;
5420 pwdev_priv->provdisc_req_issued = _FALSE;
5421 rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
5422 rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
5424 pwdev_priv->bandroid_scan = _FALSE;
5426 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
5427 pwdev_priv->power_mgmt = _TRUE;
5429 pwdev_priv->power_mgmt = _FALSE;
5431 #ifdef CONFIG_CONCURRENT_MODE
5432 ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
5433 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
5438 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
5440 wiphy_unregister(wiphy);
5448 void rtw_wdev_free(struct wireless_dev *wdev)
5450 struct rtw_wdev_priv *pwdev_priv;
5452 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
5457 pwdev_priv = wdev_to_priv(wdev);
5459 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
5460 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
5462 wiphy_free(wdev->wiphy);
5464 rtw_mfree((u8*)wdev, sizeof(struct wireless_dev));
5467 void rtw_wdev_unregister(struct wireless_dev *wdev)
5469 struct rtw_wdev_priv *pwdev_priv;
5471 DBG_8192C("%s(wdev=%p)\n", __func__, wdev);
5476 pwdev_priv = wdev_to_priv(wdev);
5478 rtw_cfg80211_indicate_scan_done(pwdev_priv, _TRUE);
5480 if (pwdev_priv->pmon_ndev) {
5481 DBG_8192C("%s, unregister monitor interface\n", __func__);
5482 unregister_netdev(pwdev_priv->pmon_ndev);
5485 wiphy_unregister(wdev->wiphy);
5488 #endif //CONFIG_IOCTL_CFG80211