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 <xmit_osdep.h>
29 #ifdef CONFIG_IOCTL_CFG80211
31 #include "ioctl_cfg80211.h"
33 #define RTW_MAX_MGMT_TX_CNT (8)
35 #define RTW_SCAN_IE_LEN_MAX 2304
36 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535 //ms
37 #define RTW_MAX_NUM_PMKIDS 4
39 #define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
41 static const u32 rtw_cipher_suites[] = {
42 WLAN_CIPHER_SUITE_WEP40,
43 WLAN_CIPHER_SUITE_WEP104,
44 WLAN_CIPHER_SUITE_TKIP,
45 WLAN_CIPHER_SUITE_CCMP,
48 #define RATETAB_ENT(_rate, _rateid, _flags) \
51 .hw_value = (_rateid), \
55 #define CHAN2G(_channel, _freq, _flags) { \
56 .band = IEEE80211_BAND_2GHZ, \
57 .center_freq = (_freq), \
58 .hw_value = (_channel), \
60 .max_antenna_gain = 0, \
64 #define CHAN5G(_channel, _flags) { \
65 .band = IEEE80211_BAND_5GHZ, \
66 .center_freq = 5000 + (5 * (_channel)), \
67 .hw_value = (_channel), \
69 .max_antenna_gain = 0, \
73 static struct ieee80211_rate rtw_rates[] = {
74 RATETAB_ENT(10, 0x1, 0),
75 RATETAB_ENT(20, 0x2, 0),
76 RATETAB_ENT(55, 0x4, 0),
77 RATETAB_ENT(110, 0x8, 0),
78 RATETAB_ENT(60, 0x10, 0),
79 RATETAB_ENT(90, 0x20, 0),
80 RATETAB_ENT(120, 0x40, 0),
81 RATETAB_ENT(180, 0x80, 0),
82 RATETAB_ENT(240, 0x100, 0),
83 RATETAB_ENT(360, 0x200, 0),
84 RATETAB_ENT(480, 0x400, 0),
85 RATETAB_ENT(540, 0x800, 0),
88 #define rtw_a_rates (rtw_rates + 4)
89 #define RTW_A_RATES_NUM 8
90 #define rtw_g_rates (rtw_rates + 0)
91 #define RTW_G_RATES_NUM 12
93 #define RTW_2G_CHANNELS_NUM 14
94 #define RTW_5G_CHANNELS_NUM 37
96 static struct ieee80211_channel rtw_2ghz_channels[] = {
113 static struct ieee80211_channel rtw_5ghz_a_channels[] = {
114 CHAN5G(34, 0), CHAN5G(36, 0),
115 CHAN5G(38, 0), CHAN5G(40, 0),
116 CHAN5G(42, 0), CHAN5G(44, 0),
117 CHAN5G(46, 0), CHAN5G(48, 0),
118 CHAN5G(52, 0), CHAN5G(56, 0),
119 CHAN5G(60, 0), CHAN5G(64, 0),
120 CHAN5G(100, 0), CHAN5G(104, 0),
121 CHAN5G(108, 0), CHAN5G(112, 0),
122 CHAN5G(116, 0), CHAN5G(120, 0),
123 CHAN5G(124, 0), CHAN5G(128, 0),
124 CHAN5G(132, 0), CHAN5G(136, 0),
125 CHAN5G(140, 0), CHAN5G(149, 0),
126 CHAN5G(153, 0), CHAN5G(157, 0),
127 CHAN5G(161, 0), CHAN5G(165, 0),
128 CHAN5G(184, 0), CHAN5G(188, 0),
129 CHAN5G(192, 0), CHAN5G(196, 0),
130 CHAN5G(200, 0), CHAN5G(204, 0),
131 CHAN5G(208, 0), CHAN5G(212, 0),
136 void rtw_2g_channels_init(struct ieee80211_channel *channels)
138 memcpy((void*)channels, (void*)rtw_2ghz_channels,
139 sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
143 void rtw_5g_channels_init(struct ieee80211_channel *channels)
145 memcpy((void*)channels, (void*)rtw_5ghz_a_channels,
146 sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
150 void rtw_2g_rates_init(struct ieee80211_rate *rates)
152 memcpy(rates, rtw_g_rates,
153 sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
157 void rtw_5g_rates_init(struct ieee80211_rate *rates)
159 memcpy(rates, rtw_a_rates,
160 sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM
164 struct ieee80211_supported_band *rtw_spt_band_alloc(
165 enum ieee80211_band band
168 struct ieee80211_supported_band *spt_band = NULL;
169 int n_channels, n_bitrates;
171 if(band == IEEE80211_BAND_2GHZ)
173 n_channels = RTW_2G_CHANNELS_NUM;
174 n_bitrates = RTW_G_RATES_NUM;
176 else if(band == IEEE80211_BAND_5GHZ)
178 n_channels = RTW_5G_CHANNELS_NUM;
179 n_bitrates = RTW_A_RATES_NUM;
186 spt_band = (struct ieee80211_supported_band *)
187 kzalloc(sizeof(struct ieee80211_supported_band) +
188 sizeof(struct ieee80211_channel)*n_channels +
189 sizeof(struct ieee80211_rate)*n_bitrates, GFP_KERNEL);
193 spt_band->channels = (struct ieee80211_channel*)(((u8*)spt_band)+sizeof(struct ieee80211_supported_band));
194 spt_band->bitrates= (struct ieee80211_rate*)(((u8*)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
195 spt_band->band = band;
196 spt_band->n_channels = n_channels;
197 spt_band->n_bitrates = n_bitrates;
199 if(band == IEEE80211_BAND_2GHZ)
201 rtw_2g_channels_init(spt_band->channels);
202 rtw_2g_rates_init(spt_band->bitrates);
204 else if(band == IEEE80211_BAND_5GHZ)
206 rtw_5g_channels_init(spt_band->channels);
207 rtw_5g_rates_init(spt_band->bitrates);
217 void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
224 if(spt_band->band == IEEE80211_BAND_2GHZ)
226 size = sizeof(struct ieee80211_supported_band)
227 + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
228 + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM;
230 else if(spt_band->band == IEEE80211_BAND_5GHZ)
232 size = sizeof(struct ieee80211_supported_band)
233 + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
234 + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM;
243 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
244 static const struct ieee80211_txrx_stypes
245 rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
246 [NL80211_IFTYPE_ADHOC] = {
248 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
250 [NL80211_IFTYPE_STATION] = {
252 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
253 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
255 [NL80211_IFTYPE_AP] = {
257 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
258 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
259 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
260 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
261 BIT(IEEE80211_STYPE_AUTH >> 4) |
262 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
263 BIT(IEEE80211_STYPE_ACTION >> 4)
265 [NL80211_IFTYPE_AP_VLAN] = {
268 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
269 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
270 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
271 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
272 BIT(IEEE80211_STYPE_AUTH >> 4) |
273 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
274 BIT(IEEE80211_STYPE_ACTION >> 4)
276 [NL80211_IFTYPE_P2P_CLIENT] = {
278 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
279 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
281 [NL80211_IFTYPE_P2P_GO] = {
283 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
284 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
285 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
286 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
287 BIT(IEEE80211_STYPE_AUTH >> 4) |
288 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
289 BIT(IEEE80211_STYPE_ACTION >> 4)
294 static int rtw_ieee80211_channel_to_frequency(int chan, int band)
296 /* see 802.11 17.3.8.3.2 and Annex J
297 * there are overlapping channel numbers in 5GHz and 2GHz bands */
299 if (band == IEEE80211_BAND_5GHZ) {
300 if (chan >= 182 && chan <= 196)
301 return 4000 + chan * 5;
303 return 5000 + chan * 5;
304 } else { /* IEEE80211_BAND_2GHZ */
308 return 2407 + chan * 5;
310 return 0; /* not supported */
314 #define MAX_BSSINFO_LEN 1000
315 static int rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork)
318 struct ieee80211_channel *notify_channel;
319 struct cfg80211_bss *bss;
320 //struct ieee80211_supported_band *band;
323 u64 notify_timestamp;
324 u16 notify_capability;
329 u8 buf[MAX_BSSINFO_LEN], *pbuf;
330 size_t len,bssinf_len=0;
331 struct rtw_ieee80211_hdr *pwlanhdr;
332 unsigned short *fctrl;
333 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
335 struct wireless_dev *wdev = padapter->rtw_wdev;
336 struct wiphy *wiphy = wdev->wiphy;
337 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
340 //DBG_8723A("%s\n", __func__);
342 bssinf_len = pnetwork->network.IELength+sizeof (struct rtw_ieee80211_hdr_3addr);
343 if(bssinf_len > MAX_BSSINFO_LEN){
344 DBG_8723A("%s IE Length too long > %d byte \n",__FUNCTION__,MAX_BSSINFO_LEN);
348 channel = pnetwork->network.Configuration.DSConfig;
349 if (channel <= RTW_CH_MAX_2G_CHANNEL)
350 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
352 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
354 notify_channel = ieee80211_get_channel(wiphy, freq);
356 //rtw_get_timestampe_from_ie()
357 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
359 notify_interval = le16_to_cpu(*(u16*)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
360 notify_capability = le16_to_cpu(*(u16*)rtw_get_capability_from_ie(pnetwork->network.IEs));
363 notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_;
364 notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_;
366 //We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm)
367 if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
368 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) {
369 notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);//dbm
371 notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);//dbm
375 DBG_8723A("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
376 pnetwork->network.MacAddress[0], pnetwork->network.MacAddress[1], pnetwork->network.MacAddress[2],
377 pnetwork->network.MacAddress[3], pnetwork->network.MacAddress[4], pnetwork->network.MacAddress[5]);
378 DBG_8723A("Channel: %d(%d)\n", channel, freq);
379 DBG_8723A("Capability: %X\n", notify_capability);
380 DBG_8723A("Beacon interval: %d\n", notify_interval);
381 DBG_8723A("Signal: %d\n", notify_signal);
382 DBG_8723A("notify_timestamp: %#018llx\n", notify_timestamp);
387 pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;
388 fctrl = &(pwlanhdr->frame_ctl);
391 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
392 //pmlmeext->mgnt_seq++;
394 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
395 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
396 SetFrameSubType(pbuf, WIFI_BEACON);
398 memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
399 SetFrameSubType(pbuf, WIFI_PROBERSP);
402 memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
403 memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
406 pbuf += sizeof(struct rtw_ieee80211_hdr_3addr);
407 len = sizeof (struct rtw_ieee80211_hdr_3addr);
409 memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength);
410 len += pnetwork->network.IELength;
413 //if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
415 // DBG_8723A("%s, got p2p_ie\n", __func__);
421 bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)buf,
422 len, notify_signal, GFP_ATOMIC);
425 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress,
426 notify_timestamp, notify_capability, notify_interval, notify_ie,
427 notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/);
430 if (unlikely(!bss)) {
431 DBG_8723A("rtw_cfg80211_inform_bss error\n");
435 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
436 #ifndef COMPAT_KERNEL_RELEASE
437 //patch for cfg80211, update beacon ies to information_elements
438 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
440 if(bss->len_information_elements != bss->len_beacon_ies)
442 bss->information_elements = bss->beacon_ies;
443 bss->len_information_elements = bss->len_beacon_ies;
446 #endif //COMPAT_KERNEL_RELEASE
447 #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
451 if( bss->information_elements == bss->proberesp_ies)
453 if( bss->len_information_elements != bss->len_proberesp_ies)
455 DBG_8723A("error!, len_information_elements != bss->len_proberesp_ies\n");
459 else if(bss->len_information_elements < bss->len_beacon_ies)
461 bss->information_elements = bss->beacon_ies;
462 bss->len_information_elements = bss->len_beacon_ies;
467 cfg80211_put_bss(bss);
474 void rtw_cfg80211_indicate_connect(_adapter *padapter)
476 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
477 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
478 struct wireless_dev *pwdev = padapter->rtw_wdev;
480 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
484 DBG_8723A("%s(padapter=%p)\n", __func__, padapter);
486 if (pwdev->iftype != NL80211_IFTYPE_STATION
487 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
488 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
494 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
498 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
500 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
501 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
502 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
503 DBG_8723A("%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));
507 #ifdef CONFIG_LAYER2_ROAMING
508 if (rtw_to_roaming(padapter) > 0) {
509 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
510 struct wiphy *wiphy = pwdev->wiphy;
511 struct ieee80211_channel *notify_channel;
513 u16 channel = cur_network->network.Configuration.DSConfig;
515 if (channel <= RTW_CH_MAX_2G_CHANNEL)
516 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
518 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
520 notify_channel = ieee80211_get_channel(wiphy, freq);
523 DBG_8723A("%s call cfg80211_roamed\n", __FUNCTION__);
524 cfg80211_roamed(padapter->pnetdev
525 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
528 , cur_network->network.MacAddress
529 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
530 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
531 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
532 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
538 DBG_8723A("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
539 cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
540 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
541 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
542 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
543 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
544 , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
545 DBG_8723A("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
549 void rtw_cfg80211_indicate_disconnect(_adapter *padapter)
551 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
552 struct wireless_dev *pwdev = padapter->rtw_wdev;
554 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
557 DBG_8723A("%s(padapter=%p)\n", __func__, padapter);
559 if (pwdev->iftype != NL80211_IFTYPE_STATION
560 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
561 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
567 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
571 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
573 _cancel_timer_ex( &pwdinfo->find_phase_timer );
574 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
575 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
577 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
578 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
580 DBG_8723A("%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));
584 if (!padapter->mlmepriv.not_indic_disco) {
585 DBG_8723A("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
587 if(pwdev->sme_state==CFG80211_SME_CONNECTING)
588 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
589 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
590 else if(pwdev->sme_state==CFG80211_SME_CONNECTED)
591 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
593 //DBG_8723A("pwdev->sme_state=%d\n", pwdev->sme_state);
595 DBG_8723A("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
600 #ifdef CONFIG_AP_MODE
601 static u8 set_pairwise_key(_adapter *padapter, struct sta_info *psta)
603 struct cmd_obj* ph2c;
604 struct set_stakey_parm *psetstakey_para;
605 struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
608 ph2c = (struct cmd_obj*)kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
614 psetstakey_para = (struct set_stakey_parm*)
615 kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
616 if(psetstakey_para==NULL){
622 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
625 psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy;
627 memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);
629 memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
632 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
640 static int set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid)
643 struct cmd_obj* pcmd;
644 struct setkey_parm *psetkeyparm;
645 struct cmd_priv *pcmdpriv=&(padapter->cmdpriv);
648 DBG_8723A("%s\n", __FUNCTION__);
650 pcmd = (struct cmd_obj*)kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
655 psetkeyparm=(struct setkey_parm*)
656 kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
657 if(psetkeyparm==NULL){
663 memset(psetkeyparm, 0, sizeof(struct setkey_parm));
665 psetkeyparm->keyid=(u8)keyid;
667 padapter->mlmepriv.key_mask |= BIT(psetkeyparm->keyid);
669 psetkeyparm->algorithm = alg;
671 psetkeyparm->set_tx = 1;
689 memcpy(&(psetkeyparm->key[0]), key, keylen);
691 pcmd->cmdcode = _SetKey_CMD_;
692 pcmd->parmbuf = (u8 *)psetkeyparm;
693 pcmd->cmdsz = (sizeof(struct setkey_parm));
698 INIT_LIST_HEAD(&pcmd->list);
700 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
709 static int set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid)
725 return set_group_key(padapter, key, alg, keyid);
729 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
732 u32 wep_key_idx, wep_key_len,wep_total_len;
733 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
734 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
735 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
736 struct security_priv* psecuritypriv=&(padapter->securitypriv);
737 struct sta_priv *pstapriv = &padapter->stapriv;
739 DBG_8723A("%s\n", __FUNCTION__);
741 param->u.crypt.err = 0;
742 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
744 //sizeof(struct ieee_param) = 64 bytes;
745 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
746 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
752 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
753 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
754 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
756 if (param->u.crypt.idx >= WEP_KEYS)
764 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
768 DBG_8723A("rtw_set_encryption(), sta has already been removed or never been added\n");
773 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
775 //todo:clear default encryption keys
777 DBG_8723A("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
783 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
785 DBG_8723A("r871x_set_encryption, crypt.alg = WEP\n");
787 wep_key_idx = param->u.crypt.idx;
788 wep_key_len = param->u.crypt.key_len;
790 DBG_8723A("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
792 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
800 wep_key_len = wep_key_len <= 5 ? 5 : 13;
803 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
805 //wep default key has not been set, so use this key index as default key.
807 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
808 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
809 psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
811 if(wep_key_len == 13)
813 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
814 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
817 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
820 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
822 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
824 set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx);
831 if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
833 if(param->u.crypt.set_tx == 0) //group key
835 if(strcmp(param->u.crypt.alg, "WEP") == 0)
837 DBG_8723A("%s, set group_key, WEP\n", __FUNCTION__);
839 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
841 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
842 if(param->u.crypt.key_len==13)
844 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
848 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
850 DBG_8723A("%s, set group_key, TKIP\n", __FUNCTION__);
852 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
854 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
856 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
858 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
859 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
861 psecuritypriv->busetkipkey = _TRUE;
864 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
866 DBG_8723A("%s, set group_key, CCMP\n", __FUNCTION__);
868 psecuritypriv->dot118021XGrpPrivacy = _AES_;
870 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
874 DBG_8723A("%s, set group_key, none\n", __FUNCTION__);
876 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
879 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
881 psecuritypriv->binstallGrpkey = _TRUE;
883 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
885 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
887 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
890 pbcmc_sta->ieee8021x_blocked = _FALSE;
891 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
900 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
902 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
904 if(param->u.crypt.set_tx ==1) //pairwise key
906 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
908 if(strcmp(param->u.crypt.alg, "WEP") == 0)
910 DBG_8723A("%s, set pairwise key, WEP\n", __FUNCTION__);
912 psta->dot118021XPrivacy = _WEP40_;
913 if(param->u.crypt.key_len==13)
915 psta->dot118021XPrivacy = _WEP104_;
918 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
920 DBG_8723A("%s, set pairwise key, TKIP\n", __FUNCTION__);
922 psta->dot118021XPrivacy = _TKIP_;
924 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
926 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
927 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
929 psecuritypriv->busetkipkey = _TRUE;
932 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
935 DBG_8723A("%s, set pairwise key, CCMP\n", __FUNCTION__);
937 psta->dot118021XPrivacy = _AES_;
941 DBG_8723A("%s, set pairwise key, none\n", __FUNCTION__);
943 psta->dot118021XPrivacy = _NO_PRIVACY_;
946 set_pairwise_key(padapter, psta);
948 psta->ieee8021x_blocked = _FALSE;
950 psta->bpairwise_key_installed = _TRUE;
955 if(strcmp(param->u.crypt.alg, "WEP") == 0)
957 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
959 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
960 if(param->u.crypt.key_len==13)
962 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
965 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
967 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
969 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
971 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
973 memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
974 memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
976 psecuritypriv->busetkipkey = _TRUE;
979 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
981 psecuritypriv->dot118021XGrpPrivacy = _AES_;
983 memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
987 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
990 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
992 psecuritypriv->binstallGrpkey = _TRUE;
994 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
996 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
998 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1001 pbcmc_sta->ieee8021x_blocked = _FALSE;
1002 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
1018 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
1021 u32 wep_key_idx, wep_key_len,wep_total_len;
1022 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1023 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1024 struct security_priv *psecuritypriv = &padapter->securitypriv;
1026 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
1031 DBG_8723A("%s\n", __func__);
1033 param->u.crypt.err = 0;
1034 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
1036 if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
1042 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
1043 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
1044 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
1046 if (param->u.crypt.idx >= WEP_KEYS)
1056 if (strcmp(param->u.crypt.alg, "WEP") == 0)
1058 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
1059 DBG_8723A("wpa_set_encryption, crypt.alg = WEP\n");
1061 wep_key_idx = param->u.crypt.idx;
1062 wep_key_len = param->u.crypt.key_len;
1064 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0))
1070 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
1072 //wep default key has not been set, so use this key index as default key.
1074 wep_key_len = wep_key_len <= 5 ? 5 : 13;
1076 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1077 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1078 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1082 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1083 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1086 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
1089 memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
1091 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
1093 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
1098 if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
1100 struct sta_info * psta,*pbcmc_sta;
1101 struct sta_priv * pstapriv = &padapter->stapriv;
1103 //DBG_8723A("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__);
1105 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
1107 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
1109 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
1110 DBG_8723A("%s, : Obtain Sta_info fail \n", __func__);
1114 //Jeff: don't disable ieee8021x_blocked while clearing key
1115 if (strcmp(param->u.crypt.alg, "none") != 0)
1116 psta->ieee8021x_blocked = _FALSE;
1119 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1120 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1122 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1125 if(param->u.crypt.set_tx ==1)//pairwise key
1128 DBG_8723A("%s, : param->u.crypt.set_tx ==1 \n", __func__);
1130 memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1132 if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
1134 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1135 memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1136 memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1138 padapter->securitypriv.busetkipkey=_FALSE;
1139 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
1142 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
1143 DBG_8723A(" ~~~~set sta key:unicastkey\n");
1145 rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE);
1149 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));
1150 memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
1151 memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
1152 padapter->securitypriv.binstallGrpkey = _TRUE;
1153 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1154 DBG_8723A(" ~~~~set sta key:groupkey\n");
1156 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1158 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1);
1160 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
1162 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
1169 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1172 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
1176 //Jeff: don't disable ieee8021x_blocked while clearing key
1177 if (strcmp(param->u.crypt.alg, "none") != 0)
1178 pbcmc_sta->ieee8021x_blocked = _FALSE;
1180 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1181 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1183 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1187 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
1194 DBG_8723A("%s, ret=%d\n", __func__, ret);
1201 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
1202 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1203 u8 key_index, bool pairwise, const u8 *mac_addr,
1204 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1205 u8 key_index, const u8 *mac_addr,
1206 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1207 struct key_params *params)
1211 struct ieee_param *param = NULL;
1213 struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
1214 _adapter *padapter = wiphy_to_adapter(wiphy);
1215 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1217 DBG_8723A(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
1218 DBG_8723A("cipher=0x%x\n", params->cipher);
1219 DBG_8723A("key_len=0x%x\n", params->key_len);
1220 DBG_8723A("seq_len=0x%x\n", params->seq_len);
1221 DBG_8723A("key_index=%d\n", key_index);
1222 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1223 DBG_8723A("pairwise=%d\n", pairwise);
1224 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1226 param_len = sizeof(struct ieee_param) + params->key_len;
1227 param = (struct ieee_param *)kmalloc(param_len, GFP_KERNEL);
1231 memset(param, 0, param_len);
1233 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1234 memset(param->sta_addr, 0xff, ETH_ALEN);
1236 switch (params->cipher) {
1237 case IW_AUTH_CIPHER_NONE:
1242 case WLAN_CIPHER_SUITE_WEP40:
1243 case WLAN_CIPHER_SUITE_WEP104:
1246 case WLAN_CIPHER_SUITE_TKIP:
1249 case WLAN_CIPHER_SUITE_CCMP:
1258 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1261 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1263 param->u.crypt.set_tx = 0; //for wpa/wpa2 group key
1265 param->u.crypt.set_tx = 1; //for wpa/wpa2 pairwise key
1269 //param->u.crypt.idx = key_index - 1;
1270 param->u.crypt.idx = key_index;
1272 if (params->seq_len && params->seq)
1274 memcpy(param->u.crypt.seq, params->seq, params->seq_len);
1277 if(params->key_len && params->key)
1279 param->u.crypt.key_len = params->key_len;
1280 memcpy(param->u.crypt.key, params->key, params->key_len);
1283 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1285 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
1287 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1289 #ifdef CONFIG_AP_MODE
1291 memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN);
1293 ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
1298 DBG_8723A("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
1312 static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
1313 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1314 u8 key_index, bool pairwise, const u8 *mac_addr,
1315 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1316 u8 key_index, const u8 *mac_addr,
1317 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1319 void (*callback)(void *cookie,
1320 struct key_params*))
1323 struct iwm_priv *iwm = ndev_to_iwm(ndev);
1324 struct iwm_key *key = &iwm->keys[key_index];
1325 struct key_params params;
1327 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
1329 memset(¶ms, 0, sizeof(params));
1331 params.cipher = key->cipher;
1332 params.key_len = key->key_len;
1333 params.seq_len = key->seq_len;
1334 params.seq = key->seq;
1335 params.key = key->key;
1337 callback(cookie, ¶ms);
1339 return key->key_len ? 0 : -ENOENT;
1341 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
1345 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
1346 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1347 u8 key_index, bool pairwise, const u8 *mac_addr)
1348 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1349 u8 key_index, const u8 *mac_addr)
1350 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1352 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1353 struct security_priv *psecuritypriv = &padapter->securitypriv;
1355 DBG_8723A(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index);
1357 if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
1359 //clear the flag of wep default key set.
1360 psecuritypriv->bWepDefaultKeyIdxSet = 0;
1366 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
1367 struct net_device *ndev, u8 key_index
1368 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1369 , bool unicast, bool multicast
1373 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1374 struct security_priv *psecuritypriv = &padapter->securitypriv;
1376 DBG_8723A(FUNC_NDEV_FMT" key_index=%d"
1377 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1378 ", unicast=%d, multicast=%d"
1380 ".\n", FUNC_NDEV_ARG(ndev), key_index
1381 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1382 , unicast, multicast
1386 if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) //set wep default key
1388 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1390 psecuritypriv->dot11PrivacyKeyIndex = key_index;
1392 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1393 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1394 if (psecuritypriv->dot11DefKeylen[key_index] == 13)
1396 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1397 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1400 psecuritypriv->bWepDefaultKeyIdxSet = 1; //set the flag to represent that wep default key has been set
1407 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
1408 struct net_device *ndev,
1409 u8 *mac, struct station_info *sinfo)
1412 _adapter *padapter = wiphy_to_adapter(wiphy);
1413 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1414 struct sta_info *psta = NULL;
1415 struct sta_priv *pstapriv = &padapter->stapriv;
1420 DBG_8723A(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
1425 psta = rtw_get_stainfo(pstapriv, mac);
1427 DBG_8723A("%s, sta_info is null\n", __func__);
1432 #ifdef CONFIG_DEBUG_CFG80211
1433 DBG_8723A(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
1436 //for infra./P2PClient mode
1437 if( check_fwstate(pmlmepriv, WIFI_STATION_STATE)
1438 && check_fwstate(pmlmepriv, _FW_LINKED)
1441 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
1443 if (memcmp(mac, cur_network->network.MacAddress, ETH_ALEN)) {
1444 DBG_8723A("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
1449 sinfo->filled |= STATION_INFO_SIGNAL;
1450 sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
1452 sinfo->filled |= STATION_INFO_TX_BITRATE;
1453 sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
1455 sinfo->filled |= STATION_INFO_RX_PACKETS;
1456 sinfo->rx_packets = sta_rx_data_pkts(psta);
1458 sinfo->filled |= STATION_INFO_TX_PACKETS;
1459 sinfo->tx_packets = psta->sta_stats.tx_pkts;
1463 //for Ad-Hoc/AP mode
1464 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
1465 ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
1466 ||check_fwstate(pmlmepriv, WIFI_AP_STATE))
1467 && check_fwstate(pmlmepriv, _FW_LINKED)
1470 //TODO: should acquire station info...
1477 extern int netdev_open(struct net_device *pnetdev);
1478 #ifdef CONFIG_CONCURRENT_MODE
1479 extern int netdev_if2_open(struct net_device *pnetdev);
1483 enum nl80211_iftype {
1484 NL80211_IFTYPE_UNSPECIFIED,
1485 NL80211_IFTYPE_ADHOC, //1
1486 NL80211_IFTYPE_STATION, //2
1487 NL80211_IFTYPE_AP, //3
1488 NL80211_IFTYPE_AP_VLAN,
1490 NL80211_IFTYPE_MONITOR, //6
1491 NL80211_IFTYPE_MESH_POINT,
1492 NL80211_IFTYPE_P2P_CLIENT, //8
1493 NL80211_IFTYPE_P2P_GO, //9
1495 NUM_NL80211_IFTYPES,
1496 NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
1499 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
1500 struct net_device *ndev,
1501 enum nl80211_iftype type, u32 *flags,
1502 struct vif_params *params)
1504 enum nl80211_iftype old_type;
1505 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
1506 _adapter *padapter = wiphy_to_adapter(wiphy);
1507 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1508 struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
1510 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
1515 #ifdef CONFIG_CONCURRENT_MODE
1516 if(padapter->adapter_type == SECONDARY_ADAPTER)
1518 DBG_8723A(FUNC_NDEV_FMT" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev));
1519 if(netdev_if2_open(ndev) != 0) {
1524 else if(padapter->adapter_type == PRIMARY_ADAPTER)
1525 #endif //CONFIG_CONCURRENT_MODE
1527 DBG_8723A(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
1528 if(netdev_open(ndev) != 0) {
1534 if(_FAIL == rtw_pwr_wakeup(padapter)) {
1539 old_type = rtw_wdev->iftype;
1540 DBG_8723A(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
1541 FUNC_NDEV_ARG(ndev), old_type, type);
1543 if(old_type != type)
1546 pmlmeext->action_public_rxseq = 0xffff;
1547 pmlmeext->action_public_dialog_token = 0xff;
1551 case NL80211_IFTYPE_ADHOC:
1552 networkType = Ndis802_11IBSS;
1554 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
1555 case NL80211_IFTYPE_P2P_CLIENT:
1557 case NL80211_IFTYPE_STATION:
1558 networkType = Ndis802_11Infrastructure;
1560 if(change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1562 _cancel_timer_ex( &pwdinfo->find_phase_timer );
1563 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
1564 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
1566 //it means remove GO and change mode from AP(GO) to station(P2P DEVICE)
1567 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1568 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
1570 DBG_8723A("%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));
1574 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
1575 case NL80211_IFTYPE_P2P_GO:
1577 case NL80211_IFTYPE_AP:
1578 networkType = Ndis802_11APMode;
1580 if(change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1582 //it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO)
1583 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1591 rtw_wdev->iftype = type;
1593 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE)
1595 rtw_wdev->iftype = old_type;
1600 rtw_setopmode_cmd(padapter, networkType);
1607 void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv, bool aborted)
1611 spin_lock_bh(&pwdev_priv->scan_req_lock);
1612 if(pwdev_priv->scan_request != NULL)
1614 //struct cfg80211_scan_request *scan_request = pwdev_priv->scan_request;
1616 #ifdef CONFIG_DEBUG_CFG80211
1617 DBG_8723A("%s with scan req\n", __FUNCTION__);
1620 //avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
1621 //if(scan_request == wiphy_to_dev(scan_request->wiphy)->scan_req)
1622 if(pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
1624 DBG_8723A("error wiphy compare\n");
1628 cfg80211_scan_done(pwdev_priv->scan_request, aborted);
1631 pwdev_priv->scan_request = NULL;
1634 #ifdef CONFIG_DEBUG_CFG80211
1635 DBG_8723A("%s without scan req\n", __FUNCTION__);
1638 spin_unlock_bh(&pwdev_priv->scan_req_lock);
1641 void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
1644 _list *plist, *phead;
1645 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1646 _queue *queue = &(pmlmepriv->scanned_queue);
1647 struct wlan_network *pnetwork = NULL;
1649 u32 wait_for_surveydone;
1652 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
1654 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
1655 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
1657 #ifdef CONFIG_DEBUG_CFG80211
1658 DBG_8723A("%s\n", __func__);
1661 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
1663 phead = get_list_head(queue);
1664 plist = get_next(phead);
1668 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
1671 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1673 //report network only if the current channel set contains the channel to which this network belongs
1674 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
1675 #ifdef CONFIG_VALIDATE_SSID
1676 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
1680 //ev=translate_scan(padapter, a, pnetwork, ev, stop);
1681 rtw_cfg80211_inform_bss(padapter, pnetwork);
1684 plist = get_next(plist);
1688 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
1690 //call this after other things have been done
1691 rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev), _FALSE);
1694 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
1703 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1705 #ifdef CONFIG_DEBUG_CFG80211
1706 DBG_8723A("%s, ielen=%d\n", __func__, len);
1711 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
1713 #ifdef CONFIG_DEBUG_CFG80211
1714 DBG_8723A("probe_req_wps_ielen=%d\n", wps_ielen);
1717 if(pmlmepriv->wps_probe_req_ie)
1719 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
1720 pmlmepriv->wps_probe_req_ie_len = 0;
1721 kfree(pmlmepriv->wps_probe_req_ie);
1722 pmlmepriv->wps_probe_req_ie = NULL;
1725 pmlmepriv->wps_probe_req_ie =
1726 kmalloc(wps_ielen, GFP_KERNEL);
1727 if ( pmlmepriv->wps_probe_req_ie == NULL) {
1728 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
1732 memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
1733 pmlmepriv->wps_probe_req_ie_len = wps_ielen;
1740 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
1742 #ifdef CONFIG_DEBUG_CFG80211
1743 DBG_8723A("probe_req_p2p_ielen=%d\n", p2p_ielen);
1746 if(pmlmepriv->p2p_probe_req_ie)
1748 u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
1749 pmlmepriv->p2p_probe_req_ie_len = 0;
1750 kfree(pmlmepriv->p2p_probe_req_ie);
1751 pmlmepriv->p2p_probe_req_ie = NULL;
1754 pmlmepriv->p2p_probe_req_ie =
1755 kmalloc(p2p_ielen, GFP_KERNEL);
1756 if ( pmlmepriv->p2p_probe_req_ie == NULL) {
1757 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
1761 memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
1762 pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
1770 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
1772 #ifdef CONFIG_DEBUG_CFG80211
1773 DBG_8723A("probe_req_wfd_ielen=%d\n", wfd_ielen);
1776 if(pmlmepriv->wfd_probe_req_ie)
1778 u32 free_len = pmlmepriv->wfd_probe_req_ie_len;
1779 pmlmepriv->wfd_probe_req_ie_len = 0;
1780 kfree(pmlmepriv->wfd_probe_req_ie);
1781 pmlmepriv->wfd_probe_req_ie = NULL;
1784 pmlmepriv->wfd_probe_req_ie =
1785 kmalloc(wfd_ielen, GFP_KERNEL);
1786 if ( pmlmepriv->wfd_probe_req_ie == NULL) {
1787 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
1791 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
1801 static int cfg80211_rtw_scan(struct wiphy *wiphy
1802 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
1803 , struct net_device *ndev
1805 , struct cfg80211_scan_request *request)
1808 u8 _status = _FALSE;
1810 _adapter *padapter = wiphy_to_adapter(wiphy);
1811 struct mlme_priv *pmlmepriv= &padapter->mlmepriv;
1812 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
1813 struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
1820 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
1822 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
1823 struct cfg80211_ssid *ssids = request->ssids;
1824 int social_channel = 0, j = 0;
1825 bool need_indicate_scan_done = _FALSE;
1826 #ifdef CONFIG_CONCURRENT_MODE
1827 PADAPTER pbuddy_adapter = NULL;
1828 struct mlme_priv *pbuddy_mlmepriv = NULL;
1829 #endif //CONFIG_CONCURRENT_MODE
1831 #ifdef CONFIG_DEBUG_CFG80211
1832 DBG_8723A(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
1835 #ifdef CONFIG_CONCURRENT_MODE
1836 if(rtw_buddy_adapter_up(padapter))
1838 pbuddy_adapter = padapter->pbuddy_adapter;
1839 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
1841 #endif //CONFIG_CONCURRENT_MODE
1843 spin_lock_bh(&pwdev_priv->scan_req_lock);
1844 pwdev_priv->scan_request = request;
1845 spin_unlock_bh(&pwdev_priv->scan_req_lock);
1847 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1850 #ifdef CONFIG_DEBUG_CFG80211
1851 DBG_8723A("%s under WIFI_AP_STATE\n", __FUNCTION__);
1853 //need_indicate_scan_done = _TRUE;
1854 //goto check_need_indicate_scan_done;
1857 if(_FAIL == rtw_pwr_wakeup(padapter)) {
1858 need_indicate_scan_done = _TRUE;
1859 goto check_need_indicate_scan_done;
1863 if (ssids->ssid != NULL &&
1864 !memcmp(ssids->ssid, "DIRECT-", 7) &&
1865 rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)) {
1866 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1868 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
1869 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = _TRUE;
1873 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
1874 #ifdef CONFIG_DEBUG_CFG80211
1875 DBG_8723A("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
1878 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
1880 if(request->n_channels == 3 &&
1881 request->channels[0]->hw_value == 1 &&
1882 request->channels[1]->hw_value == 6 &&
1883 request->channels[2]->hw_value == 11
1891 if(request->ie && request->ie_len>0)
1893 rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len );
1896 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)
1898 DBG_8723A("%s, bBusyTraffic == _TRUE\n", __func__);
1899 need_indicate_scan_done = _TRUE;
1900 goto check_need_indicate_scan_done;
1902 if (rtw_is_scan_deny(padapter)){
1903 DBG_8723A(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter));
1904 need_indicate_scan_done = _TRUE;
1905 goto check_need_indicate_scan_done;
1908 #ifdef CONFIG_CONCURRENT_MODE
1909 if(pbuddy_mlmepriv && (pbuddy_mlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))
1911 DBG_8723A("%s, bBusyTraffic == _TRUE at buddy_intf\n", __func__);
1912 need_indicate_scan_done = _TRUE;
1913 goto check_need_indicate_scan_done;
1915 #endif //CONFIG_CONCURRENT_MODE
1917 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
1919 DBG_8723A("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
1920 need_indicate_scan_done = _TRUE;
1921 goto check_need_indicate_scan_done;
1924 #ifdef CONFIG_CONCURRENT_MODE
1925 if (check_buddy_fwstate(padapter,
1926 _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
1928 if(check_buddy_fwstate(padapter, _FW_UNDER_SURVEY))
1930 DBG_8723A("scanning_via_buddy_intf\n");
1931 pmlmepriv->scanning_via_buddy_intf = _TRUE;
1934 DBG_8723A("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv->fw_state);
1936 need_indicate_scan_done = _TRUE;
1937 goto check_need_indicate_scan_done;
1943 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
1945 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
1946 rtw_free_network_queue(padapter, _TRUE);
1948 if(social_channel == 0)
1949 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
1951 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
1956 memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
1957 //parsing request ssids, n_ssids
1958 for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
1959 #ifdef CONFIG_DEBUG_CFG80211
1960 DBG_8723A("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
1962 memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
1963 ssid[i].SsidLength = ssids[i].ssid_len;
1967 /* parsing channels, n_channels */
1968 memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
1969 if (request->n_channels == 1)
1970 for (i=0;i<request->n_channels && i<RTW_CHANNEL_SCAN_AMOUNT;i++) {
1971 #ifdef CONFIG_DEBUG_CFG80211
1972 DBG_8723A(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
1974 ch[i].hw_value = request->channels[i]->hw_value;
1975 ch[i].flags = request->channels[i]->flags;
1978 spin_lock_bh(&pmlmepriv->lock);
1979 if (request->n_channels == 1) {
1980 memcpy(&ch[1], &ch[0], sizeof(struct rtw_ieee80211_channel));
1981 memcpy(&ch[2], &ch[0], sizeof(struct rtw_ieee80211_channel));
1982 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, 3);
1984 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
1986 spin_unlock_bh(&pmlmepriv->lock);
1989 if(_status == _FALSE)
1994 check_need_indicate_scan_done:
1995 if(need_indicate_scan_done)
1996 rtw_cfg80211_surveydone_event_callback(padapter);
2004 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
2007 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2009 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
2010 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
2013 iwm->conf.rts_threshold = wiphy->rts_threshold;
2015 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
2017 iwm->conf.rts_threshold);
2022 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
2023 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
2026 iwm->conf.frag_threshold = wiphy->frag_threshold;
2028 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
2030 iwm->conf.frag_threshold);
2035 DBG_8723A("%s\n", __func__);
2039 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
2040 struct cfg80211_ibss_params *params)
2043 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2044 struct ieee80211_channel *chan = params->channel;
2046 if (!test_bit(IWM_STATUS_READY, &iwm->status))
2049 /* UMAC doesn't support creating or joining an IBSS network
2050 * with specified bssid. */
2054 iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
2055 iwm->umac_profile->ibss.band = chan->band;
2056 iwm->umac_profile->ibss.channel = iwm->channel;
2057 iwm->umac_profile->ssid.ssid_len = params->ssid_len;
2058 memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
2060 return iwm_send_mlme_profile(iwm);
2062 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2066 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
2069 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2071 if (iwm->umac_profile_active)
2072 return iwm_invalidate_mlme_profile(iwm);
2074 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2078 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
2080 DBG_8723A("%s, wpa_version=%d\n", __func__, wpa_version);
2083 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2088 if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
2090 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
2094 if (wpa_version & NL80211_WPA_VERSION_2)
2096 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2104 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
2105 enum nl80211_auth_type sme_auth_type)
2107 DBG_8723A("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
2110 switch (sme_auth_type) {
2111 case NL80211_AUTHTYPE_AUTOMATIC:
2113 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2116 case NL80211_AUTHTYPE_OPEN_SYSTEM:
2118 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2120 if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
2121 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2124 case NL80211_AUTHTYPE_SHARED_KEY:
2126 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
2128 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
2133 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2141 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
2143 u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
2145 u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
2146 &psecuritypriv->dot118021XGrpPrivacy;
2148 DBG_8723A("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
2152 *profile_cipher = _NO_PRIVACY_;
2153 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
2158 case IW_AUTH_CIPHER_NONE:
2159 *profile_cipher = _NO_PRIVACY_;
2160 ndisencryptstatus = Ndis802_11EncryptionDisabled;
2162 case WLAN_CIPHER_SUITE_WEP40:
2163 *profile_cipher = _WEP40_;
2164 ndisencryptstatus = Ndis802_11Encryption1Enabled;
2166 case WLAN_CIPHER_SUITE_WEP104:
2167 *profile_cipher = _WEP104_;
2168 ndisencryptstatus = Ndis802_11Encryption1Enabled;
2170 case WLAN_CIPHER_SUITE_TKIP:
2171 *profile_cipher = _TKIP_;
2172 ndisencryptstatus = Ndis802_11Encryption2Enabled;
2174 case WLAN_CIPHER_SUITE_CCMP:
2175 *profile_cipher = _AES_;
2176 ndisencryptstatus = Ndis802_11Encryption3Enabled;
2179 DBG_8723A("Unsupported cipher: 0x%x\n", cipher);
2185 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
2187 //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
2188 // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2194 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
2196 DBG_8723A("%s, key_mgt=0x%x\n", __func__, key_mgt);
2198 if (key_mgt == WLAN_AKM_SUITE_8021X)
2199 //*auth_type = UMAC_AUTH_TYPE_8021X;
2200 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2201 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
2202 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2204 DBG_8723A("Invalid key mgt: 0x%x\n", key_mgt);
2211 static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
2213 u8 *buf=NULL, *pos=NULL;
2215 int group_cipher = 0, pairwise_cipher = 0;
2220 u8 null_addr[]= {0,0,0,0,0,0};
2222 if (pie == NULL || !ielen) {
2223 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
2224 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2228 if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
2233 buf = kzalloc(ielen, GFP_KERNEL);
2239 memcpy(buf, pie , ielen);
2244 DBG_8723A("set wpa_ie(length:%zu):\n", ielen);
2245 for(i=0;i<ielen;i=i+8)
2246 DBG_8723A("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]);
2250 if(ielen < RSN_HEADER_LEN){
2251 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
2256 pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
2257 if(pwpa && wpa_ielen>0)
2259 if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2261 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
2262 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
2263 memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
2265 DBG_8723A("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
2269 pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
2270 if(pwpa2 && wpa2_ielen>0)
2272 if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2274 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
2275 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
2276 memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
2278 DBG_8723A("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
2282 if (group_cipher == 0)
2284 group_cipher = WPA_CIPHER_NONE;
2286 if (pairwise_cipher == 0)
2288 pairwise_cipher = WPA_CIPHER_NONE;
2291 switch(group_cipher)
2293 case WPA_CIPHER_NONE:
2294 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
2295 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
2297 case WPA_CIPHER_WEP40:
2298 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
2299 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2301 case WPA_CIPHER_TKIP:
2302 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
2303 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
2305 case WPA_CIPHER_CCMP:
2306 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
2307 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
2309 case WPA_CIPHER_WEP104:
2310 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
2311 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2315 switch(pairwise_cipher)
2317 case WPA_CIPHER_NONE:
2318 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
2319 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
2321 case WPA_CIPHER_WEP40:
2322 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
2323 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2325 case WPA_CIPHER_TKIP:
2326 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
2327 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
2329 case WPA_CIPHER_CCMP:
2330 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
2331 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
2333 case WPA_CIPHER_WEP104:
2334 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
2335 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2339 {/* handle wps_ie */
2343 wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
2344 if (wps_ie && wps_ielen > 0) {
2345 DBG_8723A("got wps_ie, wps_ielen:%u\n", wps_ielen);
2346 padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
2347 memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
2348 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
2350 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2355 {//check p2p_ie for assoc req;
2358 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2360 if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen)))
2362 #ifdef CONFIG_DEBUG_CFG80211
2363 DBG_8723A("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
2366 if(pmlmepriv->p2p_assoc_req_ie)
2368 u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
2369 pmlmepriv->p2p_assoc_req_ie_len = 0;
2370 kfree(pmlmepriv->p2p_assoc_req_ie);
2371 pmlmepriv->p2p_assoc_req_ie = NULL;
2374 pmlmepriv->p2p_assoc_req_ie =
2375 kmalloc(p2p_ielen, GFP_KERNEL);
2376 if ( pmlmepriv->p2p_assoc_req_ie == NULL) {
2377 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
2380 memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
2381 pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
2387 {//check wfd_ie for assoc req;
2390 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2392 if(rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen))
2394 #ifdef CONFIG_DEBUG_CFG80211
2395 DBG_8723A("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
2398 if(pmlmepriv->wfd_assoc_req_ie)
2400 u32 free_len = pmlmepriv->wfd_assoc_req_ie_len;
2401 pmlmepriv->wfd_assoc_req_ie_len = 0;
2402 kfree(pmlmepriv->wfd_assoc_req_ie);
2403 pmlmepriv->wfd_assoc_req_ie = NULL;
2406 pmlmepriv->wfd_assoc_req_ie =
2407 kmalloc(wfd_ielen, GFP_KERNEL);
2408 if ( pmlmepriv->wfd_assoc_req_ie == NULL) {
2409 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
2412 rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
2417 //TKIP and AES disallow multicast packets until installing group key
2418 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
2419 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
2420 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
2421 //WPS open need to enable multicast
2422 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
2423 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
2425 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2426 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
2427 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
2433 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2437 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
2438 struct cfg80211_connect_params *sme)
2443 struct wlan_network *pnetwork = NULL;
2444 NDIS_802_11_AUTHENTICATION_MODE authmode;
2445 NDIS_802_11_SSID ndis_ssid;
2446 u8 *dst_ssid, *src_ssid;
2447 u8 *dst_bssid, *src_bssid;
2448 //u8 matched_by_bssid=_FALSE;
2449 //u8 matched_by_ssid=_FALSE;
2451 _adapter *padapter = wiphy_to_adapter(wiphy);
2452 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2453 struct security_priv *psecuritypriv = &padapter->securitypriv;
2454 _queue *queue = &pmlmepriv->scanned_queue;
2456 DBG_8723A("=>"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2457 DBG_8723A("privacy=%d, key=%p, key_len=%d, key_idx=%d\n",
2458 sme->privacy, sme->key, sme->key_len, sme->key_idx);
2461 if(wdev_to_priv(padapter->rtw_wdev)->block == _TRUE)
2464 DBG_8723A("%s wdev_priv.block is set\n", __FUNCTION__);
2468 if(_FAIL == rtw_pwr_wakeup(padapter)) {
2473 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2478 #ifdef CONFIG_CONCURRENT_MODE
2479 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
2480 DBG_8723A("%s, but buddy_intf is under linking\n", __FUNCTION__);
2484 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
2485 rtw_scan_abort(padapter->pbuddy_adapter);
2489 if (!sme->ssid || !sme->ssid_len)
2495 if (sme->ssid_len > IW_ESSID_MAX_SIZE){
2502 memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
2503 ndis_ssid.SsidLength = sme->ssid_len;
2504 memcpy(ndis_ssid.Ssid, sme->ssid, sme->ssid_len);
2506 DBG_8723A("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
2510 DBG_8723A("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
2513 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
2515 DBG_8723A("%s, fw_state=0x%x, goto exit\n", __FUNCTION__, pmlmepriv->fw_state);
2518 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
2519 rtw_scan_abort(padapter);
2522 spin_lock_bh(&queue->lock);
2524 phead = get_list_head(queue);
2525 pmlmepriv->pscanned = get_next(phead);
2529 if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE)
2534 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2535 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2537 dst_ssid = pnetwork->network.Ssid.Ssid;
2538 dst_bssid = pnetwork->network.MacAddress;
2541 if (memcmp(pnetwork->network.MacAddress,
2542 sme->bssid, ETH_ALEN))
2546 if(sme->ssid && sme->ssid_len) {
2547 if (pnetwork->network.Ssid.SsidLength != sme->ssid_len||
2548 memcmp(pnetwork->network.Ssid.Ssid, sme->ssid,
2556 src_bssid = sme->bssid;
2558 if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN)))
2560 DBG_8723A("matched by bssid\n");
2562 ndis_ssid.SsidLength = pnetwork->network.Ssid.SsidLength;
2563 memcpy(ndis_ssid.Ssid, pnetwork->network.Ssid.Ssid, pnetwork->network.Ssid.SsidLength);
2570 else if (sme->ssid && sme->ssid_len)
2572 src_ssid = ndis_ssid.Ssid;
2574 if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength)) &&
2575 (pnetwork->network.Ssid.SsidLength==ndis_ssid.SsidLength))
2577 DBG_8723A("matched by ssid\n");
2585 spin_unlock_bh(&queue->lock);
2587 if((matched == _FALSE) || (pnetwork== NULL))
2590 DBG_8723A("connect, matched == _FALSE, goto exit\n");
2595 if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == _FALSE)
2601 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
2602 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
2603 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2604 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
2605 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2607 ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
2611 ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
2616 DBG_8723A("%s, ie_len=%zu\n", __func__, sme->ie_len);
2618 ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len);
2622 if (sme->crypto.n_ciphers_pairwise) {
2623 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
2628 //For WEP Shared auth
2629 if((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared
2630 || psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && sme->key
2633 u32 wep_key_idx, wep_key_len,wep_total_len;
2634 NDIS_802_11_WEP *pwep = NULL;
2635 DBG_8723A("%s(): Shared/Auto WEP\n",__FUNCTION__);
2637 wep_key_idx = sme->key_idx;
2638 wep_key_len = sme->key_len;
2640 if (sme->key_idx > WEP_KEYS) {
2645 if (wep_key_len > 0)
2647 wep_key_len = wep_key_len <= 5 ? 5 : 13;
2648 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
2649 pwep =(NDIS_802_11_WEP *)kmalloc(wep_total_len,
2652 DBG_8723A(" wpa_set_encryption: pwep allocate fail !!!\n");
2657 memset(pwep, 0, wep_total_len);
2659 pwep->KeyLength = wep_key_len;
2660 pwep->Length = wep_total_len;
2664 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
2665 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
2673 pwep->KeyIndex = wep_key_idx;
2674 pwep->KeyIndex |= 0x80000000;
2676 memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
2678 if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
2691 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
2695 if (sme->crypto.n_akm_suites) {
2696 ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
2701 authmode = psecuritypriv->ndisauthtype;
2702 rtw_set_802_11_authentication_mode(padapter, authmode);
2704 //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
2706 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
2712 DBG_8723A("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy);
2716 DBG_8723A("<=%s, ret %d\n",__FUNCTION__, ret);
2721 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2724 _adapter *padapter = wiphy_to_adapter(wiphy);
2726 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2728 rtw_set_roaming(padapter, 0);
2730 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
2732 rtw_scan_abort(padapter);
2733 LeaveAllPowerSaveMode(padapter);
2734 rtw_disassoc_cmd(padapter, 500, _FALSE);
2736 DBG_8723A("%s...call rtw_indicate_disconnect\n", __FUNCTION__);
2738 padapter->mlmepriv.not_indic_disco = _TRUE;
2739 rtw_indicate_disconnect(padapter);
2740 padapter->mlmepriv.not_indic_disco = _FALSE;
2742 rtw_free_assoc_resources(padapter, 1);
2748 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
2749 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
2750 struct wireless_dev *wdev,
2752 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE)
2753 enum nl80211_tx_power_setting type, int mbm)
2755 enum tx_power_setting type, int dbm)
2759 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2763 case NL80211_TX_POWER_AUTOMATIC:
2765 case NL80211_TX_POWER_FIXED:
2766 if (mbm < 0 || (mbm % 100))
2769 if (!test_bit(IWM_STATUS_READY, &iwm->status))
2772 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
2773 CFG_TX_PWR_LIMIT_USR,
2774 MBM_TO_DBM(mbm) * 2);
2778 return iwm_tx_power_trigger(iwm);
2780 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
2784 DBG_8723A("%s\n", __func__);
2788 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
2789 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
2790 struct wireless_dev *wdev,
2794 //_adapter *padapter = wiphy_to_adapter(wiphy);
2796 DBG_8723A("%s\n", __func__);
2803 inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
2805 struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(adapter->rtw_wdev);
2806 return rtw_wdev_priv->power_mgmt;
2809 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
2810 struct net_device *ndev,
2811 bool enabled, int timeout)
2813 _adapter *padapter = wiphy_to_adapter(wiphy);
2814 struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(padapter->rtw_wdev);
2816 DBG_8723A(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
2819 rtw_wdev_priv->power_mgmt = enabled;
2823 LPS_Leave(padapter);
2829 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
2830 struct net_device *netdev,
2831 struct cfg80211_pmksa *pmksa)
2833 u8 index,blInserted = _FALSE;
2834 _adapter *padapter = wiphy_to_adapter(wiphy);
2835 struct security_priv *psecuritypriv = &padapter->securitypriv;
2836 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
2838 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev));
2840 if (!memcmp(pmksa->bssid, strZeroMacAddress, ETH_ALEN))
2845 blInserted = _FALSE;
2848 for(index=0 ; index<NUM_PMKID_CACHE; index++)
2850 if (!memcmp(psecuritypriv->PMKIDList[index].Bssid,
2851 pmksa->bssid, ETH_ALEN)) {
2852 /* BSSID is matched, the same AP => rewrite with new PMKID. */
2853 DBG_8723A(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(netdev));
2855 memcpy(psecuritypriv->PMKIDList[index].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2856 psecuritypriv->PMKIDList[index].bUsed = _TRUE;
2857 psecuritypriv->PMKIDIndex = index+1;
2866 DBG_8723A(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
2867 FUNC_NDEV_ARG(netdev), psecuritypriv->PMKIDIndex );
2869 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, pmksa->bssid, ETH_ALEN);
2870 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2872 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
2873 psecuritypriv->PMKIDIndex++ ;
2874 if(psecuritypriv->PMKIDIndex==16)
2876 psecuritypriv->PMKIDIndex =0;
2883 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
2884 struct net_device *netdev,
2885 struct cfg80211_pmksa *pmksa)
2887 u8 index, bMatched = _FALSE;
2888 _adapter *padapter = wiphy_to_adapter(wiphy);
2889 struct security_priv *psecuritypriv = &padapter->securitypriv;
2891 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev));
2893 for(index=0 ; index<NUM_PMKID_CACHE; index++)
2895 if (!memcmp(psecuritypriv->PMKIDList[index].Bssid,
2896 pmksa->bssid, ETH_ALEN)) {
2897 /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
2898 memset(psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN);
2899 memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN);
2900 psecuritypriv->PMKIDList[index].bUsed = _FALSE;
2906 if(_FALSE == bMatched)
2908 DBG_8723A(FUNC_NDEV_FMT" do not have matched BSSID\n"
2909 , FUNC_NDEV_ARG(netdev));
2916 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
2917 struct net_device *netdev)
2919 _adapter *padapter = wiphy_to_adapter(wiphy);
2920 struct security_priv *psecuritypriv = &padapter->securitypriv;
2922 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev));
2924 memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
2925 psecuritypriv->PMKIDIndex = 0;
2930 #ifdef CONFIG_AP_MODE
2931 void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
2935 struct wireless_dev *pwdev = padapter->rtw_wdev;
2936 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2937 struct net_device *ndev = padapter->pnetdev;
2939 DBG_8723A("%s(padapter=%p,%s)\n", __func__, padapter, ndev->name);
2941 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
2943 struct station_info sinfo;
2945 if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
2946 ie_offset = _ASOCREQ_IE_OFFSET_;
2947 else // WIFI_REASSOCREQ
2948 ie_offset = _REASOCREQ_IE_OFFSET_;
2951 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
2952 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
2953 sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
2954 cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
2956 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
2957 channel = pmlmeext->cur_channel;
2958 if (channel <= RTW_CH_MAX_2G_CHANNEL)
2959 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
2961 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
2963 #ifdef COMPAT_KERNEL_RELEASE
2964 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
2965 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
2966 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
2967 #else //COMPAT_KERNEL_RELEASE
2969 //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc()
2970 pwdev->iftype = NL80211_IFTYPE_STATION;
2971 DBG_8723A("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
2972 rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
2973 DBG_8723A("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
2974 pwdev->iftype = NL80211_IFTYPE_AP;
2975 //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
2977 #endif //COMPAT_KERNEL_RELEASE
2978 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
2982 void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason)
2988 struct rtw_ieee80211_hdr *pwlanhdr;
2989 unsigned short *fctrl;
2990 u8 mgmt_buf[128] = {0};
2991 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2992 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2993 struct net_device *ndev = padapter->pnetdev;
2995 DBG_8723A("%s(padapter=%p,%s)\n", __func__, padapter, ndev->name);
2997 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
2998 cfg80211_del_sta(ndev, da, GFP_ATOMIC);
2999 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
3000 channel = pmlmeext->cur_channel;
3001 if (channel <= RTW_CH_MAX_2G_CHANNEL)
3002 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3004 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3006 pmgmt_frame = mgmt_buf;
3007 pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
3009 fctrl = &(pwlanhdr->frame_ctl);
3012 //memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3013 //memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3014 memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
3015 memcpy(pwlanhdr->addr2, da, ETH_ALEN);
3016 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3018 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3019 pmlmeext->mgnt_seq++;
3020 SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
3022 pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
3023 frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
3025 reason = cpu_to_le16(reason);
3026 pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
3028 #ifdef COMPAT_KERNEL_RELEASE
3029 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
3030 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3031 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
3032 #else //COMPAT_KERNEL_RELEASE
3033 cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len);
3034 //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC);
3035 #endif //COMPAT_KERNEL_RELEASE
3036 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
3039 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
3043 DBG_8723A("%s\n", __func__);
3048 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
3052 DBG_8723A("%s\n", __func__);
3057 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
3062 int dot11_hdr_len = 24;
3064 unsigned char *pdata;
3066 unsigned char src_mac_addr[6];
3067 unsigned char dst_mac_addr[6];
3068 struct ieee80211_hdr *dot11_hdr;
3069 struct ieee80211_radiotap_header *rtap_hdr;
3070 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3072 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3074 if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
3077 rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
3078 if (unlikely(rtap_hdr->it_version))
3081 rtap_len = ieee80211_get_radiotap_len(skb->data);
3082 if (unlikely(skb->len < rtap_len))
3087 DBG_8723A("radiotap len (should be 14): %d\n", rtap_len);
3091 /* Skip the ratio tap header */
3092 skb_pull(skb, rtap_len);
3094 dot11_hdr = (struct ieee80211_hdr *)skb->data;
3095 frame_ctl = le16_to_cpu(dot11_hdr->frame_control);
3096 /* Check if the QoS bit is set */
3097 if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
3098 /* Check if this ia a Wireless Distribution System (WDS) frame
3099 * which has 4 MAC addresses
3101 if (dot11_hdr->frame_control & 0x0080)
3103 if ((dot11_hdr->frame_control & 0x0300) == 0x0300)
3106 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
3107 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
3109 /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
3110 * for two MAC addresses
3112 skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
3113 pdata = (unsigned char*)skb->data;
3114 memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
3115 memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
3117 DBG_8723A("should be eapol packet\n");
3119 /* Use the real net device to transmit the packet */
3120 ret = rtw_xmit_entry(skb, padapter->pnetdev);
3125 else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE))
3126 == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION)
3129 //only for action frames
3130 struct xmit_frame *pmgntframe;
3131 struct pkt_attrib *pattrib;
3132 unsigned char *pframe;
3133 //u8 category, action, OUI_Subtype, dialogToken=0;
3134 //unsigned char *frame_body;
3135 struct rtw_ieee80211_hdr *pwlanhdr;
3136 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3137 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3138 u8 *buf = skb->data;
3140 u8 category, action;
3143 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
3144 DBG_8723A(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
3145 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
3149 DBG_8723A("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
3150 MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
3152 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0)
3155 if (category == RTW_WLAN_CATEGORY_PUBLIC)
3156 DBG_8723A("RTW_Tx:%s\n", action_public_str(action));
3158 DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category, action);
3161 //starting alloc mgmt frame to dump it
3162 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3168 pattrib = &pmgntframe->attrib;
3169 update_mgntframe_attrib(padapter, pattrib);
3170 pattrib->retry_ctrl = _FALSE;
3172 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3174 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3176 memcpy(pframe, (void*)buf, len);
3180 struct wifi_display_info *pwfd_info;
3182 pwfd_info = padapter->wdinfo.wfd_info;
3184 if ( _TRUE == pwfd_info->wfd_enable )
3186 rtw_append_wfd_ie( padapter, pframe, &len );
3189 #endif // CONFIG_WFD
3190 pattrib->pktlen = len;
3192 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3194 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
3195 pattrib->seqnum = pmlmeext->mgnt_seq;
3196 pmlmeext->mgnt_seq++;
3199 pattrib->last_txcmdsz = pattrib->pktlen;
3201 dump_mgntframe(padapter, pmgntframe);
3206 DBG_8723A("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE));
3218 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
3220 DBG_8723A("%s\n", __func__);
3223 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
3227 DBG_8723A("%s\n", __func__);
3232 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
3233 .ndo_open = rtw_cfg80211_monitor_if_open,
3234 .ndo_stop = rtw_cfg80211_monitor_if_close,
3235 .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
3236 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
3237 .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
3239 .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
3242 static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
3245 struct net_device* mon_ndev = NULL;
3246 struct wireless_dev* mon_wdev = NULL;
3247 struct rtw_netdev_priv_indicator *pnpi;
3248 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
3251 DBG_8723A(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
3256 if (pwdev_priv->pmon_ndev) {
3257 DBG_8723A(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
3258 FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
3263 mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
3265 DBG_8723A(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
3270 mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
3271 strncpy(mon_ndev->name, name, IFNAMSIZ);
3272 mon_ndev->name[IFNAMSIZ - 1] = 0;
3273 mon_ndev->destructor = rtw_ndev_destructor;
3275 mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
3277 pnpi = netdev_priv(mon_ndev);
3278 pnpi->priv = padapter;
3279 pnpi->sizeof_priv = sizeof(_adapter);
3282 mon_wdev = (struct wireless_dev *)
3283 kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3285 DBG_8723A(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
3290 mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
3291 mon_wdev->netdev = mon_ndev;
3292 mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
3293 mon_ndev->ieee80211_ptr = mon_wdev;
3295 ret = register_netdevice(mon_ndev);
3300 *ndev = pwdev_priv->pmon_ndev = mon_ndev;
3301 memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
3304 if (ret && mon_wdev) {
3309 if (ret && mon_ndev) {
3310 free_netdev(mon_ndev);
3311 *ndev = mon_ndev = NULL;
3317 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3318 static struct wireless_dev *
3319 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
3320 static struct net_device *
3324 cfg80211_rtw_add_virtual_intf(
3325 struct wiphy *wiphy,
3326 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
3331 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
3334 struct net_device* ndev = NULL;
3335 _adapter *padapter = wiphy_to_adapter(wiphy);
3337 DBG_8723A(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
3338 FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
3341 case NL80211_IFTYPE_ADHOC:
3342 case NL80211_IFTYPE_AP_VLAN:
3343 case NL80211_IFTYPE_WDS:
3344 case NL80211_IFTYPE_MESH_POINT:
3347 case NL80211_IFTYPE_MONITOR:
3348 ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
3351 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3352 case NL80211_IFTYPE_P2P_CLIENT:
3354 case NL80211_IFTYPE_STATION:
3358 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3359 case NL80211_IFTYPE_P2P_GO:
3361 case NL80211_IFTYPE_AP:
3366 DBG_8723A("Unsupported interface type\n");
3370 DBG_8723A(FUNC_ADPT_FMT" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter), ndev, ret);
3372 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3373 return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
3374 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
3375 return ndev ? ndev : ERR_PTR(ret);
3381 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
3382 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3383 struct wireless_dev *wdev
3385 struct net_device *ndev
3389 struct rtw_wdev_priv *pwdev_priv = (struct rtw_wdev_priv *)wiphy_priv(wiphy);
3390 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3391 struct net_device *ndev;
3392 ndev = wdev ? wdev->netdev : NULL;
3398 unregister_netdevice(ndev);
3400 if (ndev == pwdev_priv->pmon_ndev) {
3401 pwdev_priv->pmon_ndev = NULL;
3402 pwdev_priv->ifname_mon[0] = '\0';
3403 DBG_8723A(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev));
3410 static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
3414 uint len, wps_ielen=0;
3417 u8 got_p2p_ie = _FALSE;
3418 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
3419 //struct sta_priv *pstapriv = &padapter->stapriv;
3422 DBG_8723A("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
3425 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
3432 pbuf = kzalloc(head_len+tail_len, GFP_KERNEL);
3437 //memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
3439 //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
3440 // pstapriv->max_num_sta = NUM_STA;
3443 memcpy(pbuf, (void *)head+24, head_len-24);// 24=beacon header len.
3444 memcpy(pbuf+head_len-24, (void *)tail, tail_len);
3446 len = head_len+tail_len-24;
3448 //check wps ie if inclued
3449 if(rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
3450 DBG_8723A("add bcn, wps_ielen=%d\n", wps_ielen);
3453 //check p2p ie if inclued
3454 if(rtw_get_p2p_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &p2p_ielen))
3456 DBG_8723A("got p2p_ie, len=%d\n", p2p_ielen);
3461 /* pbss_network->IEs will not include p2p_ie, wfd ie */
3462 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
3463 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
3465 if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS) {
3467 //check p2p if enable
3468 if(got_p2p_ie == _TRUE)
3470 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3471 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
3473 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3475 DBG_8723A("Enable P2P function for the first time\n");
3476 rtw_p2p_enable(adapter, P2P_ROLE_GO);
3477 wdev_to_priv(adapter->rtw_wdev)->p2p_enabled = _TRUE;
3481 _cancel_timer_ex( &pwdinfo->find_phase_timer );
3482 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
3483 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
3485 DBG_8723A("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);
3487 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
3488 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
3489 pwdinfo->intent = 15;
3492 pwdinfo->operating_channel = pmlmeext->cur_channel;
3511 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE)
3512 static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
3513 struct beacon_parameters *info)
3516 _adapter *adapter = wiphy_to_adapter(wiphy);
3518 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3519 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
3524 static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
3525 struct beacon_parameters *info)
3527 _adapter *padapter = wiphy_to_adapter(wiphy);
3528 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3530 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3532 pmlmeext->bstart_bss = _TRUE;
3534 cfg80211_rtw_add_beacon(wiphy, ndev, info);
3539 static int cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
3541 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3546 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3547 struct cfg80211_ap_settings *settings)
3550 _adapter *adapter = wiphy_to_adapter(wiphy);
3552 DBG_8723A(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
3553 settings->hidden_ssid, settings->auth_type);
3555 ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
3556 settings->beacon.tail, settings->beacon.tail_len);
3558 adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
3560 if (settings->ssid && settings->ssid_len) {
3561 WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
3562 WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
3565 DBG_8723A(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
3566 settings->ssid, settings->ssid_len,
3567 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
3569 memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
3570 pbss_network->Ssid.SsidLength = settings->ssid_len;
3571 memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
3572 pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
3575 DBG_8723A(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
3576 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
3577 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
3583 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3584 struct cfg80211_beacon_data *info)
3587 _adapter *adapter = wiphy_to_adapter(wiphy);
3589 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3591 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
3596 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3598 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3602 #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
3604 static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
3605 u8 *mac, struct station_parameters *params)
3607 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3612 static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
3617 _list *phead, *plist;
3619 struct sta_info *psta = NULL;
3620 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3621 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3622 struct sta_priv *pstapriv = &padapter->stapriv;
3624 DBG_8723A("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3626 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
3628 DBG_8723A("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
3635 DBG_8723A("flush all sta, and cam_entry\n");
3637 flush_all_cam_entry(padapter); //clear CAM
3639 ret = rtw_sta_flush(padapter);
3645 DBG_8723A("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
3647 if (mac[0] == 0xff && mac[1] == 0xff &&
3648 mac[2] == 0xff && mac[3] == 0xff &&
3649 mac[4] == 0xff && mac[5] == 0xff)
3655 spin_lock_bh(&pstapriv->asoc_list_lock);
3657 phead = &pstapriv->asoc_list;
3658 plist = get_next(phead);
3661 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
3663 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3665 plist = get_next(plist);
3667 if (!memcmp(mac, psta->hwaddr, ETH_ALEN))
3669 if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE)
3671 DBG_8723A("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
3675 DBG_8723A("free psta=%p, aid=%d\n", psta, psta->aid);
3677 list_del_init(&psta->asoc_list);
3678 pstapriv->asoc_list_cnt--;
3680 //spin_unlock_bh(&pstapriv->asoc_list_lock);
3681 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
3682 //spin_lock_bh(&pstapriv->asoc_list_lock);
3693 spin_unlock_bh(&pstapriv->asoc_list_lock);
3695 associated_clients_update(padapter, updated);
3697 DBG_8723A("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3703 static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
3704 u8 *mac, struct station_parameters *params)
3706 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3711 static int cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
3712 int idx, u8 *mac, struct station_info *sinfo)
3714 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3716 //TODO: dump scanned queue
3721 static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
3722 struct bss_parameters *params)
3726 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3728 DBG_8723A("use_cts_prot=%d\n", params->use_cts_prot);
3729 DBG_8723A("use_short_preamble=%d\n", params->use_short_preamble);
3730 DBG_8723A("use_short_slot_time=%d\n", params->use_short_slot_time);
3731 DBG_8723A("ap_isolate=%d\n", params->ap_isolate);
3733 DBG_8723A("basic_rates_len=%d\n", params->basic_rates_len);
3734 for(i=0; i<params->basic_rates_len; i++)
3736 DBG_8723A("basic_rates=%d\n", params->basic_rates[i]);
3744 static int cfg80211_rtw_set_channel(struct wiphy *wiphy
3745 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
3746 , struct net_device *ndev
3748 , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
3750 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
3751 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3757 static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
3758 struct cfg80211_auth_request *req)
3760 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3765 static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
3766 struct cfg80211_assoc_request *req)
3768 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3772 #endif //CONFIG_AP_MODE
3774 void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
3779 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3780 u8 category, action;
3782 channel = rtw_get_oper_ch(padapter);
3784 DBG_8723A("RTW_Rx:cur_ch=%d\n", channel);
3786 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
3790 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
3791 DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action);
3794 if (channel <= RTW_CH_MAX_2G_CHANNEL)
3795 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3797 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3799 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3800 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3802 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
3806 void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
3811 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3812 u8 category, action;
3814 channel = rtw_get_oper_ch(padapter);
3816 DBG_8723A("RTW_Rx:cur_ch=%d\n", channel);
3818 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
3821 case P2P_GO_NEGO_CONF:
3822 case P2P_PROVISION_DISC_RESP:
3823 rtw_clear_scan_deny(padapter);
3828 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
3829 DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action);
3832 if (channel <= RTW_CH_MAX_2G_CHANNEL)
3833 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3835 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3837 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3838 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3840 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
3844 void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg)
3848 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
3849 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(adapter->rtw_wdev);
3850 u8 category, action;
3852 channel = rtw_get_oper_ch(adapter);
3854 rtw_action_frame_parse(frame, frame_len, &category, &action);
3856 DBG_8723A("RTW_Rx:cur_ch=%d\n", channel);
3858 DBG_8723A("RTW_Rx:%s\n", msg);
3860 DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action);
3862 if (channel <= RTW_CH_MAX_2G_CHANNEL)
3863 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3865 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3867 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3868 rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
3870 cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
3876 void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
3878 u16 wps_devicepassword_id = 0x0000;
3879 uint wps_devicepassword_id_len = 0;
3880 u8 wpsie[ 255 ] = { 0x00 }, p2p_ie[ 255 ] = { 0x00 };
3883 u32 devinfo_contentlen = 0;
3884 u8 devinfo_content[64] = { 0x00 };
3886 uint capability_len = 0;
3888 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3889 u8 action = P2P_PUB_ACTION_ACTION;
3891 u32 p2poui = cpu_to_be32(P2POUI);
3892 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
3898 struct xmit_frame *pmgntframe;
3899 struct pkt_attrib *pattrib;
3900 unsigned char *pframe;
3901 struct rtw_ieee80211_hdr *pwlanhdr;
3902 unsigned short *fctrl;
3903 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3904 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3905 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3907 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3908 u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
3909 size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
3912 DBG_8723A( "[%s] In\n", __FUNCTION__ );
3914 //prepare for building provision_request frame
3915 memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
3916 memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
3918 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
3920 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
3921 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
3922 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
3924 switch(wps_devicepassword_id)
3927 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
3929 case WPS_DPID_USER_SPEC:
3930 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
3932 case WPS_DPID_MACHINE_SPEC:
3934 case WPS_DPID_REKEY:
3937 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
3939 case WPS_DPID_REGISTRAR_SPEC:
3940 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
3947 if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) )
3950 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);
3951 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&capability, &capability_len);
3956 //start to build provision_request frame
3957 memset(wpsie, 0, sizeof(wpsie));
3958 memset(p2p_ie, 0, sizeof(p2p_ie));
3961 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3968 pattrib = &pmgntframe->attrib;
3969 update_mgntframe_attrib(padapter, pattrib);
3971 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3973 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3974 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3976 fctrl = &(pwlanhdr->frame_ctl);
3979 memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
3980 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3981 memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
3983 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3984 pmlmeext->mgnt_seq++;
3985 SetFrameSubType(pframe, WIFI_ACTION);
3987 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3988 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3990 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3991 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3992 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3993 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3994 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
3997 //build_prov_disc_request_p2p_ie
4000 p2p_ie[ p2pielen++ ] = 0x50;
4001 p2p_ie[ p2pielen++ ] = 0x6F;
4002 p2p_ie[ p2pielen++ ] = 0x9A;
4003 p2p_ie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4005 // Commented by Albert 20110301
4006 // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
4007 // 1. P2P Capability
4009 // 3. Group ID ( When joining an operating P2P Group )
4011 // P2P Capability ATTR
4013 p2p_ie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4016 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4017 RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
4021 // Device Capability Bitmap, 1 byte
4022 // Group Capability Bitmap, 1 byte
4023 memcpy(p2p_ie + p2pielen, &capability, 2);
4029 p2p_ie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4032 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4033 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4034 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4035 RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
4039 memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
4040 p2pielen += devinfo_contentlen;
4043 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);
4044 //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr);
4045 //pframe += p2pielen;
4046 pattrib->pktlen += p2p_ielen;
4050 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4055 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4059 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4063 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
4067 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
4071 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4075 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
4078 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4082 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
4084 pattrib->pktlen += wfdielen;
4087 pattrib->last_txcmdsz = pattrib->pktlen;
4089 //dump_mgntframe(padapter, pmgntframe);
4090 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
4091 DBG_8723A("%s, ack to\n", __func__);
4093 //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
4095 // DBG_8723A("waiting for p2p peer key-in PIN CODE\n");
4096 // rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req.
4101 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
4102 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4103 struct wireless_dev *wdev,
4105 struct net_device *ndev,
4107 struct ieee80211_channel * channel,
4108 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4109 enum nl80211_channel_type channel_type,
4111 unsigned int duration, u64 *cookie)
4114 _adapter *padapter = wiphy_to_adapter(wiphy);
4115 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4116 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4117 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4118 struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4119 u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
4120 u8 ready_on_channel = _FALSE;
4122 DBG_8723A(FUNC_ADPT_FMT" ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter), remain_ch, duration);
4124 if(pcfg80211_wdinfo->is_ro_ch == _TRUE)
4126 DBG_8723A("%s, cancel ro ch timer\n", __func__);
4128 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4130 #ifdef CONFIG_CONCURRENT_MODE
4131 atomic_set(&pwdev_priv->ro_ch_to, 1);
4132 #endif //CONFIG_CONCURRENT_MODE
4134 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
4137 pcfg80211_wdinfo->is_ro_ch = _TRUE;
4139 if(_FAIL == rtw_pwr_wakeup(padapter)) {
4144 memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
4145 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4146 pcfg80211_wdinfo->remain_on_ch_type= channel_type;
4148 pcfg80211_wdinfo->remain_on_ch_cookie= *cookie;
4150 rtw_scan_abort(padapter);
4151 #ifdef CONFIG_CONCURRENT_MODE
4152 if(rtw_buddy_adapter_up(padapter))
4153 rtw_scan_abort(padapter->pbuddy_adapter);
4154 #endif //CONFIG_CONCURRENT_MODE
4156 //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
4157 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4159 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
4160 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = _TRUE;
4164 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4165 #ifdef CONFIG_DEBUG_CFG80211
4166 DBG_8723A("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
4171 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
4175 duration = duration*3;//extend from exper.
4178 #ifdef CONFIG_CONCURRENT_MODE
4179 if(check_buddy_fwstate(padapter, _FW_LINKED) &&
4180 (duration<pwdinfo->ext_listen_interval))
4182 duration = duration + pwdinfo->ext_listen_interval;
4186 pcfg80211_wdinfo->restore_channel = pmlmeext->cur_channel;
4188 if(rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) >= 0) {
4189 #ifdef CONFIG_CONCURRENT_MODE
4190 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4192 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
4193 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4195 if(remain_ch != pbuddy_mlmeext->cur_channel)
4197 if(atomic_read(&pwdev_priv->switch_ch_to)==1 ||
4198 (remain_ch != pmlmeext->cur_channel))
4200 DBG_8723A("%s, issue nulldata pwrbit=1\n", __func__);
4201 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
4203 atomic_set(&pwdev_priv->switch_ch_to, 0);
4205 DBG_8723A("%s, set switch ch timer, duration=%d\n", __func__, duration-pwdinfo->ext_listen_interval);
4206 _set_timer(&pwdinfo->ap_p2p_switch_timer, duration-pwdinfo->ext_listen_interval);
4210 ready_on_channel = _TRUE;
4211 //pmlmeext->cur_channel = remain_ch;
4212 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4214 #endif //CONFIG_CONCURRENT_MODE
4215 if(remain_ch != pmlmeext->cur_channel )
4217 ready_on_channel = _TRUE;
4218 //pmlmeext->cur_channel = remain_ch;
4219 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4222 DBG_8723A("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__, remain_ch);
4226 //call this after other things have been done
4227 #ifdef CONFIG_CONCURRENT_MODE
4228 if(atomic_read(&pwdev_priv->ro_ch_to)==1 ||
4229 (remain_ch != pmlmeext->cur_channel))
4231 u8 co_channel = 0xff;
4232 atomic_set(&pwdev_priv->ro_ch_to, 0);
4235 if(ready_on_channel == _TRUE)
4237 if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) )
4239 pmlmeext->cur_channel = remain_ch;
4242 set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4245 DBG_8723A("%s, set ro ch timer, duration=%d\n", __func__, duration);
4246 _set_timer( &pcfg80211_wdinfo->remain_on_ch_timer, duration);
4248 #ifdef CONFIG_CONCURRENT_MODE
4252 rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type, duration, GFP_KERNEL);
4254 pwdinfo->listen_channel = pmlmeext->cur_channel;
4258 pcfg80211_wdinfo->is_ro_ch = _FALSE;
4263 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
4264 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4265 struct wireless_dev *wdev,
4267 struct net_device *ndev,
4272 _adapter *padapter = wiphy_to_adapter(wiphy);
4273 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4274 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4275 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
4276 struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4278 DBG_8723A(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
4280 if (pcfg80211_wdinfo->is_ro_ch == _TRUE) {
4281 DBG_8723A("%s, cancel ro ch timer\n", __func__);
4282 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4283 #ifdef CONFIG_CONCURRENT_MODE
4284 atomic_set(&pwdev_priv->ro_ch_to, 1);
4286 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
4290 // Disable P2P Listen State
4291 if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
4293 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4295 _cancel_timer_ex( &pwdinfo->find_phase_timer );
4296 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
4297 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
4299 rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
4300 memset(pwdinfo, 0x00, sizeof(struct wifidirect_info));
4306 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
4307 #ifdef CONFIG_DEBUG_CFG80211
4308 DBG_8723A("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
4311 pcfg80211_wdinfo->is_ro_ch = _FALSE;
4318 static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, const u8 *buf, size_t len)
4320 struct xmit_frame *pmgntframe;
4321 struct pkt_attrib *pattrib;
4322 unsigned char *pframe;
4325 struct rtw_ieee80211_hdr *pwlanhdr;
4326 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4327 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4328 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4329 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4330 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4331 //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4333 if(_FAIL == rtw_pwr_wakeup(padapter)) {
4338 rtw_set_scan_deny(padapter, 1000);
4340 rtw_scan_abort(padapter);
4341 #ifdef CONFIG_CONCURRENT_MODE
4342 if(rtw_buddy_adapter_up(padapter))
4343 rtw_scan_abort(padapter->pbuddy_adapter);
4344 #endif /* CONFIG_CONCURRENT_MODE */
4346 if (padapter->cfg80211_wdinfo.is_ro_ch == _TRUE) {
4347 //DBG_8723A("%s, cancel ro ch timer\n", __func__);
4348 //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4349 //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE;
4350 #ifdef CONFIG_CONCURRENT_MODE
4351 DBG_8723A("%s, extend ro ch time\n", __func__);
4352 _set_timer( &padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
4353 #endif //CONFIG_CONCURRENT_MODE
4356 #ifdef CONFIG_CONCURRENT_MODE
4357 if (check_buddy_fwstate(padapter, _FW_LINKED )) {
4359 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
4360 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4362 co_channel = rtw_get_oper_ch(padapter);
4364 if (tx_ch != pbuddy_mlmeext->cur_channel) {
4365 if (atomic_read(&pwdev_priv->switch_ch_to)==1) {
4366 DBG_8723A("%s, issue nulldata pwrbit=1\n", __func__);
4367 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
4369 atomic_set(&pwdev_priv->switch_ch_to, 0);
4371 //DBG_8723A("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
4372 //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
4375 DBG_8723A("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
4376 _set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
4379 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
4380 pmlmeext->cur_channel = tx_ch;
4382 if (tx_ch != co_channel)
4383 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4385 #endif //CONFIG_CONCURRENT_MODE
4386 //if (tx_ch != pmlmeext->cur_channel) {
4387 if(tx_ch != rtw_get_oper_ch(padapter)) {
4388 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
4389 pmlmeext->cur_channel = tx_ch;
4390 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4393 //starting alloc mgmt frame to dump it
4394 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4402 pattrib = &pmgntframe->attrib;
4403 update_mgntframe_attrib(padapter, pattrib);
4404 pattrib->retry_ctrl = _FALSE;
4406 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4408 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4410 memcpy(pframe, (void*)buf, len);
4411 pattrib->pktlen = len;
4413 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4415 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
4416 pattrib->seqnum = pmlmeext->mgnt_seq;
4417 pmlmeext->mgnt_seq++;
4421 struct wifi_display_info *pwfd_info;
4423 pwfd_info = padapter->wdinfo.wfd_info;
4425 if ( _TRUE == pwfd_info->wfd_enable )
4427 rtw_append_wfd_ie( padapter, pframe, &pattrib->pktlen );
4430 #endif // CONFIG_WFD
4432 pattrib->last_txcmdsz = pattrib->pktlen;
4434 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
4439 #ifdef CONFIG_DEBUG_CFG80211
4440 DBG_8723A("%s, ack == _FAIL\n", __func__);
4445 #ifdef CONFIG_DEBUG_CFG80211
4446 DBG_8723A("%s, ack=%d, ok!\n", __func__, ack);
4453 #ifdef CONFIG_DEBUG_CFG80211
4454 DBG_8723A("%s, ret=%d\n", __func__, ret);
4461 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
4462 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4463 struct wireless_dev *wdev,
4465 struct net_device *ndev,
4467 struct ieee80211_channel *chan,
4468 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
4471 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4472 enum nl80211_channel_type channel_type,
4473 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4474 bool channel_type_valid,
4477 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
4480 const u8 *buf, size_t len,
4481 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
4484 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
4485 bool dont_wait_for_ack,
4489 _adapter *padapter = (_adapter *)wiphy_to_adapter(wiphy);
4490 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4493 u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
4496 u8 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
4497 u8 category, action;
4499 u32 start = rtw_get_current_time();
4501 /* cookie generation */
4502 *cookie = (unsigned long) buf;
4504 #ifdef CONFIG_DEBUG_CFG80211
4505 DBG_8723A(FUNC_ADPT_FMT" len=%zu, ch=%d"
4506 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4508 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4509 ", channel_type_valid=%d"
4512 "\n", FUNC_ADPT_ARG(padapter),
4514 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4516 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4517 , channel_type_valid
4521 #endif /* CONFIG_DEBUG_CFG80211 */
4523 /* indicate ack before issue frame to avoid racing with rsp frame */
4524 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4525 rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL);
4526 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
4527 cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
4530 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
4531 DBG_8723A(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
4532 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
4536 DBG_8723A("RTW_Tx:tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
4538 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0)
4541 if (category == RTW_WLAN_CATEGORY_PUBLIC)
4542 DBG_8723A("RTW_Tx:%s\n", action_public_str(action));
4544 DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category, action);
4549 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
4550 } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
4552 if (tx_ret != _SUCCESS || dump_cnt > 1) {
4553 DBG_8723A(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
4554 tx_ret==_SUCCESS?"OK":"FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
4558 case P2P_GO_NEGO_CONF:
4559 rtw_clear_scan_deny(padapter);
4561 case P2P_INVIT_RESP:
4562 if (pwdev_priv->invit_info.flags & BIT(0)
4563 && pwdev_priv->invit_info.status == 0)
4565 DBG_8723A(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
4566 FUNC_ADPT_ARG(padapter));
4567 rtw_set_scan_deny(padapter, 5000);
4568 rtw_pwr_wakeup_ex(padapter, 5000);
4569 rtw_clear_scan_deny(padapter);
4578 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
4579 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
4580 struct wireless_dev *wdev,
4582 struct net_device *ndev,
4584 u16 frame_type, bool reg)
4586 _adapter *adapter = wiphy_to_adapter(wiphy);
4588 #ifdef CONFIG_DEBUG_CFG80211
4589 DBG_8723A(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
4593 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
4599 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
4605 u8 wps_oui[8]={0x0,0x50,0xf2,0x04};
4609 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4610 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4611 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4613 DBG_8723A(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
4617 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
4619 #ifdef CONFIG_DEBUG_CFG80211
4620 DBG_8723A("bcn_wps_ielen=%d\n", wps_ielen);
4623 if(pmlmepriv->wps_beacon_ie)
4625 u32 free_len = pmlmepriv->wps_beacon_ie_len;
4626 pmlmepriv->wps_beacon_ie_len = 0;
4627 kfree(pmlmepriv->wps_beacon_ie);
4628 pmlmepriv->wps_beacon_ie = NULL;
4631 pmlmepriv->wps_beacon_ie =
4632 kmalloc(wps_ielen, GFP_KERNEL);
4633 if ( pmlmepriv->wps_beacon_ie == NULL) {
4634 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4639 memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
4640 pmlmepriv->wps_beacon_ie_len = wps_ielen;
4642 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
4650 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
4652 #ifdef CONFIG_DEBUG_CFG80211
4653 DBG_8723A("bcn_p2p_ielen=%d\n", p2p_ielen);
4656 if(pmlmepriv->p2p_beacon_ie)
4658 u32 free_len = pmlmepriv->p2p_beacon_ie_len;
4659 pmlmepriv->p2p_beacon_ie_len = 0;
4660 kfree(pmlmepriv->p2p_beacon_ie);
4661 pmlmepriv->p2p_beacon_ie = NULL;
4664 pmlmepriv->p2p_beacon_ie =
4665 kmalloc(p2p_ielen, GFP_KERNEL);
4666 if ( pmlmepriv->p2p_beacon_ie == NULL) {
4667 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4672 memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
4673 pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
4682 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
4684 #ifdef CONFIG_DEBUG_CFG80211
4685 DBG_8723A("bcn_wfd_ielen=%d\n", wfd_ielen);
4688 if(pmlmepriv->wfd_beacon_ie)
4690 u32 free_len = pmlmepriv->wfd_beacon_ie_len;
4691 pmlmepriv->wfd_beacon_ie_len = 0;
4692 kfree(pmlmepriv->wfd_beacon_ie);
4693 pmlmepriv->wfd_beacon_ie = NULL;
4696 pmlmepriv->wfd_beacon_ie = kmalloc(wfd_ielen);
4697 if ( pmlmepriv->wfd_beacon_ie == NULL) {
4698 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4702 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
4706 pmlmeext->bstart_bss = _TRUE;
4714 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
4723 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
4724 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4726 #ifdef CONFIG_DEBUG_CFG80211
4727 DBG_8723A("%s, ielen=%d\n", __func__, len);
4732 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
4734 uint attr_contentlen = 0;
4735 u16 uconfig_method, *puconfig_method = NULL;
4737 #ifdef CONFIG_DEBUG_CFG80211
4738 DBG_8723A("probe_resp_wps_ielen=%d\n", wps_ielen);
4741 if(pmlmepriv->wps_probe_resp_ie)
4743 u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
4744 pmlmepriv->wps_probe_resp_ie_len = 0;
4745 kfree(pmlmepriv->wps_probe_resp_ie);
4746 pmlmepriv->wps_probe_resp_ie = NULL;
4749 pmlmepriv->wps_probe_resp_ie = kmalloc(wps_ielen);
4750 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
4751 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4756 //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode
4757 if ( (puconfig_method = (u16*)rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen)) != NULL )
4759 #ifdef CONFIG_DEBUG_CFG80211
4760 //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method));
4763 uconfig_method = WPS_CM_PUSH_BUTTON;
4764 uconfig_method = cpu_to_be16( uconfig_method );
4766 *puconfig_method |= uconfig_method;
4769 memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
4770 pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
4778 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
4781 u32 attr_contentlen = 0;
4784 #ifdef CONFIG_DEBUG_CFG80211
4785 DBG_8723A("probe_resp_p2p_ielen=%d\n", p2p_ielen);
4788 //Check P2P Capability ATTR
4789 if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) )
4792 //DBG_8723A( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
4793 cap_attr = le16_to_cpu(cap_attr);
4794 grp_cap = (u8)((cap_attr >> 8)&0xff);
4796 is_GO = (grp_cap&BIT(0)) ? _TRUE:_FALSE;
4799 DBG_8723A("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
4805 if(pmlmepriv->p2p_probe_resp_ie)
4807 u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
4808 pmlmepriv->p2p_probe_resp_ie_len = 0;
4809 kfree(pmlmepriv->p2p_probe_resp_ie);
4810 pmlmepriv->p2p_probe_resp_ie = NULL;
4813 pmlmepriv->p2p_probe_resp_ie = kmalloc(p2p_ielen);
4814 if ( pmlmepriv->p2p_probe_resp_ie == NULL) {
4815 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4819 memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
4820 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
4824 if(pmlmepriv->p2p_go_probe_resp_ie)
4826 u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
4827 pmlmepriv->p2p_go_probe_resp_ie_len = 0;
4828 kfree(pmlmepriv->p2p_go_probe_resp_ie);
4829 pmlmepriv->p2p_go_probe_resp_ie = NULL;
4832 pmlmepriv->p2p_go_probe_resp_ie = kmalloc(p2p_ielen);
4833 if ( pmlmepriv->p2p_go_probe_resp_ie == NULL) {
4834 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4838 memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
4839 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
4849 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
4851 #ifdef CONFIG_DEBUG_CFG80211
4852 DBG_8723A("probe_resp_wfd_ielen=%d\n", wfd_ielen);
4855 if(pmlmepriv->wfd_probe_resp_ie)
4857 u32 free_len = pmlmepriv->wfd_probe_resp_ie_len;
4858 pmlmepriv->wfd_probe_resp_ie_len = 0;
4859 kfree(pmlmepriv->wfd_probe_resp_ie);
4860 pmlmepriv->wfd_probe_resp_ie = NULL;
4863 pmlmepriv->wfd_probe_resp_ie = kmalloc(wfd_ielen);
4864 if ( pmlmepriv->wfd_probe_resp_ie == NULL) {
4865 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4869 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
4879 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
4882 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
4883 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4885 DBG_8723A("%s, ielen=%d\n", __func__, len);
4889 if(pmlmepriv->wps_assoc_resp_ie)
4891 u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
4892 pmlmepriv->wps_assoc_resp_ie_len = 0;
4893 kfree(pmlmepriv->wps_assoc_resp_ie);
4894 pmlmepriv->wps_assoc_resp_ie = NULL;
4897 pmlmepriv->wps_assoc_resp_ie = kmalloc(len);
4898 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
4899 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4903 memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len);
4904 pmlmepriv->wps_assoc_resp_ie_len = len;
4911 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
4918 #ifdef CONFIG_DEBUG_CFG80211
4919 DBG_8723A("%s, ielen=%d\n", __func__, len);
4922 if( (rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen>0))
4924 || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen>0))
4933 ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
4935 case 0x2: //PROBE_RESP
4936 ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
4938 case 0x4: //ASSOC_RESP
4939 ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
4949 static struct cfg80211_ops rtw_cfg80211_ops = {
4950 .change_virtual_intf = cfg80211_rtw_change_iface,
4951 .add_key = cfg80211_rtw_add_key,
4952 .get_key = cfg80211_rtw_get_key,
4953 .del_key = cfg80211_rtw_del_key,
4954 .set_default_key = cfg80211_rtw_set_default_key,
4955 .get_station = cfg80211_rtw_get_station,
4956 .scan = cfg80211_rtw_scan,
4957 .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
4958 .connect = cfg80211_rtw_connect,
4959 .disconnect = cfg80211_rtw_disconnect,
4960 .join_ibss = cfg80211_rtw_join_ibss,
4961 .leave_ibss = cfg80211_rtw_leave_ibss,
4962 .set_tx_power = cfg80211_rtw_set_txpower,
4963 .get_tx_power = cfg80211_rtw_get_txpower,
4964 .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
4965 .set_pmksa = cfg80211_rtw_set_pmksa,
4966 .del_pmksa = cfg80211_rtw_del_pmksa,
4967 .flush_pmksa = cfg80211_rtw_flush_pmksa,
4969 #ifdef CONFIG_AP_MODE
4970 .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
4971 .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
4973 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
4974 .add_beacon = cfg80211_rtw_add_beacon,
4975 .set_beacon = cfg80211_rtw_set_beacon,
4976 .del_beacon = cfg80211_rtw_del_beacon,
4978 .start_ap = cfg80211_rtw_start_ap,
4979 .change_beacon = cfg80211_rtw_change_beacon,
4980 .stop_ap = cfg80211_rtw_stop_ap,
4983 .add_station = cfg80211_rtw_add_station,
4984 .del_station = cfg80211_rtw_del_station,
4985 .change_station = cfg80211_rtw_change_station,
4986 .dump_station = cfg80211_rtw_dump_station,
4987 .change_bss = cfg80211_rtw_change_bss,
4988 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
4989 .set_channel = cfg80211_rtw_set_channel,
4991 //.auth = cfg80211_rtw_auth,
4992 //.assoc = cfg80211_rtw_assoc,
4993 #endif //CONFIG_AP_MODE
4996 .remain_on_channel = cfg80211_rtw_remain_on_channel,
4997 .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
5000 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
5001 .mgmt_tx = cfg80211_rtw_mgmt_tx,
5002 .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
5003 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
5004 .action = cfg80211_rtw_mgmt_tx,
5008 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
5011 #define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
5012 #define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
5014 ht_cap->ht_supported = _TRUE;
5016 ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
5017 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
5018 IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
5021 *Maximum length of AMPDU that the STA can receive.
5022 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
5024 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5026 /*Minimum MPDU start spacing , */
5027 ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5029 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5032 *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
5035 *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
5036 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
5037 *if rx_ant >=3 rx_mask[2]=0xff;
5038 *if BW_40 rx_mask[4]=0x01;
5039 *highest supported RX rate
5041 if(rf_type == RF_1T1R)
5043 ht_cap->mcs.rx_mask[0] = 0xFF;
5044 ht_cap->mcs.rx_mask[1] = 0x00;
5045 ht_cap->mcs.rx_mask[4] = 0x01;
5047 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
5049 else if((rf_type == RF_1T2R) || (rf_type==RF_2T2R))
5051 ht_cap->mcs.rx_mask[0] = 0xFF;
5052 ht_cap->mcs.rx_mask[1] = 0xFF;
5053 ht_cap->mcs.rx_mask[4] = 0x01;
5055 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
5059 DBG_8723A("%s, error rf_type=%d\n", __func__, rf_type);
5064 void rtw_cfg80211_init_wiphy(_adapter *padapter)
5067 struct ieee80211_supported_band *bands;
5068 struct wireless_dev *pwdev = padapter->rtw_wdev;
5069 struct wiphy *wiphy = pwdev->wiphy;
5071 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
5073 DBG_8723A("%s:rf_type=%d\n", __func__, rf_type);
5075 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
5077 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
5079 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type);
5082 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
5084 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
5086 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type);
5091 struct ieee80211_iface_limit rtw_limits[] = {
5092 { .max = 1, .types = BIT(NL80211_IFTYPE_STATION)
5093 | BIT(NL80211_IFTYPE_ADHOC)
5094 #ifdef CONFIG_AP_MODE
5095 | BIT(NL80211_IFTYPE_AP)
5097 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
5098 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5099 | BIT(NL80211_IFTYPE_P2P_GO)
5102 {.max = 1, .types = BIT(NL80211_IFTYPE_MONITOR)},
5105 struct ieee80211_iface_combination rtw_combinations = {
5106 .limits = rtw_limits,
5107 .n_limits = ARRAY_SIZE(rtw_limits),
5108 .max_interfaces = 2,
5109 .num_different_channels = 1,
5113 static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy)
5116 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5118 wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
5119 wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
5120 wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
5122 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
5123 wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
5126 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
5127 | BIT(NL80211_IFTYPE_ADHOC)
5128 #ifdef CONFIG_AP_MODE
5129 | BIT(NL80211_IFTYPE_AP)
5130 | BIT(NL80211_IFTYPE_MONITOR)
5132 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
5133 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5134 | BIT(NL80211_IFTYPE_P2P_GO)
5138 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
5139 #ifdef CONFIG_AP_MODE
5140 wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
5141 #endif //CONFIG_AP_MODE
5144 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
5145 wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
5149 wiphy->iface_combinations = &rtw_combinations;
5150 wiphy->n_iface_combinations = 1;
5153 wiphy->cipher_suites = rtw_cipher_suites;
5154 wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
5156 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
5157 wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
5158 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
5159 wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
5161 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
5162 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
5165 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
5166 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
5167 wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
5170 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
5171 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
5173 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
5176 int rtw_wdev_alloc(_adapter *padapter, struct device *dev)
5179 struct wiphy *wiphy;
5180 struct wireless_dev *wdev;
5181 struct rtw_wdev_priv *pwdev_priv;
5182 struct net_device *pnetdev = padapter->pnetdev;
5184 DBG_8723A("%s(padapter=%p)\n", __func__, padapter);
5187 wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wdev_priv));
5189 DBG_8723A("Couldn't allocate wiphy device\n");
5193 set_wiphy_dev(wiphy, dev);
5194 rtw_cfg80211_preinit_wiphy(padapter, wiphy);
5196 ret = wiphy_register(wiphy);
5198 DBG_8723A("Couldn't register wiphy device\n");
5203 wdev = (struct wireless_dev *)kzalloc(sizeof(struct wireless_dev));
5205 DBG_8723A("Couldn't allocate wireless device\n");
5207 goto unregister_wiphy;
5209 wdev->wiphy = wiphy;
5210 wdev->netdev = pnetdev;
5211 //wdev->iftype = NL80211_IFTYPE_STATION;
5212 wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
5213 padapter->rtw_wdev = wdev;
5214 pnetdev->ieee80211_ptr = wdev;
5217 pwdev_priv = wdev_to_priv(wdev);
5218 pwdev_priv->rtw_wdev = wdev;
5219 pwdev_priv->pmon_ndev = NULL;
5220 pwdev_priv->ifname_mon[0] = '\0';
5221 pwdev_priv->padapter = padapter;
5222 pwdev_priv->scan_request = NULL;
5223 spin_lock_init(&pwdev_priv->scan_req_lock);
5225 pwdev_priv->p2p_enabled = _FALSE;
5226 pwdev_priv->provdisc_req_issued = _FALSE;
5227 rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
5229 pwdev_priv->bandroid_scan = _FALSE;
5231 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
5232 pwdev_priv->power_mgmt = _TRUE;
5234 pwdev_priv->power_mgmt = _FALSE;
5236 #ifdef CONFIG_CONCURRENT_MODE
5237 atomic_set(&pwdev_priv->switch_ch_to, 1);
5238 atomic_set(&pwdev_priv->ro_ch_to, 1);
5245 wiphy_unregister(wiphy);
5253 void rtw_wdev_free(struct wireless_dev *wdev)
5255 struct rtw_wdev_priv *pwdev_priv;
5257 DBG_8723A("%s(wdev=%p)\n", __func__, wdev);
5262 pwdev_priv = wdev_to_priv(wdev);
5264 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
5265 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
5267 wiphy_free(wdev->wiphy);
5272 void rtw_wdev_unregister(struct wireless_dev *wdev)
5274 struct rtw_wdev_priv *pwdev_priv;
5276 DBG_8723A("%s(wdev=%p)\n", __func__, wdev);
5281 pwdev_priv = wdev_to_priv(wdev);
5283 rtw_cfg80211_indicate_scan_done(pwdev_priv, _TRUE);
5285 if (pwdev_priv->pmon_ndev) {
5286 DBG_8723A("%s, unregister monitor interface\n", __func__);
5287 unregister_netdev(pwdev_priv->pmon_ndev);
5290 wiphy_unregister(wdev->wiphy);
5293 #endif //CONFIG_IOCTL_CFG80211