1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
20 #define _IOCTL_CFG80211_C_
23 #include <osdep_service.h>
24 #include <drv_types.h>
25 #include <rtw_ioctl.h>
26 #include <rtw_ioctl_set.h>
27 #include <rtw_ioctl_query.h>
28 #include <xmit_osdep.h>
30 #ifdef CONFIG_IOCTL_CFG80211
32 #include "ioctl_cfg80211.h"
34 #define RTW_MAX_MGMT_TX_CNT (8)
36 #define RTW_SCAN_IE_LEN_MAX 2304
37 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535 //ms
38 #define RTW_MAX_NUM_PMKIDS 4
40 #define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
42 static const u32 rtw_cipher_suites[] = {
43 WLAN_CIPHER_SUITE_WEP40,
44 WLAN_CIPHER_SUITE_WEP104,
45 WLAN_CIPHER_SUITE_TKIP,
46 WLAN_CIPHER_SUITE_CCMP,
49 #define RATETAB_ENT(_rate, _rateid, _flags) \
52 .hw_value = (_rateid), \
56 #define CHAN2G(_channel, _freq, _flags) { \
57 .band = IEEE80211_BAND_2GHZ, \
58 .center_freq = (_freq), \
59 .hw_value = (_channel), \
61 .max_antenna_gain = 0, \
65 #define CHAN5G(_channel, _flags) { \
66 .band = IEEE80211_BAND_5GHZ, \
67 .center_freq = 5000 + (5 * (_channel)), \
68 .hw_value = (_channel), \
70 .max_antenna_gain = 0, \
74 static struct ieee80211_rate rtw_rates[] = {
75 RATETAB_ENT(10, 0x1, 0),
76 RATETAB_ENT(20, 0x2, 0),
77 RATETAB_ENT(55, 0x4, 0),
78 RATETAB_ENT(110, 0x8, 0),
79 RATETAB_ENT(60, 0x10, 0),
80 RATETAB_ENT(90, 0x20, 0),
81 RATETAB_ENT(120, 0x40, 0),
82 RATETAB_ENT(180, 0x80, 0),
83 RATETAB_ENT(240, 0x100, 0),
84 RATETAB_ENT(360, 0x200, 0),
85 RATETAB_ENT(480, 0x400, 0),
86 RATETAB_ENT(540, 0x800, 0),
89 #define rtw_a_rates (rtw_rates + 4)
90 #define RTW_A_RATES_NUM 8
91 #define rtw_g_rates (rtw_rates + 0)
92 #define RTW_G_RATES_NUM 12
94 #define RTW_2G_CHANNELS_NUM 14
95 #define RTW_5G_CHANNELS_NUM 37
97 static struct ieee80211_channel rtw_2ghz_channels[] = {
114 static struct ieee80211_channel rtw_5ghz_a_channels[] = {
115 CHAN5G(34, 0), CHAN5G(36, 0),
116 CHAN5G(38, 0), CHAN5G(40, 0),
117 CHAN5G(42, 0), CHAN5G(44, 0),
118 CHAN5G(46, 0), CHAN5G(48, 0),
119 CHAN5G(52, 0), CHAN5G(56, 0),
120 CHAN5G(60, 0), CHAN5G(64, 0),
121 CHAN5G(100, 0), CHAN5G(104, 0),
122 CHAN5G(108, 0), CHAN5G(112, 0),
123 CHAN5G(116, 0), CHAN5G(120, 0),
124 CHAN5G(124, 0), CHAN5G(128, 0),
125 CHAN5G(132, 0), CHAN5G(136, 0),
126 CHAN5G(140, 0), CHAN5G(149, 0),
127 CHAN5G(153, 0), CHAN5G(157, 0),
128 CHAN5G(161, 0), CHAN5G(165, 0),
129 CHAN5G(184, 0), CHAN5G(188, 0),
130 CHAN5G(192, 0), CHAN5G(196, 0),
131 CHAN5G(200, 0), CHAN5G(204, 0),
132 CHAN5G(208, 0), CHAN5G(212, 0),
137 void rtw_2g_channels_init(struct ieee80211_channel *channels)
139 _rtw_memcpy((void*)channels, (void*)rtw_2ghz_channels,
140 sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
144 void rtw_5g_channels_init(struct ieee80211_channel *channels)
146 _rtw_memcpy((void*)channels, (void*)rtw_5ghz_a_channels,
147 sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
151 void rtw_2g_rates_init(struct ieee80211_rate *rates)
153 _rtw_memcpy(rates, rtw_g_rates,
154 sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM
158 void rtw_5g_rates_init(struct ieee80211_rate *rates)
160 _rtw_memcpy(rates, rtw_a_rates,
161 sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM
165 struct ieee80211_supported_band *rtw_spt_band_alloc(
166 enum ieee80211_band band
169 struct ieee80211_supported_band *spt_band = NULL;
170 int n_channels, n_bitrates;
172 if(band == IEEE80211_BAND_2GHZ)
174 n_channels = RTW_2G_CHANNELS_NUM;
175 n_bitrates = RTW_G_RATES_NUM;
177 else if(band == IEEE80211_BAND_5GHZ)
179 n_channels = RTW_5G_CHANNELS_NUM;
180 n_bitrates = RTW_A_RATES_NUM;
187 spt_band = (struct ieee80211_supported_band *)
188 kzalloc(sizeof(struct ieee80211_supported_band) +
189 sizeof(struct ieee80211_channel)*n_channels +
190 sizeof(struct ieee80211_rate)*n_bitrates, GFP_KERNEL);
194 spt_band->channels = (struct ieee80211_channel*)(((u8*)spt_band)+sizeof(struct ieee80211_supported_band));
195 spt_band->bitrates= (struct ieee80211_rate*)(((u8*)spt_band->channels)+sizeof(struct ieee80211_channel)*n_channels);
196 spt_band->band = band;
197 spt_band->n_channels = n_channels;
198 spt_band->n_bitrates = n_bitrates;
200 if(band == IEEE80211_BAND_2GHZ)
202 rtw_2g_channels_init(spt_band->channels);
203 rtw_2g_rates_init(spt_band->bitrates);
205 else if(band == IEEE80211_BAND_5GHZ)
207 rtw_5g_channels_init(spt_band->channels);
208 rtw_5g_rates_init(spt_band->bitrates);
218 void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
225 if(spt_band->band == IEEE80211_BAND_2GHZ)
227 size = sizeof(struct ieee80211_supported_band)
228 + sizeof(struct ieee80211_channel)*RTW_2G_CHANNELS_NUM
229 + sizeof(struct ieee80211_rate)*RTW_G_RATES_NUM;
231 else if(spt_band->band == IEEE80211_BAND_5GHZ)
233 size = sizeof(struct ieee80211_supported_band)
234 + sizeof(struct ieee80211_channel)*RTW_5G_CHANNELS_NUM
235 + sizeof(struct ieee80211_rate)*RTW_A_RATES_NUM;
244 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
245 static const struct ieee80211_txrx_stypes
246 rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
247 [NL80211_IFTYPE_ADHOC] = {
249 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
251 [NL80211_IFTYPE_STATION] = {
253 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
254 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
256 [NL80211_IFTYPE_AP] = {
258 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
259 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
260 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
261 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
262 BIT(IEEE80211_STYPE_AUTH >> 4) |
263 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
264 BIT(IEEE80211_STYPE_ACTION >> 4)
266 [NL80211_IFTYPE_AP_VLAN] = {
269 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
270 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
271 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
272 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
273 BIT(IEEE80211_STYPE_AUTH >> 4) |
274 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
275 BIT(IEEE80211_STYPE_ACTION >> 4)
277 [NL80211_IFTYPE_P2P_CLIENT] = {
279 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
280 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
282 [NL80211_IFTYPE_P2P_GO] = {
284 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
285 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
286 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
287 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
288 BIT(IEEE80211_STYPE_AUTH >> 4) |
289 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
290 BIT(IEEE80211_STYPE_ACTION >> 4)
295 static int rtw_ieee80211_channel_to_frequency(int chan, int band)
297 /* see 802.11 17.3.8.3.2 and Annex J
298 * there are overlapping channel numbers in 5GHz and 2GHz bands */
300 if (band == IEEE80211_BAND_5GHZ) {
301 if (chan >= 182 && chan <= 196)
302 return 4000 + chan * 5;
304 return 5000 + chan * 5;
305 } else { /* IEEE80211_BAND_2GHZ */
309 return 2407 + chan * 5;
311 return 0; /* not supported */
315 #define MAX_BSSINFO_LEN 1000
316 static int rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork)
319 struct ieee80211_channel *notify_channel;
320 struct cfg80211_bss *bss;
321 //struct ieee80211_supported_band *band;
324 u64 notify_timestamp;
325 u16 notify_capability;
330 u8 buf[MAX_BSSINFO_LEN], *pbuf;
331 size_t len,bssinf_len=0;
332 struct rtw_ieee80211_hdr *pwlanhdr;
333 unsigned short *fctrl;
334 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
336 struct wireless_dev *wdev = padapter->rtw_wdev;
337 struct wiphy *wiphy = wdev->wiphy;
338 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
341 //DBG_8723A("%s\n", __func__);
343 bssinf_len = pnetwork->network.IELength+sizeof (struct rtw_ieee80211_hdr_3addr);
344 if(bssinf_len > MAX_BSSINFO_LEN){
345 DBG_8723A("%s IE Length too long > %d byte \n",__FUNCTION__,MAX_BSSINFO_LEN);
349 channel = pnetwork->network.Configuration.DSConfig;
350 if (channel <= RTW_CH_MAX_2G_CHANNEL)
351 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
353 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
355 notify_channel = ieee80211_get_channel(wiphy, freq);
357 //rtw_get_timestampe_from_ie()
358 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
360 notify_interval = le16_to_cpu(*(u16*)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
361 notify_capability = le16_to_cpu(*(u16*)rtw_get_capability_from_ie(pnetwork->network.IEs));
364 notify_ie = pnetwork->network.IEs+_FIXED_IE_LENGTH_;
365 notify_ielen = pnetwork->network.IELength-_FIXED_IE_LENGTH_;
367 //We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm)
368 if ( check_fwstate(pmlmepriv, _FW_LINKED)== _TRUE &&
369 is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network)) {
370 notify_signal = 100*translate_percentage_to_dbm(padapter->recvpriv.signal_strength);//dbm
372 notify_signal = 100*translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);//dbm
376 DBG_8723A("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
377 pnetwork->network.MacAddress[0], pnetwork->network.MacAddress[1], pnetwork->network.MacAddress[2],
378 pnetwork->network.MacAddress[3], pnetwork->network.MacAddress[4], pnetwork->network.MacAddress[5]);
379 DBG_8723A("Channel: %d(%d)\n", channel, freq);
380 DBG_8723A("Capability: %X\n", notify_capability);
381 DBG_8723A("Beacon interval: %d\n", notify_interval);
382 DBG_8723A("Signal: %d\n", notify_signal);
383 DBG_8723A("notify_timestamp: %#018llx\n", notify_timestamp);
388 pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;
389 fctrl = &(pwlanhdr->frame_ctl);
392 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
393 //pmlmeext->mgnt_seq++;
395 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
396 _rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
397 SetFrameSubType(pbuf, WIFI_BEACON);
399 _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
400 SetFrameSubType(pbuf, WIFI_PROBERSP);
403 _rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
404 _rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
407 pbuf += sizeof(struct rtw_ieee80211_hdr_3addr);
408 len = sizeof (struct rtw_ieee80211_hdr_3addr);
410 _rtw_memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength);
411 len += pnetwork->network.IELength;
414 //if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
416 // DBG_8723A("%s, got p2p_ie\n", __func__);
422 bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)buf,
423 len, notify_signal, GFP_ATOMIC);
426 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress,
427 notify_timestamp, notify_capability, notify_interval, notify_ie,
428 notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/);
431 if (unlikely(!bss)) {
432 DBG_8723A("rtw_cfg80211_inform_bss error\n");
436 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38))
437 #ifndef COMPAT_KERNEL_RELEASE
438 //patch for cfg80211, update beacon ies to information_elements
439 if (pnetwork->network.Reserved[0] == 1) { // WIFI_BEACON
441 if(bss->len_information_elements != bss->len_beacon_ies)
443 bss->information_elements = bss->beacon_ies;
444 bss->len_information_elements = bss->len_beacon_ies;
447 #endif //COMPAT_KERNEL_RELEASE
448 #endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
452 if( bss->information_elements == bss->proberesp_ies)
454 if( bss->len_information_elements != bss->len_proberesp_ies)
456 DBG_8723A("error!, len_information_elements != bss->len_proberesp_ies\n");
460 else if(bss->len_information_elements < bss->len_beacon_ies)
462 bss->information_elements = bss->beacon_ies;
463 bss->len_information_elements = bss->len_beacon_ies;
468 cfg80211_put_bss(bss);
475 void rtw_cfg80211_indicate_connect(_adapter *padapter)
477 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
478 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
479 struct wireless_dev *pwdev = padapter->rtw_wdev;
481 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
485 DBG_8723A("%s(padapter=%p)\n", __func__, padapter);
487 if (pwdev->iftype != NL80211_IFTYPE_STATION
488 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
489 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
495 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
499 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
501 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
502 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
503 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
504 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));
508 #ifdef CONFIG_LAYER2_ROAMING
509 if (rtw_to_roaming(padapter) > 0) {
510 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
511 struct wiphy *wiphy = pwdev->wiphy;
512 struct ieee80211_channel *notify_channel;
514 u16 channel = cur_network->network.Configuration.DSConfig;
516 if (channel <= RTW_CH_MAX_2G_CHANNEL)
517 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
519 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
521 notify_channel = ieee80211_get_channel(wiphy, freq);
524 DBG_8723A("%s call cfg80211_roamed\n", __FUNCTION__);
525 cfg80211_roamed(padapter->pnetdev
526 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
529 , cur_network->network.MacAddress
530 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
531 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
532 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
533 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
539 DBG_8723A("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
540 cfg80211_connect_result(padapter->pnetdev, cur_network->network.MacAddress
541 , pmlmepriv->assoc_req+sizeof(struct rtw_ieee80211_hdr_3addr)+2
542 , pmlmepriv->assoc_req_len-sizeof(struct rtw_ieee80211_hdr_3addr)-2
543 , pmlmepriv->assoc_rsp+sizeof(struct rtw_ieee80211_hdr_3addr)+6
544 , pmlmepriv->assoc_rsp_len-sizeof(struct rtw_ieee80211_hdr_3addr)-6
545 , WLAN_STATUS_SUCCESS, GFP_ATOMIC);
546 DBG_8723A("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
550 void rtw_cfg80211_indicate_disconnect(_adapter *padapter)
552 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
553 struct wireless_dev *pwdev = padapter->rtw_wdev;
555 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
558 DBG_8723A("%s(padapter=%p)\n", __func__, padapter);
560 if (pwdev->iftype != NL80211_IFTYPE_STATION
561 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
562 && pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
568 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
572 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
574 _cancel_timer_ex( &pwdinfo->find_phase_timer );
575 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
576 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
578 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
579 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
581 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));
585 if (!padapter->mlmepriv.not_indic_disco) {
586 DBG_8723A("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
588 if(pwdev->sme_state==CFG80211_SME_CONNECTING)
589 cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
590 WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC/*GFP_KERNEL*/);
591 else if(pwdev->sme_state==CFG80211_SME_CONNECTED)
592 cfg80211_disconnected(padapter->pnetdev, 0, NULL, 0, GFP_ATOMIC);
594 //DBG_8723A("pwdev->sme_state=%d\n", pwdev->sme_state);
596 DBG_8723A("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
601 #ifdef CONFIG_AP_MODE
602 static u8 set_pairwise_key(_adapter *padapter, struct sta_info *psta)
604 struct cmd_obj* ph2c;
605 struct set_stakey_parm *psetstakey_para;
606 struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
609 ph2c = (struct cmd_obj*)kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
615 psetstakey_para = (struct set_stakey_parm*)
616 kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
617 if(psetstakey_para==NULL){
623 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
626 psetstakey_para->algorithm = (u8)psta->dot118021XPrivacy;
628 _rtw_memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);
630 _rtw_memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
633 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
641 static int set_group_key(_adapter *padapter, u8 *key, u8 alg, int keyid)
644 struct cmd_obj* pcmd;
645 struct setkey_parm *psetkeyparm;
646 struct cmd_priv *pcmdpriv=&(padapter->cmdpriv);
649 DBG_8723A("%s\n", __FUNCTION__);
651 pcmd = (struct cmd_obj*)kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
656 psetkeyparm=(struct setkey_parm*)
657 kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
658 if(psetkeyparm==NULL){
664 _rtw_memset(psetkeyparm, 0, sizeof(struct setkey_parm));
666 psetkeyparm->keyid=(u8)keyid;
668 padapter->mlmepriv.key_mask |= BIT(psetkeyparm->keyid);
670 psetkeyparm->algorithm = alg;
672 psetkeyparm->set_tx = 1;
690 _rtw_memcpy(&(psetkeyparm->key[0]), key, keylen);
692 pcmd->cmdcode = _SetKey_CMD_;
693 pcmd->parmbuf = (u8 *)psetkeyparm;
694 pcmd->cmdsz = (sizeof(struct setkey_parm));
699 _rtw_init_listhead(&pcmd->list);
701 res = rtw_enqueue_cmd(pcmdpriv, pcmd);
710 static int set_wep_key(_adapter *padapter, u8 *key, u8 keylen, int keyid)
726 return set_group_key(padapter, key, alg, keyid);
730 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
733 u32 wep_key_idx, wep_key_len,wep_total_len;
734 struct sta_info *psta = NULL, *pbcmc_sta = NULL;
735 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
736 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
737 struct security_priv* psecuritypriv=&(padapter->securitypriv);
738 struct sta_priv *pstapriv = &padapter->stapriv;
740 DBG_8723A("%s\n", __FUNCTION__);
742 param->u.crypt.err = 0;
743 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
745 //sizeof(struct ieee_param) = 64 bytes;
746 //if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
747 if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len)
753 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
754 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
755 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
757 if (param->u.crypt.idx >= WEP_KEYS)
765 psta = rtw_get_stainfo(pstapriv, param->sta_addr);
769 DBG_8723A("rtw_set_encryption(), sta has already been removed or never been added\n");
774 if (strcmp(param->u.crypt.alg, "none") == 0 && (psta==NULL))
776 //todo:clear default encryption keys
778 DBG_8723A("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
784 if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta==NULL))
786 DBG_8723A("r871x_set_encryption, crypt.alg = WEP\n");
788 wep_key_idx = param->u.crypt.idx;
789 wep_key_len = param->u.crypt.key_len;
791 DBG_8723A("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
793 if((wep_key_idx >= WEP_KEYS) || (wep_key_len<=0))
801 wep_key_len = wep_key_len <= 5 ? 5 : 13;
804 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
806 //wep default key has not been set, so use this key index as default key.
808 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
809 psecuritypriv->dot11PrivacyAlgrthm=_WEP40_;
810 psecuritypriv->dot118021XGrpPrivacy=_WEP40_;
812 if(wep_key_len == 13)
814 psecuritypriv->dot11PrivacyAlgrthm=_WEP104_;
815 psecuritypriv->dot118021XGrpPrivacy=_WEP104_;
818 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
821 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
823 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
825 set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx);
832 if(!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) // //group key
834 if(param->u.crypt.set_tx == 0) //group key
836 if(strcmp(param->u.crypt.alg, "WEP") == 0)
838 DBG_8723A("%s, set group_key, WEP\n", __FUNCTION__);
840 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
842 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
843 if(param->u.crypt.key_len==13)
845 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
849 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
851 DBG_8723A("%s, set group_key, TKIP\n", __FUNCTION__);
853 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
855 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
857 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
859 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
860 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
862 psecuritypriv->busetkipkey = _TRUE;
865 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
867 DBG_8723A("%s, set group_key, CCMP\n", __FUNCTION__);
869 psecuritypriv->dot118021XGrpPrivacy = _AES_;
871 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
875 DBG_8723A("%s, set group_key, none\n", __FUNCTION__);
877 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
880 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
882 psecuritypriv->binstallGrpkey = _TRUE;
884 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
886 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
888 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
891 pbcmc_sta->ieee8021x_blocked = _FALSE;
892 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
901 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) // psk/802_1x
903 if(check_fwstate(pmlmepriv, WIFI_AP_STATE))
905 if(param->u.crypt.set_tx ==1) //pairwise key
907 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
909 if(strcmp(param->u.crypt.alg, "WEP") == 0)
911 DBG_8723A("%s, set pairwise key, WEP\n", __FUNCTION__);
913 psta->dot118021XPrivacy = _WEP40_;
914 if(param->u.crypt.key_len==13)
916 psta->dot118021XPrivacy = _WEP104_;
919 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
921 DBG_8723A("%s, set pairwise key, TKIP\n", __FUNCTION__);
923 psta->dot118021XPrivacy = _TKIP_;
925 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
927 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
928 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
930 psecuritypriv->busetkipkey = _TRUE;
933 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
936 DBG_8723A("%s, set pairwise key, CCMP\n", __FUNCTION__);
938 psta->dot118021XPrivacy = _AES_;
942 DBG_8723A("%s, set pairwise key, none\n", __FUNCTION__);
944 psta->dot118021XPrivacy = _NO_PRIVACY_;
947 set_pairwise_key(padapter, psta);
949 psta->ieee8021x_blocked = _FALSE;
951 psta->bpairwise_key_installed = _TRUE;
956 if(strcmp(param->u.crypt.alg, "WEP") == 0)
958 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
960 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
961 if(param->u.crypt.key_len==13)
963 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
966 else if(strcmp(param->u.crypt.alg, "TKIP") == 0)
968 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
970 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
972 //DEBUG_ERR("set key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len);
974 _rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
975 _rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
977 psecuritypriv->busetkipkey = _TRUE;
980 else if(strcmp(param->u.crypt.alg, "CCMP") == 0)
982 psecuritypriv->dot118021XGrpPrivacy = _AES_;
984 _rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
988 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
991 psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
993 psecuritypriv->binstallGrpkey = _TRUE;
995 psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;//!!!
997 set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
999 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1002 pbcmc_sta->ieee8021x_blocked = _FALSE;
1003 pbcmc_sta->dot118021XPrivacy= psecuritypriv->dot118021XGrpPrivacy;//rx will use bmc_sta's dot118021XPrivacy
1019 static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
1022 u32 wep_key_idx, wep_key_len,wep_total_len;
1023 _adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1024 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1025 struct security_priv *psecuritypriv = &padapter->securitypriv;
1027 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
1032 DBG_8723A("%s\n", __func__);
1034 param->u.crypt.err = 0;
1035 param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
1037 if (param_len < (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len)
1043 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
1044 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
1045 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
1047 if (param->u.crypt.idx >= WEP_KEYS)
1053 #ifdef CONFIG_WAPI_SUPPORT
1054 if (strcmp(param->u.crypt.alg, "SMS4"))
1062 if (strcmp(param->u.crypt.alg, "WEP") == 0)
1064 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("wpa_set_encryption, crypt.alg = WEP\n"));
1065 DBG_8723A("wpa_set_encryption, crypt.alg = WEP\n");
1067 wep_key_idx = param->u.crypt.idx;
1068 wep_key_len = param->u.crypt.key_len;
1070 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0))
1076 if (psecuritypriv->bWepDefaultKeyIdxSet == 0)
1078 //wep default key has not been set, so use this key index as default key.
1080 wep_key_len = wep_key_len <= 5 ? 5 : 13;
1082 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1083 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1084 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1088 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1089 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1092 psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
1095 _rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
1097 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
1099 rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0);
1104 if(padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) // 802_1x
1106 struct sta_info * psta,*pbcmc_sta;
1107 struct sta_priv * pstapriv = &padapter->stapriv;
1109 //DBG_8723A("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X \n", __func__);
1111 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) //sta mode
1113 psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
1115 //DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail \n"));
1116 DBG_8723A("%s, : Obtain Sta_info fail \n", __func__);
1120 //Jeff: don't disable ieee8021x_blocked while clearing key
1121 if (strcmp(param->u.crypt.alg, "none") != 0)
1122 psta->ieee8021x_blocked = _FALSE;
1125 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1126 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1128 psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1131 if(param->u.crypt.set_tx ==1)//pairwise key
1134 DBG_8723A("%s, : param->u.crypt.set_tx ==1 \n", __func__);
1136 _rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1138 if(strcmp(param->u.crypt.alg, "TKIP") == 0)//set mic key
1140 //DEBUG_ERR(("\nset key length :param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1141 _rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1142 _rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1144 padapter->securitypriv.busetkipkey=_FALSE;
1145 //_set_timer(&padapter->securitypriv.tkip_timer, 50);
1148 //DEBUG_ERR((" param->u.crypt.key_len=%d\n",param->u.crypt.key_len));
1149 DBG_8723A(" ~~~~set sta key:unicastkey\n");
1151 rtw_setstakey_cmd(padapter, (unsigned char *)psta, _TRUE);
1155 _rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,(param->u.crypt.key_len>16 ?16:param->u.crypt.key_len));
1156 _rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[16]),8);
1157 _rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey,&(param->u.crypt.key[24]),8);
1158 padapter->securitypriv.binstallGrpkey = _TRUE;
1159 //DEBUG_ERR((" param->u.crypt.key_len=%d\n", param->u.crypt.key_len));
1160 DBG_8723A(" ~~~~set sta key:groupkey\n");
1162 padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1164 rtw_set_key(padapter,&padapter->securitypriv,param->u.crypt.idx, 1);
1166 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
1168 rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
1175 pbcmc_sta=rtw_get_bcmc_stainfo(padapter);
1178 //DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null \n"));
1182 //Jeff: don't disable ieee8021x_blocked while clearing key
1183 if (strcmp(param->u.crypt.alg, "none") != 0)
1184 pbcmc_sta->ieee8021x_blocked = _FALSE;
1186 if((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled)||
1187 (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1189 pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1193 else if(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) //adhoc mode
1198 #ifdef CONFIG_WAPI_SUPPORT
1199 if (strcmp(param->u.crypt.alg, "SMS4") == 0)
1201 PRT_WAPI_T pWapiInfo = &padapter->wapiInfo;
1202 PRT_WAPI_STA_INFO pWapiSta;
1203 u8 WapiASUEPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
1204 u8 WapiAEPNInitialValueSrc[16] = {0x37,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
1205 u8 WapiAEMultiCastPNInitialValueSrc[16] = {0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C,0x36,0x5C} ;
1207 if(param->u.crypt.set_tx == 1)
1209 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1210 if(_rtw_memcmp(pWapiSta->PeerMacAddr,param->sta_addr,6))
1212 _rtw_memcpy(pWapiSta->lastTxUnicastPN,WapiASUEPNInitialValueSrc,16);
1214 pWapiSta->wapiUsk.bSet = true;
1215 _rtw_memcpy(pWapiSta->wapiUsk.dataKey,param->u.crypt.key,16);
1216 _rtw_memcpy(pWapiSta->wapiUsk.micKey,param->u.crypt.key+16,16);
1217 pWapiSta->wapiUsk.keyId = param->u.crypt.idx ;
1218 pWapiSta->wapiUsk.bTxEnable = true;
1220 _rtw_memcpy(pWapiSta->lastRxUnicastPNBEQueue,WapiAEPNInitialValueSrc,16);
1221 _rtw_memcpy(pWapiSta->lastRxUnicastPNBKQueue,WapiAEPNInitialValueSrc,16);
1222 _rtw_memcpy(pWapiSta->lastRxUnicastPNVIQueue,WapiAEPNInitialValueSrc,16);
1223 _rtw_memcpy(pWapiSta->lastRxUnicastPNVOQueue,WapiAEPNInitialValueSrc,16);
1224 _rtw_memcpy(pWapiSta->lastRxUnicastPN,WapiAEPNInitialValueSrc,16);
1225 pWapiSta->wapiUskUpdate.bTxEnable = false;
1226 pWapiSta->wapiUskUpdate.bSet = false;
1228 if (psecuritypriv->sw_encrypt== false || psecuritypriv->sw_decrypt == false)
1230 //set unicast key for ASUE
1231 rtw_wapi_set_key(padapter, &pWapiSta->wapiUsk, pWapiSta, false, false);
1238 list_for_each_entry(pWapiSta, &pWapiInfo->wapiSTAUsedList, list) {
1239 if(_rtw_memcmp(pWapiSta->PeerMacAddr,get_bssid(pmlmepriv),6))
1241 pWapiSta->wapiMsk.bSet = true;
1242 _rtw_memcpy(pWapiSta->wapiMsk.dataKey,param->u.crypt.key,16);
1243 _rtw_memcpy(pWapiSta->wapiMsk.micKey,param->u.crypt.key+16,16);
1244 pWapiSta->wapiMsk.keyId = param->u.crypt.idx ;
1245 pWapiSta->wapiMsk.bTxEnable = false;
1246 if(!pWapiSta->bSetkeyOk)
1247 pWapiSta->bSetkeyOk = true;
1248 pWapiSta->bAuthenticateInProgress = false;
1250 _rtw_memcpy(pWapiSta->lastRxMulticastPN, WapiAEMultiCastPNInitialValueSrc, 16);
1252 if (psecuritypriv->sw_decrypt == false)
1254 //set rx broadcast key for ASUE
1255 rtw_wapi_set_key(padapter, &pWapiSta->wapiMsk, pWapiSta, true, false);
1267 DBG_8723A("%s, ret=%d\n", __func__, ret);
1274 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
1275 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1276 u8 key_index, bool pairwise, const u8 *mac_addr,
1277 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1278 u8 key_index, const u8 *mac_addr,
1279 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1280 struct key_params *params)
1284 struct ieee_param *param = NULL;
1286 struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
1287 _adapter *padapter = wiphy_to_adapter(wiphy);
1288 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1290 DBG_8723A(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
1291 DBG_8723A("cipher=0x%x\n", params->cipher);
1292 DBG_8723A("key_len=0x%x\n", params->key_len);
1293 DBG_8723A("seq_len=0x%x\n", params->seq_len);
1294 DBG_8723A("key_index=%d\n", key_index);
1295 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1296 DBG_8723A("pairwise=%d\n", pairwise);
1297 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1299 param_len = sizeof(struct ieee_param) + params->key_len;
1300 param = (struct ieee_param *)kmalloc(param_len, GFP_KERNEL);
1304 _rtw_memset(param, 0, param_len);
1306 param->cmd = IEEE_CMD_SET_ENCRYPTION;
1307 _rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
1309 switch (params->cipher) {
1310 case IW_AUTH_CIPHER_NONE:
1315 case WLAN_CIPHER_SUITE_WEP40:
1316 case WLAN_CIPHER_SUITE_WEP104:
1319 case WLAN_CIPHER_SUITE_TKIP:
1322 case WLAN_CIPHER_SUITE_CCMP:
1326 #ifdef CONFIG_WAPI_SUPPORT
1327 case WLAN_CIPHER_SUITE_SMS4:
1329 if(pairwise == NL80211_KEYTYPE_PAIRWISE) {
1330 if (key_index != 0 && key_index != 1) {
1334 _rtw_memcpy((void*)param->sta_addr, (void*)mac_addr, ETH_ALEN);
1336 DBG_8723A("mac_addr is null \n");
1338 DBG_8723A("rtw_wx_set_enc_ext: SMS4 case \n");
1347 strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1350 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1352 param->u.crypt.set_tx = 0; //for wpa/wpa2 group key
1354 param->u.crypt.set_tx = 1; //for wpa/wpa2 pairwise key
1358 //param->u.crypt.idx = key_index - 1;
1359 param->u.crypt.idx = key_index;
1361 if (params->seq_len && params->seq)
1363 _rtw_memcpy(param->u.crypt.seq, params->seq, params->seq_len);
1366 if(params->key_len && params->key)
1368 param->u.crypt.key_len = params->key_len;
1369 _rtw_memcpy(param->u.crypt.key, params->key, params->key_len);
1372 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1374 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
1376 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1378 #ifdef CONFIG_AP_MODE
1380 _rtw_memcpy(param->sta_addr, (void*)mac_addr, ETH_ALEN);
1382 ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
1387 DBG_8723A("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
1401 static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
1402 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1403 u8 key_index, bool pairwise, const u8 *mac_addr,
1404 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1405 u8 key_index, const u8 *mac_addr,
1406 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1408 void (*callback)(void *cookie,
1409 struct key_params*))
1412 struct iwm_priv *iwm = ndev_to_iwm(ndev);
1413 struct iwm_key *key = &iwm->keys[key_index];
1414 struct key_params params;
1416 IWM_DBG_WEXT(iwm, DBG, "Getting key %d\n", key_index);
1418 memset(¶ms, 0, sizeof(params));
1420 params.cipher = key->cipher;
1421 params.key_len = key->key_len;
1422 params.seq_len = key->seq_len;
1423 params.seq = key->seq;
1424 params.key = key->key;
1426 callback(cookie, ¶ms);
1428 return key->key_len ? 0 : -ENOENT;
1430 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
1434 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
1435 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
1436 u8 key_index, bool pairwise, const u8 *mac_addr)
1437 #else // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1438 u8 key_index, const u8 *mac_addr)
1439 #endif // (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1441 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1442 struct security_priv *psecuritypriv = &padapter->securitypriv;
1444 DBG_8723A(FUNC_NDEV_FMT" key_index=%d\n", FUNC_NDEV_ARG(ndev), key_index);
1446 if (key_index == psecuritypriv->dot11PrivacyKeyIndex)
1448 //clear the flag of wep default key set.
1449 psecuritypriv->bWepDefaultKeyIdxSet = 0;
1455 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
1456 struct net_device *ndev, u8 key_index
1457 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1458 , bool unicast, bool multicast
1462 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1463 struct security_priv *psecuritypriv = &padapter->securitypriv;
1465 DBG_8723A(FUNC_NDEV_FMT" key_index=%d"
1466 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1467 ", unicast=%d, multicast=%d"
1469 ".\n", FUNC_NDEV_ARG(ndev), key_index
1470 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
1471 , unicast, multicast
1475 if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) //set wep default key
1477 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1479 psecuritypriv->dot11PrivacyKeyIndex = key_index;
1481 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1482 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1483 if (psecuritypriv->dot11DefKeylen[key_index] == 13)
1485 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1486 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1489 psecuritypriv->bWepDefaultKeyIdxSet = 1; //set the flag to represent that wep default key has been set
1496 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
1497 struct net_device *ndev,
1498 u8 *mac, struct station_info *sinfo)
1501 _adapter *padapter = wiphy_to_adapter(wiphy);
1502 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1503 struct sta_info *psta = NULL;
1504 struct sta_priv *pstapriv = &padapter->stapriv;
1509 DBG_8723A(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
1514 psta = rtw_get_stainfo(pstapriv, mac);
1516 DBG_8723A("%s, sta_info is null\n", __func__);
1521 #ifdef CONFIG_DEBUG_CFG80211
1522 DBG_8723A(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
1525 //for infra./P2PClient mode
1526 if( check_fwstate(pmlmepriv, WIFI_STATION_STATE)
1527 && check_fwstate(pmlmepriv, _FW_LINKED)
1530 struct wlan_network *cur_network = &(pmlmepriv->cur_network);
1532 if (_rtw_memcmp(mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) {
1533 DBG_8723A("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
1538 sinfo->filled |= STATION_INFO_SIGNAL;
1539 sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
1541 sinfo->filled |= STATION_INFO_TX_BITRATE;
1542 sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
1544 sinfo->filled |= STATION_INFO_RX_PACKETS;
1545 sinfo->rx_packets = sta_rx_data_pkts(psta);
1547 sinfo->filled |= STATION_INFO_TX_PACKETS;
1548 sinfo->tx_packets = psta->sta_stats.tx_pkts;
1552 //for Ad-Hoc/AP mode
1553 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)
1554 ||check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
1555 ||check_fwstate(pmlmepriv, WIFI_AP_STATE))
1556 && check_fwstate(pmlmepriv, _FW_LINKED)
1559 //TODO: should acquire station info...
1566 extern int netdev_open(struct net_device *pnetdev);
1567 #ifdef CONFIG_CONCURRENT_MODE
1568 extern int netdev_if2_open(struct net_device *pnetdev);
1572 enum nl80211_iftype {
1573 NL80211_IFTYPE_UNSPECIFIED,
1574 NL80211_IFTYPE_ADHOC, //1
1575 NL80211_IFTYPE_STATION, //2
1576 NL80211_IFTYPE_AP, //3
1577 NL80211_IFTYPE_AP_VLAN,
1579 NL80211_IFTYPE_MONITOR, //6
1580 NL80211_IFTYPE_MESH_POINT,
1581 NL80211_IFTYPE_P2P_CLIENT, //8
1582 NL80211_IFTYPE_P2P_GO, //9
1584 NUM_NL80211_IFTYPES,
1585 NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
1588 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
1589 struct net_device *ndev,
1590 enum nl80211_iftype type, u32 *flags,
1591 struct vif_params *params)
1593 enum nl80211_iftype old_type;
1594 NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
1595 _adapter *padapter = wiphy_to_adapter(wiphy);
1596 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
1597 struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
1599 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
1604 #ifdef CONFIG_CONCURRENT_MODE
1605 if(padapter->adapter_type == SECONDARY_ADAPTER)
1607 DBG_8723A(FUNC_NDEV_FMT" call netdev_if2_open\n", FUNC_NDEV_ARG(ndev));
1608 if(netdev_if2_open(ndev) != 0) {
1613 else if(padapter->adapter_type == PRIMARY_ADAPTER)
1614 #endif //CONFIG_CONCURRENT_MODE
1616 DBG_8723A(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
1617 if(netdev_open(ndev) != 0) {
1623 if(_FAIL == rtw_pwr_wakeup(padapter)) {
1628 old_type = rtw_wdev->iftype;
1629 DBG_8723A(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
1630 FUNC_NDEV_ARG(ndev), old_type, type);
1632 if(old_type != type)
1635 pmlmeext->action_public_rxseq = 0xffff;
1636 pmlmeext->action_public_dialog_token = 0xff;
1640 case NL80211_IFTYPE_ADHOC:
1641 networkType = Ndis802_11IBSS;
1643 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
1644 case NL80211_IFTYPE_P2P_CLIENT:
1646 case NL80211_IFTYPE_STATION:
1647 networkType = Ndis802_11Infrastructure;
1649 if(change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1651 _cancel_timer_ex( &pwdinfo->find_phase_timer );
1652 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
1653 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
1655 //it means remove GO and change mode from AP(GO) to station(P2P DEVICE)
1656 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1657 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
1659 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));
1663 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
1664 case NL80211_IFTYPE_P2P_GO:
1666 case NL80211_IFTYPE_AP:
1667 networkType = Ndis802_11APMode;
1669 if(change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1671 //it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO)
1672 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1680 rtw_wdev->iftype = type;
1682 if (rtw_set_802_11_infrastructure_mode(padapter, networkType) ==_FALSE)
1684 rtw_wdev->iftype = old_type;
1689 rtw_setopmode_cmd(padapter, networkType);
1696 void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv, bool aborted)
1700 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
1701 if(pwdev_priv->scan_request != NULL)
1703 //struct cfg80211_scan_request *scan_request = pwdev_priv->scan_request;
1705 #ifdef CONFIG_DEBUG_CFG80211
1706 DBG_8723A("%s with scan req\n", __FUNCTION__);
1709 //avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
1710 //if(scan_request == wiphy_to_dev(scan_request->wiphy)->scan_req)
1711 if(pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
1713 DBG_8723A("error wiphy compare\n");
1717 cfg80211_scan_done(pwdev_priv->scan_request, aborted);
1720 pwdev_priv->scan_request = NULL;
1723 #ifdef CONFIG_DEBUG_CFG80211
1724 DBG_8723A("%s without scan req\n", __FUNCTION__);
1727 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
1730 void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
1733 _list *plist, *phead;
1734 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1735 _queue *queue = &(pmlmepriv->scanned_queue);
1736 struct wlan_network *pnetwork = NULL;
1738 u32 wait_for_surveydone;
1741 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
1743 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
1744 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
1746 #ifdef CONFIG_DEBUG_CFG80211
1747 DBG_8723A("%s\n", __func__);
1750 _enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1752 phead = get_list_head(queue);
1753 plist = get_next(phead);
1757 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
1760 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
1762 //report network only if the current channel set contains the channel to which this network belongs
1763 if(rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, pnetwork->network.Configuration.DSConfig) >= 0
1764 #ifdef CONFIG_VALIDATE_SSID
1765 && _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
1769 //ev=translate_scan(padapter, a, pnetwork, ev, stop);
1770 rtw_cfg80211_inform_bss(padapter, pnetwork);
1773 plist = get_next(plist);
1777 _exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
1779 //call this after other things have been done
1780 rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev), _FALSE);
1783 static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
1792 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1794 #ifdef CONFIG_DEBUG_CFG80211
1795 DBG_8723A("%s, ielen=%d\n", __func__, len);
1800 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
1802 #ifdef CONFIG_DEBUG_CFG80211
1803 DBG_8723A("probe_req_wps_ielen=%d\n", wps_ielen);
1806 if(pmlmepriv->wps_probe_req_ie)
1808 u32 free_len = pmlmepriv->wps_probe_req_ie_len;
1809 pmlmepriv->wps_probe_req_ie_len = 0;
1810 kfree(pmlmepriv->wps_probe_req_ie);
1811 pmlmepriv->wps_probe_req_ie = NULL;
1814 pmlmepriv->wps_probe_req_ie =
1815 kmalloc(wps_ielen, GFP_KERNEL);
1816 if ( pmlmepriv->wps_probe_req_ie == NULL) {
1817 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
1821 _rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
1822 pmlmepriv->wps_probe_req_ie_len = wps_ielen;
1829 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
1831 #ifdef CONFIG_DEBUG_CFG80211
1832 DBG_8723A("probe_req_p2p_ielen=%d\n", p2p_ielen);
1835 if(pmlmepriv->p2p_probe_req_ie)
1837 u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
1838 pmlmepriv->p2p_probe_req_ie_len = 0;
1839 kfree(pmlmepriv->p2p_probe_req_ie);
1840 pmlmepriv->p2p_probe_req_ie = NULL;
1843 pmlmepriv->p2p_probe_req_ie =
1844 kmalloc(p2p_ielen, GFP_KERNEL);
1845 if ( pmlmepriv->p2p_probe_req_ie == NULL) {
1846 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
1850 _rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
1851 pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
1859 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
1861 #ifdef CONFIG_DEBUG_CFG80211
1862 DBG_8723A("probe_req_wfd_ielen=%d\n", wfd_ielen);
1865 if(pmlmepriv->wfd_probe_req_ie)
1867 u32 free_len = pmlmepriv->wfd_probe_req_ie_len;
1868 pmlmepriv->wfd_probe_req_ie_len = 0;
1869 kfree(pmlmepriv->wfd_probe_req_ie);
1870 pmlmepriv->wfd_probe_req_ie = NULL;
1873 pmlmepriv->wfd_probe_req_ie =
1874 kmalloc(wfd_ielen, GFP_KERNEL);
1875 if ( pmlmepriv->wfd_probe_req_ie == NULL) {
1876 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
1880 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie, &pmlmepriv->wfd_probe_req_ie_len);
1890 static int cfg80211_rtw_scan(struct wiphy *wiphy
1891 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
1892 , struct net_device *ndev
1894 , struct cfg80211_scan_request *request)
1897 u8 _status = _FALSE;
1899 _adapter *padapter = wiphy_to_adapter(wiphy);
1900 struct mlme_priv *pmlmepriv= &padapter->mlmepriv;
1901 NDIS_802_11_SSID ssid[RTW_SSID_SCAN_AMOUNT];
1902 struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
1909 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
1911 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
1912 struct cfg80211_ssid *ssids = request->ssids;
1913 int social_channel = 0, j = 0;
1914 bool need_indicate_scan_done = _FALSE;
1915 #ifdef CONFIG_CONCURRENT_MODE
1916 PADAPTER pbuddy_adapter = NULL;
1917 struct mlme_priv *pbuddy_mlmepriv = NULL;
1918 #endif //CONFIG_CONCURRENT_MODE
1920 #ifdef CONFIG_DEBUG_CFG80211
1921 DBG_8723A(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
1924 #ifdef CONFIG_CONCURRENT_MODE
1925 if(rtw_buddy_adapter_up(padapter))
1927 pbuddy_adapter = padapter->pbuddy_adapter;
1928 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
1930 #endif //CONFIG_CONCURRENT_MODE
1932 _enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
1933 pwdev_priv->scan_request = request;
1934 _exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
1936 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1939 #ifdef CONFIG_DEBUG_CFG80211
1940 DBG_8723A("%s under WIFI_AP_STATE\n", __FUNCTION__);
1942 //need_indicate_scan_done = _TRUE;
1943 //goto check_need_indicate_scan_done;
1946 if(_FAIL == rtw_pwr_wakeup(padapter)) {
1947 need_indicate_scan_done = _TRUE;
1948 goto check_need_indicate_scan_done;
1952 if(ssids->ssid != NULL
1953 && _rtw_memcmp(ssids->ssid, "DIRECT-", 7)
1954 && rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
1957 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
1959 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
1960 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = _TRUE;
1964 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
1965 #ifdef CONFIG_DEBUG_CFG80211
1966 DBG_8723A("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
1969 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
1971 if(request->n_channels == 3 &&
1972 request->channels[0]->hw_value == 1 &&
1973 request->channels[1]->hw_value == 6 &&
1974 request->channels[2]->hw_value == 11
1982 if(request->ie && request->ie_len>0)
1984 rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len );
1987 if (pmlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE)
1989 DBG_8723A("%s, bBusyTraffic == _TRUE\n", __func__);
1990 need_indicate_scan_done = _TRUE;
1991 goto check_need_indicate_scan_done;
1993 if (rtw_is_scan_deny(padapter)){
1994 DBG_8723A(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter));
1995 need_indicate_scan_done = _TRUE;
1996 goto check_need_indicate_scan_done;
1999 #ifdef CONFIG_CONCURRENT_MODE
2000 if(pbuddy_mlmepriv && (pbuddy_mlmepriv->LinkDetectInfo.bBusyTraffic == _TRUE))
2002 DBG_8723A("%s, bBusyTraffic == _TRUE at buddy_intf\n", __func__);
2003 need_indicate_scan_done = _TRUE;
2004 goto check_need_indicate_scan_done;
2006 #endif //CONFIG_CONCURRENT_MODE
2008 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
2010 DBG_8723A("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
2011 need_indicate_scan_done = _TRUE;
2012 goto check_need_indicate_scan_done;
2015 #ifdef CONFIG_CONCURRENT_MODE
2016 if (check_buddy_fwstate(padapter,
2017 _FW_UNDER_SURVEY|_FW_UNDER_LINKING|WIFI_UNDER_WPS) == _TRUE)
2019 if(check_buddy_fwstate(padapter, _FW_UNDER_SURVEY))
2021 DBG_8723A("scanning_via_buddy_intf\n");
2022 pmlmepriv->scanning_via_buddy_intf = _TRUE;
2025 DBG_8723A("buddy_intf's mlme state:0x%x\n", pbuddy_mlmepriv->fw_state);
2027 need_indicate_scan_done = _TRUE;
2028 goto check_need_indicate_scan_done;
2034 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
2036 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
2037 rtw_free_network_queue(padapter, _TRUE);
2039 if(social_channel == 0)
2040 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
2042 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
2047 _rtw_memset(ssid, 0, sizeof(NDIS_802_11_SSID)*RTW_SSID_SCAN_AMOUNT);
2048 //parsing request ssids, n_ssids
2049 for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
2050 #ifdef CONFIG_DEBUG_CFG80211
2051 DBG_8723A("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
2053 _rtw_memcpy(ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
2054 ssid[i].SsidLength = ssids[i].ssid_len;
2058 /* parsing channels, n_channels */
2059 _rtw_memset(ch, 0, sizeof(struct rtw_ieee80211_channel)*RTW_CHANNEL_SCAN_AMOUNT);
2060 if (request->n_channels == 1)
2061 for (i=0;i<request->n_channels && i<RTW_CHANNEL_SCAN_AMOUNT;i++) {
2062 #ifdef CONFIG_DEBUG_CFG80211
2063 DBG_8723A(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
2065 ch[i].hw_value = request->channels[i]->hw_value;
2066 ch[i].flags = request->channels[i]->flags;
2069 _enter_critical_bh(&pmlmepriv->lock, &irqL);
2070 if (request->n_channels == 1) {
2071 _rtw_memcpy(&ch[1], &ch[0], sizeof(struct rtw_ieee80211_channel));
2072 _rtw_memcpy(&ch[2], &ch[0], sizeof(struct rtw_ieee80211_channel));
2073 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, ch, 3);
2075 _status = rtw_sitesurvey_cmd(padapter, ssid, RTW_SSID_SCAN_AMOUNT, NULL, 0);
2077 _exit_critical_bh(&pmlmepriv->lock, &irqL);
2080 if(_status == _FALSE)
2085 check_need_indicate_scan_done:
2086 if(need_indicate_scan_done)
2087 rtw_cfg80211_surveydone_event_callback(padapter);
2095 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
2098 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2100 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
2101 (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
2104 iwm->conf.rts_threshold = wiphy->rts_threshold;
2106 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
2108 iwm->conf.rts_threshold);
2113 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
2114 (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
2117 iwm->conf.frag_threshold = wiphy->frag_threshold;
2119 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
2121 iwm->conf.frag_threshold);
2126 DBG_8723A("%s\n", __func__);
2130 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
2131 struct cfg80211_ibss_params *params)
2134 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2135 struct ieee80211_channel *chan = params->channel;
2137 if (!test_bit(IWM_STATUS_READY, &iwm->status))
2140 /* UMAC doesn't support creating or joining an IBSS network
2141 * with specified bssid. */
2145 iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
2146 iwm->umac_profile->ibss.band = chan->band;
2147 iwm->umac_profile->ibss.channel = iwm->channel;
2148 iwm->umac_profile->ssid.ssid_len = params->ssid_len;
2149 memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
2151 return iwm_send_mlme_profile(iwm);
2153 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2157 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
2160 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2162 if (iwm->umac_profile_active)
2163 return iwm_invalidate_mlme_profile(iwm);
2165 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2169 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
2171 DBG_8723A("%s, wpa_version=%d\n", __func__, wpa_version);
2174 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2179 if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
2181 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
2185 if (wpa_version & NL80211_WPA_VERSION_2)
2187 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2195 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
2196 enum nl80211_auth_type sme_auth_type)
2198 DBG_8723A("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
2201 switch (sme_auth_type) {
2202 case NL80211_AUTHTYPE_AUTOMATIC:
2204 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2207 case NL80211_AUTHTYPE_OPEN_SYSTEM:
2209 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2211 if(psecuritypriv->ndisauthtype>Ndis802_11AuthModeWPA)
2212 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2214 #ifdef CONFIG_WAPI_SUPPORT
2215 if(psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI)
2216 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
2220 case NL80211_AUTHTYPE_SHARED_KEY:
2222 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
2224 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
2229 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2237 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
2239 u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
2241 u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
2242 &psecuritypriv->dot118021XGrpPrivacy;
2244 DBG_8723A("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
2248 *profile_cipher = _NO_PRIVACY_;
2249 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
2254 case IW_AUTH_CIPHER_NONE:
2255 *profile_cipher = _NO_PRIVACY_;
2256 ndisencryptstatus = Ndis802_11EncryptionDisabled;
2257 #ifdef CONFIG_WAPI_SUPPORT
2258 if(psecuritypriv->dot11PrivacyAlgrthm ==_SMS4_ )
2260 *profile_cipher = _SMS4_;
2264 case WLAN_CIPHER_SUITE_WEP40:
2265 *profile_cipher = _WEP40_;
2266 ndisencryptstatus = Ndis802_11Encryption1Enabled;
2268 case WLAN_CIPHER_SUITE_WEP104:
2269 *profile_cipher = _WEP104_;
2270 ndisencryptstatus = Ndis802_11Encryption1Enabled;
2272 case WLAN_CIPHER_SUITE_TKIP:
2273 *profile_cipher = _TKIP_;
2274 ndisencryptstatus = Ndis802_11Encryption2Enabled;
2276 case WLAN_CIPHER_SUITE_CCMP:
2277 *profile_cipher = _AES_;
2278 ndisencryptstatus = Ndis802_11Encryption3Enabled;
2280 #ifdef CONFIG_WAPI_SUPPORT
2281 case WLAN_CIPHER_SUITE_SMS4:
2282 *profile_cipher = _SMS4_;
2283 ndisencryptstatus = Ndis802_11_EncrypteionWAPI;
2287 DBG_8723A("Unsupported cipher: 0x%x\n", cipher);
2293 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
2295 //if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_)
2296 // psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
2302 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
2304 DBG_8723A("%s, key_mgt=0x%x\n", __func__, key_mgt);
2306 if (key_mgt == WLAN_AKM_SUITE_8021X)
2307 //*auth_type = UMAC_AUTH_TYPE_8021X;
2308 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2309 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
2310 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2312 #ifdef CONFIG_WAPI_SUPPORT
2313 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_PSK){
2314 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
2316 else if(key_mgt ==WLAN_AKM_SUITE_WAPI_CERT){
2317 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
2323 DBG_8723A("Invalid key mgt: 0x%x\n", key_mgt);
2330 static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
2332 u8 *buf=NULL, *pos=NULL;
2334 int group_cipher = 0, pairwise_cipher = 0;
2339 u8 null_addr[]= {0,0,0,0,0,0};
2341 if (pie == NULL || !ielen) {
2342 /* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
2343 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2347 if (ielen > MAX_WPA_IE_LEN+MAX_WPS_IE_LEN+MAX_P2P_IE_LEN) {
2352 buf = kzalloc(ielen, GFP_KERNEL);
2358 _rtw_memcpy(buf, pie , ielen);
2363 DBG_8723A("set wpa_ie(length:%zu):\n", ielen);
2364 for(i=0;i<ielen;i=i+8)
2365 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]);
2369 if(ielen < RSN_HEADER_LEN){
2370 RT_TRACE(_module_rtl871x_ioctl_os_c,_drv_err_,("Ie len too short %d\n", ielen));
2375 pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
2376 if(pwpa && wpa_ielen>0)
2378 if(rtw_parse_wpa_ie(pwpa, wpa_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2380 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
2381 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPAPSK;
2382 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen+2);
2384 DBG_8723A("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
2388 pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
2389 if(pwpa2 && wpa2_ielen>0)
2391 if(rtw_parse_wpa2_ie(pwpa2, wpa2_ielen+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS)
2393 padapter->securitypriv.dot11AuthAlgrthm= dot11AuthAlgrthm_8021X;
2394 padapter->securitypriv.ndisauthtype=Ndis802_11AuthModeWPA2PSK;
2395 _rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen+2);
2397 DBG_8723A("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
2401 if (group_cipher == 0)
2403 group_cipher = WPA_CIPHER_NONE;
2405 if (pairwise_cipher == 0)
2407 pairwise_cipher = WPA_CIPHER_NONE;
2410 switch(group_cipher)
2412 case WPA_CIPHER_NONE:
2413 padapter->securitypriv.dot118021XGrpPrivacy=_NO_PRIVACY_;
2414 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
2416 case WPA_CIPHER_WEP40:
2417 padapter->securitypriv.dot118021XGrpPrivacy=_WEP40_;
2418 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2420 case WPA_CIPHER_TKIP:
2421 padapter->securitypriv.dot118021XGrpPrivacy=_TKIP_;
2422 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
2424 case WPA_CIPHER_CCMP:
2425 padapter->securitypriv.dot118021XGrpPrivacy=_AES_;
2426 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
2428 case WPA_CIPHER_WEP104:
2429 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
2430 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2434 switch(pairwise_cipher)
2436 case WPA_CIPHER_NONE:
2437 padapter->securitypriv.dot11PrivacyAlgrthm=_NO_PRIVACY_;
2438 padapter->securitypriv.ndisencryptstatus=Ndis802_11EncryptionDisabled;
2440 case WPA_CIPHER_WEP40:
2441 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP40_;
2442 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2444 case WPA_CIPHER_TKIP:
2445 padapter->securitypriv.dot11PrivacyAlgrthm=_TKIP_;
2446 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
2448 case WPA_CIPHER_CCMP:
2449 padapter->securitypriv.dot11PrivacyAlgrthm=_AES_;
2450 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
2452 case WPA_CIPHER_WEP104:
2453 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
2454 padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2458 {/* handle wps_ie */
2462 wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
2463 if (wps_ie && wps_ielen > 0) {
2464 DBG_8723A("got wps_ie, wps_ielen:%u\n", wps_ielen);
2465 padapter->securitypriv.wps_ie_len = wps_ielen<MAX_WPS_IE_LEN?wps_ielen:MAX_WPS_IE_LEN;
2466 _rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
2467 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
2469 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2474 {//check p2p_ie for assoc req;
2477 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2479 if((p2p_ie=rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen)))
2481 #ifdef CONFIG_DEBUG_CFG80211
2482 DBG_8723A("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
2485 if(pmlmepriv->p2p_assoc_req_ie)
2487 u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
2488 pmlmepriv->p2p_assoc_req_ie_len = 0;
2489 kfree(pmlmepriv->p2p_assoc_req_ie);
2490 pmlmepriv->p2p_assoc_req_ie = NULL;
2493 pmlmepriv->p2p_assoc_req_ie =
2494 kmalloc(p2p_ielen, GFP_KERNEL);
2495 if ( pmlmepriv->p2p_assoc_req_ie == NULL) {
2496 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
2499 _rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
2500 pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
2506 {//check wfd_ie for assoc req;
2509 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2511 if(rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen))
2513 #ifdef CONFIG_DEBUG_CFG80211
2514 DBG_8723A("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
2517 if(pmlmepriv->wfd_assoc_req_ie)
2519 u32 free_len = pmlmepriv->wfd_assoc_req_ie_len;
2520 pmlmepriv->wfd_assoc_req_ie_len = 0;
2521 kfree(pmlmepriv->wfd_assoc_req_ie);
2522 pmlmepriv->wfd_assoc_req_ie = NULL;
2525 pmlmepriv->wfd_assoc_req_ie =
2526 kmalloc(wfd_ielen, GFP_KERNEL);
2527 if ( pmlmepriv->wfd_assoc_req_ie == NULL) {
2528 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
2531 rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie, &pmlmepriv->wfd_assoc_req_ie_len);
2536 //TKIP and AES disallow multicast packets until installing group key
2537 if(padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
2538 || padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
2539 || padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
2540 //WPS open need to enable multicast
2541 //|| check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE)
2542 rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
2544 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2545 ("rtw_set_wpa_ie: pairwise_cipher=0x%08x padapter->securitypriv.ndisencryptstatus=%d padapter->securitypriv.ndisauthtype=%d\n",
2546 pairwise_cipher, padapter->securitypriv.ndisencryptstatus, padapter->securitypriv.ndisauthtype));
2552 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2556 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
2557 struct cfg80211_connect_params *sme)
2562 struct wlan_network *pnetwork = NULL;
2563 NDIS_802_11_AUTHENTICATION_MODE authmode;
2564 NDIS_802_11_SSID ndis_ssid;
2565 u8 *dst_ssid, *src_ssid;
2566 u8 *dst_bssid, *src_bssid;
2567 //u8 matched_by_bssid=_FALSE;
2568 //u8 matched_by_ssid=_FALSE;
2570 _adapter *padapter = wiphy_to_adapter(wiphy);
2571 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2572 struct security_priv *psecuritypriv = &padapter->securitypriv;
2573 _queue *queue = &pmlmepriv->scanned_queue;
2575 DBG_8723A("=>"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2576 DBG_8723A("privacy=%d, key=%p, key_len=%d, key_idx=%d\n",
2577 sme->privacy, sme->key, sme->key_len, sme->key_idx);
2580 if(wdev_to_priv(padapter->rtw_wdev)->block == _TRUE)
2583 DBG_8723A("%s wdev_priv.block is set\n", __FUNCTION__);
2587 if(_FAIL == rtw_pwr_wakeup(padapter)) {
2592 if(check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2597 #ifdef CONFIG_CONCURRENT_MODE
2598 if (check_buddy_fwstate(padapter, _FW_UNDER_LINKING) == _TRUE) {
2599 DBG_8723A("%s, but buddy_intf is under linking\n", __FUNCTION__);
2603 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY) == _TRUE) {
2604 rtw_scan_abort(padapter->pbuddy_adapter);
2608 if (!sme->ssid || !sme->ssid_len)
2614 if (sme->ssid_len > IW_ESSID_MAX_SIZE){
2621 _rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
2622 ndis_ssid.SsidLength = sme->ssid_len;
2623 _rtw_memcpy(ndis_ssid.Ssid, sme->ssid, sme->ssid_len);
2625 DBG_8723A("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
2629 DBG_8723A("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
2632 if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
2634 DBG_8723A("%s, fw_state=0x%x, goto exit\n", __FUNCTION__, pmlmepriv->fw_state);
2637 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
2638 rtw_scan_abort(padapter);
2641 _enter_critical_bh(&queue->lock, &irqL);
2643 phead = get_list_head(queue);
2644 pmlmepriv->pscanned = get_next(phead);
2648 if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE)
2653 pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2654 pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2656 dst_ssid = pnetwork->network.Ssid.Ssid;
2657 dst_bssid = pnetwork->network.MacAddress;
2660 if(_rtw_memcmp(pnetwork->network.MacAddress, sme->bssid, ETH_ALEN) == _FALSE)
2664 if(sme->ssid && sme->ssid_len) {
2665 if( pnetwork->network.Ssid.SsidLength != sme->ssid_len
2666 || _rtw_memcmp(pnetwork->network.Ssid.Ssid, sme->ssid, sme->ssid_len) == _FALSE
2674 src_bssid = sme->bssid;
2676 if ((_rtw_memcmp(dst_bssid, src_bssid, ETH_ALEN)) == _TRUE)
2678 DBG_8723A("matched by bssid\n");
2680 ndis_ssid.SsidLength = pnetwork->network.Ssid.SsidLength;
2681 _rtw_memcpy(ndis_ssid.Ssid, pnetwork->network.Ssid.Ssid, pnetwork->network.Ssid.SsidLength);
2688 else if (sme->ssid && sme->ssid_len)
2690 src_ssid = ndis_ssid.Ssid;
2692 if ((_rtw_memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength) == _TRUE) &&
2693 (pnetwork->network.Ssid.SsidLength==ndis_ssid.SsidLength))
2695 DBG_8723A("matched by ssid\n");
2703 _exit_critical_bh(&queue->lock, &irqL);
2705 if((matched == _FALSE) || (pnetwork== NULL))
2708 DBG_8723A("connect, matched == _FALSE, goto exit\n");
2713 if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode) == _FALSE)
2719 psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
2720 psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
2721 psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2722 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; //open system
2723 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2725 #ifdef CONFIG_WAPI_SUPPORT
2726 padapter->wapiInfo.bWapiEnable = false;
2729 ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
2733 #ifdef CONFIG_WAPI_SUPPORT
2734 if(sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1)
2736 padapter->wapiInfo.bWapiEnable = true;
2737 padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
2738 padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
2742 ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
2744 #ifdef CONFIG_WAPI_SUPPORT
2745 if(psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI)
2746 padapter->mlmeextpriv.mlmext_info.auth_algo = psecuritypriv->dot11AuthAlgrthm;
2753 DBG_8723A("%s, ie_len=%zu\n", __func__, sme->ie_len);
2755 ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len);
2759 if (sme->crypto.n_ciphers_pairwise) {
2760 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
2765 //For WEP Shared auth
2766 if((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared
2767 || psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) && sme->key
2770 u32 wep_key_idx, wep_key_len,wep_total_len;
2771 NDIS_802_11_WEP *pwep = NULL;
2772 DBG_8723A("%s(): Shared/Auto WEP\n",__FUNCTION__);
2774 wep_key_idx = sme->key_idx;
2775 wep_key_len = sme->key_len;
2777 if (sme->key_idx > WEP_KEYS) {
2782 if (wep_key_len > 0)
2784 wep_key_len = wep_key_len <= 5 ? 5 : 13;
2785 wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
2786 pwep =(NDIS_802_11_WEP *)kmalloc(wep_total_len,
2789 DBG_8723A(" wpa_set_encryption: pwep allocate fail !!!\n");
2794 _rtw_memset(pwep, 0, wep_total_len);
2796 pwep->KeyLength = wep_key_len;
2797 pwep->Length = wep_total_len;
2801 padapter->securitypriv.dot11PrivacyAlgrthm=_WEP104_;
2802 padapter->securitypriv.dot118021XGrpPrivacy=_WEP104_;
2810 pwep->KeyIndex = wep_key_idx;
2811 pwep->KeyIndex |= 0x80000000;
2813 _rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
2815 if(rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
2828 ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
2832 if (sme->crypto.n_akm_suites) {
2833 ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
2838 #ifdef CONFIG_WAPI_SUPPORT
2839 if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_PSK){
2840 padapter->wapiInfo.bWapiPSK = true;
2842 else if(sme->crypto.akm_suites[0] ==WLAN_AKM_SUITE_WAPI_CERT){
2843 padapter->wapiInfo.bWapiPSK = false;
2847 authmode = psecuritypriv->ndisauthtype;
2848 rtw_set_802_11_authentication_mode(padapter, authmode);
2850 //rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus);
2852 if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
2858 DBG_8723A("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, psecuritypriv->dot118021XGrpPrivacy);
2862 DBG_8723A("<=%s, ret %d\n",__FUNCTION__, ret);
2867 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2870 _adapter *padapter = wiphy_to_adapter(wiphy);
2872 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
2874 rtw_set_roaming(padapter, 0);
2876 if(check_fwstate(&padapter->mlmepriv, _FW_LINKED))
2878 rtw_scan_abort(padapter);
2879 LeaveAllPowerSaveMode(padapter);
2880 rtw_disassoc_cmd(padapter, 500, _FALSE);
2882 DBG_8723A("%s...call rtw_indicate_disconnect\n", __FUNCTION__);
2884 padapter->mlmepriv.not_indic_disco = _TRUE;
2885 rtw_indicate_disconnect(padapter);
2886 padapter->mlmepriv.not_indic_disco = _FALSE;
2888 rtw_free_assoc_resources(padapter, 1);
2894 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
2895 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
2896 struct wireless_dev *wdev,
2898 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE)
2899 enum nl80211_tx_power_setting type, int mbm)
2901 enum tx_power_setting type, int dbm)
2905 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
2909 case NL80211_TX_POWER_AUTOMATIC:
2911 case NL80211_TX_POWER_FIXED:
2912 if (mbm < 0 || (mbm % 100))
2915 if (!test_bit(IWM_STATUS_READY, &iwm->status))
2918 ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
2919 CFG_TX_PWR_LIMIT_USR,
2920 MBM_TO_DBM(mbm) * 2);
2924 return iwm_tx_power_trigger(iwm);
2926 IWM_ERR(iwm, "Unsupported power type: %d\n", type);
2930 DBG_8723A("%s\n", __func__);
2934 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
2935 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
2936 struct wireless_dev *wdev,
2940 //_adapter *padapter = wiphy_to_adapter(wiphy);
2942 DBG_8723A("%s\n", __func__);
2949 inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
2951 struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(adapter->rtw_wdev);
2952 return rtw_wdev_priv->power_mgmt;
2955 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
2956 struct net_device *ndev,
2957 bool enabled, int timeout)
2959 _adapter *padapter = wiphy_to_adapter(wiphy);
2960 struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(padapter->rtw_wdev);
2962 DBG_8723A(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
2965 rtw_wdev_priv->power_mgmt = enabled;
2969 LPS_Leave(padapter);
2975 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
2976 struct net_device *netdev,
2977 struct cfg80211_pmksa *pmksa)
2979 u8 index,blInserted = _FALSE;
2980 _adapter *padapter = wiphy_to_adapter(wiphy);
2981 struct security_priv *psecuritypriv = &padapter->securitypriv;
2982 u8 strZeroMacAddress[ ETH_ALEN ] = { 0x00 };
2984 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev));
2986 if ( _rtw_memcmp( pmksa->bssid, strZeroMacAddress, ETH_ALEN ) == _TRUE )
2991 blInserted = _FALSE;
2994 for(index=0 ; index<NUM_PMKID_CACHE; index++)
2996 if( _rtw_memcmp( psecuritypriv->PMKIDList[index].Bssid, pmksa->bssid, ETH_ALEN) ==_TRUE )
2997 { // BSSID is matched, the same AP => rewrite with new PMKID.
2998 DBG_8723A(FUNC_NDEV_FMT" BSSID exists in the PMKList.\n", FUNC_NDEV_ARG(netdev));
3000 _rtw_memcpy( psecuritypriv->PMKIDList[index].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3001 psecuritypriv->PMKIDList[index].bUsed = _TRUE;
3002 psecuritypriv->PMKIDIndex = index+1;
3011 DBG_8723A(FUNC_NDEV_FMT" Use the new entry index = %d for this PMKID.\n",
3012 FUNC_NDEV_ARG(netdev), psecuritypriv->PMKIDIndex );
3014 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, pmksa->bssid, ETH_ALEN);
3015 _rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3017 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
3018 psecuritypriv->PMKIDIndex++ ;
3019 if(psecuritypriv->PMKIDIndex==16)
3021 psecuritypriv->PMKIDIndex =0;
3028 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
3029 struct net_device *netdev,
3030 struct cfg80211_pmksa *pmksa)
3032 u8 index, bMatched = _FALSE;
3033 _adapter *padapter = wiphy_to_adapter(wiphy);
3034 struct security_priv *psecuritypriv = &padapter->securitypriv;
3036 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev));
3038 for(index=0 ; index<NUM_PMKID_CACHE; index++)
3040 if( _rtw_memcmp( psecuritypriv->PMKIDList[index].Bssid, pmksa->bssid, ETH_ALEN) ==_TRUE )
3041 { // BSSID is matched, the same AP => Remove this PMKID information and reset it.
3042 _rtw_memset( psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN );
3043 _rtw_memset( psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN );
3044 psecuritypriv->PMKIDList[index].bUsed = _FALSE;
3050 if(_FALSE == bMatched)
3052 DBG_8723A(FUNC_NDEV_FMT" do not have matched BSSID\n"
3053 , FUNC_NDEV_ARG(netdev));
3060 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
3061 struct net_device *netdev)
3063 _adapter *padapter = wiphy_to_adapter(wiphy);
3064 struct security_priv *psecuritypriv = &padapter->securitypriv;
3066 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(netdev));
3068 _rtw_memset( &psecuritypriv->PMKIDList[ 0 ], 0x00, sizeof( RT_PMKID_LIST ) * NUM_PMKID_CACHE );
3069 psecuritypriv->PMKIDIndex = 0;
3074 #ifdef CONFIG_AP_MODE
3075 void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
3079 struct wireless_dev *pwdev = padapter->rtw_wdev;
3080 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3081 struct net_device *ndev = padapter->pnetdev;
3083 DBG_8723A("%s(padapter=%p,%s)\n", __func__, padapter, ndev->name);
3085 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
3087 struct station_info sinfo;
3089 if (GetFrameSubType(pmgmt_frame) == WIFI_ASSOCREQ)
3090 ie_offset = _ASOCREQ_IE_OFFSET_;
3091 else // WIFI_REASSOCREQ
3092 ie_offset = _REASOCREQ_IE_OFFSET_;
3095 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
3096 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
3097 sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
3098 cfg80211_new_sta(ndev, GetAddr2Ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
3100 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
3101 channel = pmlmeext->cur_channel;
3102 if (channel <= RTW_CH_MAX_2G_CHANNEL)
3103 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3105 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3107 #ifdef COMPAT_KERNEL_RELEASE
3108 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3109 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3110 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3111 #else //COMPAT_KERNEL_RELEASE
3113 //to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc()
3114 pwdev->iftype = NL80211_IFTYPE_STATION;
3115 DBG_8723A("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
3116 rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
3117 DBG_8723A("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
3118 pwdev->iftype = NL80211_IFTYPE_AP;
3119 //cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
3121 #endif //COMPAT_KERNEL_RELEASE
3122 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
3126 void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, unsigned char *da, unsigned short reason)
3132 struct rtw_ieee80211_hdr *pwlanhdr;
3133 unsigned short *fctrl;
3134 u8 mgmt_buf[128] = {0};
3135 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3136 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3137 struct net_device *ndev = padapter->pnetdev;
3139 DBG_8723A("%s(padapter=%p,%s)\n", __func__, padapter, ndev->name);
3141 #if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
3142 cfg80211_del_sta(ndev, da, GFP_ATOMIC);
3143 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
3144 channel = pmlmeext->cur_channel;
3145 if (channel <= RTW_CH_MAX_2G_CHANNEL)
3146 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3148 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3150 pmgmt_frame = mgmt_buf;
3151 pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
3153 fctrl = &(pwlanhdr->frame_ctl);
3156 //_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
3157 //_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3158 _rtw_memcpy(pwlanhdr->addr1, myid(&(padapter->eeprompriv)), ETH_ALEN);
3159 _rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN);
3160 _rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
3162 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3163 pmlmeext->mgnt_seq++;
3164 SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
3166 pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
3167 frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
3169 reason = cpu_to_le16(reason);
3170 pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
3172 #ifdef COMPAT_KERNEL_RELEASE
3173 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
3174 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
3175 rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
3176 #else //COMPAT_KERNEL_RELEASE
3177 cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len);
3178 //cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC);
3179 #endif //COMPAT_KERNEL_RELEASE
3180 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
3183 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
3187 DBG_8723A("%s\n", __func__);
3192 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
3196 DBG_8723A("%s\n", __func__);
3201 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
3206 int dot11_hdr_len = 24;
3208 unsigned char *pdata;
3210 unsigned char src_mac_addr[6];
3211 unsigned char dst_mac_addr[6];
3212 struct ieee80211_hdr *dot11_hdr;
3213 struct ieee80211_radiotap_header *rtap_hdr;
3214 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3216 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3218 if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
3221 rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
3222 if (unlikely(rtap_hdr->it_version))
3225 rtap_len = ieee80211_get_radiotap_len(skb->data);
3226 if (unlikely(skb->len < rtap_len))
3231 DBG_8723A("radiotap len (should be 14): %d\n", rtap_len);
3235 /* Skip the ratio tap header */
3236 skb_pull(skb, rtap_len);
3238 dot11_hdr = (struct ieee80211_hdr *)skb->data;
3239 frame_ctl = le16_to_cpu(dot11_hdr->frame_control);
3240 /* Check if the QoS bit is set */
3241 if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
3242 /* Check if this ia a Wireless Distribution System (WDS) frame
3243 * which has 4 MAC addresses
3245 if (dot11_hdr->frame_control & 0x0080)
3247 if ((dot11_hdr->frame_control & 0x0300) == 0x0300)
3250 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
3251 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
3253 /* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
3254 * for two MAC addresses
3256 skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
3257 pdata = (unsigned char*)skb->data;
3258 memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
3259 memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
3261 DBG_8723A("should be eapol packet\n");
3263 /* Use the real net device to transmit the packet */
3264 ret = rtw_xmit_entry(skb, padapter->pnetdev);
3269 else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE))
3270 == (RTW_IEEE80211_FTYPE_MGMT|RTW_IEEE80211_STYPE_ACTION)
3273 //only for action frames
3274 struct xmit_frame *pmgntframe;
3275 struct pkt_attrib *pattrib;
3276 unsigned char *pframe;
3277 //u8 category, action, OUI_Subtype, dialogToken=0;
3278 //unsigned char *frame_body;
3279 struct rtw_ieee80211_hdr *pwlanhdr;
3280 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3281 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3282 u8 *buf = skb->data;
3284 u8 category, action;
3287 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
3288 DBG_8723A(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
3289 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
3293 DBG_8723A("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
3294 MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
3296 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0)
3299 if (category == RTW_WLAN_CATEGORY_PUBLIC)
3300 DBG_8723A("RTW_Tx:%s\n", action_public_str(action));
3302 DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category, action);
3305 //starting alloc mgmt frame to dump it
3306 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3312 pattrib = &pmgntframe->attrib;
3313 update_mgntframe_attrib(padapter, pattrib);
3314 pattrib->retry_ctrl = _FALSE;
3316 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3318 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3320 _rtw_memcpy(pframe, (void*)buf, len);
3324 struct wifi_display_info *pwfd_info;
3326 pwfd_info = padapter->wdinfo.wfd_info;
3328 if ( _TRUE == pwfd_info->wfd_enable )
3330 rtw_append_wfd_ie( padapter, pframe, &len );
3333 #endif // CONFIG_WFD
3334 pattrib->pktlen = len;
3336 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3338 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
3339 pattrib->seqnum = pmlmeext->mgnt_seq;
3340 pmlmeext->mgnt_seq++;
3343 pattrib->last_txcmdsz = pattrib->pktlen;
3345 dump_mgntframe(padapter, pmgntframe);
3350 DBG_8723A("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE|RTW_IEEE80211_FCTL_STYPE));
3362 static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
3364 DBG_8723A("%s\n", __func__);
3367 static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
3371 DBG_8723A("%s\n", __func__);
3376 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
3377 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
3378 .ndo_open = rtw_cfg80211_monitor_if_open,
3379 .ndo_stop = rtw_cfg80211_monitor_if_close,
3380 .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
3381 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0))
3382 .ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
3384 .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
3388 static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
3391 struct net_device* mon_ndev = NULL;
3392 struct wireless_dev* mon_wdev = NULL;
3393 struct rtw_netdev_priv_indicator *pnpi;
3394 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
3397 DBG_8723A(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
3402 if (pwdev_priv->pmon_ndev) {
3403 DBG_8723A(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
3404 FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
3409 mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
3411 DBG_8723A(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
3416 mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
3417 strncpy(mon_ndev->name, name, IFNAMSIZ);
3418 mon_ndev->name[IFNAMSIZ - 1] = 0;
3419 mon_ndev->destructor = rtw_ndev_destructor;
3421 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,29))
3422 mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
3424 mon_ndev->open = rtw_cfg80211_monitor_if_open;
3425 mon_ndev->stop = rtw_cfg80211_monitor_if_close;
3426 mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry;
3427 mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address;
3430 pnpi = netdev_priv(mon_ndev);
3431 pnpi->priv = padapter;
3432 pnpi->sizeof_priv = sizeof(_adapter);
3435 mon_wdev = (struct wireless_dev *)
3436 kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3438 DBG_8723A(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
3443 mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
3444 mon_wdev->netdev = mon_ndev;
3445 mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
3446 mon_ndev->ieee80211_ptr = mon_wdev;
3448 ret = register_netdevice(mon_ndev);
3453 *ndev = pwdev_priv->pmon_ndev = mon_ndev;
3454 _rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ+1);
3457 if (ret && mon_wdev) {
3462 if (ret && mon_ndev) {
3463 free_netdev(mon_ndev);
3464 *ndev = mon_ndev = NULL;
3470 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3471 static struct wireless_dev *
3472 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
3473 static struct net_device *
3477 cfg80211_rtw_add_virtual_intf(
3478 struct wiphy *wiphy,
3479 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0))
3484 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
3487 struct net_device* ndev = NULL;
3488 _adapter *padapter = wiphy_to_adapter(wiphy);
3490 DBG_8723A(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
3491 FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
3494 case NL80211_IFTYPE_ADHOC:
3495 case NL80211_IFTYPE_AP_VLAN:
3496 case NL80211_IFTYPE_WDS:
3497 case NL80211_IFTYPE_MESH_POINT:
3500 case NL80211_IFTYPE_MONITOR:
3501 ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
3504 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3505 case NL80211_IFTYPE_P2P_CLIENT:
3507 case NL80211_IFTYPE_STATION:
3511 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3512 case NL80211_IFTYPE_P2P_GO:
3514 case NL80211_IFTYPE_AP:
3519 DBG_8723A("Unsupported interface type\n");
3523 DBG_8723A(FUNC_ADPT_FMT" ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter), ndev, ret);
3525 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3526 return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
3527 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
3528 return ndev ? ndev : ERR_PTR(ret);
3534 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
3535 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3536 struct wireless_dev *wdev
3538 struct net_device *ndev
3542 struct rtw_wdev_priv *pwdev_priv = (struct rtw_wdev_priv *)wiphy_priv(wiphy);
3543 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
3544 struct net_device *ndev;
3545 ndev = wdev ? wdev->netdev : NULL;
3551 unregister_netdevice(ndev);
3553 if (ndev == pwdev_priv->pmon_ndev) {
3554 pwdev_priv->pmon_ndev = NULL;
3555 pwdev_priv->ifname_mon[0] = '\0';
3556 DBG_8723A(FUNC_NDEV_FMT" remove monitor interface\n", FUNC_NDEV_ARG(ndev));
3563 static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
3567 uint len, wps_ielen=0;
3570 u8 got_p2p_ie = _FALSE;
3571 struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
3572 //struct sta_priv *pstapriv = &padapter->stapriv;
3575 DBG_8723A("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
3578 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
3585 pbuf = kzalloc(head_len+tail_len, GFP_KERNEL);
3590 //_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
3592 //if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0))
3593 // pstapriv->max_num_sta = NUM_STA;
3596 _rtw_memcpy(pbuf, (void *)head+24, head_len-24);// 24=beacon header len.
3597 _rtw_memcpy(pbuf+head_len-24, (void *)tail, tail_len);
3599 len = head_len+tail_len-24;
3601 //check wps ie if inclued
3602 if(rtw_get_wps_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &wps_ielen))
3603 DBG_8723A("add bcn, wps_ielen=%d\n", wps_ielen);
3606 //check p2p ie if inclued
3607 if(rtw_get_p2p_ie(pbuf+_FIXED_IE_LENGTH_, len-_FIXED_IE_LENGTH_, NULL, &p2p_ielen))
3609 DBG_8723A("got p2p_ie, len=%d\n", p2p_ielen);
3614 /* pbss_network->IEs will not include p2p_ie, wfd ie */
3615 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
3616 rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
3618 if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS) {
3620 //check p2p if enable
3621 if(got_p2p_ie == _TRUE)
3623 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3624 struct wifidirect_info *pwdinfo= &(adapter->wdinfo);
3626 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3628 DBG_8723A("Enable P2P function for the first time\n");
3629 rtw_p2p_enable(adapter, P2P_ROLE_GO);
3630 wdev_to_priv(adapter->rtw_wdev)->p2p_enabled = _TRUE;
3634 _cancel_timer_ex( &pwdinfo->find_phase_timer );
3635 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
3636 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
3638 DBG_8723A("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);
3640 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
3641 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
3642 pwdinfo->intent = 15;
3645 pwdinfo->operating_channel = pmlmeext->cur_channel;
3664 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(COMPAT_KERNEL_RELEASE)
3665 static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
3666 struct beacon_parameters *info)
3669 _adapter *adapter = wiphy_to_adapter(wiphy);
3671 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3672 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
3677 static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
3678 struct beacon_parameters *info)
3680 _adapter *padapter = wiphy_to_adapter(wiphy);
3681 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3683 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3685 pmlmeext->bstart_bss = _TRUE;
3687 cfg80211_rtw_add_beacon(wiphy, ndev, info);
3692 static int cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
3694 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3699 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3700 struct cfg80211_ap_settings *settings)
3703 _adapter *adapter = wiphy_to_adapter(wiphy);
3705 DBG_8723A(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
3706 settings->hidden_ssid, settings->auth_type);
3708 ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
3709 settings->beacon.tail, settings->beacon.tail_len);
3711 adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
3713 if (settings->ssid && settings->ssid_len) {
3714 WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
3715 WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
3718 DBG_8723A(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
3719 settings->ssid, settings->ssid_len,
3720 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
3722 _rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
3723 pbss_network->Ssid.SsidLength = settings->ssid_len;
3724 _rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
3725 pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
3728 DBG_8723A(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
3729 pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
3730 pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
3736 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3737 struct cfg80211_beacon_data *info)
3740 _adapter *adapter = wiphy_to_adapter(wiphy);
3742 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3744 ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
3749 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3751 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3755 #endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
3757 static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
3758 u8 *mac, struct station_parameters *params)
3760 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3765 static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
3770 _list *phead, *plist;
3772 struct sta_info *psta = NULL;
3773 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3774 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3775 struct sta_priv *pstapriv = &padapter->stapriv;
3777 DBG_8723A("+"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3779 if(check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE)) != _TRUE)
3781 DBG_8723A("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n", __func__);
3788 DBG_8723A("flush all sta, and cam_entry\n");
3790 flush_all_cam_entry(padapter); //clear CAM
3792 ret = rtw_sta_flush(padapter);
3798 DBG_8723A("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
3800 if (mac[0] == 0xff && mac[1] == 0xff &&
3801 mac[2] == 0xff && mac[3] == 0xff &&
3802 mac[4] == 0xff && mac[5] == 0xff)
3808 _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3810 phead = &pstapriv->asoc_list;
3811 plist = get_next(phead);
3814 while ((rtw_end_of_queue_search(phead, plist)) == _FALSE)
3816 psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3818 plist = get_next(plist);
3820 if(_rtw_memcmp(mac, psta->hwaddr, ETH_ALEN))
3822 if(psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE)
3824 DBG_8723A("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
3828 DBG_8723A("free psta=%p, aid=%d\n", psta, psta->aid);
3830 rtw_list_delete(&psta->asoc_list);
3831 pstapriv->asoc_list_cnt--;
3833 //_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3834 updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING);
3835 //_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3846 _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3848 associated_clients_update(padapter, updated);
3850 DBG_8723A("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3856 static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
3857 u8 *mac, struct station_parameters *params)
3859 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3864 static int cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
3865 int idx, u8 *mac, struct station_info *sinfo)
3867 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3869 //TODO: dump scanned queue
3874 static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
3875 struct bss_parameters *params)
3879 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3881 DBG_8723A("use_cts_prot=%d\n", params->use_cts_prot);
3882 DBG_8723A("use_short_preamble=%d\n", params->use_short_preamble);
3883 DBG_8723A("use_short_slot_time=%d\n", params->use_short_slot_time);
3884 DBG_8723A("ap_isolate=%d\n", params->ap_isolate);
3886 DBG_8723A("basic_rates_len=%d\n", params->basic_rates_len);
3887 for(i=0; i<params->basic_rates_len; i++)
3889 DBG_8723A("basic_rates=%d\n", params->basic_rates[i]);
3897 static int cfg80211_rtw_set_channel(struct wiphy *wiphy
3898 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
3899 , struct net_device *ndev
3901 , struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
3903 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
3904 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3910 static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
3911 struct cfg80211_auth_request *req)
3913 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3918 static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
3919 struct cfg80211_assoc_request *req)
3921 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3925 #endif //CONFIG_AP_MODE
3927 void rtw_cfg80211_rx_action_p2p(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
3932 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3933 u8 category, action;
3935 channel = rtw_get_oper_ch(padapter);
3937 DBG_8723A("RTW_Rx:cur_ch=%d\n", channel);
3939 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
3943 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
3944 DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action);
3947 if (channel <= RTW_CH_MAX_2G_CHANNEL)
3948 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3950 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3952 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3953 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3955 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
3959 void rtw_cfg80211_rx_p2p_action_public(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
3964 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3965 u8 category, action;
3967 channel = rtw_get_oper_ch(padapter);
3969 DBG_8723A("RTW_Rx:cur_ch=%d\n", channel);
3971 type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, _FALSE);
3974 case P2P_GO_NEGO_CONF:
3975 case P2P_PROVISION_DISC_RESP:
3976 rtw_clear_scan_deny(padapter);
3981 rtw_action_frame_parse(pmgmt_frame, frame_len, &category, &action);
3982 DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action);
3985 if (channel <= RTW_CH_MAX_2G_CHANNEL)
3986 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
3988 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
3990 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
3991 rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
3993 cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC);
3997 void rtw_cfg80211_rx_action(_adapter *adapter, u8 *frame, uint frame_len, const char*msg)
4001 struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
4002 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(adapter->rtw_wdev);
4003 u8 category, action;
4005 channel = rtw_get_oper_ch(adapter);
4007 rtw_action_frame_parse(frame, frame_len, &category, &action);
4009 DBG_8723A("RTW_Rx:cur_ch=%d\n", channel);
4011 DBG_8723A("RTW_Rx:%s\n", msg);
4013 DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action);
4015 if (channel <= RTW_CH_MAX_2G_CHANNEL)
4016 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_2GHZ);
4018 freq = rtw_ieee80211_channel_to_frequency(channel, IEEE80211_BAND_5GHZ);
4020 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4021 rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
4023 cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
4029 void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
4031 u16 wps_devicepassword_id = 0x0000;
4032 uint wps_devicepassword_id_len = 0;
4033 u8 wpsie[ 255 ] = { 0x00 }, p2p_ie[ 255 ] = { 0x00 };
4036 u32 devinfo_contentlen = 0;
4037 u8 devinfo_content[64] = { 0x00 };
4039 uint capability_len = 0;
4041 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4042 u8 action = P2P_PUB_ACTION_ACTION;
4044 u32 p2poui = cpu_to_be32(P2POUI);
4045 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
4051 struct xmit_frame *pmgntframe;
4052 struct pkt_attrib *pattrib;
4053 unsigned char *pframe;
4054 struct rtw_ieee80211_hdr *pwlanhdr;
4055 unsigned short *fctrl;
4056 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4057 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4058 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4060 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4061 u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
4062 size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
4065 DBG_8723A( "[%s] In\n", __FUNCTION__ );
4067 //prepare for building provision_request frame
4068 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
4069 _rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
4071 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
4073 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
4074 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
4075 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
4077 switch(wps_devicepassword_id)
4080 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
4082 case WPS_DPID_USER_SPEC:
4083 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
4085 case WPS_DPID_MACHINE_SPEC:
4087 case WPS_DPID_REKEY:
4090 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
4092 case WPS_DPID_REGISTRAR_SPEC:
4093 pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
4100 if ( rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen ) )
4103 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);
4104 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&capability, &capability_len);
4109 //start to build provision_request frame
4110 _rtw_memset(wpsie, 0, sizeof(wpsie));
4111 _rtw_memset(p2p_ie, 0, sizeof(p2p_ie));
4114 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4121 pattrib = &pmgntframe->attrib;
4122 update_mgntframe_attrib(padapter, pattrib);
4124 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4126 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4127 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4129 fctrl = &(pwlanhdr->frame_ctl);
4132 _rtw_memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
4133 _rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
4134 _rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
4136 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4137 pmlmeext->mgnt_seq++;
4138 SetFrameSubType(pframe, WIFI_ACTION);
4140 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4141 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4143 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4144 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4145 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4146 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4147 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
4150 //build_prov_disc_request_p2p_ie
4153 p2p_ie[ p2pielen++ ] = 0x50;
4154 p2p_ie[ p2pielen++ ] = 0x6F;
4155 p2p_ie[ p2pielen++ ] = 0x9A;
4156 p2p_ie[ p2pielen++ ] = 0x09; // WFA P2P v1.0
4158 // Commented by Albert 20110301
4159 // According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes
4160 // 1. P2P Capability
4162 // 3. Group ID ( When joining an operating P2P Group )
4164 // P2P Capability ATTR
4166 p2p_ie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4169 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4170 RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
4174 // Device Capability Bitmap, 1 byte
4175 // Group Capability Bitmap, 1 byte
4176 _rtw_memcpy(p2p_ie + p2pielen, &capability, 2);
4182 p2p_ie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
4185 // 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes)
4186 // + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes)
4187 //*(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
4188 RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
4192 _rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
4193 p2pielen += devinfo_contentlen;
4196 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);
4197 //p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr);
4198 //pframe += p2pielen;
4199 pattrib->pktlen += p2p_ielen;
4203 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4208 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4212 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4216 wpsie[wpsielen++] = WPS_VERSION_1; // Version 1.0
4220 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
4224 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4228 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
4231 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4235 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
4237 pattrib->pktlen += wfdielen;
4240 pattrib->last_txcmdsz = pattrib->pktlen;
4242 //dump_mgntframe(padapter, pmgntframe);
4243 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
4244 DBG_8723A("%s, ack to\n", __func__);
4246 //if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
4248 // DBG_8723A("waiting for p2p peer key-in PIN CODE\n");
4249 // rtw_msleep_os(15000); // 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req.
4254 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
4255 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4256 struct wireless_dev *wdev,
4258 struct net_device *ndev,
4260 struct ieee80211_channel * channel,
4261 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4262 enum nl80211_channel_type channel_type,
4264 unsigned int duration, u64 *cookie)
4267 _adapter *padapter = wiphy_to_adapter(wiphy);
4268 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4269 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4270 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4271 struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4272 u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
4273 u8 ready_on_channel = _FALSE;
4275 DBG_8723A(FUNC_ADPT_FMT" ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter), remain_ch, duration);
4277 if(pcfg80211_wdinfo->is_ro_ch == _TRUE)
4279 DBG_8723A("%s, cancel ro ch timer\n", __func__);
4281 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4283 #ifdef CONFIG_CONCURRENT_MODE
4284 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
4285 #endif //CONFIG_CONCURRENT_MODE
4287 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
4290 pcfg80211_wdinfo->is_ro_ch = _TRUE;
4292 if(_FAIL == rtw_pwr_wakeup(padapter)) {
4297 _rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
4298 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4299 pcfg80211_wdinfo->remain_on_ch_type= channel_type;
4301 pcfg80211_wdinfo->remain_on_ch_cookie= *cookie;
4303 rtw_scan_abort(padapter);
4304 #ifdef CONFIG_CONCURRENT_MODE
4305 if(rtw_buddy_adapter_up(padapter))
4306 rtw_scan_abort(padapter->pbuddy_adapter);
4307 #endif //CONFIG_CONCURRENT_MODE
4309 //if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
4310 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4312 rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
4313 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = _TRUE;
4317 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4318 #ifdef CONFIG_DEBUG_CFG80211
4319 DBG_8723A("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
4324 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
4328 duration = duration*3;//extend from exper.
4331 #ifdef CONFIG_CONCURRENT_MODE
4332 if(check_buddy_fwstate(padapter, _FW_LINKED) &&
4333 (duration<pwdinfo->ext_listen_interval))
4335 duration = duration + pwdinfo->ext_listen_interval;
4339 pcfg80211_wdinfo->restore_channel = pmlmeext->cur_channel;
4341 if(rtw_ch_set_search_ch(pmlmeext->channel_set, remain_ch) >= 0) {
4342 #ifdef CONFIG_CONCURRENT_MODE
4343 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4345 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
4346 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4348 if(remain_ch != pbuddy_mlmeext->cur_channel)
4350 if(ATOMIC_READ(&pwdev_priv->switch_ch_to)==1 ||
4351 (remain_ch != pmlmeext->cur_channel))
4353 DBG_8723A("%s, issue nulldata pwrbit=1\n", __func__);
4354 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
4356 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
4358 DBG_8723A("%s, set switch ch timer, duration=%d\n", __func__, duration-pwdinfo->ext_listen_interval);
4359 _set_timer(&pwdinfo->ap_p2p_switch_timer, duration-pwdinfo->ext_listen_interval);
4363 ready_on_channel = _TRUE;
4364 //pmlmeext->cur_channel = remain_ch;
4365 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4367 #endif //CONFIG_CONCURRENT_MODE
4368 if(remain_ch != pmlmeext->cur_channel )
4370 ready_on_channel = _TRUE;
4371 //pmlmeext->cur_channel = remain_ch;
4372 //set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4375 DBG_8723A("%s remain_ch:%u not in channel plan!!!!\n", __FUNCTION__, remain_ch);
4379 //call this after other things have been done
4380 #ifdef CONFIG_CONCURRENT_MODE
4381 if(ATOMIC_READ(&pwdev_priv->ro_ch_to)==1 ||
4382 (remain_ch != pmlmeext->cur_channel))
4384 u8 co_channel = 0xff;
4385 ATOMIC_SET(&pwdev_priv->ro_ch_to, 0);
4388 if(ready_on_channel == _TRUE)
4390 if ( !check_fwstate(&padapter->mlmepriv, _FW_LINKED ) )
4392 pmlmeext->cur_channel = remain_ch;
4395 set_channel_bwmode(padapter, remain_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4398 DBG_8723A("%s, set ro ch timer, duration=%d\n", __func__, duration);
4399 _set_timer( &pcfg80211_wdinfo->remain_on_ch_timer, duration);
4401 #ifdef CONFIG_CONCURRENT_MODE
4405 rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type, duration, GFP_KERNEL);
4407 pwdinfo->listen_channel = pmlmeext->cur_channel;
4411 pcfg80211_wdinfo->is_ro_ch = _FALSE;
4416 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
4417 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4418 struct wireless_dev *wdev,
4420 struct net_device *ndev,
4425 _adapter *padapter = wiphy_to_adapter(wiphy);
4426 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4427 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4428 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
4429 struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4431 DBG_8723A(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
4433 if (pcfg80211_wdinfo->is_ro_ch == _TRUE) {
4434 DBG_8723A("%s, cancel ro ch timer\n", __func__);
4435 _cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4436 #ifdef CONFIG_CONCURRENT_MODE
4437 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
4439 p2p_protocol_wk_hdl(padapter, P2P_RO_CH_WK);
4443 // Disable P2P Listen State
4444 if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
4446 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
4448 _cancel_timer_ex( &pwdinfo->find_phase_timer );
4449 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
4450 _cancel_timer_ex( &pwdinfo->pre_tx_scan_timer);
4452 rtw_p2p_set_state(pwdinfo, P2P_STATE_NONE);
4453 _rtw_memset(pwdinfo, 0x00, sizeof(struct wifidirect_info));
4459 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
4460 #ifdef CONFIG_DEBUG_CFG80211
4461 DBG_8723A("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
4464 pcfg80211_wdinfo->is_ro_ch = _FALSE;
4471 static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, const u8 *buf, size_t len)
4473 struct xmit_frame *pmgntframe;
4474 struct pkt_attrib *pattrib;
4475 unsigned char *pframe;
4478 struct rtw_ieee80211_hdr *pwlanhdr;
4479 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4480 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4481 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4482 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4483 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4484 //struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4486 if(_FAIL == rtw_pwr_wakeup(padapter)) {
4491 rtw_set_scan_deny(padapter, 1000);
4493 rtw_scan_abort(padapter);
4494 #ifdef CONFIG_CONCURRENT_MODE
4495 if(rtw_buddy_adapter_up(padapter))
4496 rtw_scan_abort(padapter->pbuddy_adapter);
4497 #endif /* CONFIG_CONCURRENT_MODE */
4499 if (padapter->cfg80211_wdinfo.is_ro_ch == _TRUE) {
4500 //DBG_8723A("%s, cancel ro ch timer\n", __func__);
4501 //_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
4502 //padapter->cfg80211_wdinfo.is_ro_ch = _FALSE;
4503 #ifdef CONFIG_CONCURRENT_MODE
4504 DBG_8723A("%s, extend ro ch time\n", __func__);
4505 _set_timer( &padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
4506 #endif //CONFIG_CONCURRENT_MODE
4509 #ifdef CONFIG_CONCURRENT_MODE
4510 if (check_buddy_fwstate(padapter, _FW_LINKED )) {
4512 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
4513 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4515 co_channel = rtw_get_oper_ch(padapter);
4517 if (tx_ch != pbuddy_mlmeext->cur_channel) {
4518 if (ATOMIC_READ(&pwdev_priv->switch_ch_to)==1) {
4519 DBG_8723A("%s, issue nulldata pwrbit=1\n", __func__);
4520 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
4522 ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
4524 //DBG_8723A("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
4525 //_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
4528 DBG_8723A("%s, set switch ch timer, period=%d\n", __func__, pwdinfo->ext_listen_period);
4529 _set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_period);
4532 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
4533 pmlmeext->cur_channel = tx_ch;
4535 if (tx_ch != co_channel)
4536 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4538 #endif //CONFIG_CONCURRENT_MODE
4539 //if (tx_ch != pmlmeext->cur_channel) {
4540 if(tx_ch != rtw_get_oper_ch(padapter)) {
4541 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED ))
4542 pmlmeext->cur_channel = tx_ch;
4543 set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4546 //starting alloc mgmt frame to dump it
4547 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4555 pattrib = &pmgntframe->attrib;
4556 update_mgntframe_attrib(padapter, pattrib);
4557 pattrib->retry_ctrl = _FALSE;
4559 _rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4561 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4563 _rtw_memcpy(pframe, (void*)buf, len);
4564 pattrib->pktlen = len;
4566 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4568 pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
4569 pattrib->seqnum = pmlmeext->mgnt_seq;
4570 pmlmeext->mgnt_seq++;
4574 struct wifi_display_info *pwfd_info;
4576 pwfd_info = padapter->wdinfo.wfd_info;
4578 if ( _TRUE == pwfd_info->wfd_enable )
4580 rtw_append_wfd_ie( padapter, pframe, &pattrib->pktlen );
4583 #endif // CONFIG_WFD
4585 pattrib->last_txcmdsz = pattrib->pktlen;
4587 if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
4592 #ifdef CONFIG_DEBUG_CFG80211
4593 DBG_8723A("%s, ack == _FAIL\n", __func__);
4598 #ifdef CONFIG_DEBUG_CFG80211
4599 DBG_8723A("%s, ack=%d, ok!\n", __func__, ack);
4606 #ifdef CONFIG_DEBUG_CFG80211
4607 DBG_8723A("%s, ret=%d\n", __func__, ret);
4614 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
4615 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4616 struct wireless_dev *wdev,
4618 struct net_device *ndev,
4620 struct ieee80211_channel *chan,
4621 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
4624 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4625 enum nl80211_channel_type channel_type,
4626 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4627 bool channel_type_valid,
4630 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
4633 const u8 *buf, size_t len,
4634 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
4637 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
4638 bool dont_wait_for_ack,
4642 _adapter *padapter = (_adapter *)wiphy_to_adapter(wiphy);
4643 struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
4646 u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
4649 u8 tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
4650 u8 category, action;
4652 u32 start = rtw_get_current_time();
4654 /* cookie generation */
4655 *cookie = (unsigned long) buf;
4657 #ifdef CONFIG_DEBUG_CFG80211
4658 DBG_8723A(FUNC_ADPT_FMT" len=%zu, ch=%d"
4659 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4661 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4662 ", channel_type_valid=%d"
4665 "\n", FUNC_ADPT_ARG(padapter),
4667 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
4669 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4670 , channel_type_valid
4674 #endif /* CONFIG_DEBUG_CFG80211 */
4676 /* indicate ack before issue frame to avoid racing with rsp frame */
4677 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
4678 rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack, GFP_KERNEL);
4679 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
4680 cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
4683 if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
4684 DBG_8723A(FUNC_ADPT_FMT" frame_control:0x%x\n", FUNC_ADPT_ARG(padapter),
4685 le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
4689 DBG_8723A("RTW_Tx:tx_ch=%d, da="MAC_FMT"\n", tx_ch, MAC_ARG(GetAddr1Ptr(buf)));
4691 if((type = rtw_p2p_check_frames(padapter, buf, len, _TRUE)) >= 0)
4694 if (category == RTW_WLAN_CATEGORY_PUBLIC)
4695 DBG_8723A("RTW_Tx:%s\n", action_public_str(action));
4697 DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category, action);
4702 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
4703 } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
4705 if (tx_ret != _SUCCESS || dump_cnt > 1) {
4706 DBG_8723A(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
4707 tx_ret==_SUCCESS?"OK":"FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
4711 case P2P_GO_NEGO_CONF:
4712 rtw_clear_scan_deny(padapter);
4714 case P2P_INVIT_RESP:
4715 if (pwdev_priv->invit_info.flags & BIT(0)
4716 && pwdev_priv->invit_info.status == 0)
4718 DBG_8723A(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
4719 FUNC_ADPT_ARG(padapter));
4720 rtw_set_scan_deny(padapter, 5000);
4721 rtw_pwr_wakeup_ex(padapter, 5000);
4722 rtw_clear_scan_deny(padapter);
4731 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
4732 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
4733 struct wireless_dev *wdev,
4735 struct net_device *ndev,
4737 u16 frame_type, bool reg)
4739 _adapter *adapter = wiphy_to_adapter(wiphy);
4741 #ifdef CONFIG_DEBUG_CFG80211
4742 DBG_8723A(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
4746 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
4752 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
4758 u8 wps_oui[8]={0x0,0x50,0xf2,0x04};
4762 _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4763 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4764 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4766 DBG_8723A(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
4770 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
4772 #ifdef CONFIG_DEBUG_CFG80211
4773 DBG_8723A("bcn_wps_ielen=%d\n", wps_ielen);
4776 if(pmlmepriv->wps_beacon_ie)
4778 u32 free_len = pmlmepriv->wps_beacon_ie_len;
4779 pmlmepriv->wps_beacon_ie_len = 0;
4780 kfree(pmlmepriv->wps_beacon_ie);
4781 pmlmepriv->wps_beacon_ie = NULL;
4784 pmlmepriv->wps_beacon_ie =
4785 kmalloc(wps_ielen, GFP_KERNEL);
4786 if ( pmlmepriv->wps_beacon_ie == NULL) {
4787 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4792 _rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
4793 pmlmepriv->wps_beacon_ie_len = wps_ielen;
4795 update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE);
4803 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
4805 #ifdef CONFIG_DEBUG_CFG80211
4806 DBG_8723A("bcn_p2p_ielen=%d\n", p2p_ielen);
4809 if(pmlmepriv->p2p_beacon_ie)
4811 u32 free_len = pmlmepriv->p2p_beacon_ie_len;
4812 pmlmepriv->p2p_beacon_ie_len = 0;
4813 kfree(pmlmepriv->p2p_beacon_ie);
4814 pmlmepriv->p2p_beacon_ie = NULL;
4817 pmlmepriv->p2p_beacon_ie =
4818 kmalloc(p2p_ielen, GFP_KERNEL);
4819 if ( pmlmepriv->p2p_beacon_ie == NULL) {
4820 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4825 _rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
4826 pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
4835 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
4837 #ifdef CONFIG_DEBUG_CFG80211
4838 DBG_8723A("bcn_wfd_ielen=%d\n", wfd_ielen);
4841 if(pmlmepriv->wfd_beacon_ie)
4843 u32 free_len = pmlmepriv->wfd_beacon_ie_len;
4844 pmlmepriv->wfd_beacon_ie_len = 0;
4845 kfree(pmlmepriv->wfd_beacon_ie);
4846 pmlmepriv->wfd_beacon_ie = NULL;
4849 pmlmepriv->wfd_beacon_ie = kmalloc(wfd_ielen);
4850 if ( pmlmepriv->wfd_beacon_ie == NULL) {
4851 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4855 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie, &pmlmepriv->wfd_beacon_ie_len);
4859 pmlmeext->bstart_bss = _TRUE;
4867 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
4876 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
4877 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4879 #ifdef CONFIG_DEBUG_CFG80211
4880 DBG_8723A("%s, ielen=%d\n", __func__, len);
4885 if((wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen)))
4887 uint attr_contentlen = 0;
4888 u16 uconfig_method, *puconfig_method = NULL;
4890 #ifdef CONFIG_DEBUG_CFG80211
4891 DBG_8723A("probe_resp_wps_ielen=%d\n", wps_ielen);
4894 if(pmlmepriv->wps_probe_resp_ie)
4896 u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
4897 pmlmepriv->wps_probe_resp_ie_len = 0;
4898 kfree(pmlmepriv->wps_probe_resp_ie);
4899 pmlmepriv->wps_probe_resp_ie = NULL;
4902 pmlmepriv->wps_probe_resp_ie = kmalloc(wps_ielen);
4903 if ( pmlmepriv->wps_probe_resp_ie == NULL) {
4904 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4909 //add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode
4910 if ( (puconfig_method = (u16*)rtw_get_wps_attr_content( wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen)) != NULL )
4912 #ifdef CONFIG_DEBUG_CFG80211
4913 //printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method));
4916 uconfig_method = WPS_CM_PUSH_BUTTON;
4917 uconfig_method = cpu_to_be16( uconfig_method );
4919 *puconfig_method |= uconfig_method;
4922 _rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
4923 pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
4931 if((p2p_ie=rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen)))
4934 u32 attr_contentlen = 0;
4937 #ifdef CONFIG_DEBUG_CFG80211
4938 DBG_8723A("probe_resp_p2p_ielen=%d\n", p2p_ielen);
4941 //Check P2P Capability ATTR
4942 if( rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8*)&cap_attr, (uint*) &attr_contentlen) )
4945 //DBG_8723A( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ );
4946 cap_attr = le16_to_cpu(cap_attr);
4947 grp_cap = (u8)((cap_attr >> 8)&0xff);
4949 is_GO = (grp_cap&BIT(0)) ? _TRUE:_FALSE;
4952 DBG_8723A("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
4958 if(pmlmepriv->p2p_probe_resp_ie)
4960 u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
4961 pmlmepriv->p2p_probe_resp_ie_len = 0;
4962 kfree(pmlmepriv->p2p_probe_resp_ie);
4963 pmlmepriv->p2p_probe_resp_ie = NULL;
4966 pmlmepriv->p2p_probe_resp_ie = kmalloc(p2p_ielen);
4967 if ( pmlmepriv->p2p_probe_resp_ie == NULL) {
4968 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4972 _rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
4973 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
4977 if(pmlmepriv->p2p_go_probe_resp_ie)
4979 u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
4980 pmlmepriv->p2p_go_probe_resp_ie_len = 0;
4981 kfree(pmlmepriv->p2p_go_probe_resp_ie);
4982 pmlmepriv->p2p_go_probe_resp_ie = NULL;
4985 pmlmepriv->p2p_go_probe_resp_ie = kmalloc(p2p_ielen);
4986 if ( pmlmepriv->p2p_go_probe_resp_ie == NULL) {
4987 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
4991 _rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
4992 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
5002 if(rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen))
5004 #ifdef CONFIG_DEBUG_CFG80211
5005 DBG_8723A("probe_resp_wfd_ielen=%d\n", wfd_ielen);
5008 if(pmlmepriv->wfd_probe_resp_ie)
5010 u32 free_len = pmlmepriv->wfd_probe_resp_ie_len;
5011 pmlmepriv->wfd_probe_resp_ie_len = 0;
5012 kfree(pmlmepriv->wfd_probe_resp_ie);
5013 pmlmepriv->wfd_probe_resp_ie = NULL;
5016 pmlmepriv->wfd_probe_resp_ie = kmalloc(wfd_ielen);
5017 if ( pmlmepriv->wfd_probe_resp_ie == NULL) {
5018 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
5022 rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie, &pmlmepriv->wfd_probe_resp_ie_len);
5032 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
5035 _adapter *padapter = (_adapter *)rtw_netdev_priv(net);
5036 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5038 DBG_8723A("%s, ielen=%d\n", __func__, len);
5042 if(pmlmepriv->wps_assoc_resp_ie)
5044 u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
5045 pmlmepriv->wps_assoc_resp_ie_len = 0;
5046 kfree(pmlmepriv->wps_assoc_resp_ie);
5047 pmlmepriv->wps_assoc_resp_ie = NULL;
5050 pmlmepriv->wps_assoc_resp_ie = kmalloc(len);
5051 if ( pmlmepriv->wps_assoc_resp_ie == NULL) {
5052 DBG_8723A("%s()-%d: kmalloc() ERROR!\n", __FUNCTION__, __LINE__);
5056 _rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len);
5057 pmlmepriv->wps_assoc_resp_ie_len = len;
5064 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
5071 #ifdef CONFIG_DEBUG_CFG80211
5072 DBG_8723A("%s, ielen=%d\n", __func__, len);
5075 if( (rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen>0))
5077 || (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen>0))
5086 ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
5088 case 0x2: //PROBE_RESP
5089 ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
5091 case 0x4: //ASSOC_RESP
5092 ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
5102 static struct cfg80211_ops rtw_cfg80211_ops = {
5103 .change_virtual_intf = cfg80211_rtw_change_iface,
5104 .add_key = cfg80211_rtw_add_key,
5105 .get_key = cfg80211_rtw_get_key,
5106 .del_key = cfg80211_rtw_del_key,
5107 .set_default_key = cfg80211_rtw_set_default_key,
5108 .get_station = cfg80211_rtw_get_station,
5109 .scan = cfg80211_rtw_scan,
5110 .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
5111 .connect = cfg80211_rtw_connect,
5112 .disconnect = cfg80211_rtw_disconnect,
5113 .join_ibss = cfg80211_rtw_join_ibss,
5114 .leave_ibss = cfg80211_rtw_leave_ibss,
5115 .set_tx_power = cfg80211_rtw_set_txpower,
5116 .get_tx_power = cfg80211_rtw_get_txpower,
5117 .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
5118 .set_pmksa = cfg80211_rtw_set_pmksa,
5119 .del_pmksa = cfg80211_rtw_del_pmksa,
5120 .flush_pmksa = cfg80211_rtw_flush_pmksa,
5122 #ifdef CONFIG_AP_MODE
5123 .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
5124 .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
5126 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
5127 .add_beacon = cfg80211_rtw_add_beacon,
5128 .set_beacon = cfg80211_rtw_set_beacon,
5129 .del_beacon = cfg80211_rtw_del_beacon,
5131 .start_ap = cfg80211_rtw_start_ap,
5132 .change_beacon = cfg80211_rtw_change_beacon,
5133 .stop_ap = cfg80211_rtw_stop_ap,
5136 .add_station = cfg80211_rtw_add_station,
5137 .del_station = cfg80211_rtw_del_station,
5138 .change_station = cfg80211_rtw_change_station,
5139 .dump_station = cfg80211_rtw_dump_station,
5140 .change_bss = cfg80211_rtw_change_bss,
5141 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
5142 .set_channel = cfg80211_rtw_set_channel,
5144 //.auth = cfg80211_rtw_auth,
5145 //.assoc = cfg80211_rtw_assoc,
5146 #endif //CONFIG_AP_MODE
5149 .remain_on_channel = cfg80211_rtw_remain_on_channel,
5150 .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
5153 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
5154 .mgmt_tx = cfg80211_rtw_mgmt_tx,
5155 .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
5156 #elif (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,34) && LINUX_VERSION_CODE<=KERNEL_VERSION(2,6,35))
5157 .action = cfg80211_rtw_mgmt_tx,
5161 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap, enum ieee80211_band band, u8 rf_type)
5164 #define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
5165 #define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
5167 ht_cap->ht_supported = _TRUE;
5169 ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
5170 IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
5171 IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
5174 *Maximum length of AMPDU that the STA can receive.
5175 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
5177 ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5179 /*Minimum MPDU start spacing , */
5180 ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5182 ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5185 *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
5188 *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
5189 *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
5190 *if rx_ant >=3 rx_mask[2]=0xff;
5191 *if BW_40 rx_mask[4]=0x01;
5192 *highest supported RX rate
5194 if(rf_type == RF_1T1R)
5196 ht_cap->mcs.rx_mask[0] = 0xFF;
5197 ht_cap->mcs.rx_mask[1] = 0x00;
5198 ht_cap->mcs.rx_mask[4] = 0x01;
5200 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
5202 else if((rf_type == RF_1T2R) || (rf_type==RF_2T2R))
5204 ht_cap->mcs.rx_mask[0] = 0xFF;
5205 ht_cap->mcs.rx_mask[1] = 0xFF;
5206 ht_cap->mcs.rx_mask[4] = 0x01;
5208 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
5212 DBG_8723A("%s, error rf_type=%d\n", __func__, rf_type);
5217 void rtw_cfg80211_init_wiphy(_adapter *padapter)
5220 struct ieee80211_supported_band *bands;
5221 struct wireless_dev *pwdev = padapter->rtw_wdev;
5222 struct wiphy *wiphy = pwdev->wiphy;
5224 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
5226 DBG_8723A("%s:rf_type=%d\n", __func__, rf_type);
5228 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
5230 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
5232 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_2GHZ, rf_type);
5235 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
5237 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
5239 rtw_cfg80211_init_ht_capab(&bands->ht_cap, IEEE80211_BAND_5GHZ, rf_type);
5244 struct ieee80211_iface_limit rtw_limits[] = {
5245 { .max = 1, .types = BIT(NL80211_IFTYPE_STATION)
5246 | BIT(NL80211_IFTYPE_ADHOC)
5247 #ifdef CONFIG_AP_MODE
5248 | BIT(NL80211_IFTYPE_AP)
5250 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
5251 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5252 | BIT(NL80211_IFTYPE_P2P_GO)
5255 {.max = 1, .types = BIT(NL80211_IFTYPE_MONITOR)},
5258 struct ieee80211_iface_combination rtw_combinations = {
5259 .limits = rtw_limits,
5260 .n_limits = ARRAY_SIZE(rtw_limits),
5261 .max_interfaces = 2,
5262 .num_different_channels = 1,
5266 static void rtw_cfg80211_preinit_wiphy(_adapter *padapter, struct wiphy *wiphy)
5269 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5271 wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
5272 wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
5273 wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
5275 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)) || defined(COMPAT_KERNEL_RELEASE)
5276 wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
5279 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
5280 | BIT(NL80211_IFTYPE_ADHOC)
5281 #ifdef CONFIG_AP_MODE
5282 | BIT(NL80211_IFTYPE_AP)
5283 | BIT(NL80211_IFTYPE_MONITOR)
5285 #if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE))
5286 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5287 | BIT(NL80211_IFTYPE_P2P_GO)
5291 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
5292 #ifdef CONFIG_AP_MODE
5293 wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
5294 #endif //CONFIG_AP_MODE
5297 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0))
5298 wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
5302 wiphy->iface_combinations = &rtw_combinations;
5303 wiphy->n_iface_combinations = 1;
5306 wiphy->cipher_suites = rtw_cipher_suites;
5307 wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
5309 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
5310 wiphy->bands[IEEE80211_BAND_2GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
5311 /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
5312 wiphy->bands[IEEE80211_BAND_5GHZ] = rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
5314 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) && LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0))
5315 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
5318 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
5319 wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
5320 wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
5323 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
5324 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
5326 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
5329 int rtw_wdev_alloc(_adapter *padapter, struct device *dev)
5332 struct wiphy *wiphy;
5333 struct wireless_dev *wdev;
5334 struct rtw_wdev_priv *pwdev_priv;
5335 struct net_device *pnetdev = padapter->pnetdev;
5337 DBG_8723A("%s(padapter=%p)\n", __func__, padapter);
5340 wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wdev_priv));
5342 DBG_8723A("Couldn't allocate wiphy device\n");
5346 set_wiphy_dev(wiphy, dev);
5347 rtw_cfg80211_preinit_wiphy(padapter, wiphy);
5349 ret = wiphy_register(wiphy);
5351 DBG_8723A("Couldn't register wiphy device\n");
5356 wdev = (struct wireless_dev *)kzalloc(sizeof(struct wireless_dev));
5358 DBG_8723A("Couldn't allocate wireless device\n");
5360 goto unregister_wiphy;
5362 wdev->wiphy = wiphy;
5363 wdev->netdev = pnetdev;
5364 //wdev->iftype = NL80211_IFTYPE_STATION;
5365 wdev->iftype = NL80211_IFTYPE_MONITOR; // for rtw_setopmode_cmd() in cfg80211_rtw_change_iface()
5366 padapter->rtw_wdev = wdev;
5367 pnetdev->ieee80211_ptr = wdev;
5370 pwdev_priv = wdev_to_priv(wdev);
5371 pwdev_priv->rtw_wdev = wdev;
5372 pwdev_priv->pmon_ndev = NULL;
5373 pwdev_priv->ifname_mon[0] = '\0';
5374 pwdev_priv->padapter = padapter;
5375 pwdev_priv->scan_request = NULL;
5376 _rtw_spinlock_init(&pwdev_priv->scan_req_lock);
5378 pwdev_priv->p2p_enabled = _FALSE;
5379 pwdev_priv->provdisc_req_issued = _FALSE;
5380 rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
5382 pwdev_priv->bandroid_scan = _FALSE;
5384 if(padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
5385 pwdev_priv->power_mgmt = _TRUE;
5387 pwdev_priv->power_mgmt = _FALSE;
5389 #ifdef CONFIG_CONCURRENT_MODE
5390 ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
5391 ATOMIC_SET(&pwdev_priv->ro_ch_to, 1);
5398 wiphy_unregister(wiphy);
5406 void rtw_wdev_free(struct wireless_dev *wdev)
5408 struct rtw_wdev_priv *pwdev_priv;
5410 DBG_8723A("%s(wdev=%p)\n", __func__, wdev);
5415 pwdev_priv = wdev_to_priv(wdev);
5417 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
5418 rtw_spt_band_free(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
5420 wiphy_free(wdev->wiphy);
5425 void rtw_wdev_unregister(struct wireless_dev *wdev)
5427 struct rtw_wdev_priv *pwdev_priv;
5429 DBG_8723A("%s(wdev=%p)\n", __func__, wdev);
5434 pwdev_priv = wdev_to_priv(wdev);
5436 rtw_cfg80211_indicate_scan_done(pwdev_priv, _TRUE);
5438 if (pwdev_priv->pmon_ndev) {
5439 DBG_8723A("%s, unregister monitor interface\n", __func__);
5440 unregister_netdev(pwdev_priv->pmon_ndev);
5443 wiphy_unregister(wdev->wiphy);
5446 #endif //CONFIG_IOCTL_CFG80211