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