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