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