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