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