cfg80211: remove enum ieee80211_band
[cascardo/linux.git] / drivers / staging / rtl8723au / os_dep / ioctl_cfg80211.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15 #define  _IOCTL_CFG80211_C_
16
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 #include <xmit_osdep.h>
20
21 #include "ioctl_cfg80211.h"
22
23 #define RTW_MAX_MGMT_TX_CNT 8
24
25 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535        /* ms */
26 #define RTW_MAX_NUM_PMKIDS 4
27
28 static const u32 rtw_cipher_suites[] = {
29         WLAN_CIPHER_SUITE_WEP40,
30         WLAN_CIPHER_SUITE_WEP104,
31         WLAN_CIPHER_SUITE_TKIP,
32         WLAN_CIPHER_SUITE_CCMP,
33 };
34
35 #define RATETAB_ENT(_rate, _rateid, _flags) {                   \
36         .bitrate        = (_rate),                              \
37         .hw_value       = (_rateid),                            \
38         .flags          = (_flags),                             \
39 }
40
41 #define CHAN2G(_channel, _freq, _flags) {                       \
42         .band                   = NL80211_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                   = NL80211_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 nl80211_band band)
147 {
148         struct ieee80211_supported_band *spt_band = NULL;
149         int n_channels, n_bitrates;
150
151         if (band == NL80211_BAND_2GHZ) {
152                 n_channels = RTW_2G_CHANNELS_NUM;
153                 n_bitrates = RTW_G_RATES_NUM;
154         } else if (band == NL80211_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 == NL80211_BAND_2GHZ) {
180                 rtw_2g_channels_init(spt_band->channels);
181                 rtw_2g_rates_init(spt_band->bitrates);
182         } else if (band == NL80211_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                                                       NL80211_BAND_2GHZ);
261         else
262                 freq = ieee80211_channel_to_frequency(channel,
263                                                       NL80211_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                                                            NL80211_BAND_2GHZ);
326                 else
327                         freq =
328                             ieee80211_channel_to_frequency(channel,
329                                                            NL80211_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, false, 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                                        (min(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                                        (min(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, (min(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                                        (min(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                                        (min(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                                                (min(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                                                (min(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 *phead;
1274         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1275         struct rtw_queue *queue = &pmlmepriv->scanned_queue;
1276         struct wlan_network *pnetwork, *ptmp;
1277
1278         spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1279         phead = get_list_head(queue);
1280         list_for_each_entry_safe(pnetwork, ptmp, phead, list) {
1281                 /* report network only if the current channel set
1282                    contains the channel to which this network belongs */
1283                 if (rtw_ch_set_search_ch23a
1284                     (padapter->mlmeextpriv.channel_set,
1285                      pnetwork->network.DSConfig) >= 0)
1286                         rtw_cfg80211_inform_bss(padapter, pnetwork);
1287         }
1288         spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1289
1290         /* call this after other things have been done */
1291         rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev),
1292                                         false);
1293 }
1294
1295 static int rtw_cfg80211_set_probe_req_wpsp2pie(struct rtw_adapter *padapter,
1296                                                char *buf, int len)
1297 {
1298         int ret = 0;
1299         const u8 *wps_ie;
1300         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1301
1302         DBG_8723A("%s, ielen =%d\n", __func__, len);
1303
1304         if (len > 0) {
1305                 wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1306                                                  WLAN_OUI_TYPE_MICROSOFT_WPS,
1307                                                  buf, len);
1308                 if (wps_ie) {
1309                         DBG_8723A("probe_req_wps_ielen =%d\n", wps_ie[1]);
1310
1311                         if (pmlmepriv->wps_probe_req_ie) {
1312                                 pmlmepriv->wps_probe_req_ie_len = 0;
1313                                 kfree(pmlmepriv->wps_probe_req_ie);
1314                                 pmlmepriv->wps_probe_req_ie = NULL;
1315                         }
1316
1317                         pmlmepriv->wps_probe_req_ie = kmemdup(wps_ie, wps_ie[1],
1318                                                               GFP_KERNEL);
1319                         if (pmlmepriv->wps_probe_req_ie == NULL) {
1320                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
1321                                           __func__, __LINE__);
1322                                 return -EINVAL;
1323                         }
1324                         pmlmepriv->wps_probe_req_ie_len = wps_ie[1];
1325                 }
1326         }
1327
1328         return ret;
1329 }
1330
1331 static int cfg80211_rtw_scan(struct wiphy *wiphy,
1332                              struct cfg80211_scan_request *request)
1333 {
1334         int i;
1335         u8 _status = false;
1336         int ret = 0;
1337         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
1338         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1339         struct cfg80211_ssid ssid[RTW_SSID_SCAN_AMOUNT];
1340         struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
1341         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
1342         struct cfg80211_ssid *ssids = request->ssids;
1343         bool need_indicate_scan_done = false;
1344
1345         DBG_8723A("%s(%s)\n", __func__, padapter->pnetdev->name);
1346
1347         spin_lock_bh(&pwdev_priv->scan_req_lock);
1348         pwdev_priv->scan_request = request;
1349         spin_unlock_bh(&pwdev_priv->scan_req_lock);
1350
1351         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1352                 DBG_8723A("%s under WIFI_AP_STATE\n", __func__);
1353                 /* need_indicate_scan_done = true; */
1354                 /* goto check_need_indicate_scan_done; */
1355         }
1356
1357         if (rtw_pwr_wakeup(padapter) == _FAIL) {
1358                 need_indicate_scan_done = true;
1359                 goto check_need_indicate_scan_done;
1360         }
1361
1362         if (request->ie && request->ie_len > 0) {
1363                 rtw_cfg80211_set_probe_req_wpsp2pie(padapter,
1364                                                     (u8 *) request->ie,
1365                                                     request->ie_len);
1366         }
1367
1368         if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true) {
1369                 DBG_8723A("%s, bBusyTraffic == true\n", __func__);
1370                 need_indicate_scan_done = true;
1371                 goto check_need_indicate_scan_done;
1372         }
1373         if (rtw_is_scan_deny(padapter)) {
1374                 DBG_8723A("%s(%s): scan deny\n", __func__,
1375                           padapter->pnetdev->name);
1376                 need_indicate_scan_done = true;
1377                 goto check_need_indicate_scan_done;
1378         }
1379
1380         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) ==
1381             true) {
1382                 DBG_8723A("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
1383                 need_indicate_scan_done = true;
1384                 goto check_need_indicate_scan_done;
1385         }
1386
1387         memset(ssid, 0, sizeof(struct cfg80211_ssid) * RTW_SSID_SCAN_AMOUNT);
1388         /* parsing request ssids, n_ssids */
1389         for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
1390                 DBG_8723A("ssid =%s, len =%d\n", ssids[i].ssid,
1391                           ssids[i].ssid_len);
1392                 memcpy(ssid[i].ssid, ssids[i].ssid, ssids[i].ssid_len);
1393                 ssid[i].ssid_len = ssids[i].ssid_len;
1394         }
1395
1396         /* parsing channels, n_channels */
1397         memset(ch, 0,
1398                sizeof(struct rtw_ieee80211_channel) * RTW_CHANNEL_SCAN_AMOUNT);
1399
1400         if (request->n_channels == 1) {
1401                 for (i = 0; i < request->n_channels &&
1402                      i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
1403                         DBG_8723A("%s:(%s):" CHAN_FMT "\n",
1404                                   __func__, padapter->pnetdev->name,
1405                                   CHAN_ARG(request->channels[i]));
1406                         ch[i].hw_value = request->channels[i]->hw_value;
1407                         ch[i].flags = request->channels[i]->flags;
1408                 }
1409         }
1410
1411         spin_lock_bh(&pmlmepriv->lock);
1412         if (request->n_channels == 1) {
1413                 memcpy(&ch[1], &ch[0], sizeof(struct rtw_ieee80211_channel));
1414                 memcpy(&ch[2], &ch[0], sizeof(struct rtw_ieee80211_channel));
1415                 _status = rtw_sitesurvey_cmd23a(padapter, ssid,
1416                                              RTW_SSID_SCAN_AMOUNT, ch, 3);
1417         } else {
1418                 _status = rtw_sitesurvey_cmd23a(padapter, ssid,
1419                                              RTW_SSID_SCAN_AMOUNT, NULL, 0);
1420         }
1421         spin_unlock_bh(&pmlmepriv->lock);
1422
1423         if (_status == false)
1424                 ret = -1;
1425
1426 check_need_indicate_scan_done:
1427         if (need_indicate_scan_done)
1428                 rtw_cfg80211_surveydone_event_callback(padapter);
1429         return ret;
1430 }
1431
1432 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1433 {
1434         DBG_8723A("%s\n", __func__);
1435         return 0;
1436 }
1437
1438 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1439                                   struct cfg80211_ibss_params *params)
1440 {
1441         DBG_8723A("%s(%s)\n", __func__, ndev->name);
1442         return 0;
1443 }
1444
1445 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1446 {
1447         DBG_8723A("%s(%s)\n", __func__, ndev->name);
1448         return 0;
1449 }
1450
1451 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv,
1452                                         u32 wpa_version)
1453 {
1454         DBG_8723A("%s, wpa_version =%d\n", __func__, wpa_version);
1455
1456         if (!wpa_version) {
1457                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
1458                 return 0;
1459         }
1460
1461         if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1462                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
1463
1464 /*
1465         if (wpa_version & NL80211_WPA_VERSION_2)
1466         {
1467                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
1468         }
1469 */
1470
1471         return 0;
1472 }
1473
1474 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
1475                                       enum nl80211_auth_type sme_auth_type)
1476 {
1477         DBG_8723A("%s, nl80211_auth_type =%d\n", __func__, sme_auth_type);
1478
1479         switch (sme_auth_type) {
1480         case NL80211_AUTHTYPE_AUTOMATIC:
1481                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1482
1483                 break;
1484         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1485                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1486
1487                 if (psecuritypriv->ndisauthtype > Ndis802_11AuthModeWPA)
1488                         psecuritypriv->dot11AuthAlgrthm =
1489                                 dot11AuthAlgrthm_8021X;
1490                 break;
1491         case NL80211_AUTHTYPE_SHARED_KEY:
1492                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1493
1494                 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1495                 break;
1496         default:
1497                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1498                 /* return -ENOTSUPP; */
1499         }
1500
1501         return 0;
1502 }
1503
1504 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv,
1505                                    u32 cipher, bool ucast)
1506 {
1507         u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
1508
1509         u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
1510             &psecuritypriv->dot118021XGrpPrivacy;
1511
1512         DBG_8723A("%s, ucast =%d, cipher = 0x%x\n", __func__, ucast, cipher);
1513
1514         if (!cipher) {
1515                 *profile_cipher = 0;
1516                 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
1517                 return 0;
1518         }
1519
1520         switch (cipher) {
1521         case IW_AUTH_CIPHER_NONE:
1522                 *profile_cipher = 0;
1523                 ndisencryptstatus = Ndis802_11EncryptionDisabled;
1524                 break;
1525         case WLAN_CIPHER_SUITE_WEP40:
1526                 *profile_cipher = WLAN_CIPHER_SUITE_WEP40;
1527                 ndisencryptstatus = Ndis802_11Encryption1Enabled;
1528                 break;
1529         case WLAN_CIPHER_SUITE_WEP104:
1530                 *profile_cipher = WLAN_CIPHER_SUITE_WEP104;
1531                 ndisencryptstatus = Ndis802_11Encryption1Enabled;
1532                 break;
1533         case WLAN_CIPHER_SUITE_TKIP:
1534                 *profile_cipher = WLAN_CIPHER_SUITE_TKIP;
1535                 ndisencryptstatus = Ndis802_11Encryption2Enabled;
1536                 break;
1537         case WLAN_CIPHER_SUITE_CCMP:
1538                 *profile_cipher = WLAN_CIPHER_SUITE_CCMP;
1539                 ndisencryptstatus = Ndis802_11Encryption3Enabled;
1540                 break;
1541         default:
1542                 DBG_8723A("Unsupported cipher: 0x%x\n", cipher);
1543                 return -ENOTSUPP;
1544         }
1545
1546         if (ucast)
1547                 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
1548
1549         return 0;
1550 }
1551
1552 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv,
1553                                     u32 key_mgt)
1554 {
1555         DBG_8723A("%s, key_mgt = 0x%x\n", __func__, key_mgt);
1556
1557         if (key_mgt == WLAN_AKM_SUITE_8021X)
1558                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1559         else if (key_mgt == WLAN_AKM_SUITE_PSK)
1560                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1561         else
1562                 DBG_8723A("Invalid key mgt: 0x%x\n", key_mgt);
1563
1564         return 0;
1565 }
1566
1567 static int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie,
1568                                    size_t ielen)
1569 {
1570         const u8 *wps_ie;
1571         int group_cipher = 0, pairwise_cipher = 0;
1572         int ret = 0;
1573         const u8 *pwpa, *pwpa2;
1574         int i;
1575
1576         if (!pie || !ielen) {
1577                 /* Treat this as normal case, but need to clear
1578                    WIFI_UNDER_WPS */
1579                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1580                 goto exit;
1581         }
1582         if (ielen > MAX_WPA_IE_LEN + MAX_WPS_IE_LEN + MAX_P2P_IE_LEN) {
1583                 ret = -EINVAL;
1584                 goto exit;
1585         }
1586
1587         /* dump */
1588         DBG_8723A("set wpa_ie(length:%zu):\n", ielen);
1589         for (i = 0; i < ielen; i = i + 8)
1590                 DBG_8723A("0x%.2x 0x%.2x 0x%.2x 0x%.2x "
1591                           "0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
1592                           pie[i], pie[i + 1], pie[i + 2], pie[i + 3],
1593                           pie[i + 4], pie[i + 5], pie[i + 6], pie[i + 7]);
1594         if (ielen < RSN_HEADER_LEN) {
1595                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
1596                          "Ie len too short %d\n", (int)ielen);
1597                 ret = -1;
1598                 goto exit;
1599         }
1600
1601         pwpa = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1602                                        WLAN_OUI_TYPE_MICROSOFT_WPA,
1603                                        pie, ielen);
1604         if (pwpa && pwpa[1] > 0) {
1605                 if (rtw_parse_wpa_ie23a(pwpa, pwpa[1] + 2, &group_cipher,
1606                                         &pairwise_cipher, NULL) == _SUCCESS) {
1607                         padapter->securitypriv.dot11AuthAlgrthm =
1608                                 dot11AuthAlgrthm_8021X;
1609                         padapter->securitypriv.ndisauthtype =
1610                                 Ndis802_11AuthModeWPAPSK;
1611                         memcpy(padapter->securitypriv.supplicant_ie, pwpa,
1612                                pwpa[1] + 2);
1613
1614                         DBG_8723A("got wpa_ie, wpa_ielen:%u\n", pwpa[1]);
1615                 }
1616         }
1617
1618         pwpa2 = cfg80211_find_ie(WLAN_EID_RSN, pie, ielen);
1619         if (pwpa2 && pwpa2[1] > 0) {
1620                 if (rtw_parse_wpa2_ie23a (pwpa2, pwpa2[1] + 2, &group_cipher,
1621                                           &pairwise_cipher, NULL) == _SUCCESS) {
1622                         padapter->securitypriv.dot11AuthAlgrthm =
1623                                 dot11AuthAlgrthm_8021X;
1624                         padapter->securitypriv.ndisauthtype =
1625                                 Ndis802_11AuthModeWPA2PSK;
1626                         memcpy(padapter->securitypriv.supplicant_ie, pwpa2,
1627                                pwpa2[1] + 2);
1628
1629                         DBG_8723A("got wpa2_ie, wpa2_ielen:%u\n", pwpa2[1]);
1630                 }
1631         }
1632
1633         if (group_cipher == 0) {
1634                 group_cipher = WPA_CIPHER_NONE;
1635         }
1636         if (pairwise_cipher == 0) {
1637                 pairwise_cipher = WPA_CIPHER_NONE;
1638         }
1639
1640         switch (group_cipher) {
1641         case WPA_CIPHER_NONE:
1642                 padapter->securitypriv.dot118021XGrpPrivacy = 0;
1643                 padapter->securitypriv.ndisencryptstatus =
1644                         Ndis802_11EncryptionDisabled;
1645                 break;
1646         case WPA_CIPHER_WEP40:
1647                 padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP40;
1648                 padapter->securitypriv.ndisencryptstatus =
1649                         Ndis802_11Encryption1Enabled;
1650                 break;
1651         case WPA_CIPHER_TKIP:
1652                 padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_TKIP;
1653                 padapter->securitypriv.ndisencryptstatus =
1654                         Ndis802_11Encryption2Enabled;
1655                 break;
1656         case WPA_CIPHER_CCMP:
1657                 padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_CCMP;
1658                 padapter->securitypriv.ndisencryptstatus =
1659                         Ndis802_11Encryption3Enabled;
1660                 break;
1661         case WPA_CIPHER_WEP104:
1662                 padapter->securitypriv.dot118021XGrpPrivacy = WLAN_CIPHER_SUITE_WEP104;
1663                 padapter->securitypriv.ndisencryptstatus =
1664                         Ndis802_11Encryption1Enabled;
1665                 break;
1666         }
1667
1668         switch (pairwise_cipher) {
1669         case WPA_CIPHER_NONE:
1670                 padapter->securitypriv.dot11PrivacyAlgrthm = 0;
1671                 padapter->securitypriv.ndisencryptstatus =
1672                         Ndis802_11EncryptionDisabled;
1673                 break;
1674         case WPA_CIPHER_WEP40:
1675                 padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
1676                 padapter->securitypriv.ndisencryptstatus =
1677                         Ndis802_11Encryption1Enabled;
1678                 break;
1679         case WPA_CIPHER_TKIP:
1680                 padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_TKIP;
1681                 padapter->securitypriv.ndisencryptstatus =
1682                         Ndis802_11Encryption2Enabled;
1683                 break;
1684         case WPA_CIPHER_CCMP:
1685                 padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_CCMP;
1686                 padapter->securitypriv.ndisencryptstatus =
1687                         Ndis802_11Encryption3Enabled;
1688                 break;
1689         case WPA_CIPHER_WEP104:
1690                 padapter->securitypriv.dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104;
1691                 padapter->securitypriv.ndisencryptstatus =
1692                         Ndis802_11Encryption1Enabled;
1693                 break;
1694         }
1695
1696         wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1697                                          WLAN_OUI_TYPE_MICROSOFT_WPS,
1698                                          pie, ielen);
1699         if (wps_ie && wps_ie[1] > 0) {
1700                 DBG_8723A("got wps_ie, wps_ielen:%u\n", wps_ie[1]);
1701                 padapter->securitypriv.wps_ie_len = wps_ie[1];
1702                 memcpy(padapter->securitypriv.wps_ie, wps_ie,
1703                        padapter->securitypriv.wps_ie_len);
1704                 set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
1705         } else {
1706                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1707         }
1708
1709         /* TKIP and AES disallow multicast packets until installing group key */
1710         if (padapter->securitypriv.dot11PrivacyAlgrthm ==
1711             WLAN_CIPHER_SUITE_TKIP ||
1712             padapter->securitypriv.dot11PrivacyAlgrthm ==
1713             WLAN_CIPHER_SUITE_CCMP)
1714                 /* WPS open need to enable multicast */
1715                 /* check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true)*/
1716                 rtl8723a_off_rcr_am(padapter);
1717
1718         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
1719                  "rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->securitypriv.ndisencryptstatus =%d padapter->securitypriv.ndisauthtype =%d\n",
1720                  pairwise_cipher,
1721                  padapter->securitypriv.ndisencryptstatus,
1722                  padapter->securitypriv.ndisauthtype);
1723
1724 exit:
1725         if (ret)
1726                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1727         return ret;
1728 }
1729
1730 static int rtw_cfg80211_add_wep(struct rtw_adapter *padapter,
1731                                 struct rtw_wep_key *wep, u8 keyid)
1732 {
1733         int res;
1734         struct security_priv *psecuritypriv = &padapter->securitypriv;
1735
1736         if (keyid >= NUM_WEP_KEYS) {
1737                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
1738                          "%s:keyid>4 =>fail\n", __func__);
1739                 res = _FAIL;
1740                 goto exit;
1741         }
1742
1743         switch (wep->keylen) {
1744         case WLAN_KEY_LEN_WEP40:
1745                 psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP40;
1746                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1747                          "%s:wep->KeyLength = 5\n", __func__);
1748                 break;
1749         case WLAN_KEY_LEN_WEP104:
1750                 psecuritypriv->dot11PrivacyAlgrthm = WLAN_CIPHER_SUITE_WEP104;
1751                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1752                          "%s:wep->KeyLength = 13\n", __func__);
1753                 break;
1754         default:
1755                 psecuritypriv->dot11PrivacyAlgrthm = 0;
1756                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1757                          "%s:wep->KeyLength!= 5 or 13\n", __func__);
1758                 res = _FAIL;
1759                 goto exit;
1760         }
1761
1762         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1763                  "%s:before memcpy, wep->KeyLength = 0x%x keyid =%x\n",
1764                  __func__, wep->keylen, keyid);
1765
1766         memcpy(&psecuritypriv->wep_key[keyid], wep, sizeof(struct rtw_wep_key));
1767
1768         psecuritypriv->dot11PrivacyKeyIndex = keyid;
1769
1770         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1771                  "%s:security key material : %x %x %x %x %x %x %x %x %x %x %x %x %x\n",
1772                  __func__,
1773                  psecuritypriv->wep_key[keyid].key[0],
1774                  psecuritypriv->wep_key[keyid].key[1],
1775                  psecuritypriv->wep_key[keyid].key[2],
1776                  psecuritypriv->wep_key[keyid].key[3],
1777                  psecuritypriv->wep_key[keyid].key[4],
1778                  psecuritypriv->wep_key[keyid].key[5],
1779                  psecuritypriv->wep_key[keyid].key[6],
1780                  psecuritypriv->wep_key[keyid].key[7],
1781                  psecuritypriv->wep_key[keyid].key[8],
1782                  psecuritypriv->wep_key[keyid].key[9],
1783                  psecuritypriv->wep_key[keyid].key[10],
1784                  psecuritypriv->wep_key[keyid].key[11],
1785                  psecuritypriv->wep_key[keyid].key[12]);
1786
1787         res = rtw_set_key23a(padapter, psecuritypriv, keyid, 1);
1788
1789 exit:
1790
1791         return res;
1792 }
1793
1794 static int rtw_set_ssid(struct rtw_adapter *padapter,
1795                         struct wlan_network *newnetwork)
1796 {
1797         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1798         struct wlan_network *pnetwork = &pmlmepriv->cur_network;
1799         int status = _SUCCESS;
1800         u32 cur_time = 0;
1801
1802         DBG_8723A_LEVEL(_drv_always_, "set ssid [%s] fw_state = 0x%08x\n",
1803                         newnetwork->network.Ssid.ssid, get_fwstate(pmlmepriv));
1804
1805         if (padapter->hw_init_completed == false) {
1806                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
1807                          "set_ssid: hw_init_completed == false =>exit!!!\n");
1808                 status = _FAIL;
1809                 goto exit;
1810         }
1811
1812         spin_lock_bh(&pmlmepriv->lock);
1813
1814         DBG_8723A("Set SSID under fw_state = 0x%08x\n", get_fwstate(pmlmepriv));
1815         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
1816                 goto handle_tkip_countermeasure;
1817
1818         if (check_fwstate(pmlmepriv, _FW_LINKED|WIFI_ADHOC_MASTER_STATE)) {
1819                 RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1820                          "set_ssid: _FW_LINKED||WIFI_ADHOC_MASTER_STATE\n");
1821
1822                 if (pmlmepriv->assoc_ssid.ssid_len ==
1823                     newnetwork->network.Ssid.ssid_len &&
1824                     !memcmp(&pmlmepriv->assoc_ssid.ssid,
1825                             newnetwork->network.Ssid.ssid,
1826                             newnetwork->network.Ssid.ssid_len)) {
1827                         if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1828                                 RT_TRACE(_module_rtl871x_ioctl_set_c_,
1829                                          _drv_err_,
1830                                          "New SSID is same SSID, fw_state = 0x%08x\n",
1831                                          get_fwstate(pmlmepriv));
1832
1833                                 if (rtw_is_same_ibss23a(padapter, pnetwork)) {
1834                                         /*
1835                                          * it means driver is in
1836                                          * WIFI_ADHOC_MASTER_STATE, we needn't
1837                                          * create bss again.
1838                                          */
1839                                         goto release_mlme_lock;
1840                                 }
1841
1842                                 /*
1843                                  * if in WIFI_ADHOC_MASTER_STATE |
1844                                  * WIFI_ADHOC_STATE, create bss or
1845                                  * rejoin again
1846                                  */
1847                                 rtw_disassoc_cmd23a(padapter, 0, true);
1848
1849                                 if (check_fwstate(pmlmepriv, _FW_LINKED))
1850                                         rtw_indicate_disconnect23a(padapter);
1851
1852                                 rtw_free_assoc_resources23a(padapter, 1);
1853
1854                                 if (check_fwstate(pmlmepriv,
1855                                                   WIFI_ADHOC_MASTER_STATE)) {
1856                                         _clr_fwstate_(pmlmepriv,
1857                                                       WIFI_ADHOC_MASTER_STATE);
1858                                         set_fwstate(pmlmepriv,
1859                                                     WIFI_ADHOC_STATE);
1860                                 }
1861                         } else {
1862                                 rtw_lps_ctrl_wk_cmd23a(padapter,
1863                                                        LPS_CTRL_JOINBSS, 1);
1864                         }
1865                 } else {
1866                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1867                                  "Set SSID not the same ssid\n");
1868                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1869                                  "set_ssid =[%s] len = 0x%x\n",
1870                                  newnetwork->network.Ssid.ssid,
1871                                  newnetwork->network.Ssid.ssid_len);
1872                         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_info_,
1873                                  "assoc_ssid =[%s] len = 0x%x\n",
1874                                  pmlmepriv->assoc_ssid.ssid,
1875                                  pmlmepriv->assoc_ssid.ssid_len);
1876
1877                         rtw_disassoc_cmd23a(padapter, 0, true);
1878
1879                         if (check_fwstate(pmlmepriv, _FW_LINKED))
1880                                 rtw_indicate_disconnect23a(padapter);
1881
1882                         rtw_free_assoc_resources23a(padapter, 1);
1883
1884                         if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1885                                 _clr_fwstate_(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
1886                                 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE);
1887                         }
1888                 }
1889         }
1890
1891 handle_tkip_countermeasure:
1892
1893         if (padapter->securitypriv.btkip_countermeasure == true) {
1894                 cur_time = jiffies;
1895
1896                 if ((cur_time -
1897                      padapter->securitypriv.btkip_countermeasure_time) >
1898                     60 * HZ) {
1899                         padapter->securitypriv.btkip_countermeasure = false;
1900                         padapter->securitypriv.btkip_countermeasure_time = 0;
1901                 } else {
1902                         status = _FAIL;
1903                         goto release_mlme_lock;
1904                 }
1905         }
1906
1907         memcpy(&pmlmepriv->assoc_ssid, &newnetwork->network.Ssid,
1908                sizeof(struct cfg80211_ssid));
1909
1910         pmlmepriv->assoc_by_bssid = false;
1911
1912         pmlmepriv->to_join = true;
1913
1914         if (!check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
1915                 pmlmepriv->cur_network.join_res = -2;
1916
1917                 status = rtw_do_join_network(padapter, newnetwork);
1918                 if (status == _SUCCESS) {
1919                         pmlmepriv->to_join = false;
1920                 } else {
1921                         if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {
1922                                 /* switch to ADHOC_MASTER */
1923                                 status = rtw_do_join_adhoc(padapter);
1924                                 if (status != _SUCCESS)
1925                                         goto release_mlme_lock;
1926                         } else {
1927                                 /* can't associate ; reset under-linking */
1928                                 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING);
1929                                 status = _FAIL;
1930                                 pmlmepriv->to_join = false;
1931                         }
1932                 }
1933         }
1934 release_mlme_lock:
1935         spin_unlock_bh(&pmlmepriv->lock);
1936
1937 exit:
1938         RT_TRACE(_module_rtl871x_ioctl_set_c_, _drv_err_,
1939                  "-%s: status =%d\n", __func__, status);
1940
1941         return status;
1942 }
1943
1944 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
1945                                 struct cfg80211_connect_params *sme)
1946 {
1947         int ret = 0;
1948         struct list_head *phead, *plist, *ptmp;
1949         struct wlan_network *pnetwork = NULL;
1950         /* u8 matched_by_bssid = false; */
1951         /* u8 matched_by_ssid = false; */
1952         u8 matched = false;
1953         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
1954         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1955         struct security_priv *psecuritypriv = &padapter->securitypriv;
1956         struct rtw_queue *queue = &pmlmepriv->scanned_queue;
1957
1958         DBG_8723A("=>" "%s(%s)\n", __func__, ndev->name);
1959         DBG_8723A("privacy =%d, key =%p, key_len =%d, key_idx =%d\n",
1960                   sme->privacy, sme->key, sme->key_len, sme->key_idx);
1961
1962         if (_FAIL == rtw_pwr_wakeup(padapter)) {
1963                 ret = -EPERM;
1964                 goto exit;
1965         }
1966
1967         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1968                 ret = -EPERM;
1969                 goto exit;
1970         }
1971
1972         if (!sme->ssid || !sme->ssid_len ||
1973             sme->ssid_len > IEEE80211_MAX_SSID_LEN) {
1974                 ret = -EINVAL;
1975                 goto exit;
1976         }
1977
1978         DBG_8723A("ssid =%s, len =%zu\n", sme->ssid, sme->ssid_len);
1979
1980         if (sme->bssid)
1981                 DBG_8723A("bssid=%pM\n", sme->bssid);
1982
1983         if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
1984                 ret = -EBUSY;
1985                 DBG_8723A("%s, fw_state = 0x%x, goto exit\n", __func__,
1986                           pmlmepriv->fw_state);
1987                 goto exit;
1988         }
1989         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
1990                 rtw_scan_abort23a(padapter);
1991         }
1992
1993         spin_lock_bh(&queue->lock);
1994
1995         phead = get_list_head(queue);
1996
1997         list_for_each_safe(plist, ptmp, phead) {
1998                 pnetwork = container_of(plist, struct wlan_network, list);
1999
2000                 if (sme->bssid) {
2001                         if (!ether_addr_equal(pnetwork->network.MacAddress,
2002                                               sme->bssid))
2003                                 continue;
2004                 }
2005
2006                 if (sme->ssid && sme->ssid_len) {
2007                         if (pnetwork->network.Ssid.ssid_len != sme->ssid_len ||
2008                             memcmp(pnetwork->network.Ssid.ssid, sme->ssid,
2009                                    sme->ssid_len))
2010                                 continue;
2011                 }
2012
2013                 if (sme->bssid) {
2014                         if (ether_addr_equal(pnetwork->network.MacAddress,
2015                                              sme->bssid)) {
2016                                 DBG_8723A("matched by bssid\n");
2017
2018                                 matched = true;
2019                                 break;
2020                         }
2021                 } else if (sme->ssid && sme->ssid_len) {
2022                         if (!memcmp(pnetwork->network.Ssid.ssid,
2023                                     sme->ssid, sme->ssid_len) &&
2024                             pnetwork->network.Ssid.ssid_len == sme->ssid_len) {
2025                                 DBG_8723A("matched by ssid\n");
2026
2027                                 matched = true;
2028                                 break;
2029                         }
2030                 }
2031         }
2032
2033         spin_unlock_bh(&queue->lock);
2034
2035         if (!matched || !pnetwork) {
2036                 ret = -ENOENT;
2037                 DBG_8723A("connect, matched == false, goto exit\n");
2038                 goto exit;
2039         }
2040
2041         if (cfg80211_infrastructure_mode(
2042                     padapter, pnetwork->network.ifmode) != _SUCCESS) {
2043                 ret = -EPERM;
2044                 goto exit;
2045         }
2046
2047         psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
2048         psecuritypriv->dot11PrivacyAlgrthm = 0;
2049         psecuritypriv->dot118021XGrpPrivacy = 0;
2050         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2051         psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2052
2053         ret = rtw_cfg80211_set_wpa_version(psecuritypriv,
2054                                            sme->crypto.wpa_versions);
2055         if (ret < 0)
2056                 goto exit;
2057
2058         ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
2059
2060         if (ret < 0)
2061                 goto exit;
2062
2063         DBG_8723A("%s, ie_len =%zu\n", __func__, sme->ie_len);
2064
2065         ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len);
2066         if (ret < 0)
2067                 goto exit;
2068
2069         if (sme->crypto.n_ciphers_pairwise) {
2070                 ret = rtw_cfg80211_set_cipher(psecuritypriv,
2071                                               sme->crypto.ciphers_pairwise[0],
2072                                               true);
2073                 if (ret < 0)
2074                         goto exit;
2075         }
2076
2077         /* For WEP Shared auth */
2078         if ((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared ||
2079              psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) &&
2080             sme->key) {
2081                 struct rtw_wep_key wep_key;
2082                 u8 wep_key_idx, wep_key_len;
2083                 DBG_8723A("%s(): Shared/Auto WEP\n", __func__);
2084
2085                 wep_key_idx = sme->key_idx;
2086                 wep_key_len = sme->key_len;
2087
2088                 if (wep_key_idx > WEP_KEYS || !wep_key_len ||
2089                     wep_key_len > WLAN_KEY_LEN_WEP104) {
2090                         ret = -EINVAL;
2091                         goto exit;
2092                 }
2093
2094                 wep_key_len = wep_key_len <= 5 ? 5 : 13;
2095
2096                 memset(&wep_key, 0, sizeof(struct rtw_wep_key));
2097
2098                 wep_key.keylen = wep_key_len;
2099
2100                 if (wep_key_len == 13) {
2101                         padapter->securitypriv.dot11PrivacyAlgrthm =
2102                                 WLAN_CIPHER_SUITE_WEP104;
2103                         padapter->securitypriv.dot118021XGrpPrivacy =
2104                                 WLAN_CIPHER_SUITE_WEP104;
2105                 } else {
2106                         padapter->securitypriv.dot11PrivacyAlgrthm =
2107                                 WLAN_CIPHER_SUITE_WEP40;
2108                         padapter->securitypriv.dot118021XGrpPrivacy =
2109                                 WLAN_CIPHER_SUITE_WEP40;
2110                 }
2111
2112                 memcpy(wep_key.key, (void *)sme->key, wep_key.keylen);
2113
2114                 if (rtw_cfg80211_add_wep(padapter, &wep_key, wep_key_idx) !=
2115                     _SUCCESS)
2116                         ret = -EOPNOTSUPP;
2117
2118                 if (ret < 0)
2119                         goto exit;
2120         }
2121
2122         ret = rtw_cfg80211_set_cipher(psecuritypriv,
2123                                       sme->crypto.cipher_group, false);
2124         if (ret < 0)
2125                 goto exit;
2126
2127         if (sme->crypto.n_akm_suites) {
2128                 ret = rtw_cfg80211_set_key_mgt(psecuritypriv,
2129                                                sme->crypto.akm_suites[0]);
2130                 if (ret < 0)
2131                         goto exit;
2132         }
2133
2134         if (psecuritypriv->ndisauthtype > 3)
2135                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
2136
2137         if (rtw_set_auth23a(padapter, psecuritypriv) != _SUCCESS) {
2138                 ret = -EBUSY;
2139                 goto exit;
2140         }
2141
2142         /* rtw_set_802_11_encryption_mode(padapter,
2143            padapter->securitypriv.ndisencryptstatus); */
2144
2145         if (rtw_set_ssid(padapter, pnetwork) != _SUCCESS) {
2146                 ret = -EBUSY;
2147                 goto exit;
2148         }
2149
2150         DBG_8723A("set ssid:dot11AuthAlgrthm =%d, dot11PrivacyAlgrthm =%d, "
2151                   "dot118021XGrpPrivacy =%d\n", psecuritypriv->dot11AuthAlgrthm,
2152                   psecuritypriv->dot11PrivacyAlgrthm,
2153                   psecuritypriv->dot118021XGrpPrivacy);
2154
2155 exit:
2156
2157         DBG_8723A("<=%s, ret %d\n", __func__, ret);
2158
2159         return ret;
2160 }
2161
2162 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2163                                    u16 reason_code)
2164 {
2165         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2166
2167         DBG_8723A("%s(%s)\n", __func__, ndev->name);
2168
2169         rtw_set_roaming(padapter, 0);
2170
2171         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
2172                 rtw_scan_abort23a(padapter);
2173                 LeaveAllPowerSaveMode23a(padapter);
2174                 rtw_disassoc_cmd23a(padapter, 500, false);
2175
2176                 DBG_8723A("%s...call rtw_indicate_disconnect23a\n", __func__);
2177
2178                 padapter->mlmepriv.not_indic_disco = true;
2179                 rtw_indicate_disconnect23a(padapter);
2180                 padapter->mlmepriv.not_indic_disco = false;
2181
2182                 rtw_free_assoc_resources23a(padapter, 1);
2183         }
2184
2185         return 0;
2186 }
2187
2188 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
2189                                     struct wireless_dev *wdev,
2190                                     enum nl80211_tx_power_setting type, int mbm)
2191 {
2192         DBG_8723A("%s\n", __func__);
2193         return 0;
2194 }
2195
2196 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
2197                                     struct wireless_dev *wdev, int *dbm)
2198 {
2199         DBG_8723A("%s\n", __func__);
2200         *dbm = 12;
2201         return 0;
2202 }
2203
2204 inline bool rtw_cfg80211_pwr_mgmt(struct rtw_adapter *adapter)
2205 {
2206         struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(adapter->rtw_wdev);
2207         return rtw_wdev_priv->power_mgmt;
2208 }
2209
2210 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
2211                                        struct net_device *ndev,
2212                                        bool enabled, int timeout)
2213 {
2214         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2215         struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(padapter->rtw_wdev);
2216
2217         DBG_8723A("%s(%s): enabled:%u, timeout:%d\n",
2218                   __func__, ndev->name, enabled, timeout);
2219
2220         rtw_wdev_priv->power_mgmt = enabled;
2221
2222         if (!enabled)
2223                 LPS_Leave23a(padapter);
2224
2225         return 0;
2226 }
2227
2228 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
2229                                   struct net_device *netdev,
2230                                   struct cfg80211_pmksa *pmksa)
2231 {
2232         u8 index, blInserted = false;
2233         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2234         struct security_priv *psecuritypriv = &padapter->securitypriv;
2235
2236         DBG_8723A("%s(%s)\n", __func__, netdev->name);
2237
2238         if (is_zero_ether_addr(pmksa->bssid))
2239                 return -EINVAL;
2240
2241         blInserted = false;
2242
2243         /* overwrite PMKID */
2244         for (index = 0; index < NUM_PMKID_CACHE; index++) {
2245                 if (ether_addr_equal(psecuritypriv->PMKIDList[index].Bssid,
2246                                      pmksa->bssid)) {
2247                         /* BSSID is matched, the same AP => rewrite with
2248                            new PMKID. */
2249                         DBG_8723A("%s(%s):  BSSID exists in the PMKList.\n",
2250                                   __func__, netdev->name);
2251
2252                         memcpy(psecuritypriv->PMKIDList[index].PMKID,
2253                                pmksa->pmkid, WLAN_PMKID_LEN);
2254                         psecuritypriv->PMKIDList[index].bUsed = true;
2255                         psecuritypriv->PMKIDIndex = index + 1;
2256                         blInserted = true;
2257                         break;
2258                 }
2259         }
2260
2261         if (!blInserted) {
2262                 /*  Find a new entry */
2263                 DBG_8723A("%s(%s): Use new entry index = %d for this PMKID\n",
2264                           __func__, netdev->name, psecuritypriv->PMKIDIndex);
2265
2266                 ether_addr_copy(
2267                         psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
2268                         Bssid, pmksa->bssid);
2269                 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
2270                        PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2271
2272                 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed =
2273                         true;
2274                 psecuritypriv->PMKIDIndex++;
2275                 if (psecuritypriv->PMKIDIndex == 16) {
2276                         psecuritypriv->PMKIDIndex = 0;
2277                 }
2278         }
2279
2280         return 0;
2281 }
2282
2283 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
2284                                   struct net_device *netdev,
2285                                   struct cfg80211_pmksa *pmksa)
2286 {
2287         u8 index, bMatched = false;
2288         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2289         struct security_priv *psecuritypriv = &padapter->securitypriv;
2290
2291         DBG_8723A("%s(%s)\n", __func__, netdev->name);
2292
2293         for (index = 0; index < NUM_PMKID_CACHE; index++) {
2294                 if (ether_addr_equal(psecuritypriv->PMKIDList[index].Bssid,
2295                                      pmksa->bssid)) {
2296                         /* BSSID is matched, the same AP => Remove this PMKID
2297                            information and reset it. */
2298                         eth_zero_addr(psecuritypriv->PMKIDList[index].Bssid);
2299                         memset(psecuritypriv->PMKIDList[index].PMKID, 0x00,
2300                                WLAN_PMKID_LEN);
2301                         psecuritypriv->PMKIDList[index].bUsed = false;
2302                         bMatched = true;
2303                         break;
2304                 }
2305         }
2306
2307         if (false == bMatched) {
2308                 DBG_8723A("%s(%s): do not have matched BSSID\n", __func__,
2309                           netdev->name);
2310                 return -EINVAL;
2311         }
2312
2313         return 0;
2314 }
2315
2316 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
2317                                     struct net_device *netdev)
2318 {
2319         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2320         struct security_priv *psecuritypriv = &padapter->securitypriv;
2321
2322         DBG_8723A("%s(%s)\n", __func__, netdev->name);
2323
2324         memset(&psecuritypriv->PMKIDList[0], 0x00,
2325                sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
2326         psecuritypriv->PMKIDIndex = 0;
2327
2328         return 0;
2329 }
2330
2331 #ifdef CONFIG_8723AU_AP_MODE
2332 void rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter,
2333                                      u8 *pmgmt_frame, uint frame_len)
2334 {
2335         s32 freq;
2336         int channel;
2337         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2338         struct net_device *ndev = padapter->pnetdev;
2339
2340         DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name);
2341
2342 #if defined(RTW_USE_CFG80211_STA_EVENT)
2343         {
2344                 struct station_info sinfo;
2345                 u8 ie_offset;
2346
2347                 if (ieee80211_is_assoc_req(hdr->frame_control))
2348                         ie_offset = offsetof(struct ieee80211_mgmt,
2349                                              u.assoc_req.variable);
2350                 else            /*  WIFI_REASSOCREQ */
2351                         ie_offset = offsetof(struct ieee80211_mgmt,
2352                                              u.reassoc_req.variable);
2353
2354                 sinfo.filled = 0;
2355                 sinfo.assoc_req_ies = pmgmt_frame + ie_offset;
2356                 sinfo.assoc_req_ies_len = frame_len - ie_offset;
2357                 cfg80211_new_sta(ndev, hdr->addr2, &sinfo, GFP_ATOMIC);
2358         }
2359 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
2360         channel = pmlmeext->cur_channel;
2361         if (channel <= RTW_CH_MAX_2G_CHANNEL)
2362                 freq = ieee80211_channel_to_frequency(channel,
2363                                                       NL80211_BAND_2GHZ);
2364         else
2365                 freq = ieee80211_channel_to_frequency(channel,
2366                                                       NL80211_BAND_5GHZ);
2367
2368         cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, pmgmt_frame, frame_len,
2369                          0);
2370 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
2371 }
2372
2373 void rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter,
2374                                         unsigned char *da,
2375                                         unsigned short reason)
2376 {
2377         s32 freq;
2378         int channel;
2379         uint frame_len;
2380         struct ieee80211_mgmt mgmt;
2381         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2382         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2383         struct net_device *ndev = padapter->pnetdev;
2384
2385         DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name);
2386
2387         memset(&mgmt, 0, sizeof(struct ieee80211_mgmt));
2388
2389 #if defined(RTW_USE_CFG80211_STA_EVENT)
2390         cfg80211_del_sta(ndev, da, GFP_ATOMIC);
2391 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
2392         channel = pmlmeext->cur_channel;
2393         if (channel <= RTW_CH_MAX_2G_CHANNEL)
2394                 freq = ieee80211_channel_to_frequency(channel,
2395                                                       NL80211_BAND_2GHZ);
2396         else
2397                 freq = ieee80211_channel_to_frequency(channel,
2398                                                       NL80211_BAND_5GHZ);
2399
2400         mgmt.frame_control =
2401                 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH);
2402
2403         ether_addr_copy(mgmt.da, myid(&padapter->eeprompriv));
2404         ether_addr_copy(mgmt.sa, da);
2405         ether_addr_copy(mgmt.bssid, get_my_bssid23a(&pmlmeinfo->network));
2406
2407         mgmt.seq_ctrl = cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext->mgnt_seq));
2408         pmlmeext->mgnt_seq++;
2409
2410         mgmt.u.disassoc.reason_code = cpu_to_le16(reason);
2411
2412         frame_len = sizeof(struct ieee80211_hdr_3addr) + 2;
2413
2414         cfg80211_rx_mgmt(padapter->rtw_wdev, freq, 0, (u8 *)&mgmt, frame_len,
2415                          0);
2416 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
2417 }
2418
2419 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
2420 {
2421         DBG_8723A("%s\n", __func__);
2422
2423         return 0;
2424 }
2425
2426 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
2427 {
2428         DBG_8723A("%s\n", __func__);
2429
2430         return 0;
2431 }
2432
2433 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb,
2434                                               struct net_device *ndev)
2435 {
2436         int ret = 0;
2437         int rtap_len;
2438         int qos_len = 0;
2439         int dot11_hdr_len = 24;
2440         int snap_len = 6;
2441         unsigned char *pdata;
2442         unsigned char src_mac_addr[6];
2443         unsigned char dst_mac_addr[6];
2444         struct ieee80211_hdr *dot11_hdr;
2445         struct ieee80211_radiotap_header *rtap_hdr;
2446         struct rtw_adapter *padapter = netdev_priv(ndev);
2447
2448         DBG_8723A("%s(%s)\n", __func__, ndev->name);
2449
2450         if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
2451                 goto fail;
2452
2453         rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
2454         if (unlikely(rtap_hdr->it_version))
2455                 goto fail;
2456
2457         rtap_len = ieee80211_get_radiotap_len(skb->data);
2458         if (unlikely(skb->len < rtap_len))
2459                 goto fail;
2460
2461         if (rtap_len != 14) {
2462                 DBG_8723A("radiotap len (should be 14): %d\n", rtap_len);
2463                 goto fail;
2464         }
2465
2466         /* Skip the ratio tap header */
2467         skb_pull(skb, rtap_len);
2468
2469         dot11_hdr = (struct ieee80211_hdr *)skb->data;
2470         /* Check if the QoS bit is set */
2471         if (ieee80211_is_data(dot11_hdr->frame_control)) {
2472                 /* Check if this ia a Wireless Distribution System (WDS) frame
2473                  * which has 4 MAC addresses
2474                  */
2475                 if (ieee80211_is_data_qos(dot11_hdr->frame_control))
2476                         qos_len = IEEE80211_QOS_CTL_LEN;
2477                 if (ieee80211_has_a4(dot11_hdr->frame_control))
2478                         dot11_hdr_len += 6;
2479
2480                 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
2481                 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
2482
2483                 /*
2484                  * Skip the 802.11 header, QoS (if any) and SNAP,
2485                  * but leave spaces for two MAC addresses
2486                  */
2487                 skb_pull(skb, dot11_hdr_len + qos_len + snap_len -
2488                          ETH_ALEN * 2);
2489                 pdata = (unsigned char *)skb->data;
2490                 ether_addr_copy(pdata, dst_mac_addr);
2491                 ether_addr_copy(pdata + ETH_ALEN, src_mac_addr);
2492
2493                 DBG_8723A("should be eapol packet\n");
2494
2495                 /* Use the real net device to transmit the packet */
2496                 ret = rtw_xmit23a_entry23a(skb, padapter->pnetdev);
2497
2498                 return ret;
2499
2500         } else if (ieee80211_is_action(dot11_hdr->frame_control)) {
2501                 struct ieee80211_mgmt *mgmt;
2502                 /* only for action frames */
2503                 struct xmit_frame *pmgntframe;
2504                 struct pkt_attrib *pattrib;
2505                 unsigned char *pframe;
2506                 /* u8 category, action, OUI_Subtype, dialogToken = 0; */
2507                 /* unsigned char        *frame_body; */
2508                 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2509                 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2510                 u32 len = skb->len;
2511                 u8 category, action;
2512
2513                 mgmt = (struct ieee80211_mgmt *)dot11_hdr;
2514
2515                 DBG_8723A("RTW_Tx:da=%pM via %s(%s)\n",
2516                           mgmt->da, __func__, ndev->name);
2517                 category = mgmt->u.action.category;
2518                 action = mgmt->u.action.u.wme_action.action_code;
2519                 DBG_8723A("RTW_Tx:category(%u), action(%u)\n",
2520                           category, action);
2521
2522                 /* starting alloc mgmt frame to dump it */
2523                 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2524                 if (pmgntframe == NULL)
2525                         goto fail;
2526
2527                 /* update attribute */
2528                 pattrib = &pmgntframe->attrib;
2529                 update_mgntframe_attrib23a(padapter, pattrib);
2530                 pattrib->retry_ctrl = false;
2531
2532                 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2533
2534                 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2535
2536                 memcpy(pframe, skb->data, len);
2537                 pattrib->pktlen = len;
2538
2539                 /* update seq number */
2540                 pmlmeext->mgnt_seq = le16_to_cpu(dot11_hdr->seq_ctrl) >> 4;
2541                 pattrib->seqnum = pmlmeext->mgnt_seq;
2542                 pmlmeext->mgnt_seq++;
2543
2544                 pattrib->last_txcmdsz = pattrib->pktlen;
2545
2546                 dump_mgntframe23a(padapter, pmgntframe);
2547         }
2548
2549 fail:
2550
2551         dev_kfree_skb(skb);
2552
2553         return 0;
2554 }
2555
2556 static int
2557 rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
2558 {
2559         DBG_8723A("%s\n", __func__);
2560
2561         return 0;
2562 }
2563
2564 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
2565         .ndo_open = rtw_cfg80211_monitor_if_open,
2566         .ndo_stop = rtw_cfg80211_monitor_if_close,
2567         .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
2568         .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
2569 };
2570
2571 static int rtw_cfg80211_add_monitor_if(struct rtw_adapter *padapter, char *name,
2572                                        unsigned char name_assign_type,
2573                                        struct net_device **ndev)
2574 {
2575         int ret = 0;
2576         struct net_device *mon_ndev = NULL;
2577         struct wireless_dev *mon_wdev = NULL;
2578         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
2579
2580         if (!name) {
2581                 DBG_8723A("%s(%s): without specific name\n",
2582                           __func__, padapter->pnetdev->name);
2583                 ret = -EINVAL;
2584                 goto out;
2585         }
2586
2587         if (pwdev_priv->pmon_ndev) {
2588                 DBG_8723A("%s(%s): monitor interface exist: %s\n", __func__,
2589                           padapter->pnetdev->name, pwdev_priv->pmon_ndev->name);
2590                 ret = -EBUSY;
2591                 goto out;
2592         }
2593
2594         mon_ndev = alloc_etherdev(sizeof(struct rtw_adapter));
2595         if (!mon_ndev) {
2596                 DBG_8723A("%s(%s): allocate ndev fail\n", __func__,
2597                           padapter->pnetdev->name);
2598                 ret = -ENOMEM;
2599                 goto out;
2600         }
2601
2602         mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
2603         strncpy(mon_ndev->name, name, IFNAMSIZ);
2604         mon_ndev->name[IFNAMSIZ - 1] = 0;
2605         mon_ndev->name_assign_type = name_assign_type;
2606         mon_ndev->destructor = rtw_ndev_destructor;
2607
2608         mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
2609
2610         /*  wdev */
2611         mon_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2612         if (!mon_wdev) {
2613                 ret = -ENOMEM;
2614                 goto out;
2615         }
2616
2617         mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
2618         mon_wdev->netdev = mon_ndev;
2619         mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
2620         mon_ndev->ieee80211_ptr = mon_wdev;
2621
2622         ret = register_netdevice(mon_ndev);
2623         if (ret) {
2624                 goto out;
2625         }
2626
2627         *ndev = pwdev_priv->pmon_ndev = mon_ndev;
2628         memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ + 1);
2629
2630 out:
2631         if (ret) {
2632                 kfree(mon_wdev);
2633                 mon_wdev = NULL;
2634         }
2635
2636         if (ret && mon_ndev) {
2637                 free_netdev(mon_ndev);
2638                 *ndev = mon_ndev = NULL;
2639         }
2640
2641         return ret;
2642 }
2643
2644 static struct wireless_dev *
2645 cfg80211_rtw_add_virtual_intf(struct wiphy *wiphy, const char *name,
2646                               unsigned char name_assign_type,
2647                               enum nl80211_iftype type, u32 *flags,
2648                               struct vif_params *params)
2649 {
2650         int ret = 0;
2651         struct net_device *ndev = NULL;
2652         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2653
2654         DBG_8723A("%s(%s): wiphy:%s, name:%s, type:%d\n", __func__,
2655                   padapter->pnetdev->name, wiphy_name(wiphy), name, type);
2656
2657         switch (type) {
2658         case NL80211_IFTYPE_ADHOC:
2659         case NL80211_IFTYPE_AP_VLAN:
2660         case NL80211_IFTYPE_WDS:
2661         case NL80211_IFTYPE_MESH_POINT:
2662                 ret = -ENODEV;
2663                 break;
2664         case NL80211_IFTYPE_MONITOR:
2665                 ret =
2666                     rtw_cfg80211_add_monitor_if(padapter, (char *)name,
2667                                                 name_assign_type, &ndev);
2668                 break;
2669
2670         case NL80211_IFTYPE_P2P_CLIENT:
2671         case NL80211_IFTYPE_STATION:
2672                 ret = -ENODEV;
2673                 break;
2674
2675         case NL80211_IFTYPE_P2P_GO:
2676         case NL80211_IFTYPE_AP:
2677                 ret = -ENODEV;
2678                 break;
2679         default:
2680                 ret = -ENODEV;
2681                 DBG_8723A("Unsupported interface type\n");
2682                 break;
2683         }
2684
2685         DBG_8723A("%s(%s): ndev:%p, ret:%d\n", __func__,
2686                   padapter->pnetdev->name,
2687                   ndev, ret);
2688
2689         return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
2690 }
2691
2692 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
2693                                          struct wireless_dev *wdev)
2694 {
2695         struct rtw_wdev_priv *pwdev_priv =
2696             (struct rtw_wdev_priv *)wiphy_priv(wiphy);
2697         struct net_device *ndev;
2698         ndev = wdev ? wdev->netdev : NULL;
2699
2700         if (!ndev)
2701                 goto exit;
2702
2703         unregister_netdevice(ndev);
2704
2705         if (ndev == pwdev_priv->pmon_ndev) {
2706                 pwdev_priv->pmon_ndev = NULL;
2707                 pwdev_priv->ifname_mon[0] = '\0';
2708                 DBG_8723A("%s(%s): remove monitor interface\n",
2709                           __func__, ndev->name);
2710         }
2711
2712 exit:
2713         return 0;
2714 }
2715
2716 static int rtw_add_beacon(struct rtw_adapter *adapter, const u8 *head,
2717                           size_t head_len, const u8 *tail, size_t tail_len)
2718 {
2719         int ret = 0;
2720         u8 *pbuf;
2721         uint len, ielen, wps_ielen = 0;
2722         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2723         struct wlan_bssid_ex *bss = &pmlmepriv->cur_network.network;
2724         const struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)head;
2725         struct ieee80211_mgmt *tmpmgmt;
2726         /* struct sta_priv *pstapriv = &padapter->stapriv; */
2727
2728         DBG_8723A("%s beacon_head_len =%zu, beacon_tail_len =%zu\n",
2729                   __func__, head_len, tail_len);
2730
2731         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2732                 return -EINVAL;
2733
2734         if (head_len < offsetof(struct ieee80211_mgmt, u.beacon.variable))
2735                 return -EINVAL;
2736
2737         pbuf = kzalloc(head_len + tail_len, GFP_KERNEL);
2738         if (!pbuf)
2739                 return -ENOMEM;
2740         tmpmgmt = (struct ieee80211_mgmt *)pbuf;
2741
2742         bss->beacon_interval = get_unaligned_le16(&mgmt->u.beacon.beacon_int);
2743         bss->capability = get_unaligned_le16(&mgmt->u.beacon.capab_info);
2744         bss->tsf = get_unaligned_le64(&mgmt->u.beacon.timestamp);
2745
2746         /*  24 = beacon header len. */
2747         memcpy(pbuf, (void *)head, head_len);
2748         memcpy(pbuf + head_len, (void *)tail, tail_len);
2749
2750         len = head_len + tail_len;
2751         ielen = len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
2752         /* check wps ie if inclued */
2753         if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
2754                                     WLAN_OUI_TYPE_MICROSOFT_WPS,
2755                                     tmpmgmt->u.beacon.variable, ielen))
2756                 DBG_8723A("add bcn, wps_ielen =%d\n", wps_ielen);
2757
2758         /* pbss_network->IEs will not include p2p_ie, wfd ie */
2759         rtw_ies_remove_ie23a(tmpmgmt->u.beacon.variable, &ielen, 0,
2760                              WLAN_EID_VENDOR_SPECIFIC, P2P_OUI23A, 4);
2761         rtw_ies_remove_ie23a(tmpmgmt->u.beacon.variable, &ielen, 0,
2762                              WLAN_EID_VENDOR_SPECIFIC, WFD_OUI23A, 4);
2763
2764         len = ielen + offsetof(struct ieee80211_mgmt, u.beacon.variable);
2765         if (rtw_check_beacon_data23a(adapter, tmpmgmt, len) == _SUCCESS) {
2766                 ret = 0;
2767         } else {
2768                 ret = -EINVAL;
2769         }
2770
2771         kfree(pbuf);
2772
2773         return ret;
2774 }
2775
2776 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
2777                                  struct cfg80211_ap_settings *settings)
2778 {
2779         int ret = 0;
2780         struct rtw_adapter *adapter = wiphy_to_adapter(wiphy);
2781
2782         DBG_8723A("%s(%s): hidden_ssid:%d, auth_type:%d\n",
2783                   __func__, ndev->name, settings->hidden_ssid,
2784                   settings->auth_type);
2785
2786         ret = rtw_add_beacon(adapter, settings->beacon.head,
2787                              settings->beacon.head_len, settings->beacon.tail,
2788                              settings->beacon.tail_len);
2789
2790         adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode =
2791                 settings->hidden_ssid;
2792
2793         if (settings->ssid && settings->ssid_len) {
2794                 struct wlan_bssid_ex *pbss_network =
2795                         &adapter->mlmepriv.cur_network.network;
2796                 struct wlan_bssid_ex *pbss_network_ext =
2797                         &adapter->mlmeextpriv.mlmext_info.network;
2798
2799                 memcpy(pbss_network->Ssid.ssid, (void *)settings->ssid,
2800                        settings->ssid_len);
2801                 pbss_network->Ssid.ssid_len = settings->ssid_len;
2802                 memcpy(pbss_network_ext->Ssid.ssid, (void *)settings->ssid,
2803                        settings->ssid_len);
2804                 pbss_network_ext->Ssid.ssid_len = settings->ssid_len;
2805         }
2806
2807         return ret;
2808 }
2809
2810 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy,
2811                                       struct net_device *ndev,
2812                                       struct cfg80211_beacon_data *info)
2813 {
2814         int ret = 0;
2815         struct rtw_adapter *adapter = wiphy_to_adapter(wiphy);
2816
2817         DBG_8723A("%s(%s)\n", __func__, ndev->name);
2818
2819         ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail,
2820                              info->tail_len);
2821
2822         return ret;
2823 }
2824
2825 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
2826 {
2827         DBG_8723A("%s(%s)\n", __func__, ndev->name);
2828         return 0;
2829 }
2830
2831 static int cfg80211_rtw_add_station(struct wiphy *wiphy,
2832                                     struct net_device *ndev, const u8 *mac,
2833                                     struct station_parameters *params)
2834 {
2835         DBG_8723A("%s(%s)\n", __func__, ndev->name);
2836
2837         return 0;
2838 }
2839
2840 static int cfg80211_rtw_del_station(struct wiphy *wiphy,
2841                                     struct net_device *ndev,
2842                                     struct station_del_parameters *params)
2843 {
2844         const u8 *mac = params->mac;
2845         int ret = 0;
2846         struct list_head *phead;
2847         u8 updated = 0;
2848         struct sta_info *psta, *ptmp;
2849         struct rtw_adapter *padapter = netdev_priv(ndev);
2850         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2851         struct sta_priv *pstapriv = &padapter->stapriv;
2852
2853         DBG_8723A("+%s(%s)\n", __func__, ndev->name);
2854
2855         if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != true) {
2856                 DBG_8723A("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n",
2857                           __func__);
2858                 return -EINVAL;
2859         }
2860
2861         if (!mac) {
2862                 DBG_8723A("flush all sta, and cam_entry\n");
2863
2864                 flush_all_cam_entry23a(padapter);       /* clear CAM */
2865
2866                 ret = rtw_sta_flush23a(padapter);
2867
2868                 return ret;
2869         }
2870
2871         DBG_8723A("free sta macaddr=%pM\n", mac);
2872
2873         if (is_broadcast_ether_addr(mac))
2874                 return -EINVAL;
2875
2876         spin_lock_bh(&pstapriv->asoc_list_lock);
2877         phead = &pstapriv->asoc_list;
2878         /* check asoc_queue */
2879         list_for_each_entry_safe(psta, ptmp, phead, asoc_list) {
2880                 if (ether_addr_equal(mac, psta->hwaddr)) {
2881                         if (psta->dot8021xalg == 1 &&
2882                             psta->bpairwise_key_installed == false) {
2883                                 DBG_8723A("%s, sta's dot8021xalg = 1 and "
2884                                           "key_installed = false\n", __func__);
2885                         } else {
2886                                 DBG_8723A("free psta =%p, aid =%d\n", psta,
2887                                           psta->aid);
2888
2889                                 list_del_init(&psta->asoc_list);
2890                                 pstapriv->asoc_list_cnt--;
2891
2892                                 /* spin_unlock_bh(&pstapriv->asoc_list_lock); */
2893                                 updated =
2894                                     ap_free_sta23a(padapter, psta, true,
2895                                                 WLAN_REASON_DEAUTH_LEAVING);
2896                                 /* spin_lock_bh(&pstapriv->asoc_list_lock); */
2897
2898                                 psta = NULL;
2899
2900                                 break;
2901                         }
2902                 }
2903         }
2904         spin_unlock_bh(&pstapriv->asoc_list_lock);
2905
2906         associated_clients_update23a(padapter, updated);
2907
2908         DBG_8723A("-%s(%s)\n", __func__, ndev->name);
2909
2910         return ret;
2911 }
2912
2913 static int cfg80211_rtw_change_station(struct wiphy *wiphy,
2914                                        struct net_device *ndev, const u8 *mac,
2915                                        struct station_parameters *params)
2916 {
2917         DBG_8723A("%s(%s)\n", __func__, ndev->name);
2918         return 0;
2919 }
2920
2921 static int cfg80211_rtw_dump_station(struct wiphy *wiphy,
2922                                      struct net_device *ndev, int idx, u8 *mac,
2923                                      struct station_info *sinfo)
2924 {
2925         DBG_8723A("%s(%s)\n", __func__, ndev->name);
2926
2927         /* TODO: dump scanned queue */
2928
2929         return -ENOENT;
2930 }
2931
2932 static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
2933                                    struct bss_parameters *params)
2934 {
2935         DBG_8723A("%s(%s)\n", __func__, ndev->name);
2936         return 0;
2937 }
2938 #endif /* CONFIG_8723AU_AP_MODE */
2939
2940 static int _cfg80211_rtw_mgmt_tx(struct rtw_adapter *padapter, u8 tx_ch,
2941                                  const u8 *buf, size_t len)
2942 {
2943         struct xmit_frame *pmgntframe;
2944         struct pkt_attrib *pattrib;
2945         unsigned char *pframe;
2946         int ret = _FAIL;
2947         struct ieee80211_hdr *pwlanhdr;
2948         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2949         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2950
2951         if (_FAIL == rtw_pwr_wakeup(padapter)) {
2952                 ret = -EFAULT;
2953                 goto exit;
2954         }
2955
2956         rtw_set_scan_deny(padapter, 1000);
2957
2958         rtw_scan_abort23a(padapter);
2959
2960         if (tx_ch != rtw_get_oper_ch23a(padapter)) {
2961                 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
2962                         pmlmeext->cur_channel = tx_ch;
2963                 set_channel_bwmode23a(padapter, tx_ch,
2964                                    HAL_PRIME_CHNL_OFFSET_DONT_CARE,
2965                                    HT_CHANNEL_WIDTH_20);
2966         }
2967
2968         /* starting alloc mgmt frame to dump it */
2969         pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2970         if (!pmgntframe) {
2971                 /* ret = -ENOMEM; */
2972                 ret = _FAIL;
2973                 goto exit;
2974         }
2975
2976         /* update attribute */
2977         pattrib = &pmgntframe->attrib;
2978         update_mgntframe_attrib23a(padapter, pattrib);
2979         pattrib->retry_ctrl = false;
2980
2981         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2982
2983         pframe = (u8 *) (pmgntframe->buf_addr) + TXDESC_OFFSET;
2984
2985         memcpy(pframe, (void *)buf, len);
2986         pattrib->pktlen = len;
2987
2988         pwlanhdr = (struct ieee80211_hdr *)pframe;
2989         /* update seq number */
2990         pmlmeext->mgnt_seq = le16_to_cpu(pwlanhdr->seq_ctrl) >> 4;
2991         pattrib->seqnum = pmlmeext->mgnt_seq;
2992         pmlmeext->mgnt_seq++;
2993
2994         pattrib->last_txcmdsz = pattrib->pktlen;
2995
2996         ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
2997
2998         if (ret  != _SUCCESS)
2999                 DBG_8723A("%s, ack == false\n", __func__);
3000         else
3001                 DBG_8723A("%s, ack == true\n", __func__);
3002
3003 exit:
3004
3005         DBG_8723A("%s, ret =%d\n", __func__, ret);
3006
3007         return ret;
3008 }
3009
3010 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3011                                 struct cfg80211_mgmt_tx_params *params,
3012                                 u64 *cookie)
3013 {
3014         struct rtw_adapter *padapter =
3015                 (struct rtw_adapter *)wiphy_to_adapter(wiphy);
3016         int ret = 0;
3017         int tx_ret;
3018         u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
3019         u32 dump_cnt = 0;
3020         bool ack = true;
3021         u8 category, action;
3022         unsigned long start = jiffies;
3023         size_t len = params->len;
3024         struct ieee80211_channel *chan = params->chan;
3025         const u8 *buf = params->buf;
3026         struct ieee80211_mgmt *hdr = (struct ieee80211_mgmt *)buf;
3027         u8 tx_ch = (u8) ieee80211_frequency_to_channel(chan->center_freq);
3028
3029         if (!ieee80211_is_action(hdr->frame_control))
3030                 return -EINVAL;
3031
3032         /* cookie generation */
3033         *cookie = (unsigned long)buf;
3034
3035         DBG_8723A("%s(%s): len =%zu, ch =%d\n", __func__,
3036                   padapter->pnetdev->name, len, tx_ch);
3037
3038         /* indicate ack before issue frame to avoid racing with rsp frame */
3039         cfg80211_mgmt_tx_status(padapter->rtw_wdev, *cookie, buf, len, ack,
3040                                 GFP_KERNEL);
3041
3042         DBG_8723A("RTW_Tx:tx_ch =%d, da =%pM\n", tx_ch, hdr->da);
3043         category = hdr->u.action.category;
3044         action = hdr->u.action.u.wme_action.action_code;
3045         DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category, action);
3046
3047         do {
3048                 dump_cnt++;
3049                 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
3050         } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
3051
3052         if (tx_ret != _SUCCESS || dump_cnt > 1) {
3053                 DBG_8723A("%s(%s): %s (%d/%d) in %d ms\n",
3054                           __func__, padapter->pnetdev->name,
3055                           tx_ret == _SUCCESS ? "OK" : "FAIL", dump_cnt,
3056                           dump_limit, jiffies_to_msecs(jiffies - start));
3057         }
3058
3059         return ret;
3060 }
3061
3062 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
3063                                              struct wireless_dev *wdev,
3064                                              u16 frame_type, bool reg)
3065 {
3066         if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
3067                 return;
3068
3069         return;
3070 }
3071
3072 static struct cfg80211_ops rtw_cfg80211_ops = {
3073         .change_virtual_intf = cfg80211_rtw_change_iface,
3074         .add_key = cfg80211_rtw_add_key,
3075         .get_key = cfg80211_rtw_get_key,
3076         .del_key = cfg80211_rtw_del_key,
3077         .set_default_key = cfg80211_rtw_set_default_key,
3078         .get_station = cfg80211_rtw_get_station,
3079         .scan = cfg80211_rtw_scan,
3080         .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
3081         .connect = cfg80211_rtw_connect,
3082         .disconnect = cfg80211_rtw_disconnect,
3083         .join_ibss = cfg80211_rtw_join_ibss,
3084         .leave_ibss = cfg80211_rtw_leave_ibss,
3085         .set_tx_power = cfg80211_rtw_set_txpower,
3086         .get_tx_power = cfg80211_rtw_get_txpower,
3087         .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
3088         .set_pmksa = cfg80211_rtw_set_pmksa,
3089         .del_pmksa = cfg80211_rtw_del_pmksa,
3090         .flush_pmksa = cfg80211_rtw_flush_pmksa,
3091
3092 #ifdef CONFIG_8723AU_AP_MODE
3093         .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
3094         .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
3095
3096         .start_ap = cfg80211_rtw_start_ap,
3097         .change_beacon = cfg80211_rtw_change_beacon,
3098         .stop_ap = cfg80211_rtw_stop_ap,
3099
3100         .add_station = cfg80211_rtw_add_station,
3101         .del_station = cfg80211_rtw_del_station,
3102         .change_station = cfg80211_rtw_change_station,
3103         .dump_station = cfg80211_rtw_dump_station,
3104         .change_bss = cfg80211_rtw_change_bss,
3105 #endif /* CONFIG_8723AU_AP_MODE */
3106
3107         .mgmt_tx = cfg80211_rtw_mgmt_tx,
3108         .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
3109 };
3110
3111 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap,
3112                                        enum nl80211_band band, u8 rf_type)
3113 {
3114
3115 #define MAX_BIT_RATE_40MHZ_MCS15        300     /* Mbps */
3116 #define MAX_BIT_RATE_40MHZ_MCS7         150     /* Mbps */
3117
3118         ht_cap->ht_supported = true;
3119
3120         ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
3121             IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
3122             IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
3123
3124         /*
3125          *Maximum length of AMPDU that the STA can receive.
3126          *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
3127          */
3128         ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
3129
3130         /*Minimum MPDU start spacing , */
3131         ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
3132
3133         ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
3134
3135         /*
3136          *hw->wiphy->bands[NL80211_BAND_2GHZ]
3137          *base on ant_num
3138          *rx_mask: RX mask
3139          *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7
3140          *if rx_ant = 2 rx_mask[1]= 0xff;==>MCS8-MCS15
3141          *if rx_ant >= 3 rx_mask[2]= 0xff;
3142          *if BW_40 rx_mask[4]= 0x01;
3143          *highest supported RX rate
3144          */
3145         if (rf_type == RF_1T1R) {
3146                 ht_cap->mcs.rx_mask[0] = 0xFF;
3147                 ht_cap->mcs.rx_mask[1] = 0x00;
3148                 ht_cap->mcs.rx_mask[4] = 0x01;
3149
3150                 ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7);
3151         } else if ((rf_type == RF_1T2R) || (rf_type == RF_2T2R)) {
3152                 ht_cap->mcs.rx_mask[0] = 0xFF;
3153                 ht_cap->mcs.rx_mask[1] = 0xFF;
3154                 ht_cap->mcs.rx_mask[4] = 0x01;
3155
3156                 ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15);
3157         } else {
3158                 DBG_8723A("%s, error rf_type =%d\n", __func__, rf_type);
3159         }
3160
3161 }
3162
3163 void rtw_cfg80211_init_wiphy(struct rtw_adapter *padapter)
3164 {
3165         u8 rf_type;
3166         struct ieee80211_supported_band *bands;
3167         struct wireless_dev *pwdev = padapter->rtw_wdev;
3168         struct wiphy *wiphy = pwdev->wiphy;
3169
3170         rf_type = rtl8723a_get_rf_type(padapter);
3171
3172         DBG_8723A("%s:rf_type =%d\n", __func__, rf_type);
3173
3174         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
3175         {
3176                 bands = wiphy->bands[NL80211_BAND_2GHZ];
3177                 if (bands)
3178                         rtw_cfg80211_init_ht_capab(&bands->ht_cap,
3179                                                    NL80211_BAND_2GHZ,
3180                                                    rf_type);
3181         }
3182
3183         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
3184         {
3185                 bands = wiphy->bands[NL80211_BAND_5GHZ];
3186                 if (bands)
3187                         rtw_cfg80211_init_ht_capab(&bands->ht_cap,
3188                                                    NL80211_BAND_5GHZ,
3189                                                    rf_type);
3190         }
3191 }
3192
3193 static void rtw_cfg80211_preinit_wiphy(struct rtw_adapter *padapter,
3194                                        struct wiphy *wiphy)
3195 {
3196         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3197
3198         wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
3199         wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
3200         wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
3201
3202         wiphy->max_remain_on_channel_duration =
3203             RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
3204
3205         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3206             BIT(NL80211_IFTYPE_ADHOC) |
3207 #ifdef CONFIG_8723AU_AP_MODE
3208             BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) |
3209 #endif
3210             0;
3211
3212 #ifdef CONFIG_8723AU_AP_MODE
3213         wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
3214 #endif /* CONFIG_8723AU_AP_MODE */
3215
3216         wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
3217
3218         /*
3219            wiphy->iface_combinations = &rtw_combinations;
3220            wiphy->n_iface_combinations = 1;
3221          */
3222
3223         wiphy->cipher_suites = rtw_cipher_suites;
3224         wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
3225
3226         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
3227         wiphy->bands[NL80211_BAND_2GHZ] =
3228             rtw_spt_band_alloc(NL80211_BAND_2GHZ);
3229         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
3230         wiphy->bands[NL80211_BAND_5GHZ] =
3231             rtw_spt_band_alloc(NL80211_BAND_5GHZ);
3232
3233         wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
3234         wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
3235
3236         if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
3237                 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
3238         else
3239                 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
3240 }
3241
3242 int rtw_wdev_alloc(struct rtw_adapter *padapter, struct device *dev)
3243 {
3244         int ret = 0;
3245         struct wiphy *wiphy;
3246         struct wireless_dev *wdev;
3247         struct rtw_wdev_priv *pwdev_priv;
3248         struct net_device *pnetdev = padapter->pnetdev;
3249
3250         DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
3251
3252         /* wiphy */
3253         wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wdev_priv));
3254         if (!wiphy) {
3255                 DBG_8723A("Couldn't allocate wiphy device\n");
3256                 ret = -ENOMEM;
3257                 goto exit;
3258         }
3259
3260         /*  wdev */
3261         wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3262         if (!wdev) {
3263                 ret = -ENOMEM;
3264                 goto free_wiphy;
3265         }
3266
3267         set_wiphy_dev(wiphy, dev);
3268         rtw_cfg80211_preinit_wiphy(padapter, wiphy);
3269
3270         ret = wiphy_register(wiphy);
3271         if (ret < 0) {
3272                 DBG_8723A("Couldn't register wiphy device\n");
3273                 goto free_wdev;
3274         }
3275
3276         wdev->wiphy = wiphy;
3277         wdev->netdev = pnetdev;
3278         /* wdev->iftype = NL80211_IFTYPE_STATION; */
3279         /*  for rtw_setopmode_cmd23a() in cfg80211_rtw_change_iface() */
3280         wdev->iftype = NL80211_IFTYPE_MONITOR;
3281         padapter->rtw_wdev = wdev;
3282         pnetdev->ieee80211_ptr = wdev;
3283
3284         /* init pwdev_priv */
3285         pwdev_priv = wdev_to_priv(wdev);
3286         pwdev_priv->rtw_wdev = wdev;
3287         pwdev_priv->pmon_ndev = NULL;
3288         pwdev_priv->ifname_mon[0] = '\0';
3289         pwdev_priv->padapter = padapter;
3290         pwdev_priv->scan_request = NULL;
3291         spin_lock_init(&pwdev_priv->scan_req_lock);
3292
3293         pwdev_priv->p2p_enabled = false;
3294
3295         if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
3296                 pwdev_priv->power_mgmt = true;
3297         else
3298                 pwdev_priv->power_mgmt = false;
3299
3300         return ret;
3301 free_wdev:
3302         kfree(wdev);
3303 free_wiphy:
3304         wiphy_free(wiphy);
3305 exit:
3306         return ret;
3307 }
3308
3309 void rtw_wdev_free(struct wireless_dev *wdev)
3310 {
3311         DBG_8723A("%s(wdev =%p)\n", __func__, wdev);
3312
3313         if (!wdev)
3314                 return;
3315
3316         kfree(wdev->wiphy->bands[NL80211_BAND_2GHZ]);
3317         kfree(wdev->wiphy->bands[NL80211_BAND_5GHZ]);
3318
3319         wiphy_free(wdev->wiphy);
3320
3321         kfree(wdev);
3322 }
3323
3324 void rtw_wdev_unregister(struct wireless_dev *wdev)
3325 {
3326         struct rtw_wdev_priv *pwdev_priv;
3327
3328         DBG_8723A("%s(wdev =%p)\n", __func__, wdev);
3329
3330         if (!wdev)
3331                 return;
3332
3333         pwdev_priv = wdev_to_priv(wdev);
3334
3335         rtw_cfg80211_indicate_scan_done(pwdev_priv, true);
3336
3337         if (pwdev_priv->pmon_ndev) {
3338                 DBG_8723A("%s, unregister monitor interface\n", __func__);
3339                 unregister_netdev(pwdev_priv->pmon_ndev);
3340         }
3341
3342         wiphy_unregister(wdev->wiphy);
3343 }