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