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