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