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