ioctl_cfg80211.c revision 4d9c63bbd207b20ae648bd6bd3ebcf6e52619616
1/******************************************************************************
2 *
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4 *
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.
8 *
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
12 * more details.
13 *
14 ******************************************************************************/
15#define  _IOCTL_CFG80211_C_
16
17#include <osdep_service.h>
18#include <drv_types.h>
19#include <rtw_ioctl_set.h>
20#include <xmit_osdep.h>
21
22#include "ioctl_cfg80211.h"
23
24#define RTW_MAX_MGMT_TX_CNT 8
25
26#define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535	/* ms */
27#define RTW_MAX_NUM_PMKIDS 4
28
29static const u32 rtw_cipher_suites[] = {
30	WLAN_CIPHER_SUITE_WEP40,
31	WLAN_CIPHER_SUITE_WEP104,
32	WLAN_CIPHER_SUITE_TKIP,
33	WLAN_CIPHER_SUITE_CCMP,
34};
35
36#define RATETAB_ENT(_rate, _rateid, _flags) {			\
37	.bitrate	= (_rate),				\
38	.hw_value	= (_rateid),				\
39	.flags		= (_flags),				\
40}
41
42#define CHAN2G(_channel, _freq, _flags) {			\
43	.band			= IEEE80211_BAND_2GHZ,		\
44	.center_freq		= (_freq),			\
45	.hw_value		= (_channel),			\
46	.flags			= (_flags),			\
47	.max_antenna_gain	= 0,				\
48	.max_power		= 30,				\
49}
50
51#define CHAN5G(_channel, _flags) {				\
52	.band			= IEEE80211_BAND_5GHZ,		\
53	.center_freq		= 5000 + (5 * (_channel)),	\
54	.hw_value		= (_channel),			\
55	.flags			= (_flags),			\
56	.max_antenna_gain	= 0,				\
57	.max_power		= 30,				\
58}
59
60static struct ieee80211_rate rtw_rates[] = {
61	RATETAB_ENT(10, 0x1, 0),
62	RATETAB_ENT(20, 0x2, 0),
63	RATETAB_ENT(55, 0x4, 0),
64	RATETAB_ENT(110, 0x8, 0),
65	RATETAB_ENT(60, 0x10, 0),
66	RATETAB_ENT(90, 0x20, 0),
67	RATETAB_ENT(120, 0x40, 0),
68	RATETAB_ENT(180, 0x80, 0),
69	RATETAB_ENT(240, 0x100, 0),
70	RATETAB_ENT(360, 0x200, 0),
71	RATETAB_ENT(480, 0x400, 0),
72	RATETAB_ENT(540, 0x800, 0),
73};
74
75#define rtw_a_rates		(rtw_rates + 4)
76#define RTW_A_RATES_NUM	8
77#define rtw_g_rates		(rtw_rates + 0)
78#define RTW_G_RATES_NUM	12
79
80#define RTW_2G_CHANNELS_NUM 14
81#define RTW_5G_CHANNELS_NUM 37
82
83static struct ieee80211_channel rtw_2ghz_channels[] = {
84	CHAN2G(1, 2412, 0),
85	CHAN2G(2, 2417, 0),
86	CHAN2G(3, 2422, 0),
87	CHAN2G(4, 2427, 0),
88	CHAN2G(5, 2432, 0),
89	CHAN2G(6, 2437, 0),
90	CHAN2G(7, 2442, 0),
91	CHAN2G(8, 2447, 0),
92	CHAN2G(9, 2452, 0),
93	CHAN2G(10, 2457, 0),
94	CHAN2G(11, 2462, 0),
95	CHAN2G(12, 2467, 0),
96	CHAN2G(13, 2472, 0),
97	CHAN2G(14, 2484, 0),
98};
99
100static struct ieee80211_channel rtw_5ghz_a_channels[] = {
101	CHAN5G(34, 0), CHAN5G(36, 0),
102	CHAN5G(38, 0), CHAN5G(40, 0),
103	CHAN5G(42, 0), CHAN5G(44, 0),
104	CHAN5G(46, 0), CHAN5G(48, 0),
105	CHAN5G(52, 0), CHAN5G(56, 0),
106	CHAN5G(60, 0), CHAN5G(64, 0),
107	CHAN5G(100, 0), CHAN5G(104, 0),
108	CHAN5G(108, 0), CHAN5G(112, 0),
109	CHAN5G(116, 0), CHAN5G(120, 0),
110	CHAN5G(124, 0), CHAN5G(128, 0),
111	CHAN5G(132, 0), CHAN5G(136, 0),
112	CHAN5G(140, 0), CHAN5G(149, 0),
113	CHAN5G(153, 0), CHAN5G(157, 0),
114	CHAN5G(161, 0), CHAN5G(165, 0),
115	CHAN5G(184, 0), CHAN5G(188, 0),
116	CHAN5G(192, 0), CHAN5G(196, 0),
117	CHAN5G(200, 0), CHAN5G(204, 0),
118	CHAN5G(208, 0), CHAN5G(212, 0),
119	CHAN5G(216, 0),
120};
121
122static void rtw_2g_channels_init(struct ieee80211_channel *channels)
123{
124	memcpy((void *)channels, (void *)rtw_2ghz_channels,
125	       sizeof(struct ieee80211_channel) * RTW_2G_CHANNELS_NUM);
126}
127
128static void rtw_5g_channels_init(struct ieee80211_channel *channels)
129{
130	memcpy((void *)channels, (void *)rtw_5ghz_a_channels,
131	       sizeof(struct ieee80211_channel) * RTW_5G_CHANNELS_NUM);
132}
133
134static void rtw_2g_rates_init(struct ieee80211_rate *rates)
135{
136	memcpy(rates, rtw_g_rates,
137	       sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM);
138}
139
140static void rtw_5g_rates_init(struct ieee80211_rate *rates)
141{
142	memcpy(rates, rtw_a_rates,
143	       sizeof(struct ieee80211_rate) * RTW_A_RATES_NUM);
144}
145
146static struct ieee80211_supported_band *
147rtw_spt_band_alloc(enum ieee80211_band band)
148{
149	struct ieee80211_supported_band *spt_band = NULL;
150	int n_channels, n_bitrates;
151
152	if (band == IEEE80211_BAND_2GHZ) {
153		n_channels = RTW_2G_CHANNELS_NUM;
154		n_bitrates = RTW_G_RATES_NUM;
155	} else if (band == IEEE80211_BAND_5GHZ) {
156		n_channels = RTW_5G_CHANNELS_NUM;
157		n_bitrates = RTW_A_RATES_NUM;
158	} else {
159		goto exit;
160	}
161	spt_band = kzalloc(sizeof(struct ieee80211_supported_band) +
162			   sizeof(struct ieee80211_channel) * n_channels +
163			   sizeof(struct ieee80211_rate) * n_bitrates,
164			   GFP_KERNEL);
165	if (!spt_band)
166		goto exit;
167
168	spt_band->channels =
169		(struct ieee80211_channel *)(((u8 *) spt_band) +
170					     sizeof(struct
171						    ieee80211_supported_band));
172	spt_band->bitrates =
173		(struct ieee80211_rate *)(((u8 *) spt_band->channels) +
174					  sizeof(struct ieee80211_channel) *
175					  n_channels);
176	spt_band->band = band;
177	spt_band->n_channels = n_channels;
178	spt_band->n_bitrates = n_bitrates;
179
180	if (band == IEEE80211_BAND_2GHZ) {
181		rtw_2g_channels_init(spt_band->channels);
182		rtw_2g_rates_init(spt_band->bitrates);
183	} else if (band == IEEE80211_BAND_5GHZ) {
184		rtw_5g_channels_init(spt_band->channels);
185		rtw_5g_rates_init(spt_band->bitrates);
186	}
187
188	/* spt_band.ht_cap */
189
190exit:
191	return spt_band;
192}
193
194static const struct ieee80211_txrx_stypes
195rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
196	[NL80211_IFTYPE_ADHOC] = {
197		.tx = 0xffff,
198		.rx = BIT(IEEE80211_STYPE_ACTION >> 4)
199	},
200	[NL80211_IFTYPE_STATION] = {
201		.tx = 0xffff,
202		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
203		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
204	},
205	[NL80211_IFTYPE_AP] = {
206		.tx = 0xffff,
207		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
208		      BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
209		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
210		      BIT(IEEE80211_STYPE_DISASSOC >> 4) |
211		      BIT(IEEE80211_STYPE_AUTH >> 4) |
212		      BIT(IEEE80211_STYPE_DEAUTH >> 4) |
213		      BIT(IEEE80211_STYPE_ACTION >> 4)
214	},
215	[NL80211_IFTYPE_AP_VLAN] = {
216		/* copy AP */
217		.tx = 0xffff,
218		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
219		      BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
220		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
221		      BIT(IEEE80211_STYPE_DISASSOC >> 4) |
222		      BIT(IEEE80211_STYPE_AUTH >> 4) |
223		      BIT(IEEE80211_STYPE_DEAUTH >> 4) |
224		      BIT(IEEE80211_STYPE_ACTION >> 4)
225	},
226	[NL80211_IFTYPE_P2P_CLIENT] = {
227		.tx = 0xffff,
228		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
229		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
230	},
231	[NL80211_IFTYPE_P2P_GO] = {
232		.tx = 0xffff,
233		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
234		      BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
235		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
236		      BIT(IEEE80211_STYPE_DISASSOC >> 4) |
237		      BIT(IEEE80211_STYPE_AUTH >> 4) |
238		      BIT(IEEE80211_STYPE_DEAUTH >> 4) |
239		      BIT(IEEE80211_STYPE_ACTION >> 4)
240	},
241};
242
243#define MAX_BSSINFO_LEN 1000
244static int rtw_cfg80211_inform_bss(struct rtw_adapter *padapter,
245				   struct wlan_network *pnetwork)
246{
247	int ret = 0;
248	struct ieee80211_channel *notify_channel;
249	struct cfg80211_bss *bss;
250	/* struct ieee80211_supported_band *band; */
251	u16 channel;
252	u32 freq;
253	u64 notify_timestamp;
254	u16 notify_capability;
255	u16 notify_interval;
256	u8 *notify_ie;
257	size_t notify_ielen;
258	s32 notify_signal;
259	u8 buf[MAX_BSSINFO_LEN], *pbuf;
260	size_t len;
261	struct ieee80211_hdr *pwlanhdr;
262	struct wireless_dev *wdev = padapter->rtw_wdev;
263	struct wiphy *wiphy = wdev->wiphy;
264	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
265
266	/* DBG_8723A("%s\n", __func__); */
267
268	if (pnetwork->network.IELength > MAX_IE_SZ) {
269		DBG_8723A("%s IE Length too long > %d byte\n", __func__,
270			  MAX_IE_SZ);
271		goto exit;
272	}
273
274	channel = pnetwork->network.DSConfig;
275	if (channel <= RTW_CH_MAX_2G_CHANNEL)
276		freq = ieee80211_channel_to_frequency(channel,
277						      IEEE80211_BAND_2GHZ);
278	else
279		freq = ieee80211_channel_to_frequency(channel,
280						      IEEE80211_BAND_5GHZ);
281
282	notify_channel = ieee80211_get_channel(wiphy, freq);
283
284	notify_timestamp = jiffies_to_msecs(jiffies) * 1000;	/* uSec */
285
286	notify_interval =
287		get_unaligned_le16(
288			rtw_get_beacon_interval23a_from_ie(pnetwork->network.IEs));
289	notify_capability =
290		get_unaligned_le16(
291			rtw_get_capability23a_from_ie(pnetwork->network.IEs));
292
293	notify_ie = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
294	notify_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
295
296	/* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM:
297	 *  signal strength in mBm (100*dBm)
298	 */
299	if (check_fwstate(pmlmepriv, _FW_LINKED) &&
300	    is_same_network23a(&pmlmepriv->cur_network.network,
301			    &pnetwork->network)) {
302		notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength);	/* dbm */
303	} else {
304		notify_signal = 100 * translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);	/* dbm */
305	}
306	pbuf = buf;
307
308	pwlanhdr = (struct ieee80211_hdr *)pbuf;
309
310	pwlanhdr->seq_ctrl = 0;
311
312	if (pnetwork->network.reserved == 1) {	/*  WIFI_BEACON */
313		eth_broadcast_addr(pwlanhdr->addr1);
314		pwlanhdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
315						      IEEE80211_STYPE_BEACON);
316	} else {
317		ether_addr_copy(pwlanhdr->addr1, myid(&padapter->eeprompriv));
318		pwlanhdr->frame_control =
319			cpu_to_le16(IEEE80211_FTYPE_MGMT |
320				    IEEE80211_STYPE_PROBE_RESP);
321	}
322
323	ether_addr_copy(pwlanhdr->addr2, pnetwork->network.MacAddress);
324	ether_addr_copy(pwlanhdr->addr3, pnetwork->network.MacAddress);
325
326	pbuf += sizeof(struct ieee80211_hdr_3addr);
327	len = sizeof(struct ieee80211_hdr_3addr);
328
329	memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength);
330	len += pnetwork->network.IELength;
331
332	bss = cfg80211_inform_bss_frame(wiphy, notify_channel,
333					(struct ieee80211_mgmt *)buf, len,
334					notify_signal, GFP_ATOMIC);
335
336	if (unlikely(!bss)) {
337		DBG_8723A("rtw_cfg80211_inform_bss error\n");
338		return -EINVAL;
339	}
340
341	cfg80211_put_bss(wiphy, bss);
342
343exit:
344	return ret;
345}
346
347void rtw_cfg80211_indicate_connect(struct rtw_adapter *padapter)
348{
349	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
350	struct wlan_network *cur_network = &pmlmepriv->cur_network;
351	struct wireless_dev *pwdev = padapter->rtw_wdev;
352
353	DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
354
355	if (pwdev->iftype != NL80211_IFTYPE_STATION &&
356	    pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
357		return;
358
359	if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
360		return;
361
362	if (padapter->mlmepriv.to_roaming > 0) {
363		struct wiphy *wiphy = pwdev->wiphy;
364		struct ieee80211_channel *notify_channel;
365		u32 freq;
366		u16 channel = cur_network->network.DSConfig;
367
368		if (channel <= RTW_CH_MAX_2G_CHANNEL)
369			freq =
370			    ieee80211_channel_to_frequency(channel,
371							   IEEE80211_BAND_2GHZ);
372		else
373			freq =
374			    ieee80211_channel_to_frequency(channel,
375							   IEEE80211_BAND_5GHZ);
376
377		notify_channel = ieee80211_get_channel(wiphy, freq);
378
379		DBG_8723A("%s call cfg80211_roamed\n", __func__);
380		cfg80211_roamed(padapter->pnetdev, notify_channel,
381				cur_network->network.MacAddress,
382				pmlmepriv->assoc_req +
383				sizeof(struct ieee80211_hdr_3addr) + 2,
384				pmlmepriv->assoc_req_len -
385				sizeof(struct ieee80211_hdr_3addr) - 2,
386				pmlmepriv->assoc_rsp +
387				sizeof(struct ieee80211_hdr_3addr) + 6,
388				pmlmepriv->assoc_rsp_len -
389				sizeof(struct ieee80211_hdr_3addr) - 6,
390				GFP_ATOMIC);
391	} else {
392		cfg80211_connect_result(padapter->pnetdev,
393					cur_network->network.MacAddress,
394					pmlmepriv->assoc_req +
395					sizeof(struct ieee80211_hdr_3addr) + 2,
396					pmlmepriv->assoc_req_len -
397					sizeof(struct ieee80211_hdr_3addr) - 2,
398					pmlmepriv->assoc_rsp +
399					sizeof(struct ieee80211_hdr_3addr) + 6,
400					pmlmepriv->assoc_rsp_len -
401					sizeof(struct ieee80211_hdr_3addr) - 6,
402					WLAN_STATUS_SUCCESS, GFP_ATOMIC);
403	}
404}
405
406void rtw_cfg80211_indicate_disconnect(struct rtw_adapter *padapter)
407{
408	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
409	struct wireless_dev *pwdev = padapter->rtw_wdev;
410
411	DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
412
413	if (pwdev->iftype != NL80211_IFTYPE_STATION &&
414	    pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
415		return;
416
417	if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
418		return;
419
420	if (!padapter->mlmepriv.not_indic_disco) {
421		if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING)) {
422			cfg80211_connect_result(padapter->pnetdev, NULL, NULL,
423						0, NULL, 0,
424						WLAN_STATUS_UNSPECIFIED_FAILURE,
425						GFP_ATOMIC);
426		} else {
427			cfg80211_disconnected(padapter->pnetdev, 0, NULL,
428					      0, GFP_ATOMIC);
429		}
430	}
431}
432
433#ifdef CONFIG_8723AU_AP_MODE
434static int set_pairwise_key(struct rtw_adapter *padapter, struct sta_info *psta)
435{
436	struct cmd_obj *ph2c;
437	struct set_stakey_parm *psetstakey_para;
438	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
439	int res = _SUCCESS;
440
441	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
442	if (ph2c == NULL) {
443		res = _FAIL;
444		goto exit;
445	}
446
447	psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
448	if (psetstakey_para == NULL) {
449		kfree(ph2c);
450		res = _FAIL;
451		goto exit;
452	}
453
454	init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
455
456	psetstakey_para->algorithm = psta->dot118021XPrivacy;
457
458	ether_addr_copy(psetstakey_para->addr, psta->hwaddr);
459
460	memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
461
462	res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
463
464exit:
465	return res;
466}
467
468static int set_group_key(struct rtw_adapter *padapter, u8 *key, u32 alg,
469			 u8 keyid)
470{
471	u8 keylen;
472	struct cmd_obj *pcmd;
473	struct setkey_parm *psetkeyparm;
474	struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
475	int res = _SUCCESS;
476
477	DBG_8723A("%s\n", __func__);
478
479	if (keyid >= 4) {
480		res = _FAIL;
481		goto exit;
482	}
483
484	pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
485	if (!pcmd) {
486		res = _FAIL;
487		goto exit;
488	}
489	psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
490	if (!psetkeyparm) {
491		kfree(pcmd);
492		res = _FAIL;
493		goto exit;
494	}
495
496	psetkeyparm->keyid = keyid;
497	if (is_wep_enc(alg))
498		padapter->mlmepriv.key_mask |= BIT(psetkeyparm->keyid);
499
500	psetkeyparm->algorithm = alg;
501
502	psetkeyparm->set_tx = 1;
503
504	switch (alg) {
505	case WLAN_CIPHER_SUITE_WEP40:
506		keylen = 5;
507		break;
508	case WLAN_CIPHER_SUITE_WEP104:
509		keylen = 13;
510		break;
511	case WLAN_CIPHER_SUITE_TKIP:
512	case WLAN_CIPHER_SUITE_CCMP:
513	default:
514		keylen = 16;
515	}
516
517	memcpy(&psetkeyparm->key[0], key, keylen);
518
519	pcmd->cmdcode = _SetKey_CMD_;
520	pcmd->parmbuf = (u8 *) psetkeyparm;
521	pcmd->cmdsz = (sizeof(struct setkey_parm));
522	pcmd->rsp = NULL;
523	pcmd->rspsz = 0;
524
525	res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
526
527exit:
528	return res;
529}
530
531static int set_wep_key(struct rtw_adapter *padapter, u8 *key, u16 keylen,
532		       u8 keyid)
533{
534	u32 alg;
535
536	switch (keylen) {
537	case 5:
538		alg = WLAN_CIPHER_SUITE_WEP40;
539		break;
540	case 13:
541		alg = WLAN_CIPHER_SUITE_WEP104;
542		break;
543	default:
544		alg = 0;
545	}
546
547	return set_group_key(padapter, key, alg, keyid);
548}
549
550static int rtw_cfg80211_ap_set_encryption(struct net_device *dev,
551					  struct ieee_param *param,
552					  u32 param_len)
553{
554	int ret = 0;
555	u16 wep_key_len;
556	u8 wep_key_idx;
557	struct sta_info *psta = NULL, *pbcmc_sta = NULL;
558	struct rtw_adapter *padapter = netdev_priv(dev);
559	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
560	struct security_priv *psecuritypriv = &padapter->securitypriv;
561	struct sta_priv *pstapriv = &padapter->stapriv;
562
563	DBG_8723A("%s\n", __func__);
564
565	param->u.crypt.err = 0;
566	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
567
568	/* sizeof(struct ieee_param) = 64 bytes; */
569	/* if (param_len !=  (u32) ((u8 *) param->u.crypt.key -
570	   (u8 *) param) + param->u.crypt.key_len) */
571	if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
572		ret = -EINVAL;
573		goto exit;
574	}
575
576	if (is_broadcast_ether_addr(param->sta_addr)) {
577		if (param->u.crypt.idx >= WEP_KEYS) {
578			ret = -EINVAL;
579			goto exit;
580		}
581	} else {
582		psta = rtw_get_stainfo23a(pstapriv, param->sta_addr);
583		if (!psta) {
584			/* ret = -EINVAL; */
585			DBG_8723A("rtw_set_encryption(), sta has already "
586				  "been removed or never been added\n");
587			goto exit;
588		}
589	}
590
591	if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
592		/* todo:clear default encryption keys */
593
594		DBG_8723A("clear default encryption keys, keyid =%d\n",
595			  param->u.crypt.idx);
596
597		goto exit;
598	}
599
600	if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
601		DBG_8723A("r871x_set_encryption, crypt.alg = WEP\n");
602
603		wep_key_idx = param->u.crypt.idx;
604		wep_key_len = param->u.crypt.key_len;
605
606		DBG_8723A("r871x_set_encryption, wep_key_idx =%d, len =%d\n",
607			  wep_key_idx, wep_key_len);
608
609		if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
610			ret = -EINVAL;
611			goto exit;
612		}
613
614		if (wep_key_len > 0) {
615			wep_key_len = wep_key_len <= 5 ? 5 : 13;
616		}
617
618		if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
619			/* wep default key has not been set, so use
620			   this key index as default key. */
621
622			psecuritypriv->ndisencryptstatus =
623				Ndis802_11Encryption1Enabled;
624			psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
625			psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40;
626
627			if (wep_key_len == 13) {
628				psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104;
629				psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP104;
630			}
631
632			psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
633		}
634
635		memcpy(&psecuritypriv->wep_key[wep_key_idx].key,
636		       param->u.crypt.key, wep_key_len);
637
638		psecuritypriv->wep_key[wep_key_idx].keylen = wep_key_len;
639
640		set_wep_key(padapter, param->u.crypt.key, wep_key_len,
641			    wep_key_idx);
642
643		goto exit;
644
645	}
646
647	if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) {	/*  group key */
648		if (param->u.crypt.set_tx == 0) {	/* group key */
649			if (strcmp(param->u.crypt.alg, "WEP") == 0) {
650				DBG_8723A("%s, set group_key, WEP\n", __func__);
651
652				memcpy(psecuritypriv->
653				       dot118021XGrpKey[param->u.crypt.idx].
654				       skey, param->u.crypt.key,
655				       (param->u.crypt.key_len >
656					16 ? 16 : param->u.crypt.key_len));
657
658				psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40;
659				if (param->u.crypt.key_len == 13) {
660					psecuritypriv->dot118021XGrpPrivacy =
661					    WLAN_CIPHER_SUITE_WEP104;
662				}
663
664			} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
665				DBG_8723A("%s, set group_key, TKIP\n",
666					  __func__);
667
668				psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_TKIP;
669
670				memcpy(psecuritypriv->
671				       dot118021XGrpKey[param->u.crypt.idx].
672				       skey, param->u.crypt.key,
673				       (param->u.crypt.key_len >
674					16 ? 16 : param->u.crypt.key_len));
675
676				/* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
677				/* set mic key */
678				memcpy(psecuritypriv->
679				       dot118021XGrptxmickey[param->u.crypt.
680							     idx].skey,
681				       &param->u.crypt.key[16], 8);
682				memcpy(psecuritypriv->
683				       dot118021XGrprxmickey[param->u.crypt.
684							     idx].skey,
685				       &param->u.crypt.key[24], 8);
686
687				psecuritypriv->busetkipkey = 1;
688
689			} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
690				DBG_8723A("%s, set group_key, CCMP\n",
691					  __func__);
692
693				psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_CCMP;
694
695				memcpy(psecuritypriv->
696				       dot118021XGrpKey[param->u.crypt.idx].
697				       skey, param->u.crypt.key,
698				       (param->u.crypt.key_len >
699					16 ? 16 : param->u.crypt.key_len));
700			} else {
701				DBG_8723A("%s, set group_key, none\n",
702					  __func__);
703
704				psecuritypriv->dot118021XGrpPrivacy =
705				    0;
706			}
707
708			psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
709
710			psecuritypriv->binstallGrpkey = 1;
711
712			psecuritypriv->dot11PrivacyAlgrthm =
713				psecuritypriv->dot118021XGrpPrivacy;
714
715			set_group_key(padapter, param->u.crypt.key,
716				      psecuritypriv->dot118021XGrpPrivacy,
717				      param->u.crypt.idx);
718
719			pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter);
720			if (pbcmc_sta) {
721				pbcmc_sta->ieee8021x_blocked = false;
722				/* rx will use bmc_sta's dot118021XPrivacy */
723				pbcmc_sta->dot118021XPrivacy =
724					psecuritypriv->dot118021XGrpPrivacy;
725
726			}
727
728		}
729
730		goto exit;
731	}
732
733	if (psecuritypriv->dot11AuthAlgrthm ==
734	    dot11AuthAlgrthm_8021X && psta) {	/*  psk/802_1x */
735		if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
736			if (param->u.crypt.set_tx == 1) {
737				/* pairwise key */
738				memcpy(psta->dot118021x_UncstKey.skey,
739				       param->u.crypt.key,
740				       (param->u.crypt.key_len >
741					16 ? 16 : param->u.crypt.key_len));
742
743				if (!strcmp(param->u.crypt.alg, "WEP")) {
744					DBG_8723A("%s, set pairwise key, WEP\n",
745						  __func__);
746
747					psta->dot118021XPrivacy = WLAN_CIPHER_SUITE_WEP40;
748					if (param->u.crypt.key_len == 13) {
749						psta->dot118021XPrivacy =
750							WLAN_CIPHER_SUITE_WEP104;
751					}
752				} else if (!strcmp(param->u.crypt.alg, "TKIP")) {
753					DBG_8723A("%s, set pairwise key, "
754						  "TKIP\n", __func__);
755
756					psta->dot118021XPrivacy = WLAN_CIPHER_SUITE_TKIP;
757
758					/* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
759					/* set mic key */
760					memcpy(psta->dot11tkiptxmickey.skey,
761					       &param->u.crypt.key[16], 8);
762					memcpy(psta->dot11tkiprxmickey.skey,
763					       &param->u.crypt.key[24], 8);
764
765					psecuritypriv->busetkipkey = 1;
766
767				} else if (!strcmp(param->u.crypt.alg, "CCMP")) {
768
769					DBG_8723A("%s, set pairwise key, "
770						  "CCMP\n", __func__);
771
772					psta->dot118021XPrivacy = WLAN_CIPHER_SUITE_CCMP;
773				} else {
774					DBG_8723A("%s, set pairwise key, "
775						  "none\n", __func__);
776
777					psta->dot118021XPrivacy = 0;
778				}
779
780				set_pairwise_key(padapter, psta);
781
782				psta->ieee8021x_blocked = false;
783
784				psta->bpairwise_key_installed = true;
785			} else {	/* group key??? */
786				if (!strcmp(param->u.crypt.alg, "WEP")) {
787					memcpy(psecuritypriv->
788					       dot118021XGrpKey[param->u.crypt.
789								idx].skey,
790					       param->u.crypt.key,
791					       (param->u.crypt.key_len >
792						16 ? 16 : param->u.crypt.
793						key_len));
794
795					psecuritypriv->dot118021XGrpPrivacy =
796						WLAN_CIPHER_SUITE_WEP40;
797					if (param->u.crypt.key_len == 13) {
798						psecuritypriv->
799						    dot118021XGrpPrivacy =
800							WLAN_CIPHER_SUITE_WEP104;
801					}
802				} else if (!strcmp(param->u.crypt.alg, "TKIP")) {
803					psecuritypriv->dot118021XGrpPrivacy =
804					    WLAN_CIPHER_SUITE_TKIP;
805
806					memcpy(psecuritypriv->
807					       dot118021XGrpKey[param->u.crypt.
808								idx].skey,
809					       param->u.crypt.key,
810					       (param->u.crypt.key_len >
811						16 ? 16 : param->u.crypt.
812						key_len));
813
814					/* DEBUG_ERR("set key length :param->u"
815					   ".crypt.key_len =%d\n",
816					   param->u.crypt.key_len); */
817					/* set mic key */
818					memcpy(psecuritypriv->
819					       dot118021XGrptxmickey[param->u.
820								     crypt.idx].
821					       skey, &param->u.crypt.key[16],
822					       8);
823					memcpy(psecuritypriv->
824					       dot118021XGrprxmickey[param->u.
825								     crypt.idx].
826					       skey, &param->u.crypt.key[24],
827					       8);
828
829					psecuritypriv->busetkipkey = 1;
830
831				} else if (!strcmp(param->u.crypt.alg, "CCMP")) {
832					psecuritypriv->dot118021XGrpPrivacy =
833						WLAN_CIPHER_SUITE_CCMP;
834
835					memcpy(psecuritypriv->
836					       dot118021XGrpKey[param->u.crypt.
837								idx].skey,
838					       param->u.crypt.key,
839					       (param->u.crypt.key_len >
840						16 ? 16 : param->u.crypt.
841						key_len));
842				} else {
843					psecuritypriv->dot118021XGrpPrivacy =
844						0;
845				}
846
847				psecuritypriv->dot118021XGrpKeyid =
848					param->u.crypt.idx;
849
850				psecuritypriv->binstallGrpkey = 1;
851
852				psecuritypriv->dot11PrivacyAlgrthm =
853					psecuritypriv->dot118021XGrpPrivacy;
854
855				set_group_key(padapter, param->u.crypt.key,
856					      psecuritypriv->
857					      dot118021XGrpPrivacy,
858					      param->u.crypt.idx);
859
860				pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter);
861				if (pbcmc_sta) {
862					/* rx will use bmc_sta's
863					   dot118021XPrivacy */
864					pbcmc_sta->ieee8021x_blocked = false;
865					pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;
866				}
867			}
868		}
869	}
870
871exit:
872
873	return ret;
874
875}
876#endif
877
878static int rtw_cfg80211_set_encryption(struct net_device *dev,
879				       struct ieee_param *param, u32 param_len)
880{
881	int ret = 0;
882	u32 wep_key_idx;
883	u16 wep_key_len;
884	struct rtw_adapter *padapter = netdev_priv(dev);
885	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
886	struct security_priv *psecuritypriv = &padapter->securitypriv;
887
888	DBG_8723A("%s\n", __func__);
889
890	param->u.crypt.err = 0;
891	param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
892
893	if (param_len <
894	    (u32) ((u8 *) param->u.crypt.key - (u8 *) param) +
895	    param->u.crypt.key_len) {
896		ret = -EINVAL;
897		goto exit;
898	}
899
900	if (is_broadcast_ether_addr(param->sta_addr)) {
901		if (param->u.crypt.idx >= WEP_KEYS) {
902			ret = -EINVAL;
903			goto exit;
904		}
905	} else {
906		ret = -EINVAL;
907		goto exit;
908	}
909
910	if (strcmp(param->u.crypt.alg, "WEP") == 0) {
911		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
912			 ("wpa_set_encryption, crypt.alg = WEP\n"));
913		DBG_8723A("wpa_set_encryption, crypt.alg = WEP\n");
914
915		wep_key_idx = param->u.crypt.idx;
916		wep_key_len = param->u.crypt.key_len;
917
918		if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0)) {
919			ret = -EINVAL;
920			goto exit;
921		}
922
923		if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
924			/* wep default key has not been set, so use this
925			   key index as default key. */
926
927			wep_key_len = wep_key_len <= 5 ? 5 : 13;
928
929			psecuritypriv->ndisencryptstatus =
930				Ndis802_11Encryption1Enabled;
931			psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
932			psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40;
933
934			if (wep_key_len == 13) {
935				psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104;
936				psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP104;
937			}
938
939			psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
940		}
941
942		memcpy(&psecuritypriv->wep_key[wep_key_idx].key,
943		       param->u.crypt.key, wep_key_len);
944
945		psecuritypriv->wep_key[wep_key_idx].keylen = wep_key_len;
946
947		rtw_set_key23a(padapter, psecuritypriv, wep_key_idx, 0);
948
949		goto exit;
950	}
951
952	if (padapter->securitypriv.dot11AuthAlgrthm ==
953	    dot11AuthAlgrthm_8021X) {	/*  802_1x */
954		struct sta_info *psta, *pbcmc_sta;
955		struct sta_priv *pstapriv = &padapter->stapriv;
956
957		if (check_fwstate(pmlmepriv,
958				  WIFI_STATION_STATE | WIFI_MP_STATE)) {
959			/* sta mode */
960			psta = rtw_get_stainfo23a(pstapriv, get_bssid(pmlmepriv));
961			if (psta == NULL) {
962				DBG_8723A("%s, : Obtain Sta_info fail\n",
963					  __func__);
964			} else {
965				/* Jeff: don't disable ieee8021x_blocked
966				   while clearing key */
967				if (strcmp(param->u.crypt.alg, "none") != 0)
968					psta->ieee8021x_blocked = false;
969
970				if ((padapter->securitypriv.ndisencryptstatus ==
971				     Ndis802_11Encryption2Enabled) ||
972				    (padapter->securitypriv.ndisencryptstatus ==
973				     Ndis802_11Encryption3Enabled)) {
974					psta->dot118021XPrivacy =
975						padapter->securitypriv.
976						dot11PrivacyAlgrthm;
977				}
978
979				if (param->u.crypt.set_tx == 1) {
980					/* pairwise key */
981					DBG_8723A("%s, : param->u.crypt.set_tx"
982						  " == 1\n", __func__);
983
984					memcpy(psta->dot118021x_UncstKey.skey,
985					       param->u.crypt.key,
986					       (param->u.crypt.key_len >
987						16 ? 16 : param->u.crypt.
988						key_len));
989
990					if (strcmp(param->u.crypt.alg,
991						   "TKIP") == 0) {
992						memcpy(psta->dot11tkiptxmickey.
993						       skey,
994						       &param->u.crypt.key[16],
995						       8);
996						memcpy(psta->dot11tkiprxmickey.
997						       skey,
998						       &param->u.crypt.key[24],
999						       8);
1000
1001						padapter->securitypriv.
1002							busetkipkey = 0;
1003					}
1004					DBG_8723A(" ~~~~set sta key:unicastkey\n");
1005
1006					rtw_setstakey_cmd23a(padapter,
1007							  (unsigned char *)psta,
1008							  true);
1009				} else {	/* group key */
1010					memcpy(padapter->securitypriv.
1011					       dot118021XGrpKey[param->u.crypt.
1012								idx].skey,
1013					       param->u.crypt.key,
1014					       (param->u.crypt.key_len >
1015						16 ? 16 : param->u.crypt.
1016						key_len));
1017					memcpy(padapter->securitypriv.
1018					       dot118021XGrptxmickey[param->u.
1019								     crypt.idx].
1020					       skey, &param->u.crypt.key[16],
1021					       8);
1022					memcpy(padapter->securitypriv.
1023					       dot118021XGrprxmickey[param->u.
1024								     crypt.idx].
1025					       skey, &param->u.crypt.key[24],
1026					       8);
1027					padapter->securitypriv.binstallGrpkey =
1028						1;
1029					/* DEBUG_ERR((" param->u.crypt.key_len"
1030					   "=%d\n", param->u.crypt.key_len)); */
1031					DBG_8723A
1032					    (" ~~~~set sta key:groupkey\n");
1033
1034					padapter->securitypriv.
1035					    dot118021XGrpKeyid =
1036						param->u.crypt.idx;
1037
1038					rtw_set_key23a(padapter,
1039						    &padapter->securitypriv,
1040						    param->u.crypt.idx, 1);
1041				}
1042			}
1043
1044			pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter);
1045			if (pbcmc_sta) {
1046				/* Jeff: don't disable ieee8021x_blocked
1047				   while clearing key */
1048				if (strcmp(param->u.crypt.alg, "none") != 0)
1049					pbcmc_sta->ieee8021x_blocked = false;
1050
1051				if ((padapter->securitypriv.ndisencryptstatus ==
1052				     Ndis802_11Encryption2Enabled) ||
1053				    (padapter->securitypriv.ndisencryptstatus ==
1054				     Ndis802_11Encryption3Enabled)) {
1055					pbcmc_sta->dot118021XPrivacy =
1056					    padapter->securitypriv.
1057					    dot11PrivacyAlgrthm;
1058				}
1059			}
1060		} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {	/* adhoc mode */
1061		}
1062	}
1063
1064exit:
1065
1066	DBG_8723A("%s, ret =%d\n", __func__, ret);
1067
1068
1069
1070	return ret;
1071}
1072
1073static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
1074				u8 key_index, bool pairwise,
1075				const u8 *mac_addr, struct key_params *params)
1076{
1077	char *alg_name;
1078	u32 param_len;
1079	struct ieee_param *param;
1080	int ret = 0;
1081	struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
1082	struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
1083	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1084
1085	DBG_8723A("%s(%s): adding key for %pM\n", __func__, ndev->name,
1086		  mac_addr);
1087	DBG_8723A("cipher = 0x%x\n", params->cipher);
1088	DBG_8723A("key_len = 0x%x\n", params->key_len);
1089	DBG_8723A("seq_len = 0x%x\n", params->seq_len);
1090	DBG_8723A("key_index =%d\n", key_index);
1091	DBG_8723A("pairwise =%d\n", pairwise);
1092
1093	param_len = sizeof(struct ieee_param) + params->key_len;
1094	param = kzalloc(param_len, GFP_KERNEL);
1095	if (!param)
1096		return -ENOMEM;
1097
1098	param->cmd = IEEE_CMD_SET_ENCRYPTION;
1099	eth_broadcast_addr(param->sta_addr);
1100
1101	switch (params->cipher) {
1102	case IW_AUTH_CIPHER_NONE:
1103		/* todo: remove key */
1104		/* remove = 1; */
1105		alg_name = "none";
1106		break;
1107	case WLAN_CIPHER_SUITE_WEP40:
1108	case WLAN_CIPHER_SUITE_WEP104:
1109		alg_name = "WEP";
1110		break;
1111	case WLAN_CIPHER_SUITE_TKIP:
1112		alg_name = "TKIP";
1113		break;
1114	case WLAN_CIPHER_SUITE_CCMP:
1115		alg_name = "CCMP";
1116		break;
1117
1118	default:
1119		ret = -ENOTSUPP;
1120		goto addkey_end;
1121	}
1122
1123	strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1124
1125	if (!mac_addr || is_broadcast_ether_addr(mac_addr)) {
1126		param->u.crypt.set_tx = 0;	/* for wpa/wpa2 group key */
1127	} else {
1128		param->u.crypt.set_tx = 1;	/* for wpa/wpa2 pairwise key */
1129	}
1130
1131	/* param->u.crypt.idx = key_index - 1; */
1132	param->u.crypt.idx = key_index;
1133
1134	if (params->seq_len && params->seq) {
1135		memcpy(param->u.crypt.seq, params->seq, params->seq_len);
1136	}
1137
1138	if (params->key_len && params->key) {
1139		param->u.crypt.key_len = params->key_len;
1140		memcpy(param->u.crypt.key, params->key, params->key_len);
1141	}
1142
1143	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1144		ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
1145	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1146#ifdef CONFIG_8723AU_AP_MODE
1147		if (mac_addr)
1148			ether_addr_copy(param->sta_addr, mac_addr);
1149
1150		ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
1151#endif
1152	} else {
1153		DBG_8723A("error! fw_state = 0x%x, iftype =%d\n",
1154			  pmlmepriv->fw_state, rtw_wdev->iftype);
1155
1156	}
1157
1158addkey_end:
1159	kfree(param);
1160
1161	return ret;
1162}
1163
1164static int
1165cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
1166		     u8 key_index, bool pairwise, const u8 *mac_addr,
1167		     void *cookie,
1168		     void (*callback) (void *cookie, struct key_params *))
1169{
1170	DBG_8723A("%s(%s)\n", __func__, ndev->name);
1171	return 0;
1172}
1173
1174static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
1175				u8 key_index, bool pairwise,
1176				const u8 *mac_addr)
1177{
1178	struct rtw_adapter *padapter = netdev_priv(ndev);
1179	struct security_priv *psecuritypriv = &padapter->securitypriv;
1180
1181	DBG_8723A("%s(%s): key_index =%d\n", __func__, ndev->name, key_index);
1182
1183	if (key_index == psecuritypriv->dot11PrivacyKeyIndex) {
1184		/* clear the flag of wep default key set. */
1185		psecuritypriv->bWepDefaultKeyIdxSet = 0;
1186	}
1187
1188	return 0;
1189}
1190
1191static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
1192					struct net_device *ndev, u8 key_index,
1193					bool unicast, bool multicast)
1194{
1195	struct rtw_adapter *padapter = netdev_priv(ndev);
1196	struct security_priv *psecuritypriv = &padapter->securitypriv;
1197
1198	DBG_8723A("%s(%s): key_index =%d, unicast =%d, multicast =%d.\n",
1199		  __func__, ndev->name, key_index, unicast, multicast);
1200
1201	if (key_index < NUM_WEP_KEYS &&
1202	    (psecuritypriv->dot11PrivacyAlgrthm == WLAN_CIPHER_SUITE_WEP40 ||
1203	     psecuritypriv->dot11PrivacyAlgrthm == WLAN_CIPHER_SUITE_WEP104)) {
1204		/* set wep default key */
1205		psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1206
1207		psecuritypriv->dot11PrivacyKeyIndex = key_index;
1208
1209		psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
1210		psecuritypriv->dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40;
1211		if (psecuritypriv->wep_key[key_index].keylen == 13) {
1212			psecuritypriv->dot11PrivacyAlgrthm =
1213				WLAN_CIPHER_SUITE_WEP104;
1214			psecuritypriv->dot118021XGrpPrivacy =
1215				WLAN_CIPHER_SUITE_WEP104;
1216		}
1217
1218		/* set the flag to represent that wep default key
1219		   has been set */
1220		psecuritypriv->bWepDefaultKeyIdxSet = 1;
1221	}
1222
1223	return 0;
1224}
1225
1226static int cfg80211_rtw_get_station(struct wiphy *wiphy,
1227				    struct net_device *ndev,
1228				    const u8 *mac, struct station_info *sinfo)
1229{
1230	int ret = 0;
1231	struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
1232	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1233	struct sta_info *psta = NULL;
1234	struct sta_priv *pstapriv = &padapter->stapriv;
1235
1236	sinfo->filled = 0;
1237
1238	if (!mac) {
1239		DBG_8723A("%s(%s): mac ==%p\n", __func__, ndev->name, mac);
1240		ret = -ENOENT;
1241		goto exit;
1242	}
1243
1244	psta = rtw_get_stainfo23a(pstapriv, mac);
1245	if (psta == NULL) {
1246		DBG_8723A("%s, sta_info is null\n", __func__);
1247		ret = -ENOENT;
1248		goto exit;
1249	}
1250	DBG_8723A("%s(%s): mac =" MAC_FMT "\n", __func__, ndev->name,
1251		  MAC_ARG(mac));
1252
1253	/* for infra./P2PClient mode */
1254	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
1255	    check_fwstate(pmlmepriv, _FW_LINKED)) {
1256		struct wlan_network *cur_network = &pmlmepriv->cur_network;
1257
1258		if (!ether_addr_equal(mac, cur_network->network.MacAddress)) {
1259			DBG_8723A("%s, mismatch bssid =" MAC_FMT "\n", __func__,
1260				  MAC_ARG(cur_network->network.MacAddress));
1261			ret = -ENOENT;
1262			goto exit;
1263		}
1264
1265		sinfo->filled |= STATION_INFO_SIGNAL;
1266		sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.
1267							    signal_strength);
1268
1269		sinfo->filled |= STATION_INFO_TX_BITRATE;
1270		sinfo->txrate.legacy = rtw_get_cur_max_rate23a(padapter);
1271
1272		sinfo->filled |= STATION_INFO_RX_PACKETS;
1273		sinfo->rx_packets = sta_rx_data_pkts(psta);
1274
1275		sinfo->filled |= STATION_INFO_TX_PACKETS;
1276		sinfo->tx_packets = psta->sta_stats.tx_pkts;
1277	}
1278
1279	/* for Ad-Hoc/AP mode */
1280	if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
1281	     check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1282	     check_fwstate(pmlmepriv, WIFI_AP_STATE)) &&
1283	    check_fwstate(pmlmepriv, _FW_LINKED)
1284	    ) {
1285		/* TODO: should acquire station info... */
1286	}
1287
1288exit:
1289	return ret;
1290}
1291
1292int cfg80211_infrastructure_mode(struct rtw_adapter* padapter,
1293				 enum nl80211_iftype ifmode)
1294{
1295	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1296	struct wlan_network *cur_network = &pmlmepriv->cur_network;
1297	enum nl80211_iftype old_mode;
1298
1299	old_mode = cur_network->network.ifmode;
1300
1301	RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_notice_,
1302		 ("+%s: old =%d new =%d fw_state = 0x%08x\n", __func__,
1303		  old_mode, ifmode, get_fwstate(pmlmepriv)));
1304
1305	if (old_mode != ifmode) {
1306		spin_lock_bh(&pmlmepriv->lock);
1307
1308		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1309			 (" change mode!"));
1310
1311		if (old_mode == NL80211_IFTYPE_AP ||
1312		    old_mode == NL80211_IFTYPE_P2P_GO) {
1313			/* change to other mode from Ndis802_11APMode */
1314			cur_network->join_res = -1;
1315
1316#ifdef CONFIG_8723AU_AP_MODE
1317			stop_ap_mode23a(padapter);
1318#endif
1319		}
1320
1321		if (check_fwstate(pmlmepriv, _FW_LINKED) ||
1322		    old_mode == NL80211_IFTYPE_ADHOC)
1323			rtw_disassoc_cmd23a(padapter, 0, true);
1324
1325		if (check_fwstate(pmlmepriv, _FW_LINKED) ||
1326		    check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE))
1327			rtw_free_assoc_resources23a(padapter, 1);
1328
1329		if (old_mode == NL80211_IFTYPE_STATION ||
1330		    old_mode == NL80211_IFTYPE_P2P_CLIENT ||
1331		    old_mode == NL80211_IFTYPE_ADHOC) {
1332			if (check_fwstate(pmlmepriv, _FW_LINKED)) {
1333				/* will clr Linked_state; before this function,
1334				   we must have chked whether issue
1335				   dis-assoc_cmd or not */
1336				rtw_indicate_disconnect23a(padapter);
1337			}
1338	       }
1339
1340		cur_network->network.ifmode = ifmode;
1341
1342		_clr_fwstate_(pmlmepriv, ~WIFI_NULL_STATE);
1343
1344		switch (ifmode) {
1345		case NL80211_IFTYPE_ADHOC:
1346			set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
1347			break;
1348
1349		case NL80211_IFTYPE_P2P_CLIENT:
1350		case NL80211_IFTYPE_STATION:
1351			set_fwstate(pmlmepriv, WIFI_STATION_STATE);
1352			break;
1353
1354		case NL80211_IFTYPE_P2P_GO:
1355		case NL80211_IFTYPE_AP:
1356			set_fwstate(pmlmepriv, WIFI_AP_STATE);
1357#ifdef CONFIG_8723AU_AP_MODE
1358			start_ap_mode23a(padapter);
1359			/* rtw_indicate_connect23a(padapter); */
1360#endif
1361			break;
1362
1363		default:
1364			break;
1365		}
1366
1367		/* SecClearAllKeys(adapter); */
1368
1369		/* RT_TRACE(COMP_OID_SET, DBG_LOUD,
1370		   ("set_infrastructure: fw_state:%x after changing mode\n", */
1371		/* get_fwstate(pmlmepriv))); */
1372
1373		spin_unlock_bh(&pmlmepriv->lock);
1374	}
1375
1376	return _SUCCESS;
1377}
1378
1379static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
1380				     struct net_device *ndev,
1381				     enum nl80211_iftype type, u32 *flags,
1382				     struct vif_params *params)
1383{
1384	enum nl80211_iftype old_type;
1385	struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
1386	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1387	struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
1388	int ret = 0;
1389
1390	DBG_8723A("%s(%s): call netdev_open23a\n", __func__, ndev->name);
1391
1392	old_type = rtw_wdev->iftype;
1393	DBG_8723A("%s(%s): old_iftype =%d, new_iftype =%d\n",
1394		  __func__, ndev->name, old_type, type);
1395
1396	if (old_type != type) {
1397		pmlmeext->action_public_rxseq = 0xffff;
1398		pmlmeext->action_public_dialog_token = 0xff;
1399	}
1400
1401	switch (type) {
1402	case NL80211_IFTYPE_ADHOC:
1403	case NL80211_IFTYPE_P2P_CLIENT:
1404	case NL80211_IFTYPE_STATION:
1405	case NL80211_IFTYPE_P2P_GO:
1406	case NL80211_IFTYPE_AP:
1407	case NL80211_IFTYPE_UNSPECIFIED:
1408		break;
1409	default:
1410		return -EOPNOTSUPP;
1411	}
1412
1413	rtw_wdev->iftype = type;
1414
1415	if (cfg80211_infrastructure_mode(padapter, type) != _SUCCESS) {
1416		rtw_wdev->iftype = old_type;
1417		ret = -EPERM;
1418		goto exit;
1419	}
1420
1421	rtw_setopmode_cmd23a(padapter, type);
1422
1423exit:
1424	return ret;
1425}
1426
1427void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv,
1428				     bool aborted)
1429{
1430	spin_lock_bh(&pwdev_priv->scan_req_lock);
1431	if (pwdev_priv->scan_request != NULL) {
1432		DBG_8723A("%s with scan req\n", __func__);
1433
1434		if (pwdev_priv->scan_request->wiphy !=
1435		    pwdev_priv->rtw_wdev->wiphy)
1436			DBG_8723A("error wiphy compare\n");
1437		else
1438			cfg80211_scan_done(pwdev_priv->scan_request, aborted);
1439
1440		pwdev_priv->scan_request = NULL;
1441	} else {
1442		DBG_8723A("%s without scan req\n", __func__);
1443	}
1444	spin_unlock_bh(&pwdev_priv->scan_req_lock);
1445}
1446
1447void rtw_cfg80211_surveydone_event_callback(struct rtw_adapter *padapter)
1448{
1449	struct list_head *plist, *phead, *ptmp;
1450	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1451	struct rtw_queue *queue = &pmlmepriv->scanned_queue;
1452	struct wlan_network *pnetwork;
1453
1454	spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1455
1456	phead = get_list_head(queue);
1457
1458	list_for_each_safe(plist, ptmp, phead) {
1459		pnetwork = container_of(plist, struct wlan_network, list);
1460
1461		/* report network only if the current channel set
1462		   contains the channel to which this network belongs */
1463		if (rtw_ch_set_search_ch23a
1464		    (padapter->mlmeextpriv.channel_set,
1465		     pnetwork->network.DSConfig) >= 0)
1466			rtw_cfg80211_inform_bss(padapter, pnetwork);
1467	}
1468
1469	spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1470
1471	/* call this after other things have been done */
1472	rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev),
1473					false);
1474}
1475
1476static int rtw_cfg80211_set_probe_req_wpsp2pie(struct rtw_adapter *padapter,
1477					       char *buf, int len)
1478{
1479	int ret = 0;
1480	const u8 *wps_ie;
1481	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1482
1483	DBG_8723A("%s, ielen =%d\n", __func__, len);
1484
1485	if (len > 0) {
1486		wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1487						 WLAN_OUI_TYPE_MICROSOFT_WPS,
1488						 buf, len);
1489		if (wps_ie) {
1490			DBG_8723A("probe_req_wps_ielen =%d\n", wps_ie[1]);
1491
1492			if (pmlmepriv->wps_probe_req_ie) {
1493				pmlmepriv->wps_probe_req_ie_len = 0;
1494				kfree(pmlmepriv->wps_probe_req_ie);
1495				pmlmepriv->wps_probe_req_ie = NULL;
1496			}
1497
1498			pmlmepriv->wps_probe_req_ie = kmemdup(wps_ie, wps_ie[1],
1499							      GFP_KERNEL);
1500			if (pmlmepriv->wps_probe_req_ie == NULL) {
1501				DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
1502					  __func__, __LINE__);
1503				return -EINVAL;
1504			}
1505			pmlmepriv->wps_probe_req_ie_len = wps_ie[1];
1506		}
1507	}
1508
1509	return ret;
1510}
1511
1512static int cfg80211_rtw_scan(struct wiphy *wiphy,
1513			     struct cfg80211_scan_request *request)
1514{
1515	int i;
1516	u8 _status = false;
1517	int ret = 0;
1518	struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
1519	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1520	struct cfg80211_ssid ssid[RTW_SSID_SCAN_AMOUNT];
1521	struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
1522	struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
1523	struct cfg80211_ssid *ssids = request->ssids;
1524	bool need_indicate_scan_done = false;
1525
1526	DBG_8723A("%s(%s)\n", __func__, padapter->pnetdev->name);
1527
1528	spin_lock_bh(&pwdev_priv->scan_req_lock);
1529	pwdev_priv->scan_request = request;
1530	spin_unlock_bh(&pwdev_priv->scan_req_lock);
1531
1532	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1533		DBG_8723A("%s under WIFI_AP_STATE\n", __func__);
1534		/* need_indicate_scan_done = true; */
1535		/* goto check_need_indicate_scan_done; */
1536	}
1537
1538	if (rtw_pwr_wakeup(padapter) == _FAIL) {
1539		need_indicate_scan_done = true;
1540		goto check_need_indicate_scan_done;
1541	}
1542
1543	if (request->ie && request->ie_len > 0) {
1544		rtw_cfg80211_set_probe_req_wpsp2pie(padapter,
1545						    (u8 *) request->ie,
1546						    request->ie_len);
1547	}
1548
1549	if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true) {
1550		DBG_8723A("%s, bBusyTraffic == true\n", __func__);
1551		need_indicate_scan_done = true;
1552		goto check_need_indicate_scan_done;
1553	}
1554	if (rtw_is_scan_deny(padapter)) {
1555		DBG_8723A("%s(%s): scan deny\n", __func__,
1556			  padapter->pnetdev->name);
1557		need_indicate_scan_done = true;
1558		goto check_need_indicate_scan_done;
1559	}
1560
1561	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) ==
1562	    true) {
1563		DBG_8723A("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
1564		need_indicate_scan_done = true;
1565		goto check_need_indicate_scan_done;
1566	}
1567
1568	memset(ssid, 0, sizeof(struct cfg80211_ssid) * RTW_SSID_SCAN_AMOUNT);
1569	/* parsing request ssids, n_ssids */
1570	for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
1571		DBG_8723A("ssid =%s, len =%d\n", ssids[i].ssid,
1572			  ssids[i].ssid_len);
1573		memcpy(ssid[i].ssid, ssids[i].ssid, ssids[i].ssid_len);
1574		ssid[i].ssid_len = ssids[i].ssid_len;
1575	}
1576
1577	/* parsing channels, n_channels */
1578	memset(ch, 0,
1579	       sizeof(struct rtw_ieee80211_channel) * RTW_CHANNEL_SCAN_AMOUNT);
1580
1581	if (request->n_channels == 1) {
1582		for (i = 0; i < request->n_channels &&
1583		     i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
1584			DBG_8723A("%s:(%s):" CHAN_FMT "\n",
1585				  __func__, padapter->pnetdev->name,
1586				  CHAN_ARG(request->channels[i]));
1587			ch[i].hw_value = request->channels[i]->hw_value;
1588			ch[i].flags = request->channels[i]->flags;
1589		}
1590	}
1591
1592	spin_lock_bh(&pmlmepriv->lock);
1593	if (request->n_channels == 1) {
1594		memcpy(&ch[1], &ch[0], sizeof(struct rtw_ieee80211_channel));
1595		memcpy(&ch[2], &ch[0], sizeof(struct rtw_ieee80211_channel));
1596		_status = rtw_sitesurvey_cmd23a(padapter, ssid,
1597					     RTW_SSID_SCAN_AMOUNT, ch, 3);
1598	} else {
1599		_status = rtw_sitesurvey_cmd23a(padapter, ssid,
1600					     RTW_SSID_SCAN_AMOUNT, NULL, 0);
1601	}
1602	spin_unlock_bh(&pmlmepriv->lock);
1603
1604	if (_status == false)
1605		ret = -1;
1606
1607check_need_indicate_scan_done:
1608	if (need_indicate_scan_done)
1609		rtw_cfg80211_surveydone_event_callback(padapter);
1610	return ret;
1611}
1612
1613static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1614{
1615	DBG_8723A("%s\n", __func__);
1616	return 0;
1617}
1618
1619static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1620				  struct cfg80211_ibss_params *params)
1621{
1622	DBG_8723A("%s(%s)\n", __func__, ndev->name);
1623	return 0;
1624}
1625
1626static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1627{
1628	DBG_8723A("%s(%s)\n", __func__, ndev->name);
1629	return 0;
1630}
1631
1632static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv,
1633					u32 wpa_version)
1634{
1635	DBG_8723A("%s, wpa_version =%d\n", __func__, wpa_version);
1636
1637	if (!wpa_version) {
1638		psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
1639		return 0;
1640	}
1641
1642	if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) {
1643		psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
1644	}
1645
1646/*
1647	if (wpa_version & NL80211_WPA_VERSION_2)
1648	{
1649		psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
1650	}
1651*/
1652
1653	return 0;
1654}
1655
1656static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
1657				      enum nl80211_auth_type sme_auth_type)
1658{
1659	DBG_8723A("%s, nl80211_auth_type =%d\n", __func__, sme_auth_type);
1660
1661	switch (sme_auth_type) {
1662	case NL80211_AUTHTYPE_AUTOMATIC:
1663		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1664
1665		break;
1666	case NL80211_AUTHTYPE_OPEN_SYSTEM:
1667		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1668
1669		if (psecuritypriv->ndisauthtype > Ndis802_11AuthModeWPA)
1670			psecuritypriv->dot11AuthAlgrthm =
1671				dot11AuthAlgrthm_8021X;
1672		break;
1673	case NL80211_AUTHTYPE_SHARED_KEY:
1674		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1675
1676		psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1677		break;
1678	default:
1679		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1680		/* return -ENOTSUPP; */
1681	}
1682
1683	return 0;
1684}
1685
1686static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv,
1687				   u32 cipher, bool ucast)
1688{
1689	u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
1690
1691	u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
1692	    &psecuritypriv->dot118021XGrpPrivacy;
1693
1694	DBG_8723A("%s, ucast =%d, cipher = 0x%x\n", __func__, ucast, cipher);
1695
1696	if (!cipher) {
1697		*profile_cipher = 0;
1698		psecuritypriv->ndisencryptstatus = ndisencryptstatus;
1699		return 0;
1700	}
1701
1702	switch (cipher) {
1703	case IW_AUTH_CIPHER_NONE:
1704		*profile_cipher = 0;
1705		ndisencryptstatus = Ndis802_11EncryptionDisabled;
1706		break;
1707	case WLAN_CIPHER_SUITE_WEP40:
1708		*profile_cipher = WLAN_CIPHER_SUITE_WEP40;
1709		ndisencryptstatus = Ndis802_11Encryption1Enabled;
1710		break;
1711	case WLAN_CIPHER_SUITE_WEP104:
1712		*profile_cipher = WLAN_CIPHER_SUITE_WEP104;
1713		ndisencryptstatus = Ndis802_11Encryption1Enabled;
1714		break;
1715	case WLAN_CIPHER_SUITE_TKIP:
1716		*profile_cipher = WLAN_CIPHER_SUITE_TKIP;
1717		ndisencryptstatus = Ndis802_11Encryption2Enabled;
1718		break;
1719	case WLAN_CIPHER_SUITE_CCMP:
1720		*profile_cipher = WLAN_CIPHER_SUITE_CCMP;
1721		ndisencryptstatus = Ndis802_11Encryption3Enabled;
1722		break;
1723	default:
1724		DBG_8723A("Unsupported cipher: 0x%x\n", cipher);
1725		return -ENOTSUPP;
1726	}
1727
1728	if (ucast)
1729		psecuritypriv->ndisencryptstatus = ndisencryptstatus;
1730
1731	return 0;
1732}
1733
1734static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv,
1735				    u32 key_mgt)
1736{
1737	DBG_8723A("%s, key_mgt = 0x%x\n", __func__, key_mgt);
1738
1739	if (key_mgt == WLAN_AKM_SUITE_8021X)
1740		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1741	else if (key_mgt == WLAN_AKM_SUITE_PSK)
1742		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1743	else
1744		DBG_8723A("Invalid key mgt: 0x%x\n", key_mgt);
1745
1746	return 0;
1747}
1748
1749static int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie,
1750				   size_t ielen)
1751{
1752	const u8 *wps_ie;
1753	u8 *buf = NULL;
1754	int group_cipher = 0, pairwise_cipher = 0;
1755	int ret = 0;
1756	const u8 *pwpa, *pwpa2;
1757	int i;
1758
1759	if (!pie || !ielen) {
1760		/* Treat this as normal case, but need to clear
1761		   WIFI_UNDER_WPS */
1762		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1763		goto exit;
1764	}
1765	if (ielen > MAX_WPA_IE_LEN + MAX_WPS_IE_LEN + MAX_P2P_IE_LEN) {
1766		ret = -EINVAL;
1767		goto exit;
1768	}
1769	buf = kmemdup(pie, ielen, GFP_KERNEL);
1770	if (buf == NULL) {
1771		ret = -ENOMEM;
1772		goto exit;
1773	}
1774
1775	/* dump */
1776	DBG_8723A("set wpa_ie(length:%zu):\n", ielen);
1777	for (i = 0; i < ielen; i = i + 8)
1778		DBG_8723A("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
1779			  buf[i], buf[i + 1],
1780			  buf[i + 2], buf[i + 3], buf[i + 4],
1781			  buf[i + 5], buf[i + 6], buf[i + 7]);
1782	if (ielen < RSN_HEADER_LEN) {
1783		RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
1784			 ("Ie len too short %d\n", (int)ielen));
1785		ret = -1;
1786		goto exit;
1787	}
1788
1789	pwpa = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1790				       WLAN_OUI_TYPE_MICROSOFT_WPA,
1791				       buf, ielen);
1792	if (pwpa && pwpa[1] > 0) {
1793		if (rtw_parse_wpa_ie23a(pwpa, pwpa[1] + 2, &group_cipher,
1794					&pairwise_cipher, NULL) == _SUCCESS) {
1795			padapter->securitypriv.dot11AuthAlgrthm =
1796				dot11AuthAlgrthm_8021X;
1797			padapter->securitypriv.ndisauthtype =
1798				Ndis802_11AuthModeWPAPSK;
1799			memcpy(padapter->securitypriv.supplicant_ie, pwpa,
1800			       pwpa[1] + 2);
1801
1802			DBG_8723A("got wpa_ie, wpa_ielen:%u\n", pwpa[1]);
1803		}
1804	}
1805
1806	pwpa2 = cfg80211_find_ie(WLAN_EID_RSN, buf, ielen);
1807	if (pwpa2 && pwpa2[1] > 0) {
1808		if (rtw_parse_wpa2_ie23a (pwpa2, pwpa2[1] + 2, &group_cipher,
1809					  &pairwise_cipher, NULL) == _SUCCESS) {
1810			padapter->securitypriv.dot11AuthAlgrthm =
1811				dot11AuthAlgrthm_8021X;
1812			padapter->securitypriv.ndisauthtype =
1813				Ndis802_11AuthModeWPA2PSK;
1814			memcpy(padapter->securitypriv.supplicant_ie, pwpa2,
1815			       pwpa2[1] + 2);
1816
1817			DBG_8723A("got wpa2_ie, wpa2_ielen:%u\n", pwpa2[1]);
1818		}
1819	}
1820
1821	if (group_cipher == 0) {
1822		group_cipher = WPA_CIPHER_NONE;
1823	}
1824	if (pairwise_cipher == 0) {
1825		pairwise_cipher = WPA_CIPHER_NONE;
1826	}
1827
1828	switch (group_cipher) {
1829	case WPA_CIPHER_NONE:
1830		padapter->securitypriv.dot118021XGrpPrivacy = 0;
1831		padapter->securitypriv.ndisencryptstatus =
1832			Ndis802_11EncryptionDisabled;
1833		break;
1834	case WPA_CIPHER_WEP40:
1835		padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40;
1836		padapter->securitypriv.ndisencryptstatus =
1837			Ndis802_11Encryption1Enabled;
1838		break;
1839	case WPA_CIPHER_TKIP:
1840		padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_TKIP;
1841		padapter->securitypriv.ndisencryptstatus =
1842			Ndis802_11Encryption2Enabled;
1843		break;
1844	case WPA_CIPHER_CCMP:
1845		padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_CCMP;
1846		padapter->securitypriv.ndisencryptstatus =
1847			Ndis802_11Encryption3Enabled;
1848		break;
1849	case WPA_CIPHER_WEP104:
1850		padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP104;
1851		padapter->securitypriv.ndisencryptstatus =
1852			Ndis802_11Encryption1Enabled;
1853		break;
1854	}
1855
1856	switch (pairwise_cipher) {
1857	case WPA_CIPHER_NONE:
1858		padapter->securitypriv.dot11PrivacyAlgrthm = 0;
1859		padapter->securitypriv.ndisencryptstatus =
1860			Ndis802_11EncryptionDisabled;
1861		break;
1862	case WPA_CIPHER_WEP40:
1863		padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
1864		padapter->securitypriv.ndisencryptstatus =
1865			Ndis802_11Encryption1Enabled;
1866		break;
1867	case WPA_CIPHER_TKIP:
1868		padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_TKIP;
1869		padapter->securitypriv.ndisencryptstatus =
1870			Ndis802_11Encryption2Enabled;
1871		break;
1872	case WPA_CIPHER_CCMP:
1873		padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_CCMP;
1874		padapter->securitypriv.ndisencryptstatus =
1875			Ndis802_11Encryption3Enabled;
1876		break;
1877	case WPA_CIPHER_WEP104:
1878		padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104;
1879		padapter->securitypriv.ndisencryptstatus =
1880			Ndis802_11Encryption1Enabled;
1881		break;
1882	}
1883
1884	wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1885					 WLAN_OUI_TYPE_MICROSOFT_WPS,
1886					 buf, ielen);
1887	if (wps_ie && wps_ie[1] > 0) {
1888		DBG_8723A("got wps_ie, wps_ielen:%u\n", wps_ie[1]);
1889		padapter->securitypriv.wps_ie_len = wps_ie[1];
1890		memcpy(padapter->securitypriv.wps_ie, wps_ie,
1891		       padapter->securitypriv.wps_ie_len);
1892		set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
1893	} else {
1894		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1895	}
1896
1897	/* TKIP and AES disallow multicast packets until installing group key */
1898	if (padapter->securitypriv.dot11PrivacyAlgrthm ==
1899	    WLAN_CIPHER_SUITE_TKIP ||
1900	    padapter->securitypriv.dot11PrivacyAlgrthm ==
1901	    WLAN_CIPHER_SUITE_CCMP)
1902		/* WPS open need to enable multicast */
1903		/* check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true)*/
1904		rtl8723a_off_rcr_am(padapter);
1905
1906	RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1907		 ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->"
1908		  "securitypriv.ndisencryptstatus =%d padapter->"
1909		  "securitypriv.ndisauthtype =%d\n", pairwise_cipher,
1910		  padapter->securitypriv.ndisencryptstatus,
1911		  padapter->securitypriv.ndisauthtype));
1912
1913exit:
1914	kfree(buf);
1915	if (ret)
1916		_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1917	return ret;
1918}
1919
1920static int rtw_cfg80211_add_wep(struct rtw_adapter *padapter,
1921				struct rtw_wep_key *wep, u8 keyid)
1922{
1923	int res;
1924	struct security_priv *psecuritypriv = &padapter->securitypriv;
1925
1926	if (keyid >= NUM_WEP_KEYS) {
1927		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
1928			 ("%s:keyid>4 =>fail\n", __func__));
1929		res = _FAIL;
1930		goto exit;
1931	}
1932
1933	switch (wep->keylen) {
1934	case WLAN_KEY_LEN_WEP40:
1935		psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
1936		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1937			 ("%s:wep->KeyLength = 5\n", __func__));
1938		break;
1939	case WLAN_KEY_LEN_WEP104:
1940		psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104;
1941		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1942			 ("%s:wep->KeyLength = 13\n", __func__));
1943		break;
1944	default:
1945		psecuritypriv->dot11PrivacyAlgrthm = 0;
1946		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1947			 ("%s:wep->KeyLength!= 5 or 13\n", __func__));
1948		res = _FAIL;
1949		goto exit;
1950	}
1951
1952	RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1953		 ("%s:before memcpy, wep->KeyLength = 0x%x keyid =%x\n",
1954		  __func__, wep->keylen, keyid));
1955
1956	memcpy(&psecuritypriv->wep_key[keyid], wep, sizeof(struct rtw_wep_key));
1957
1958	psecuritypriv->dot11PrivacyKeyIndex = keyid;
1959
1960	RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1961		 ("%s:security key material : "
1962		  "%x %x %x %x %x %x %x %x %x %x %x %x %x\n", __func__,
1963		  psecuritypriv->wep_key[keyid].key[0],
1964		  psecuritypriv->wep_key[keyid].key[1],
1965		  psecuritypriv->wep_key[keyid].key[2],
1966		  psecuritypriv->wep_key[keyid].key[3],
1967		  psecuritypriv->wep_key[keyid].key[4],
1968		  psecuritypriv->wep_key[keyid].key[5],
1969		  psecuritypriv->wep_key[keyid].key[6],
1970		  psecuritypriv->wep_key[keyid].key[7],
1971		  psecuritypriv->wep_key[keyid].key[8],
1972		  psecuritypriv->wep_key[keyid].key[9],
1973		  psecuritypriv->wep_key[keyid].key[10],
1974		  psecuritypriv->wep_key[keyid].key[11],
1975		  psecuritypriv->wep_key[keyid].key[12]));
1976
1977	res = rtw_set_key23a(padapter, psecuritypriv, keyid, 1);
1978
1979exit:
1980
1981	return res;
1982}
1983
1984static int rtw_set_ssid(struct rtw_adapter *padapter,
1985			struct wlan_network *newnetwork)
1986{
1987	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1988	struct wlan_network *pnetwork = &pmlmepriv->cur_network;
1989	int status = _SUCCESS;
1990	u32 cur_time = 0;
1991
1992	DBG_8723A_LEVEL(_drv_always_, "set ssid [%s] fw_state = 0x%08x\n",
1993			newnetwork->network.Ssid.ssid, get_fwstate(pmlmepriv));
1994
1995	if (padapter->hw_init_completed == false) {
1996		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
1997			 ("set_ssid: hw_init_completed == false =>exit!!!\n"));
1998		status = _FAIL;
1999		goto exit;
2000	}
2001
2002	spin_lock_bh(&pmlmepriv->lock);
2003
2004	DBG_8723A("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
2005	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
2006		goto handle_tkip_countermeasure;
2007
2008	if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
2009		RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
2010			 ("set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n"));
2011
2012		if (pmlmepriv->assoc_ssid.ssid_len ==
2013		    newnetwork->network.Ssid.ssid_len &&
2014		    !memcmp(&pmlmepriv->assoc_ssid.ssid,
2015			    newnetwork->network.Ssid.ssid,
2016			    newnetwork->network.Ssid.ssid_len)) {
2017			if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
2018				RT_TRACE(_module_rtl871x_ioctl_set_c_,
2019					 _drv_err_, ("New SSID is same SSID, "
2020						     "fw_state = 0x%08x\n",
2021						     get_fwstate(pmlmepriv)));
2022
2023				if (rtw_is_same_ibss23a(padapter, pnetwork)) {
2024					/*
2025					 * it means driver is in
2026					 * WIFI_ADHOC_MASTER_STATE, we needn't
2027					 * create bss again.
2028					 */
2029					goto release_mlme_lock;
2030				}
2031
2032				/*
2033				 * if in WIFI_ADHOC_MASTER_STATE |
2034				 * WIFI_ADHOC_STATE, create bss or
2035				 * rejoin again
2036				 */
2037				rtw_disassoc_cmd23a(padapter, 0, true);
2038
2039				if (check_fwstate(pmlmepriv, _FW_LINKED))
2040					rtw_indicate_disconnect23a(padapter);
2041
2042				rtw_free_assoc_resources23a(padapter, 1);
2043
2044				if (check_fwstate(pmlmepriv,
2045						  WIFI_ADHOC_MASTER_STATE)) {
2046					_clr_fwstate_(pmlmepriv,
2047						      WIFI_ADHOC_MASTER_STATE);
2048					set_fwstate(pmlmepriv,
2049						    WIFI_ADHOC_STATE);
2050				}
2051			} else {
2052				rtw_lps_ctrl_wk_cmd23a(padapter,
2053						       LPS_CTRL_JOINBSS, 1);
2054			}
2055		} else {
2056			RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
2057				 ("Set SSID not the same ssid\n"));
2058			RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
2059				 ("set_ssid =[%s] len = 0x%x\n",
2060				  newnetwork->network.Ssid.ssid,
2061				  newnetwork->network.Ssid.ssid_len));
2062			RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
2063				 ("assoc_ssid =[%s] len = 0x%x\n",
2064				  pmlmepriv->assoc_ssid.ssid,
2065				  pmlmepriv->assoc_ssid.ssid_len));
2066
2067			rtw_disassoc_cmd23a(padapter, 0, true);
2068
2069			if (check_fwstate(pmlmepriv, _FW_LINKED))
2070				rtw_indicate_disconnect23a(padapter);
2071
2072			rtw_free_assoc_resources23a(padapter, 1);
2073
2074			if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
2075				_clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
2076				set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
2077			}
2078		}
2079	}
2080
2081handle_tkip_countermeasure:
2082
2083	if (padapter->securitypriv.btkip_countermeasure == true) {
2084		cur_time = jiffies;
2085
2086		if ((cur_time -
2087		     padapter->securitypriv.btkip_countermeasure_time) >
2088		    60 * HZ) {
2089			padapter->securitypriv.btkip_countermeasure = false;
2090			padapter->securitypriv.btkip_countermeasure_time = 0;
2091		} else {
2092			status = _FAIL;
2093			goto release_mlme_lock;
2094		}
2095	}
2096
2097	memcpy(&pmlmepriv->assoc_ssid, &newnetwork->network.Ssid,
2098	       sizeof(struct cfg80211_ssid));
2099
2100	pmlmepriv->assoc_by_bssid = false;
2101
2102	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
2103		pmlmepriv->to_join = true;
2104	else
2105		status = rtw_do_join23a(padapter);
2106
2107release_mlme_lock:
2108	spin_unlock_bh(&pmlmepriv->lock);
2109
2110exit:
2111	RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
2112		 ("-%s: status =%d\n", __func__, status));
2113
2114	return status;
2115}
2116
2117static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
2118				struct cfg80211_connect_params *sme)
2119{
2120	int ret = 0;
2121	struct list_head *phead, *plist, *ptmp;
2122	struct wlan_network *pnetwork = NULL;
2123	/* u8 matched_by_bssid = false; */
2124	/* u8 matched_by_ssid = false; */
2125	u8 matched = false;
2126	struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2127	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2128	struct security_priv *psecuritypriv = &padapter->securitypriv;
2129	struct rtw_queue *queue = &pmlmepriv->scanned_queue;
2130
2131	DBG_8723A("=>" "%s(%s)\n", __func__, ndev->name);
2132	DBG_8723A("privacy =%d, key =%p, key_len =%d, key_idx =%d\n",
2133		  sme->privacy, sme->key, sme->key_len, sme->key_idx);
2134
2135	if (_FAIL == rtw_pwr_wakeup(padapter)) {
2136		ret = -EPERM;
2137		goto exit;
2138	}
2139
2140	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2141		ret = -EPERM;
2142		goto exit;
2143	}
2144
2145	if (!sme->ssid || !sme->ssid_len ||
2146	    sme->ssid_len > IEEE80211_MAX_SSID_LEN) {
2147		ret = -EINVAL;
2148		goto exit;
2149	}
2150
2151	DBG_8723A("ssid =%s, len =%zu\n", sme->ssid, sme->ssid_len);
2152
2153	if (sme->bssid)
2154		DBG_8723A("bssid =" MAC_FMT "\n", MAC_ARG(sme->bssid));
2155
2156	if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
2157		ret = -EBUSY;
2158		DBG_8723A("%s, fw_state = 0x%x, goto exit\n", __func__,
2159			  pmlmepriv->fw_state);
2160		goto exit;
2161	}
2162	if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
2163		rtw_scan_abort23a(padapter);
2164	}
2165
2166	spin_lock_bh(&queue->lock);
2167
2168	phead = get_list_head(queue);
2169
2170	list_for_each_safe(plist, ptmp, phead) {
2171		pnetwork = container_of(plist, struct wlan_network, list);
2172
2173		if (sme->bssid) {
2174			if (!ether_addr_equal(pnetwork->network.MacAddress,
2175					      sme->bssid))
2176				continue;
2177		}
2178
2179		if (sme->ssid && sme->ssid_len) {
2180			if (pnetwork->network.Ssid.ssid_len != sme->ssid_len ||
2181			    memcmp(pnetwork->network.Ssid.ssid, sme->ssid,
2182				   sme->ssid_len))
2183				continue;
2184		}
2185
2186		if (sme->bssid) {
2187			if (ether_addr_equal(pnetwork->network.MacAddress,
2188					     sme->bssid)) {
2189				DBG_8723A("matched by bssid\n");
2190
2191				matched = true;
2192				break;
2193			}
2194		} else if (sme->ssid && sme->ssid_len) {
2195			if (!memcmp(pnetwork->network.Ssid.ssid,
2196				    sme->ssid, sme->ssid_len) &&
2197			    pnetwork->network.Ssid.ssid_len == sme->ssid_len) {
2198				DBG_8723A("matched by ssid\n");
2199
2200				matched = true;
2201				break;
2202			}
2203		}
2204	}
2205
2206	spin_unlock_bh(&queue->lock);
2207
2208	if (!matched || !pnetwork) {
2209		ret = -ENOENT;
2210		DBG_8723A("connect, matched == false, goto exit\n");
2211		goto exit;
2212	}
2213
2214	if (cfg80211_infrastructure_mode(
2215		    padapter, pnetwork->network.ifmode) != _SUCCESS) {
2216		ret = -EPERM;
2217		goto exit;
2218	}
2219
2220	psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
2221	psecuritypriv->dot11PrivacyAlgrthm = 0;
2222	psecuritypriv->dot118021XGrpPrivacy = 0;
2223	psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2224	psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2225
2226	ret = rtw_cfg80211_set_wpa_version(psecuritypriv,
2227					   sme->crypto.wpa_versions);
2228	if (ret < 0)
2229		goto exit;
2230
2231	ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
2232
2233	if (ret < 0)
2234		goto exit;
2235
2236	DBG_8723A("%s, ie_len =%zu\n", __func__, sme->ie_len);
2237
2238	ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len);
2239	if (ret < 0)
2240		goto exit;
2241
2242	if (sme->crypto.n_ciphers_pairwise) {
2243		ret = rtw_cfg80211_set_cipher(psecuritypriv,
2244					      sme->crypto.ciphers_pairwise[0],
2245					      true);
2246		if (ret < 0)
2247			goto exit;
2248	}
2249
2250	/* For WEP Shared auth */
2251	if ((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared ||
2252	     psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) &&
2253	    sme->key) {
2254		struct rtw_wep_key wep_key;
2255		u8 wep_key_idx, wep_key_len;
2256		DBG_8723A("%s(): Shared/Auto WEP\n", __func__);
2257
2258		wep_key_idx = sme->key_idx;
2259		wep_key_len = sme->key_len;
2260
2261		if (wep_key_idx > WEP_KEYS || !wep_key_len ||
2262		    wep_key_len > WLAN_KEY_LEN_WEP104) {
2263			ret = -EINVAL;
2264			goto exit;
2265		}
2266
2267		wep_key_len = wep_key_len <= 5 ? 5 : 13;
2268
2269		memset(&wep_key, 0, sizeof(struct rtw_wep_key));
2270
2271		wep_key.keylen = wep_key_len;
2272
2273		if (wep_key_len == 13) {
2274			padapter->securitypriv.dot11PrivacyAlgrthm =
2275				WLAN_CIPHER_SUITE_WEP104;
2276			padapter->securitypriv.dot118021XGrpPrivacy =
2277				WLAN_CIPHER_SUITE_WEP104;
2278		} else {
2279			padapter->securitypriv.dot11PrivacyAlgrthm =
2280				WLAN_CIPHER_SUITE_WEP40;
2281			padapter->securitypriv.dot118021XGrpPrivacy =
2282				WLAN_CIPHER_SUITE_WEP40;
2283		}
2284
2285		memcpy(wep_key.key, (void *)sme->key, wep_key.keylen);
2286
2287		if (rtw_cfg80211_add_wep(padapter, &wep_key, wep_key_idx) !=
2288		    _SUCCESS)
2289			ret = -EOPNOTSUPP;
2290
2291		if (ret < 0)
2292			goto exit;
2293	}
2294
2295	ret = rtw_cfg80211_set_cipher(psecuritypriv,
2296				      sme->crypto.cipher_group, false);
2297	if (ret < 0)
2298		goto exit;
2299
2300	if (sme->crypto.n_akm_suites) {
2301		ret = rtw_cfg80211_set_key_mgt(psecuritypriv,
2302					       sme->crypto.akm_suites[0]);
2303		if (ret < 0)
2304			goto exit;
2305	}
2306
2307	if (psecuritypriv->ndisauthtype > 3)
2308		psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2309
2310	if (rtw_set_auth23a(padapter, psecuritypriv) != _SUCCESS) {
2311		ret = -EBUSY;
2312		goto exit;
2313	}
2314
2315	/* rtw_set_802_11_encryption_mode(padapter,
2316	   padapter->securitypriv.ndisencryptstatus); */
2317
2318	if (rtw_set_ssid(padapter, pnetwork) != _SUCCESS) {
2319		ret = -EBUSY;
2320		goto exit;
2321	}
2322
2323	DBG_8723A("set ssid:dot11AuthAlgrthm =%d, dot11PrivacyAlgrthm =%d, "
2324		  "dot118021XGrpPrivacy =%d\n", psecuritypriv->dot11AuthAlgrthm,
2325		  psecuritypriv->dot11PrivacyAlgrthm,
2326		  psecuritypriv->dot118021XGrpPrivacy);
2327
2328exit:
2329
2330	DBG_8723A("<=%s, ret %d\n", __func__, ret);
2331
2332	return ret;
2333}
2334
2335static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2336				   u16 reason_code)
2337{
2338	struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2339
2340	DBG_8723A("%s(%s)\n", __func__, ndev->name);
2341
2342	rtw_set_roaming(padapter, 0);
2343
2344	if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
2345		rtw_scan_abort23a(padapter);
2346		LeaveAllPowerSaveMode23a(padapter);
2347		rtw_disassoc_cmd23a(padapter, 500, false);
2348
2349		DBG_8723A("%s...call rtw_indicate_disconnect23a\n", __func__);
2350
2351		padapter->mlmepriv.not_indic_disco = true;
2352		rtw_indicate_disconnect23a(padapter);
2353		padapter->mlmepriv.not_indic_disco = false;
2354
2355		rtw_free_assoc_resources23a(padapter, 1);
2356	}
2357
2358	return 0;
2359}
2360
2361static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
2362				    struct wireless_dev *wdev,
2363				    enum nl80211_tx_power_setting type, int mbm)
2364{
2365	DBG_8723A("%s\n", __func__);
2366	return 0;
2367}
2368
2369static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
2370				    struct wireless_dev *wdev, int *dbm)
2371{
2372	DBG_8723A("%s\n", __func__);
2373	*dbm = (12);
2374	return 0;
2375}
2376
2377inline bool rtw_cfg80211_pwr_mgmt(struct rtw_adapter *adapter)
2378{
2379	struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(adapter->rtw_wdev);
2380	return rtw_wdev_priv->power_mgmt;
2381}
2382
2383static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
2384				       struct net_device *ndev,
2385				       bool enabled, int timeout)
2386{
2387	struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2388	struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(padapter->rtw_wdev);
2389
2390	DBG_8723A("%s(%s): enabled:%u, timeout:%d\n",
2391		  __func__, ndev->name, enabled, timeout);
2392
2393	rtw_wdev_priv->power_mgmt = enabled;
2394
2395	if (!enabled)
2396		LPS_Leave23a(padapter);
2397
2398	return 0;
2399}
2400
2401static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
2402				  struct net_device *netdev,
2403				  struct cfg80211_pmksa *pmksa)
2404{
2405	u8 index, blInserted = false;
2406	struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2407	struct security_priv *psecuritypriv = &padapter->securitypriv;
2408
2409	DBG_8723A("%s(%s)\n", __func__, netdev->name);
2410
2411	if (is_zero_ether_addr(pmksa->bssid))
2412		return -EINVAL;
2413
2414	blInserted = false;
2415
2416	/* overwrite PMKID */
2417	for (index = 0; index < NUM_PMKID_CACHE; index++) {
2418		if (ether_addr_equal(psecuritypriv->PMKIDList[index].Bssid,
2419				     pmksa->bssid)) {
2420			/* BSSID is matched, the same AP => rewrite with
2421			   new PMKID. */
2422			DBG_8723A("%s(%s):  BSSID exists in the PMKList.\n",
2423				  __func__, netdev->name);
2424
2425			memcpy(psecuritypriv->PMKIDList[index].PMKID,
2426			       pmksa->pmkid, WLAN_PMKID_LEN);
2427			psecuritypriv->PMKIDList[index].bUsed = true;
2428			psecuritypriv->PMKIDIndex = index + 1;
2429			blInserted = true;
2430			break;
2431		}
2432	}
2433
2434	if (!blInserted) {
2435		/*  Find a new entry */
2436		DBG_8723A("%s(%s): Use new entry index = %d for this PMKID\n",
2437			  __func__, netdev->name, psecuritypriv->PMKIDIndex);
2438
2439		ether_addr_copy(
2440			psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
2441			Bssid, pmksa->bssid);
2442		memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
2443		       PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2444
2445		psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed =
2446			true;
2447		psecuritypriv->PMKIDIndex++;
2448		if (psecuritypriv->PMKIDIndex == 16) {
2449			psecuritypriv->PMKIDIndex = 0;
2450		}
2451	}
2452
2453	return 0;
2454}
2455
2456static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
2457				  struct net_device *netdev,
2458				  struct cfg80211_pmksa *pmksa)
2459{
2460	u8 index, bMatched = false;
2461	struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2462	struct security_priv *psecuritypriv = &padapter->securitypriv;
2463
2464	DBG_8723A("%s(%s)\n", __func__, netdev->name);
2465
2466	for (index = 0; index < NUM_PMKID_CACHE; index++) {
2467		if (ether_addr_equal(psecuritypriv->PMKIDList[index].Bssid,
2468				     pmksa->bssid)) {
2469			/* BSSID is matched, the same AP => Remove this PMKID
2470			   information and reset it. */
2471			eth_zero_addr(psecuritypriv->PMKIDList[index].Bssid);
2472			memset(psecuritypriv->PMKIDList[index].PMKID, 0x00,
2473			       WLAN_PMKID_LEN);
2474			psecuritypriv->PMKIDList[index].bUsed = false;
2475			bMatched = true;
2476			break;
2477		}
2478	}
2479
2480	if (false == bMatched) {
2481		DBG_8723A("%s(%s): do not have matched BSSID\n", __func__,
2482			  netdev->name);
2483		return -EINVAL;
2484	}
2485
2486	return 0;
2487}
2488
2489static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
2490				    struct net_device *netdev)
2491{
2492	struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2493	struct security_priv *psecuritypriv = &padapter->securitypriv;
2494
2495	DBG_8723A("%s(%s)\n", __func__, netdev->name);
2496
2497	memset(&psecuritypriv->PMKIDList[0], 0x00,
2498	       sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
2499	psecuritypriv->PMKIDIndex = 0;
2500
2501	return 0;
2502}
2503
2504#ifdef CONFIG_8723AU_AP_MODE
2505void rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter,
2506				     u8 *pmgmt_frame, uint frame_len)
2507{
2508	s32 freq;
2509	int channel;
2510	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2511	struct net_device *ndev = padapter->pnetdev;
2512
2513	DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name);
2514
2515#if defined(RTW_USE_CFG80211_STA_EVENT)
2516	{
2517		struct station_info sinfo;
2518		u8 ie_offset;
2519		if (ieee80211_is_assoc_req(hdr->frame_control))
2520			ie_offset = _ASOCREQ_IE_OFFSET_;
2521		else		/*  WIFI_REASSOCREQ */
2522			ie_offset = _REASOCREQ_IE_OFFSET_;
2523
2524		sinfo.filled = 0;
2525		sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
2526		sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
2527		sinfo.assoc_req_ies_len =
2528			frame_len - WLAN_HDR_A3_LEN - ie_offset;
2529		cfg80211_new_sta(ndev, hdr->addr2, &sinfo, GFP_ATOMIC);
2530	}
2531#else /* defined(RTW_USE_CFG80211_STA_EVENT) */
2532	channel = pmlmeext->cur_channel;
2533	if (channel <= RTW_CH_MAX_2G_CHANNEL)
2534		freq = ieee80211_channel_to_frequency(channel,
2535						      IEEE80211_BAND_2GHZ);
2536	else
2537		freq = ieee80211_channel_to_frequency(channel,
2538						      IEEE80211_BAND_5GHZ);
2539
2540	cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pmgmt_frame, frame_len,
2541			 0, GFP_ATOMIC);
2542#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
2543}
2544
2545void rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter,
2546					unsigned char *da,
2547					unsigned short reason)
2548{
2549	s32 freq;
2550	int channel;
2551	uint frame_len;
2552	struct ieee80211_mgmt mgmt;
2553	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2554	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2555	struct net_device *ndev = padapter->pnetdev;
2556
2557	DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name);
2558
2559	memset(&mgmt, 0, sizeof(struct ieee80211_mgmt));
2560
2561#if defined(RTW_USE_CFG80211_STA_EVENT)
2562	cfg80211_del_sta(ndev, da, GFP_ATOMIC);
2563#else /* defined(RTW_USE_CFG80211_STA_EVENT) */
2564	channel = pmlmeext->cur_channel;
2565	if (channel <= RTW_CH_MAX_2G_CHANNEL)
2566		freq = ieee80211_channel_to_frequency(channel,
2567						      IEEE80211_BAND_2GHZ);
2568	else
2569		freq = ieee80211_channel_to_frequency(channel,
2570						      IEEE80211_BAND_5GHZ);
2571
2572	mgmt.frame_control =
2573		cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);
2574
2575	ether_addr_copy(mgmt.da, myid(&padapter->eeprompriv));
2576	ether_addr_copy(mgmt.sa, da);
2577	ether_addr_copy(mgmt.bssid, get_my_bssid23a(&pmlmeinfo->network));
2578
2579	mgmt.seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
2580	pmlmeext->mgnt_seq++;
2581
2582	mgmt.u.disassoc.reason_code = cpu_to_le16(reason);
2583
2584	frame_len = sizeof(struct ieee80211_hdr_3addr) + 2;
2585
2586	cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, (u8 *)&mgmt, frame_len,
2587			 0, GFP_ATOMIC);
2588#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
2589}
2590
2591static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
2592{
2593	int ret = 0;
2594
2595	DBG_8723A("%s\n", __func__);
2596
2597	return ret;
2598}
2599
2600static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
2601{
2602	int ret = 0;
2603
2604	DBG_8723A("%s\n", __func__);
2605
2606	return ret;
2607}
2608
2609static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb,
2610					      struct net_device *ndev)
2611{
2612	int ret = 0;
2613	int rtap_len;
2614	int qos_len = 0;
2615	int dot11_hdr_len = 24;
2616	int snap_len = 6;
2617	unsigned char *pdata;
2618	unsigned char src_mac_addr[6];
2619	unsigned char dst_mac_addr[6];
2620	struct ieee80211_hdr *dot11_hdr;
2621	struct ieee80211_radiotap_header *rtap_hdr;
2622	struct rtw_adapter *padapter = netdev_priv(ndev);
2623
2624	DBG_8723A("%s(%s)\n", __func__, ndev->name);
2625
2626	if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
2627		goto fail;
2628
2629	rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
2630	if (unlikely(rtap_hdr->it_version))
2631		goto fail;
2632
2633	rtap_len = ieee80211_get_radiotap_len(skb->data);
2634	if (unlikely(skb->len < rtap_len))
2635		goto fail;
2636
2637	if (rtap_len != 14) {
2638		DBG_8723A("radiotap len (should be 14): %d\n", rtap_len);
2639		goto fail;
2640	}
2641
2642	/* Skip the ratio tap header */
2643	skb_pull(skb, rtap_len);
2644
2645	dot11_hdr = (struct ieee80211_hdr *)skb->data;
2646	/* Check if the QoS bit is set */
2647	if (ieee80211_is_data(dot11_hdr->frame_control)) {
2648		/* Check if this ia a Wireless Distribution System (WDS) frame
2649		 * which has 4 MAC addresses
2650		 */
2651		if (ieee80211_is_data_qos(dot11_hdr->frame_control))
2652			qos_len = IEEE80211_QOS_CTL_LEN;
2653		if (ieee80211_has_a4(dot11_hdr->frame_control))
2654			dot11_hdr_len += 6;
2655
2656		memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
2657		memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
2658
2659		/*
2660		 * Skip the 802.11 header, QoS (if any) and SNAP,
2661		 * but leave spaces for two MAC addresses
2662		 */
2663		skb_pull(skb, dot11_hdr_len + qos_len + snap_len -
2664			 ETH_ALEN * 2);
2665		pdata = (unsigned char *)skb->data;
2666		ether_addr_copy(pdata, dst_mac_addr);
2667		ether_addr_copy(pdata + ETH_ALEN, src_mac_addr);
2668
2669		DBG_8723A("should be eapol packet\n");
2670
2671		/* Use the real net device to transmit the packet */
2672		ret = rtw_xmit23a_entry23a(skb, padapter->pnetdev);
2673
2674		return ret;
2675
2676	} else if (ieee80211_is_action(dot11_hdr->frame_control)) {
2677		struct ieee80211_mgmt *mgmt;
2678		/* only for action frames */
2679		struct xmit_frame *pmgntframe;
2680		struct pkt_attrib *pattrib;
2681		unsigned char *pframe;
2682		/* u8 category, action, OUI_Subtype, dialogToken = 0; */
2683		/* unsigned char        *frame_body; */
2684		struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2685		struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2686		u32 len = skb->len;
2687		u8 category, action;
2688
2689		mgmt = (struct ieee80211_mgmt *)dot11_hdr;
2690
2691		DBG_8723A("RTW_Tx:da =" MAC_FMT " via %s(%s)\n",
2692			  MAC_ARG(mgmt->da), __func__, ndev->name);
2693		category = mgmt->u.action.category;
2694		action = mgmt->u.action.u.wme_action.action_code;
2695		DBG_8723A("RTW_Tx:category(%u), action(%u)\n",
2696			  category, action);
2697
2698		/* starting alloc mgmt frame to dump it */
2699		pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2700		if (pmgntframe == NULL)
2701			goto fail;
2702
2703		/* update attribute */
2704		pattrib = &pmgntframe->attrib;
2705		update_mgntframe_attrib23a(padapter, pattrib);
2706		pattrib->retry_ctrl = false;
2707
2708		memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2709
2710		pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2711
2712		memcpy(pframe, skb->data, len);
2713		pattrib->pktlen = len;
2714
2715		/* update seq number */
2716		pmlmeext->mgnt_seq = le16_to_cpu(dot11_hdr->seq_ctrl) >> 4;
2717		pattrib->seqnum = pmlmeext->mgnt_seq;
2718		pmlmeext->mgnt_seq++;
2719
2720		pattrib->last_txcmdsz = pattrib->pktlen;
2721
2722		dump_mgntframe23a(padapter, pmgntframe);
2723	}
2724
2725fail:
2726
2727	dev_kfree_skb(skb);
2728
2729	return 0;
2730}
2731
2732static int
2733rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
2734{
2735	int ret = 0;
2736
2737	DBG_8723A("%s\n", __func__);
2738
2739	return ret;
2740}
2741
2742static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
2743	.ndo_open = rtw_cfg80211_monitor_if_open,
2744	.ndo_stop = rtw_cfg80211_monitor_if_close,
2745	.ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
2746	.ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
2747};
2748
2749static int rtw_cfg80211_add_monitor_if(struct rtw_adapter *padapter, char *name,
2750				       struct net_device **ndev)
2751{
2752	int ret = 0;
2753	struct net_device *mon_ndev = NULL;
2754	struct wireless_dev *mon_wdev = NULL;
2755	struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
2756
2757	if (!name) {
2758		DBG_8723A("%s(%s): without specific name\n",
2759			  __func__, padapter->pnetdev->name);
2760		ret = -EINVAL;
2761		goto out;
2762	}
2763
2764	if (pwdev_priv->pmon_ndev) {
2765		DBG_8723A("%s(%s): monitor interface exist: %s\n", __func__,
2766			  padapter->pnetdev->name, pwdev_priv->pmon_ndev->name);
2767		ret = -EBUSY;
2768		goto out;
2769	}
2770
2771	mon_ndev = alloc_etherdev(sizeof(struct rtw_adapter));
2772	if (!mon_ndev) {
2773		DBG_8723A("%s(%s): allocate ndev fail\n", __func__,
2774			  padapter->pnetdev->name);
2775		ret = -ENOMEM;
2776		goto out;
2777	}
2778
2779	mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
2780	strncpy(mon_ndev->name, name, IFNAMSIZ);
2781	mon_ndev->name[IFNAMSIZ - 1] = 0;
2782	mon_ndev->destructor = rtw_ndev_destructor;
2783
2784	mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
2785
2786	/*  wdev */
2787	mon_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2788	if (!mon_wdev) {
2789		DBG_8723A("%s(%s): allocate mon_wdev fail\n", __func__,
2790			  padapter->pnetdev->name);
2791		ret = -ENOMEM;
2792		goto out;
2793	}
2794
2795	mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
2796	mon_wdev->netdev = mon_ndev;
2797	mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
2798	mon_ndev->ieee80211_ptr = mon_wdev;
2799
2800	ret = register_netdevice(mon_ndev);
2801	if (ret) {
2802		goto out;
2803	}
2804
2805	*ndev = pwdev_priv->pmon_ndev = mon_ndev;
2806	memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ + 1);
2807
2808out:
2809	if (ret) {
2810		kfree(mon_wdev);
2811		mon_wdev = NULL;
2812	}
2813
2814	if (ret && mon_ndev) {
2815		free_netdev(mon_ndev);
2816		*ndev = mon_ndev = NULL;
2817	}
2818
2819	return ret;
2820}
2821
2822static struct wireless_dev *
2823cfg80211_rtw_add_virtual_intf(struct wiphy *wiphy, const char *name,
2824			      enum nl80211_iftype type, u32 *flags,
2825			      struct vif_params *params)
2826{
2827	int ret = 0;
2828	struct net_device *ndev = NULL;
2829	struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2830
2831	DBG_8723A("%s(%s): wiphy:%s, name:%s, type:%d\n", __func__,
2832		  padapter->pnetdev->name, wiphy_name(wiphy), name, type);
2833
2834	switch (type) {
2835	case NL80211_IFTYPE_ADHOC:
2836	case NL80211_IFTYPE_AP_VLAN:
2837	case NL80211_IFTYPE_WDS:
2838	case NL80211_IFTYPE_MESH_POINT:
2839		ret = -ENODEV;
2840		break;
2841	case NL80211_IFTYPE_MONITOR:
2842		ret =
2843		    rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
2844		break;
2845
2846	case NL80211_IFTYPE_P2P_CLIENT:
2847	case NL80211_IFTYPE_STATION:
2848		ret = -ENODEV;
2849		break;
2850
2851	case NL80211_IFTYPE_P2P_GO:
2852	case NL80211_IFTYPE_AP:
2853		ret = -ENODEV;
2854		break;
2855	default:
2856		ret = -ENODEV;
2857		DBG_8723A("Unsupported interface type\n");
2858		break;
2859	}
2860
2861	DBG_8723A("%s(%s): ndev:%p, ret:%d\n", __func__,
2862		  padapter->pnetdev->name,
2863		  ndev, ret);
2864
2865	return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
2866}
2867
2868static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
2869					 struct wireless_dev *wdev)
2870{
2871	struct rtw_wdev_priv *pwdev_priv =
2872	    (struct rtw_wdev_priv *)wiphy_priv(wiphy);
2873	struct net_device *ndev;
2874	ndev = wdev ? wdev->netdev : NULL;
2875
2876	if (!ndev)
2877		goto exit;
2878
2879	unregister_netdevice(ndev);
2880
2881	if (ndev == pwdev_priv->pmon_ndev) {
2882		pwdev_priv->pmon_ndev = NULL;
2883		pwdev_priv->ifname_mon[0] = '\0';
2884		DBG_8723A("%s(%s): remove monitor interface\n",
2885			  __func__, ndev->name);
2886	}
2887
2888exit:
2889	return 0;
2890}
2891
2892static int rtw_add_beacon(struct rtw_adapter *adapter, const u8 *head,
2893			  size_t head_len, const u8 *tail, size_t tail_len)
2894{
2895	int ret = 0;
2896	u8 *pbuf = NULL;
2897	uint len, wps_ielen = 0;
2898	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2899	/* struct sta_priv *pstapriv = &padapter->stapriv; */
2900
2901	DBG_8723A("%s beacon_head_len =%zu, beacon_tail_len =%zu\n",
2902		  __func__, head_len, tail_len);
2903
2904	if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2905		return -EINVAL;
2906
2907	if (head_len < 24)
2908		return -EINVAL;
2909
2910	pbuf = kzalloc(head_len + tail_len, GFP_KERNEL);
2911	if (!pbuf)
2912		return -ENOMEM;
2913	/*  24 = beacon header len. */
2914	memcpy(pbuf, (void *)head + 24, head_len - 24);
2915	memcpy(pbuf + head_len - 24, (void *)tail, tail_len);
2916
2917	len = head_len + tail_len - 24;
2918
2919	/* check wps ie if inclued */
2920	if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
2921				    WLAN_OUI_TYPE_MICROSOFT_WPS,
2922				    pbuf + _FIXED_IE_LENGTH_,
2923				    len - _FIXED_IE_LENGTH_))
2924		DBG_8723A("add bcn, wps_ielen =%d\n", wps_ielen);
2925
2926	/* pbss_network->IEs will not include p2p_ie, wfd ie */
2927	rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_,
2928			     WLAN_EID_VENDOR_SPECIFIC, P2P_OUI23A, 4);
2929	rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_,
2930			     WLAN_EID_VENDOR_SPECIFIC, WFD_OUI23A, 4);
2931
2932	if (rtw_check_beacon_data23a(adapter, pbuf, len) == _SUCCESS) {
2933		ret = 0;
2934	} else {
2935		ret = -EINVAL;
2936	}
2937
2938	kfree(pbuf);
2939
2940	return ret;
2941}
2942
2943static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
2944				 struct cfg80211_ap_settings *settings)
2945{
2946	int ret = 0;
2947	struct rtw_adapter *adapter = wiphy_to_adapter(wiphy);
2948
2949	DBG_8723A("%s(%s): hidden_ssid:%d, auth_type:%d\n",
2950		  __func__, ndev->name, settings->hidden_ssid,
2951		  settings->auth_type);
2952
2953	ret = rtw_add_beacon(adapter, settings->beacon.head,
2954			     settings->beacon.head_len, settings->beacon.tail,
2955			     settings->beacon.tail_len);
2956
2957	adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode =
2958		settings->hidden_ssid;
2959
2960	if (settings->ssid && settings->ssid_len) {
2961		struct wlan_bssid_ex *pbss_network =
2962			&adapter->mlmepriv.cur_network.network;
2963		struct wlan_bssid_ex *pbss_network_ext =
2964			&adapter->mlmeextpriv.mlmext_info.network;
2965
2966		memcpy(pbss_network->Ssid.ssid, (void *)settings->ssid,
2967		       settings->ssid_len);
2968		pbss_network->Ssid.ssid_len = settings->ssid_len;
2969		memcpy(pbss_network_ext->Ssid.ssid, (void *)settings->ssid,
2970		       settings->ssid_len);
2971		pbss_network_ext->Ssid.ssid_len = settings->ssid_len;
2972	}
2973
2974	return ret;
2975}
2976
2977static int cfg80211_rtw_change_beacon(struct wiphy *wiphy,
2978				      struct net_device *ndev,
2979				      struct cfg80211_beacon_data *info)
2980{
2981	int ret = 0;
2982	struct rtw_adapter *adapter = wiphy_to_adapter(wiphy);
2983
2984	DBG_8723A("%s(%s)\n", __func__, ndev->name);
2985
2986	ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail,
2987			     info->tail_len);
2988
2989	return ret;
2990}
2991
2992static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
2993{
2994	DBG_8723A("%s(%s)\n", __func__, ndev->name);
2995	return 0;
2996}
2997
2998static int cfg80211_rtw_add_station(struct wiphy *wiphy,
2999				    struct net_device *ndev, const u8 *mac,
3000				    struct station_parameters *params)
3001{
3002	DBG_8723A("%s(%s)\n", __func__, ndev->name);
3003
3004	return 0;
3005}
3006
3007static int cfg80211_rtw_del_station(struct wiphy *wiphy,
3008				    struct net_device *ndev, const u8 *mac)
3009{
3010	int ret = 0;
3011	struct list_head *phead, *plist, *ptmp;
3012	u8 updated = 0;
3013	struct sta_info *psta;
3014	struct rtw_adapter *padapter = netdev_priv(ndev);
3015	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3016	struct sta_priv *pstapriv = &padapter->stapriv;
3017
3018	DBG_8723A("+%s(%s)\n", __func__, ndev->name);
3019
3020	if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != true) {
3021		DBG_8723A("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n",
3022			  __func__);
3023		return -EINVAL;
3024	}
3025
3026	if (!mac) {
3027		DBG_8723A("flush all sta, and cam_entry\n");
3028
3029		flush_all_cam_entry23a(padapter);	/* clear CAM */
3030
3031		ret = rtw_sta_flush23a(padapter);
3032
3033		return ret;
3034	}
3035
3036	DBG_8723A("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
3037
3038	if (is_broadcast_ether_addr(mac))
3039		return -EINVAL;
3040
3041	spin_lock_bh(&pstapriv->asoc_list_lock);
3042
3043	phead = &pstapriv->asoc_list;
3044
3045	/* check asoc_queue */
3046	list_for_each_safe(plist, ptmp, phead) {
3047		psta = container_of(plist, struct sta_info, asoc_list);
3048
3049		if (ether_addr_equal(mac, psta->hwaddr)) {
3050			if (psta->dot8021xalg == 1 &&
3051			    psta->bpairwise_key_installed == false) {
3052				DBG_8723A("%s, sta's dot8021xalg = 1 and "
3053					  "key_installed = false\n", __func__);
3054			} else {
3055				DBG_8723A("free psta =%p, aid =%d\n", psta,
3056					  psta->aid);
3057
3058				list_del_init(&psta->asoc_list);
3059				pstapriv->asoc_list_cnt--;
3060
3061				/* spin_unlock_bh(&pstapriv->asoc_list_lock); */
3062				updated =
3063				    ap_free_sta23a(padapter, psta, true,
3064						WLAN_REASON_DEAUTH_LEAVING);
3065				/* spin_lock_bh(&pstapriv->asoc_list_lock); */
3066
3067				psta = NULL;
3068
3069				break;
3070			}
3071		}
3072	}
3073
3074	spin_unlock_bh(&pstapriv->asoc_list_lock);
3075
3076	associated_clients_update23a(padapter, updated);
3077
3078	DBG_8723A("-%s(%s)\n", __func__, ndev->name);
3079
3080	return ret;
3081}
3082
3083static int cfg80211_rtw_change_station(struct wiphy *wiphy,
3084				       struct net_device *ndev, const u8 *mac,
3085				       struct station_parameters *params)
3086{
3087	DBG_8723A("%s(%s)\n", __func__, ndev->name);
3088	return 0;
3089}
3090
3091static int cfg80211_rtw_dump_station(struct wiphy *wiphy,
3092				     struct net_device *ndev, int idx, u8 *mac,
3093				     struct station_info *sinfo)
3094{
3095	DBG_8723A("%s(%s)\n", __func__, ndev->name);
3096
3097	/* TODO: dump scanned queue */
3098
3099	return -ENOENT;
3100}
3101
3102static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
3103				   struct bss_parameters *params)
3104{
3105	DBG_8723A("%s(%s)\n", __func__, ndev->name);
3106	return 0;
3107}
3108#endif /* CONFIG_8723AU_AP_MODE */
3109
3110static int _cfg80211_rtw_mgmt_tx(struct rtw_adapter *padapter, u8 tx_ch,
3111				 const u8 *buf, size_t len)
3112{
3113	struct xmit_frame *pmgntframe;
3114	struct pkt_attrib *pattrib;
3115	unsigned char *pframe;
3116	int ret = _FAIL;
3117	struct ieee80211_hdr *pwlanhdr;
3118	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3119	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3120
3121	if (_FAIL == rtw_pwr_wakeup(padapter)) {
3122		ret = -EFAULT;
3123		goto exit;
3124	}
3125
3126	rtw_set_scan_deny(padapter, 1000);
3127
3128	rtw_scan_abort23a(padapter);
3129
3130	if (tx_ch != rtw_get_oper_ch23a(padapter)) {
3131		if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
3132			pmlmeext->cur_channel = tx_ch;
3133		set_channel_bwmode23a(padapter, tx_ch,
3134				   HAL_PRIME_CHNL_OFFSET_DONT_CARE,
3135				   HT_CHANNEL_WIDTH_20);
3136	}
3137
3138	/* starting alloc mgmt frame to dump it */
3139	pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3140	if (!pmgntframe) {
3141		/* ret = -ENOMEM; */
3142		ret = _FAIL;
3143		goto exit;
3144	}
3145
3146	/* update attribute */
3147	pattrib = &pmgntframe->attrib;
3148	update_mgntframe_attrib23a(padapter, pattrib);
3149	pattrib->retry_ctrl = false;
3150
3151	memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3152
3153	pframe = (u8 *) (pmgntframe->buf_addr) + TXDESC_OFFSET;
3154
3155	memcpy(pframe, (void *)buf, len);
3156	pattrib->pktlen = len;
3157
3158	pwlanhdr = (struct ieee80211_hdr *)pframe;
3159	/* update seq number */
3160	pmlmeext->mgnt_seq = le16_to_cpu(pwlanhdr->seq_ctrl) >> 4;
3161	pattrib->seqnum = pmlmeext->mgnt_seq;
3162	pmlmeext->mgnt_seq++;
3163
3164	pattrib->last_txcmdsz = pattrib->pktlen;
3165
3166	ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3167
3168	if (ret  != _SUCCESS)
3169		DBG_8723A("%s, ack == false\n", __func__);
3170	else
3171		DBG_8723A("%s, ack == true\n", __func__);
3172
3173exit:
3174
3175	DBG_8723A("%s, ret =%d\n", __func__, ret);
3176
3177	return ret;
3178}
3179
3180static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3181				struct cfg80211_mgmt_tx_params *params,
3182				u64 *cookie)
3183{
3184	struct rtw_adapter *padapter =
3185		(struct rtw_adapter *)wiphy_to_adapter(wiphy);
3186	int ret = 0;
3187	int tx_ret;
3188	u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
3189	u32 dump_cnt = 0;
3190	bool ack = true;
3191	u8 category, action;
3192	unsigned long start = jiffies;
3193	size_t len = params->len;
3194	struct ieee80211_channel *chan = params->chan;
3195	const u8 *buf = params->buf;
3196	struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *)buf;
3197	u8 tx_ch = (u8) ieee80211_frequency_to_channel(chan->center_freq);
3198
3199	if (!ieee80211_is_action(hdr->frame_control))
3200		return -EINVAL;
3201
3202	/* cookie generation */
3203	*cookie = (unsigned long)buf;
3204
3205	DBG_8723A("%s(%s): len =%zu, ch =%d\n", __func__,
3206		  padapter->pnetdev->name, len, tx_ch);
3207
3208	/* indicate ack before issue frame to avoid racing with rsp frame */
3209	cfg80211_mgmt_tx_status(padapter->rtw_wdev, *cookie, buf, len, ack,
3210				GFP_KERNEL);
3211
3212	DBG_8723A("RTW_Tx:tx_ch =%d, da =" MAC_FMT "\n", tx_ch,
3213		  MAC_ARG(hdr->da));
3214	category = hdr->u.action.category;
3215	action = hdr->u.action.u.wme_action.action_code;
3216	DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category, action);
3217
3218	do {
3219		dump_cnt++;
3220		tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
3221	} while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
3222
3223	if (tx_ret != _SUCCESS || dump_cnt > 1) {
3224		DBG_8723A("%s(%s): %s (%d/%d) in %d ms\n",
3225			  __func__, padapter->pnetdev->name,
3226			  tx_ret == _SUCCESS ? "OK" : "FAIL", dump_cnt,
3227			  dump_limit, jiffies_to_msecs(jiffies - start));
3228	}
3229
3230	return ret;
3231}
3232
3233static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
3234					     struct wireless_dev *wdev,
3235					     u16 frame_type, bool reg)
3236{
3237	if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
3238		return;
3239
3240	return;
3241}
3242
3243static struct cfg80211_ops rtw_cfg80211_ops = {
3244	.change_virtual_intf = cfg80211_rtw_change_iface,
3245	.add_key = cfg80211_rtw_add_key,
3246	.get_key = cfg80211_rtw_get_key,
3247	.del_key = cfg80211_rtw_del_key,
3248	.set_default_key = cfg80211_rtw_set_default_key,
3249	.get_station = cfg80211_rtw_get_station,
3250	.scan = cfg80211_rtw_scan,
3251	.set_wiphy_params = cfg80211_rtw_set_wiphy_params,
3252	.connect = cfg80211_rtw_connect,
3253	.disconnect = cfg80211_rtw_disconnect,
3254	.join_ibss = cfg80211_rtw_join_ibss,
3255	.leave_ibss = cfg80211_rtw_leave_ibss,
3256	.set_tx_power = cfg80211_rtw_set_txpower,
3257	.get_tx_power = cfg80211_rtw_get_txpower,
3258	.set_power_mgmt = cfg80211_rtw_set_power_mgmt,
3259	.set_pmksa = cfg80211_rtw_set_pmksa,
3260	.del_pmksa = cfg80211_rtw_del_pmksa,
3261	.flush_pmksa = cfg80211_rtw_flush_pmksa,
3262
3263#ifdef CONFIG_8723AU_AP_MODE
3264	.add_virtual_intf = cfg80211_rtw_add_virtual_intf,
3265	.del_virtual_intf = cfg80211_rtw_del_virtual_intf,
3266
3267	.start_ap = cfg80211_rtw_start_ap,
3268	.change_beacon = cfg80211_rtw_change_beacon,
3269	.stop_ap = cfg80211_rtw_stop_ap,
3270
3271	.add_station = cfg80211_rtw_add_station,
3272	.del_station = cfg80211_rtw_del_station,
3273	.change_station = cfg80211_rtw_change_station,
3274	.dump_station = cfg80211_rtw_dump_station,
3275	.change_bss = cfg80211_rtw_change_bss,
3276#endif /* CONFIG_8723AU_AP_MODE */
3277
3278	.mgmt_tx = cfg80211_rtw_mgmt_tx,
3279	.mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
3280};
3281
3282static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap,
3283				       enum ieee80211_band band, u8 rf_type)
3284{
3285
3286#define MAX_BIT_RATE_40MHZ_MCS15	300	/* Mbps */
3287#define MAX_BIT_RATE_40MHZ_MCS7		150	/* Mbps */
3288
3289	ht_cap->ht_supported = true;
3290
3291	ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
3292	    IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
3293	    IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
3294
3295	/*
3296	 *Maximum length of AMPDU that the STA can receive.
3297	 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
3298	 */
3299	ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
3300
3301	/*Minimum MPDU start spacing , */
3302	ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
3303
3304	ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
3305
3306	/*
3307	 *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
3308	 *base on ant_num
3309	 *rx_mask: RX mask
3310	 *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7
3311	 *if rx_ant = 2 rx_mask[1]= 0xff;==>MCS8-MCS15
3312	 *if rx_ant >= 3 rx_mask[2]= 0xff;
3313	 *if BW_40 rx_mask[4]= 0x01;
3314	 *highest supported RX rate
3315	 */
3316	if (rf_type == RF_1T1R) {
3317		ht_cap->mcs.rx_mask[0] = 0xFF;
3318		ht_cap->mcs.rx_mask[1] = 0x00;
3319		ht_cap->mcs.rx_mask[4] = 0x01;
3320
3321		ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
3322	} else if ((rf_type == RF_1T2R) || (rf_type == RF_2T2R)) {
3323		ht_cap->mcs.rx_mask[0] = 0xFF;
3324		ht_cap->mcs.rx_mask[1] = 0xFF;
3325		ht_cap->mcs.rx_mask[4] = 0x01;
3326
3327		ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
3328	} else {
3329		DBG_8723A("%s, error rf_type =%d\n", __func__, rf_type);
3330	}
3331
3332}
3333
3334void rtw_cfg80211_init_wiphy(struct rtw_adapter *padapter)
3335{
3336	u8 rf_type;
3337	struct ieee80211_supported_band *bands;
3338	struct wireless_dev *pwdev = padapter->rtw_wdev;
3339	struct wiphy *wiphy = pwdev->wiphy;
3340
3341	rf_type = rtl8723a_get_rf_type(padapter);
3342
3343	DBG_8723A("%s:rf_type =%d\n", __func__, rf_type);
3344
3345	/* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
3346	{
3347		bands = wiphy->bands[IEEE80211_BAND_2GHZ];
3348		if (bands)
3349			rtw_cfg80211_init_ht_capab(&bands->ht_cap,
3350						   IEEE80211_BAND_2GHZ,
3351						   rf_type);
3352	}
3353
3354	/* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
3355	{
3356		bands = wiphy->bands[IEEE80211_BAND_5GHZ];
3357		if (bands)
3358			rtw_cfg80211_init_ht_capab(&bands->ht_cap,
3359						   IEEE80211_BAND_5GHZ,
3360						   rf_type);
3361	}
3362}
3363
3364static void rtw_cfg80211_preinit_wiphy(struct rtw_adapter *padapter,
3365				       struct wiphy *wiphy)
3366{
3367	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3368
3369	wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
3370	wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
3371	wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
3372
3373	wiphy->max_remain_on_channel_duration =
3374	    RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
3375
3376	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3377	    BIT(NL80211_IFTYPE_ADHOC) |
3378#ifdef CONFIG_8723AU_AP_MODE
3379	    BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) |
3380#endif
3381	    0;
3382
3383#ifdef CONFIG_8723AU_AP_MODE
3384	wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
3385#endif /* CONFIG_8723AU_AP_MODE */
3386
3387	wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
3388
3389	/*
3390	   wiphy->iface_combinations = &rtw_combinations;
3391	   wiphy->n_iface_combinations = 1;
3392	 */
3393
3394	wiphy->cipher_suites = rtw_cipher_suites;
3395	wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
3396
3397	/* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
3398	wiphy->bands[IEEE80211_BAND_2GHZ] =
3399	    rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
3400	/* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
3401	wiphy->bands[IEEE80211_BAND_5GHZ] =
3402	    rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
3403
3404	wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
3405	wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
3406
3407	if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
3408		wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
3409	else
3410		wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
3411}
3412
3413int rtw_wdev_alloc(struct rtw_adapter *padapter, struct device *dev)
3414{
3415	int ret = 0;
3416	struct wiphy *wiphy;
3417	struct wireless_dev *wdev;
3418	struct rtw_wdev_priv *pwdev_priv;
3419	struct net_device *pnetdev = padapter->pnetdev;
3420
3421	DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
3422
3423	/* wiphy */
3424	wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wdev_priv));
3425	if (!wiphy) {
3426		DBG_8723A("Couldn't allocate wiphy device\n");
3427		ret = -ENOMEM;
3428		goto exit;
3429	}
3430
3431	/*  wdev */
3432	wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3433	if (!wdev) {
3434		DBG_8723A("Couldn't allocate wireless device\n");
3435		ret = -ENOMEM;
3436		goto free_wiphy;
3437	}
3438
3439	set_wiphy_dev(wiphy, dev);
3440	rtw_cfg80211_preinit_wiphy(padapter, wiphy);
3441
3442	ret = wiphy_register(wiphy);
3443	if (ret < 0) {
3444		DBG_8723A("Couldn't register wiphy device\n");
3445		goto free_wdev;
3446	}
3447
3448	wdev->wiphy = wiphy;
3449	wdev->netdev = pnetdev;
3450	/* wdev->iftype = NL80211_IFTYPE_STATION; */
3451	/*  for rtw_setopmode_cmd23a() in cfg80211_rtw_change_iface() */
3452	wdev->iftype = NL80211_IFTYPE_MONITOR;
3453	padapter->rtw_wdev = wdev;
3454	pnetdev->ieee80211_ptr = wdev;
3455
3456	/* init pwdev_priv */
3457	pwdev_priv = wdev_to_priv(wdev);
3458	pwdev_priv->rtw_wdev = wdev;
3459	pwdev_priv->pmon_ndev = NULL;
3460	pwdev_priv->ifname_mon[0] = '\0';
3461	pwdev_priv->padapter = padapter;
3462	pwdev_priv->scan_request = NULL;
3463	spin_lock_init(&pwdev_priv->scan_req_lock);
3464
3465	pwdev_priv->p2p_enabled = false;
3466
3467	if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
3468		pwdev_priv->power_mgmt = true;
3469	else
3470		pwdev_priv->power_mgmt = false;
3471
3472	return ret;
3473free_wdev:
3474	kfree(wdev);
3475free_wiphy:
3476	wiphy_free(wiphy);
3477exit:
3478	return ret;
3479}
3480
3481void rtw_wdev_free(struct wireless_dev *wdev)
3482{
3483	DBG_8723A("%s(wdev =%p)\n", __func__, wdev);
3484
3485	if (!wdev)
3486		return;
3487
3488	kfree(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
3489	kfree(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
3490
3491	wiphy_free(wdev->wiphy);
3492
3493	kfree(wdev);
3494}
3495
3496void rtw_wdev_unregister(struct wireless_dev *wdev)
3497{
3498	struct rtw_wdev_priv *pwdev_priv;
3499
3500	DBG_8723A("%s(wdev =%p)\n", __func__, wdev);
3501
3502	if (!wdev)
3503		return;
3504
3505	pwdev_priv = wdev_to_priv(wdev);
3506
3507	rtw_cfg80211_indicate_scan_done(pwdev_priv, true);
3508
3509	if (pwdev_priv->pmon_ndev) {
3510		DBG_8723A("%s, unregister monitor interface\n", __func__);
3511		unregister_netdev(pwdev_priv->pmon_ndev);
3512	}
3513
3514	wiphy_unregister(wdev->wiphy);
3515}
3516