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