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