Linux 3.15-rc2
[firefly-linux-kernel-4.4.55.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 #include <linux/version.h>
24
25 #define RTW_MAX_MGMT_TX_CNT 8
26
27 #define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 65535        /* ms */
28 #define RTW_MAX_NUM_PMKIDS 4
29
30 #define RTW_CH_MAX_2G_CHANNEL               14  /* Max channel in 2G band */
31
32 static const u32 rtw_cipher_suites[] = {
33         WLAN_CIPHER_SUITE_WEP40,
34         WLAN_CIPHER_SUITE_WEP104,
35         WLAN_CIPHER_SUITE_TKIP,
36         WLAN_CIPHER_SUITE_CCMP,
37 };
38
39 #define RATETAB_ENT(_rate, _rateid, _flags) {                   \
40         .bitrate        = (_rate),                              \
41         .hw_value       = (_rateid),                            \
42         .flags          = (_flags),                             \
43 }
44
45 #define CHAN2G(_channel, _freq, _flags) {                       \
46         .band                   = IEEE80211_BAND_2GHZ,          \
47         .center_freq            = (_freq),                      \
48         .hw_value               = (_channel),                   \
49         .flags                  = (_flags),                     \
50         .max_antenna_gain       = 0,                            \
51         .max_power              = 30,                           \
52 }
53
54 #define CHAN5G(_channel, _flags) {                              \
55         .band                   = IEEE80211_BAND_5GHZ,          \
56         .center_freq            = 5000 + (5 * (_channel)),      \
57         .hw_value               = (_channel),                   \
58         .flags                  = (_flags),                     \
59         .max_antenna_gain       = 0,                            \
60         .max_power              = 30,                           \
61 }
62
63 static struct ieee80211_rate rtw_rates[] = {
64         RATETAB_ENT(10, 0x1, 0),
65         RATETAB_ENT(20, 0x2, 0),
66         RATETAB_ENT(55, 0x4, 0),
67         RATETAB_ENT(110, 0x8, 0),
68         RATETAB_ENT(60, 0x10, 0),
69         RATETAB_ENT(90, 0x20, 0),
70         RATETAB_ENT(120, 0x40, 0),
71         RATETAB_ENT(180, 0x80, 0),
72         RATETAB_ENT(240, 0x100, 0),
73         RATETAB_ENT(360, 0x200, 0),
74         RATETAB_ENT(480, 0x400, 0),
75         RATETAB_ENT(540, 0x800, 0),
76 };
77
78 #define rtw_a_rates             (rtw_rates + 4)
79 #define RTW_A_RATES_NUM 8
80 #define rtw_g_rates             (rtw_rates + 0)
81 #define RTW_G_RATES_NUM 12
82
83 #define RTW_2G_CHANNELS_NUM 14
84 #define RTW_5G_CHANNELS_NUM 37
85
86 static struct ieee80211_channel rtw_2ghz_channels[] = {
87         CHAN2G(1, 2412, 0),
88         CHAN2G(2, 2417, 0),
89         CHAN2G(3, 2422, 0),
90         CHAN2G(4, 2427, 0),
91         CHAN2G(5, 2432, 0),
92         CHAN2G(6, 2437, 0),
93         CHAN2G(7, 2442, 0),
94         CHAN2G(8, 2447, 0),
95         CHAN2G(9, 2452, 0),
96         CHAN2G(10, 2457, 0),
97         CHAN2G(11, 2462, 0),
98         CHAN2G(12, 2467, 0),
99         CHAN2G(13, 2472, 0),
100         CHAN2G(14, 2484, 0),
101 };
102
103 static struct ieee80211_channel rtw_5ghz_a_channels[] = {
104         CHAN5G(34, 0), CHAN5G(36, 0),
105         CHAN5G(38, 0), CHAN5G(40, 0),
106         CHAN5G(42, 0), CHAN5G(44, 0),
107         CHAN5G(46, 0), CHAN5G(48, 0),
108         CHAN5G(52, 0), CHAN5G(56, 0),
109         CHAN5G(60, 0), CHAN5G(64, 0),
110         CHAN5G(100, 0), CHAN5G(104, 0),
111         CHAN5G(108, 0), CHAN5G(112, 0),
112         CHAN5G(116, 0), CHAN5G(120, 0),
113         CHAN5G(124, 0), CHAN5G(128, 0),
114         CHAN5G(132, 0), CHAN5G(136, 0),
115         CHAN5G(140, 0), CHAN5G(149, 0),
116         CHAN5G(153, 0), CHAN5G(157, 0),
117         CHAN5G(161, 0), CHAN5G(165, 0),
118         CHAN5G(184, 0), CHAN5G(188, 0),
119         CHAN5G(192, 0), CHAN5G(196, 0),
120         CHAN5G(200, 0), CHAN5G(204, 0),
121         CHAN5G(208, 0), CHAN5G(212, 0),
122         CHAN5G(216, 0),
123 };
124
125 static void rtw_2g_channels_init(struct ieee80211_channel *channels)
126 {
127         memcpy((void *)channels, (void *)rtw_2ghz_channels,
128                sizeof(struct ieee80211_channel) * RTW_2G_CHANNELS_NUM);
129 }
130
131 static void rtw_5g_channels_init(struct ieee80211_channel *channels)
132 {
133         memcpy((void *)channels, (void *)rtw_5ghz_a_channels,
134                sizeof(struct ieee80211_channel) * RTW_5G_CHANNELS_NUM);
135 }
136
137 static void rtw_2g_rates_init(struct ieee80211_rate *rates)
138 {
139         memcpy(rates, rtw_g_rates,
140                sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM);
141 }
142
143 static void rtw_5g_rates_init(struct ieee80211_rate *rates)
144 {
145         memcpy(rates, rtw_a_rates,
146                sizeof(struct ieee80211_rate) * RTW_A_RATES_NUM);
147 }
148
149 static struct ieee80211_supported_band *
150 rtw_spt_band_alloc(enum ieee80211_band band)
151 {
152         struct ieee80211_supported_band *spt_band = NULL;
153         int n_channels, n_bitrates;
154
155         if (band == IEEE80211_BAND_2GHZ) {
156                 n_channels = RTW_2G_CHANNELS_NUM;
157                 n_bitrates = RTW_G_RATES_NUM;
158         } else if (band == IEEE80211_BAND_5GHZ) {
159                 n_channels = RTW_5G_CHANNELS_NUM;
160                 n_bitrates = RTW_A_RATES_NUM;
161         } else {
162                 goto exit;
163         }
164         spt_band = kzalloc(sizeof(struct ieee80211_supported_band) +
165                            sizeof(struct ieee80211_channel) * n_channels +
166                            sizeof(struct ieee80211_rate) * n_bitrates,
167                            GFP_KERNEL);
168         if (!spt_band)
169                 goto exit;
170
171         spt_band->channels =
172                 (struct ieee80211_channel *)(((u8 *) spt_band) +
173                                              sizeof(struct
174                                                     ieee80211_supported_band));
175         spt_band->bitrates =
176                 (struct ieee80211_rate *)(((u8 *) spt_band->channels) +
177                                           sizeof(struct ieee80211_channel) *
178                                           n_channels);
179         spt_band->band = band;
180         spt_band->n_channels = n_channels;
181         spt_band->n_bitrates = n_bitrates;
182
183         if (band == IEEE80211_BAND_2GHZ) {
184                 rtw_2g_channels_init(spt_band->channels);
185                 rtw_2g_rates_init(spt_band->bitrates);
186         } else if (band == IEEE80211_BAND_5GHZ) {
187                 rtw_5g_channels_init(spt_band->channels);
188                 rtw_5g_rates_init(spt_band->bitrates);
189         }
190
191         /* spt_band.ht_cap */
192
193 exit:
194         return spt_band;
195 }
196
197 static const struct ieee80211_txrx_stypes
198 rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
199         [NL80211_IFTYPE_ADHOC] = {
200                 .tx = 0xffff,
201                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4)
202         },
203         [NL80211_IFTYPE_STATION] = {
204                 .tx = 0xffff,
205                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
206                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
207         },
208         [NL80211_IFTYPE_AP] = {
209                 .tx = 0xffff,
210                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
211                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
212                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
213                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
214                       BIT(IEEE80211_STYPE_AUTH >> 4) |
215                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
216                       BIT(IEEE80211_STYPE_ACTION >> 4)
217         },
218         [NL80211_IFTYPE_AP_VLAN] = {
219                 /* copy AP */
220                 .tx = 0xffff,
221                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
222                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
223                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
224                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
225                       BIT(IEEE80211_STYPE_AUTH >> 4) |
226                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
227                       BIT(IEEE80211_STYPE_ACTION >> 4)
228         },
229         [NL80211_IFTYPE_P2P_CLIENT] = {
230                 .tx = 0xffff,
231                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
232                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
233         },
234         [NL80211_IFTYPE_P2P_GO] = {
235                 .tx = 0xffff,
236                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
237                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
238                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
239                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
240                       BIT(IEEE80211_STYPE_AUTH >> 4) |
241                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
242                       BIT(IEEE80211_STYPE_ACTION >> 4)
243         },
244 };
245
246 #define MAX_BSSINFO_LEN 1000
247 static int rtw_cfg80211_inform_bss(struct rtw_adapter *padapter,
248                                    struct wlan_network *pnetwork)
249 {
250         int ret = 0;
251         struct ieee80211_channel *notify_channel;
252         struct cfg80211_bss *bss;
253         /* struct ieee80211_supported_band *band; */
254         u16 channel;
255         u32 freq;
256         u64 notify_timestamp;
257         u16 notify_capability;
258         u16 notify_interval;
259         u8 *notify_ie;
260         size_t notify_ielen;
261         s32 notify_signal;
262         u8 buf[MAX_BSSINFO_LEN], *pbuf;
263         size_t len, bssinf_len = 0;
264         struct ieee80211_hdr *pwlanhdr;
265         unsigned short *fctrl;
266         u8 bc_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
267
268         struct wireless_dev *wdev = padapter->rtw_wdev;
269         struct wiphy *wiphy = wdev->wiphy;
270         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
271
272         /* DBG_8723A("%s\n", __func__); */
273
274         bssinf_len =
275                 pnetwork->network.IELength + sizeof(struct ieee80211_hdr_3addr);
276         if (bssinf_len > MAX_BSSINFO_LEN) {
277                 DBG_8723A("%s IE Length too long > %d byte\n", __func__,
278                           MAX_BSSINFO_LEN);
279                 goto exit;
280         }
281
282         channel = pnetwork->network.Configuration.DSConfig;
283         if (channel <= RTW_CH_MAX_2G_CHANNEL)
284                 freq = ieee80211_channel_to_frequency(channel,
285                                                       IEEE80211_BAND_2GHZ);
286         else
287                 freq = ieee80211_channel_to_frequency(channel,
288                                                       IEEE80211_BAND_5GHZ);
289
290         notify_channel = ieee80211_get_channel(wiphy, freq);
291
292         /* rtw_get_timestampe_from_ie23a() */
293         notify_timestamp = jiffies_to_msecs(jiffies) * 1000;    /* uSec */
294
295         notify_interval =
296             le16_to_cpu(*(u16 *)
297                         rtw_get_beacon_interval23a_from_ie(pnetwork->network.IEs));
298         notify_capability =
299             le16_to_cpu(*(u16 *)
300                         rtw_get_capability23a_from_ie(pnetwork->network.IEs));
301
302         notify_ie = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
303         notify_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
304
305         /* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM:
306          *  signal strength in mBm (100*dBm)
307          */
308         if (check_fwstate(pmlmepriv, _FW_LINKED) &&
309             is_same_network23a(&pmlmepriv->cur_network.network,
310                             &pnetwork->network)) {
311                 notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength);  /* dbm */
312         } else {
313                 notify_signal = 100 * translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength);    /* dbm */
314         }
315         pbuf = buf;
316
317         pwlanhdr = (struct ieee80211_hdr *)pbuf;
318         fctrl = &pwlanhdr->frame_control;
319         *(fctrl) = 0;
320
321         SetSeqNum(pwlanhdr, 0);
322
323         if (pnetwork->network.reserved == 1) {  /*  WIFI_BEACON */
324                 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
325                 SetFrameSubType(pbuf, WIFI_BEACON);
326         } else {
327                 memcpy(pwlanhdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN);
328                 SetFrameSubType(pbuf, WIFI_PROBERSP);
329         }
330
331         memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
332         memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
333
334         pbuf += sizeof(struct ieee80211_hdr_3addr);
335         len = sizeof(struct ieee80211_hdr_3addr);
336
337         memcpy(pbuf, pnetwork->network.IEs, pnetwork->network.IELength);
338         len += pnetwork->network.IELength;
339
340         bss = cfg80211_inform_bss_frame(wiphy, notify_channel,
341                                         (struct ieee80211_mgmt *)buf, len,
342                                         notify_signal, GFP_ATOMIC);
343
344         if (unlikely(!bss)) {
345                 DBG_8723A("rtw_cfg80211_inform_bss error\n");
346                 return -EINVAL;
347         }
348
349         cfg80211_put_bss(wiphy, bss);
350
351 exit:
352         return ret;
353 }
354
355 void rtw_cfg80211_indicate_connect(struct rtw_adapter *padapter)
356 {
357         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
358         struct wlan_network *cur_network = &pmlmepriv->cur_network;
359         struct wireless_dev *pwdev = padapter->rtw_wdev;
360 #ifdef CONFIG_8723AU_P2P
361         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
362 #endif
363
364         DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
365
366         if (pwdev->iftype != NL80211_IFTYPE_STATION &&
367             pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
368                 return;
369
370         if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
371                 return;
372
373 #ifdef CONFIG_8723AU_P2P
374         if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
375                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
376                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
377                 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
378                 DBG_8723A("%s, role =%d, p2p_state =%d, pre_p2p_state =%d\n",
379                           __func__, rtw_p2p_role(pwdinfo),
380                           rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
381         }
382 #endif /* CONFIG_8723AU_P2P */
383
384         if (rtw_to_roaming(padapter) > 0) {
385                 struct wiphy *wiphy = pwdev->wiphy;
386                 struct ieee80211_channel *notify_channel;
387                 u32 freq;
388                 u16 channel = cur_network->network.Configuration.DSConfig;
389
390                 if (channel <= RTW_CH_MAX_2G_CHANNEL)
391                         freq =
392                             ieee80211_channel_to_frequency(channel,
393                                                            IEEE80211_BAND_2GHZ);
394                 else
395                         freq =
396                             ieee80211_channel_to_frequency(channel,
397                                                            IEEE80211_BAND_5GHZ);
398
399                 notify_channel = ieee80211_get_channel(wiphy, freq);
400
401                 DBG_8723A("%s call cfg80211_roamed\n", __func__);
402                 cfg80211_roamed(padapter->pnetdev, notify_channel,
403                                 cur_network->network.MacAddress,
404                                 pmlmepriv->assoc_req +
405                                 sizeof(struct ieee80211_hdr_3addr) + 2,
406                                 pmlmepriv->assoc_req_len -
407                                 sizeof(struct ieee80211_hdr_3addr) - 2,
408                                 pmlmepriv->assoc_rsp +
409                                 sizeof(struct ieee80211_hdr_3addr) + 6,
410                                 pmlmepriv->assoc_rsp_len -
411                                 sizeof(struct ieee80211_hdr_3addr) - 6,
412                                 GFP_ATOMIC);
413         } else {
414                 cfg80211_connect_result(padapter->pnetdev,
415                                         cur_network->network.MacAddress,
416                                         pmlmepriv->assoc_req +
417                                         sizeof(struct ieee80211_hdr_3addr) + 2,
418                                         pmlmepriv->assoc_req_len -
419                                         sizeof(struct ieee80211_hdr_3addr) - 2,
420                                         pmlmepriv->assoc_rsp +
421                                         sizeof(struct ieee80211_hdr_3addr) + 6,
422                                         pmlmepriv->assoc_rsp_len -
423                                         sizeof(struct ieee80211_hdr_3addr) - 6,
424                                         WLAN_STATUS_SUCCESS, GFP_ATOMIC);
425         }
426 }
427
428 void rtw_cfg80211_indicate_disconnect(struct rtw_adapter *padapter)
429 {
430         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
431         struct wireless_dev *pwdev = padapter->rtw_wdev;
432 #ifdef CONFIG_8723AU_P2P
433         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
434 #endif
435
436         DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
437
438         if (pwdev->iftype != NL80211_IFTYPE_STATION &&
439             pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
440                 return;
441
442         if (check_fwstate(pmlmepriv, WIFI_AP_STATE))
443                 return;
444
445 #ifdef CONFIG_8723AU_P2P
446         if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
447                 del_timer_sync(&pwdinfo->find_phase_timer);
448                 del_timer_sync(&pwdinfo->restore_p2p_state_timer);
449                 del_timer_sync(&pwdinfo->pre_tx_scan_timer);
450
451                 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
452                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
453
454                 DBG_8723A("%s, role =%d, p2p_state =%d, pre_p2p_state =%d\n",
455                           __func__, rtw_p2p_role(pwdinfo),
456                           rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
457         }
458 #endif /* CONFIG_8723AU_P2P */
459
460         if (!padapter->mlmepriv.not_indic_disco) {
461                 if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING)) {
462                         cfg80211_connect_result(padapter->pnetdev, NULL, NULL,
463                                                 0, NULL, 0,
464                                                 WLAN_STATUS_UNSPECIFIED_FAILURE,
465                                                 GFP_ATOMIC);
466                 } else {
467                         cfg80211_disconnected(padapter->pnetdev, 0, NULL,
468                                               0, GFP_ATOMIC);
469                 }
470         }
471 }
472
473 #ifdef CONFIG_8723AU_AP_MODE
474 static u8 set_pairwise_key(struct rtw_adapter *padapter, struct sta_info *psta)
475 {
476         struct cmd_obj *ph2c;
477         struct set_stakey_parm *psetstakey_para;
478         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
479         u8 res = _SUCCESS;
480
481         ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
482         if (ph2c == NULL) {
483                 res = _FAIL;
484                 goto exit;
485         }
486
487         psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL);
488         if (psetstakey_para == NULL) {
489                 kfree(ph2c);
490                 res = _FAIL;
491                 goto exit;
492         }
493
494         init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
495
496         psetstakey_para->algorithm = (u8) psta->dot118021XPrivacy;
497
498         memcpy(psetstakey_para->addr, psta->hwaddr, ETH_ALEN);
499
500         memcpy(psetstakey_para->key, &psta->dot118021x_UncstKey, 16);
501
502         res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
503
504 exit:
505         return res;
506 }
507
508 static int set_group_key(struct rtw_adapter *padapter, u8 *key, u8 alg,
509                          int keyid)
510 {
511         u8 keylen;
512         struct cmd_obj *pcmd;
513         struct setkey_parm *psetkeyparm;
514         struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
515         int res = _SUCCESS;
516
517         DBG_8723A("%s\n", __func__);
518
519         pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
520         if (!pcmd) {
521                 res = _FAIL;
522                 goto exit;
523         }
524         psetkeyparm = kzalloc(sizeof(struct setkey_parm), GFP_KERNEL);
525         if (!psetkeyparm) {
526                 kfree(pcmd);
527                 res = _FAIL;
528                 goto exit;
529         }
530
531         psetkeyparm->keyid = (u8) keyid;
532         if (is_wep_enc(alg))
533                 padapter->mlmepriv.key_mask |= CHKBIT(psetkeyparm->keyid);
534
535         psetkeyparm->algorithm = alg;
536
537         psetkeyparm->set_tx = 1;
538
539         switch (alg) {
540         case _WEP40_:
541                 keylen = 5;
542                 break;
543         case _WEP104_:
544                 keylen = 13;
545                 break;
546         case _TKIP_:
547         case _TKIP_WTMIC_:
548         case _AES_:
549         default:
550                 keylen = 16;
551         }
552
553         memcpy(&psetkeyparm->key[0], key, keylen);
554
555         pcmd->cmdcode = _SetKey_CMD_;
556         pcmd->parmbuf = (u8 *) psetkeyparm;
557         pcmd->cmdsz = (sizeof(struct setkey_parm));
558         pcmd->rsp = NULL;
559         pcmd->rspsz = 0;
560
561         INIT_LIST_HEAD(&pcmd->list);
562
563         res = rtw_enqueue_cmd23a(pcmdpriv, pcmd);
564
565 exit:
566         return res;
567 }
568
569 static int set_wep_key(struct rtw_adapter *padapter, u8 *key, u8 keylen,
570                        int keyid)
571 {
572         u8 alg;
573
574         switch (keylen) {
575         case 5:
576                 alg = _WEP40_;
577                 break;
578         case 13:
579                 alg = _WEP104_;
580                 break;
581         default:
582                 alg = _NO_PRIVACY_;
583         }
584
585         return set_group_key(padapter, key, alg, keyid);
586 }
587
588 static int rtw_cfg80211_ap_set_encryption(struct net_device *dev,
589                                           struct ieee_param *param,
590                                           u32 param_len)
591 {
592         int ret = 0;
593         u32 wep_key_idx, wep_key_len;
594         struct sta_info *psta = NULL, *pbcmc_sta = NULL;
595         struct rtw_adapter *padapter = netdev_priv(dev);
596         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
597         struct security_priv *psecuritypriv = &padapter->securitypriv;
598         struct sta_priv *pstapriv = &padapter->stapriv;
599
600         DBG_8723A("%s\n", __func__);
601
602         param->u.crypt.err = 0;
603         param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
604
605         /* sizeof(struct ieee_param) = 64 bytes; */
606         /* if (param_len !=  (u32) ((u8 *) param->u.crypt.key -
607            (u8 *) param) + param->u.crypt.key_len) */
608         if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
609                 ret = -EINVAL;
610                 goto exit;
611         }
612
613         if (is_broadcast_ether_addr(param->sta_addr)) {
614                 if (param->u.crypt.idx >= WEP_KEYS) {
615                         ret = -EINVAL;
616                         goto exit;
617                 }
618         } else {
619                 psta = rtw_get_stainfo23a(pstapriv, param->sta_addr);
620                 if (!psta) {
621                         /* ret = -EINVAL; */
622                         DBG_8723A("rtw_set_encryption(), sta has already "
623                                   "been removed or never been added\n");
624                         goto exit;
625                 }
626         }
627
628         if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
629                 /* todo:clear default encryption keys */
630
631                 DBG_8723A("clear default encryption keys, keyid =%d\n",
632                           param->u.crypt.idx);
633
634                 goto exit;
635         }
636
637         if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
638                 DBG_8723A("r871x_set_encryption, crypt.alg = WEP\n");
639
640                 wep_key_idx = param->u.crypt.idx;
641                 wep_key_len = param->u.crypt.key_len;
642
643                 DBG_8723A("r871x_set_encryption, wep_key_idx =%d, len =%d\n",
644                           wep_key_idx, wep_key_len);
645
646                 if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
647                         ret = -EINVAL;
648                         goto exit;
649                 }
650
651                 if (wep_key_len > 0) {
652                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
653                 }
654
655                 if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
656                         /* wep default key has not been set, so use
657                            this key index as default key. */
658
659                         psecuritypriv->ndisencryptstatus =
660                                 Ndis802_11Encryption1Enabled;
661                         psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
662                         psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
663
664                         if (wep_key_len == 13) {
665                                 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
666                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
667                         }
668
669                         psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
670                 }
671
672                 memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0],
673                        param->u.crypt.key, wep_key_len);
674
675                 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
676
677                 set_wep_key(padapter, param->u.crypt.key, wep_key_len,
678                             wep_key_idx);
679
680                 goto exit;
681
682         }
683
684         if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) { /*  group key */
685                 if (param->u.crypt.set_tx == 0) {       /* group key */
686                         if (strcmp(param->u.crypt.alg, "WEP") == 0) {
687                                 DBG_8723A("%s, set group_key, WEP\n",
688                                           __func__);
689
690                                 memcpy(psecuritypriv->
691                                        dot118021XGrpKey[param->u.crypt.idx].
692                                        skey, param->u.crypt.key,
693                                        (param->u.crypt.key_len >
694                                         16 ? 16 : param->u.crypt.key_len));
695
696                                 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
697                                 if (param->u.crypt.key_len == 13) {
698                                         psecuritypriv->dot118021XGrpPrivacy =
699                                             _WEP104_;
700                                 }
701
702                         } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
703                                 DBG_8723A("%s, set group_key, TKIP\n",
704                                           __func__);
705
706                                 psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
707
708                                 memcpy(psecuritypriv->
709                                        dot118021XGrpKey[param->u.crypt.idx].
710                                        skey, param->u.crypt.key,
711                                        (param->u.crypt.key_len >
712                                         16 ? 16 : param->u.crypt.key_len));
713
714                                 /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
715                                 /* set mic key */
716                                 memcpy(psecuritypriv->
717                                        dot118021XGrptxmickey[param->u.crypt.
718                                                              idx].skey,
719                                        &param->u.crypt.key[16], 8);
720                                 memcpy(psecuritypriv->
721                                        dot118021XGrprxmickey[param->u.crypt.
722                                                              idx].skey,
723                                        &param->u.crypt.key[24], 8);
724
725                                 psecuritypriv->busetkipkey = true;
726
727                         } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
728                                 DBG_8723A("%s, set group_key, CCMP\n",
729                                           __func__);
730
731                                 psecuritypriv->dot118021XGrpPrivacy = _AES_;
732
733                                 memcpy(psecuritypriv->
734                                        dot118021XGrpKey[param->u.crypt.idx].
735                                        skey, param->u.crypt.key,
736                                        (param->u.crypt.key_len >
737                                         16 ? 16 : param->u.crypt.key_len));
738                         } else {
739                                 DBG_8723A("%s, set group_key, none\n",
740                                           __func__);
741
742                                 psecuritypriv->dot118021XGrpPrivacy =
743                                     _NO_PRIVACY_;
744                         }
745
746                         psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
747
748                         psecuritypriv->binstallGrpkey = true;
749
750                         psecuritypriv->dot11PrivacyAlgrthm =
751                                 psecuritypriv->dot118021XGrpPrivacy;
752
753                         set_group_key(padapter, param->u.crypt.key,
754                                       psecuritypriv->dot118021XGrpPrivacy,
755                                       param->u.crypt.idx);
756
757                         pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter);
758                         if (pbcmc_sta) {
759                                 pbcmc_sta->ieee8021x_blocked = false;
760                                 /* rx will use bmc_sta's dot118021XPrivacy */
761                                 pbcmc_sta->dot118021XPrivacy =
762                                         psecuritypriv->dot118021XGrpPrivacy;
763
764                         }
765
766                 }
767
768                 goto exit;
769         }
770
771         if (psecuritypriv->dot11AuthAlgrthm ==
772             dot11AuthAlgrthm_8021X && psta) {   /*  psk/802_1x */
773                 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
774                         if (param->u.crypt.set_tx == 1) {
775                                 /* pairwise key */
776                                 memcpy(psta->dot118021x_UncstKey.skey,
777                                        param->u.crypt.key,
778                                        (param->u.crypt.key_len >
779                                         16 ? 16 : param->u.crypt.key_len));
780
781                                 if (!strcmp(param->u.crypt.alg, "WEP")) {
782                                         DBG_8723A("%s, set pairwise key, WEP\n",
783                                                   __func__);
784
785                                         psta->dot118021XPrivacy = _WEP40_;
786                                         if (param->u.crypt.key_len == 13) {
787                                                 psta->dot118021XPrivacy =
788                                                         _WEP104_;
789                                         }
790                                 } else if (!strcmp(param->u.crypt.alg, "TKIP")) {
791                                         DBG_8723A("%s, set pairwise key, "
792                                                   "TKIP\n", __func__);
793
794                                         psta->dot118021XPrivacy = _TKIP_;
795
796                                         /* DEBUG_ERR("set key length :param->u.crypt.key_len =%d\n", param->u.crypt.key_len); */
797                                         /* set mic key */
798                                         memcpy(psta->dot11tkiptxmickey.skey,
799                                                &param->u.crypt.key[16], 8);
800                                         memcpy(psta->dot11tkiprxmickey.skey,
801                                                &param->u.crypt.key[24], 8);
802
803                                         psecuritypriv->busetkipkey = true;
804
805                                 } else if (!strcmp(param->u.crypt.alg, "CCMP")) {
806
807                                         DBG_8723A("%s, set pairwise key, "
808                                                   "CCMP\n", __func__);
809
810                                         psta->dot118021XPrivacy = _AES_;
811                                 } else {
812                                         DBG_8723A("%s, set pairwise key, "
813                                                   "none\n", __func__);
814
815                                         psta->dot118021XPrivacy = _NO_PRIVACY_;
816                                 }
817
818                                 set_pairwise_key(padapter, psta);
819
820                                 psta->ieee8021x_blocked = false;
821
822                                 psta->bpairwise_key_installed = true;
823                         } else {        /* group key??? */
824                                 if (!strcmp(param->u.crypt.alg, "WEP")) {
825                                         memcpy(psecuritypriv->
826                                                dot118021XGrpKey[param->u.crypt.
827                                                                 idx].skey,
828                                                param->u.crypt.key,
829                                                (param->u.crypt.key_len >
830                                                 16 ? 16 : param->u.crypt.
831                                                 key_len));
832
833                                         psecuritypriv->dot118021XGrpPrivacy =
834                                                 _WEP40_;
835                                         if (param->u.crypt.key_len == 13) {
836                                                 psecuritypriv->
837                                                     dot118021XGrpPrivacy =
838                                                         _WEP104_;
839                                         }
840                                 } else if (!strcmp(param->u.crypt.alg, "TKIP")) {
841                                         psecuritypriv->dot118021XGrpPrivacy =
842                                             _TKIP_;
843
844                                         memcpy(psecuritypriv->
845                                                dot118021XGrpKey[param->u.crypt.
846                                                                 idx].skey,
847                                                param->u.crypt.key,
848                                                (param->u.crypt.key_len >
849                                                 16 ? 16 : param->u.crypt.
850                                                 key_len));
851
852                                         /* DEBUG_ERR("set key length :param->u"
853                                            ".crypt.key_len =%d\n",
854                                            param->u.crypt.key_len); */
855                                         /* set mic key */
856                                         memcpy(psecuritypriv->
857                                                dot118021XGrptxmickey[param->u.
858                                                                      crypt.idx].
859                                                skey, &param->u.crypt.key[16],
860                                                8);
861                                         memcpy(psecuritypriv->
862                                                dot118021XGrprxmickey[param->u.
863                                                                      crypt.idx].
864                                                skey, &param->u.crypt.key[24],
865                                                8);
866
867                                         psecuritypriv->busetkipkey = true;
868
869                                 } else if (!strcmp(param->u.crypt.alg, "CCMP")) {
870                                         psecuritypriv->dot118021XGrpPrivacy =
871                                                 _AES_;
872
873                                         memcpy(psecuritypriv->
874                                                dot118021XGrpKey[param->u.crypt.
875                                                                 idx].skey,
876                                                param->u.crypt.key,
877                                                (param->u.crypt.key_len >
878                                                 16 ? 16 : param->u.crypt.
879                                                 key_len));
880                                 } else {
881                                         psecuritypriv->dot118021XGrpPrivacy =
882                                                 _NO_PRIVACY_;
883                                 }
884
885                                 psecuritypriv->dot118021XGrpKeyid =
886                                         param->u.crypt.idx;
887
888                                 psecuritypriv->binstallGrpkey = true;
889
890                                 psecuritypriv->dot11PrivacyAlgrthm =
891                                         psecuritypriv->dot118021XGrpPrivacy;
892
893                                 set_group_key(padapter, param->u.crypt.key,
894                                               psecuritypriv->
895                                               dot118021XGrpPrivacy,
896                                               param->u.crypt.idx);
897
898                                 pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter);
899                                 if (pbcmc_sta) {
900                                         /* rx will use bmc_sta's
901                                            dot118021XPrivacy */
902                                         pbcmc_sta->ieee8021x_blocked = false;
903                                         pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy;
904                                 }
905                         }
906                 }
907         }
908
909 exit:
910
911         return ret;
912
913 }
914 #endif
915
916 static int rtw_cfg80211_set_encryption(struct net_device *dev,
917                                        struct ieee_param *param, u32 param_len)
918 {
919         int ret = 0;
920         u32 wep_key_idx, wep_key_len;
921         struct rtw_adapter *padapter = netdev_priv(dev);
922         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
923         struct security_priv *psecuritypriv = &padapter->securitypriv;
924 #ifdef CONFIG_8723AU_P2P
925         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
926 #endif /* CONFIG_8723AU_P2P */
927
928
929
930         DBG_8723A("%s\n", __func__);
931
932         param->u.crypt.err = 0;
933         param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
934
935         if (param_len <
936             (u32) ((u8 *) param->u.crypt.key - (u8 *) param) +
937             param->u.crypt.key_len) {
938                 ret = -EINVAL;
939                 goto exit;
940         }
941
942         if (is_broadcast_ether_addr(param->sta_addr)) {
943                 if (param->u.crypt.idx >= WEP_KEYS) {
944                         ret = -EINVAL;
945                         goto exit;
946                 }
947         } else {
948                 ret = -EINVAL;
949                 goto exit;
950         }
951
952         if (strcmp(param->u.crypt.alg, "WEP") == 0) {
953                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
954                          ("wpa_set_encryption, crypt.alg = WEP\n"));
955                 DBG_8723A("wpa_set_encryption, crypt.alg = WEP\n");
956
957                 wep_key_idx = param->u.crypt.idx;
958                 wep_key_len = param->u.crypt.key_len;
959
960                 if ((wep_key_idx > WEP_KEYS) || (wep_key_len <= 0)) {
961                         ret = -EINVAL;
962                         goto exit;
963                 }
964
965                 if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
966                         /* wep default key has not been set, so use this
967                            key index as default key. */
968
969                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
970
971                         psecuritypriv->ndisencryptstatus =
972                                 Ndis802_11Encryption1Enabled;
973                         psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
974                         psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
975
976                         if (wep_key_len == 13) {
977                                 psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
978                                 psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
979                         }
980
981                         psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
982                 }
983
984                 memcpy(&psecuritypriv->dot11DefKey[wep_key_idx].skey[0],
985                        param->u.crypt.key, wep_key_len);
986
987                 psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
988
989                 rtw_set_key23a(padapter, psecuritypriv, wep_key_idx, 0);
990
991                 goto exit;
992         }
993
994         if (padapter->securitypriv.dot11AuthAlgrthm ==
995             dot11AuthAlgrthm_8021X) {   /*  802_1x */
996                 struct sta_info *psta, *pbcmc_sta;
997                 struct sta_priv *pstapriv = &padapter->stapriv;
998
999                 if (check_fwstate(pmlmepriv,
1000                                   WIFI_STATION_STATE | WIFI_MP_STATE)) {
1001                         /* sta mode */
1002                         psta = rtw_get_stainfo23a(pstapriv, get_bssid(pmlmepriv));
1003                         if (psta == NULL) {
1004                                 DBG_8723A("%s, : Obtain Sta_info fail\n",
1005                                           __func__);
1006                         } else {
1007                                 /* Jeff: don't disable ieee8021x_blocked
1008                                    while clearing key */
1009                                 if (strcmp(param->u.crypt.alg, "none") != 0)
1010                                         psta->ieee8021x_blocked = false;
1011
1012                                 if ((padapter->securitypriv.ndisencryptstatus ==
1013                                      Ndis802_11Encryption2Enabled) ||
1014                                     (padapter->securitypriv.ndisencryptstatus ==
1015                                      Ndis802_11Encryption3Enabled)) {
1016                                         psta->dot118021XPrivacy =
1017                                                 padapter->securitypriv.
1018                                                 dot11PrivacyAlgrthm;
1019                                 }
1020
1021                                 if (param->u.crypt.set_tx == 1) {
1022                                         /* pairwise key */
1023                                         DBG_8723A("%s, : param->u.crypt.set_tx"
1024                                                   " == 1\n", __func__);
1025
1026                                         memcpy(psta->dot118021x_UncstKey.skey,
1027                                                param->u.crypt.key,
1028                                                (param->u.crypt.key_len >
1029                                                 16 ? 16 : param->u.crypt.
1030                                                 key_len));
1031
1032                                         if (strcmp(param->u.crypt.alg,
1033                                                    "TKIP") == 0) {
1034                                                 memcpy(psta->dot11tkiptxmickey.
1035                                                        skey,
1036                                                        &param->u.crypt.key[16],
1037                                                        8);
1038                                                 memcpy(psta->dot11tkiprxmickey.
1039                                                        skey,
1040                                                        &param->u.crypt.key[24],
1041                                                        8);
1042
1043                                                 padapter->securitypriv.
1044                                                         busetkipkey = false;
1045                                         }
1046                                         DBG_8723A(" ~~~~set sta key:unicastkey\n");
1047
1048                                         rtw_setstakey_cmd23a(padapter,
1049                                                           (unsigned char *)psta,
1050                                                           true);
1051                                 } else {        /* group key */
1052                                         memcpy(padapter->securitypriv.
1053                                                dot118021XGrpKey[param->u.crypt.
1054                                                                 idx].skey,
1055                                                param->u.crypt.key,
1056                                                (param->u.crypt.key_len >
1057                                                 16 ? 16 : param->u.crypt.
1058                                                 key_len));
1059                                         memcpy(padapter->securitypriv.
1060                                                dot118021XGrptxmickey[param->u.
1061                                                                      crypt.idx].
1062                                                skey, &param->u.crypt.key[16],
1063                                                8);
1064                                         memcpy(padapter->securitypriv.
1065                                                dot118021XGrprxmickey[param->u.
1066                                                                      crypt.idx].
1067                                                skey, &param->u.crypt.key[24],
1068                                                8);
1069                                         padapter->securitypriv.binstallGrpkey =
1070                                             true;
1071                                         /* DEBUG_ERR((" param->u.crypt.key_len"
1072                                            "=%d\n", param->u.crypt.key_len)); */
1073                                         DBG_8723A
1074                                             (" ~~~~set sta key:groupkey\n");
1075
1076                                         padapter->securitypriv.
1077                                             dot118021XGrpKeyid =
1078                                                 param->u.crypt.idx;
1079
1080                                         rtw_set_key23a(padapter,
1081                                                     &padapter->securitypriv,
1082                                                     param->u.crypt.idx, 1);
1083 #ifdef CONFIG_8723AU_P2P
1084                                         if (rtw_p2p_chk_state
1085                                             (pwdinfo,
1086                                              P2P_STATE_PROVISIONING_ING)) {
1087                                                 rtw_p2p_set_state(pwdinfo,
1088                                                                   P2P_STATE_PROVISIONING_DONE);
1089                                         }
1090 #endif /* CONFIG_8723AU_P2P */
1091
1092                                 }
1093                         }
1094
1095                         pbcmc_sta = rtw_get_bcmc_stainfo23a(padapter);
1096                         if (pbcmc_sta) {
1097                                 /* Jeff: don't disable ieee8021x_blocked
1098                                    while clearing key */
1099                                 if (strcmp(param->u.crypt.alg, "none") != 0)
1100                                         pbcmc_sta->ieee8021x_blocked = false;
1101
1102                                 if ((padapter->securitypriv.ndisencryptstatus ==
1103                                      Ndis802_11Encryption2Enabled) ||
1104                                     (padapter->securitypriv.ndisencryptstatus ==
1105                                      Ndis802_11Encryption3Enabled)) {
1106                                         pbcmc_sta->dot118021XPrivacy =
1107                                             padapter->securitypriv.
1108                                             dot11PrivacyAlgrthm;
1109                                 }
1110                         }
1111                 } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) {        /* adhoc mode */
1112                 }
1113         }
1114
1115 exit:
1116
1117         DBG_8723A("%s, ret =%d\n", __func__, ret);
1118
1119
1120
1121         return ret;
1122 }
1123
1124 static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev,
1125                                 u8 key_index, bool pairwise,
1126                                 const u8 *mac_addr, struct key_params *params)
1127 {
1128         char *alg_name;
1129         u32 param_len;
1130         struct ieee_param *param = NULL;
1131         int ret = 0;
1132         struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
1133         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
1134         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1135
1136         DBG_8723A(FUNC_NDEV_FMT " adding key for %pM\n", FUNC_NDEV_ARG(ndev),
1137                   mac_addr);
1138         DBG_8723A("cipher = 0x%x\n", params->cipher);
1139         DBG_8723A("key_len = 0x%x\n", params->key_len);
1140         DBG_8723A("seq_len = 0x%x\n", params->seq_len);
1141         DBG_8723A("key_index =%d\n", key_index);
1142         DBG_8723A("pairwise =%d\n", pairwise);
1143
1144         param_len = sizeof(struct ieee_param) + params->key_len;
1145         param = kzalloc(param_len, GFP_KERNEL);
1146         if (param == NULL)
1147                 return -1;
1148
1149         param->cmd = IEEE_CMD_SET_ENCRYPTION;
1150         memset(param->sta_addr, 0xff, ETH_ALEN);
1151
1152         switch (params->cipher) {
1153         case IW_AUTH_CIPHER_NONE:
1154                 /* todo: remove key */
1155                 /* remove = 1; */
1156                 alg_name = "none";
1157                 break;
1158         case WLAN_CIPHER_SUITE_WEP40:
1159         case WLAN_CIPHER_SUITE_WEP104:
1160                 alg_name = "WEP";
1161                 break;
1162         case WLAN_CIPHER_SUITE_TKIP:
1163                 alg_name = "TKIP";
1164                 break;
1165         case WLAN_CIPHER_SUITE_CCMP:
1166                 alg_name = "CCMP";
1167                 break;
1168
1169         default:
1170                 ret = -ENOTSUPP;
1171                 goto addkey_end;
1172         }
1173
1174         strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1175
1176         if (!mac_addr || is_broadcast_ether_addr(mac_addr)) {
1177                 param->u.crypt.set_tx = 0;      /* for wpa/wpa2 group key */
1178         } else {
1179                 param->u.crypt.set_tx = 1;      /* for wpa/wpa2 pairwise key */
1180         }
1181
1182         /* param->u.crypt.idx = key_index - 1; */
1183         param->u.crypt.idx = key_index;
1184
1185         if (params->seq_len && params->seq) {
1186                 memcpy(param->u.crypt.seq, params->seq, params->seq_len);
1187         }
1188
1189         if (params->key_len && params->key) {
1190                 param->u.crypt.key_len = params->key_len;
1191                 memcpy(param->u.crypt.key, params->key, params->key_len);
1192         }
1193
1194         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
1195                 ret = rtw_cfg80211_set_encryption(ndev, param, param_len);
1196         } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1197 #ifdef CONFIG_8723AU_AP_MODE
1198                 if (mac_addr)
1199                         memcpy(param->sta_addr, (void *)mac_addr, ETH_ALEN);
1200
1201                 ret = rtw_cfg80211_ap_set_encryption(ndev, param, param_len);
1202 #endif
1203         } else {
1204                 DBG_8723A("error! fw_state = 0x%x, iftype =%d\n",
1205                           pmlmepriv->fw_state, rtw_wdev->iftype);
1206
1207         }
1208
1209 addkey_end:
1210         kfree(param);
1211
1212         return ret;
1213 }
1214
1215 static int
1216 cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev,
1217                      u8 key_index, bool pairwise, const u8 *mac_addr,
1218                      void *cookie,
1219                      void (*callback) (void *cookie, struct key_params *))
1220 {
1221         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
1222         return 0;
1223 }
1224
1225 static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
1226                                 u8 key_index, bool pairwise,
1227                                 const u8 *mac_addr)
1228 {
1229         struct rtw_adapter *padapter = netdev_priv(ndev);
1230         struct security_priv *psecuritypriv = &padapter->securitypriv;
1231
1232         DBG_8723A(FUNC_NDEV_FMT " key_index =%d\n", FUNC_NDEV_ARG(ndev),
1233                   key_index);
1234
1235         if (key_index == psecuritypriv->dot11PrivacyKeyIndex) {
1236                 /* clear the flag of wep default key set. */
1237                 psecuritypriv->bWepDefaultKeyIdxSet = 0;
1238         }
1239
1240         return 0;
1241 }
1242
1243 static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
1244                                         struct net_device *ndev, u8 key_index,
1245                                         bool unicast, bool multicast)
1246 {
1247         struct rtw_adapter *padapter = netdev_priv(ndev);
1248         struct security_priv *psecuritypriv = &padapter->securitypriv;
1249
1250         DBG_8723A(FUNC_NDEV_FMT " key_index =%d"
1251                   ", unicast =%d, multicast =%d.\n", FUNC_NDEV_ARG(ndev),
1252                   key_index, unicast, multicast);
1253
1254         if ((key_index < WEP_KEYS) &&
1255             ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) ||
1256              (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) {
1257                 /* set wep default key */
1258                 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1259
1260                 psecuritypriv->dot11PrivacyKeyIndex = key_index;
1261
1262                 psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1263                 psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1264                 if (psecuritypriv->dot11DefKeylen[key_index] == 13) {
1265                         psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1266                         psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1267                 }
1268
1269                 /* set the flag to represent that wep default key
1270                    has been set */
1271                 psecuritypriv->bWepDefaultKeyIdxSet = 1;
1272         }
1273
1274         return 0;
1275 }
1276
1277 static int cfg80211_rtw_get_station(struct wiphy *wiphy,
1278                                     struct net_device *ndev,
1279                                     u8 *mac, struct station_info *sinfo)
1280 {
1281         int ret = 0;
1282         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
1283         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1284         struct sta_info *psta = NULL;
1285         struct sta_priv *pstapriv = &padapter->stapriv;
1286
1287         sinfo->filled = 0;
1288
1289         if (!mac) {
1290                 DBG_8723A(FUNC_NDEV_FMT " mac ==%p\n", FUNC_NDEV_ARG(ndev), mac);
1291                 ret = -ENOENT;
1292                 goto exit;
1293         }
1294
1295         psta = rtw_get_stainfo23a(pstapriv, mac);
1296         if (psta == NULL) {
1297                 DBG_8723A("%s, sta_info is null\n", __func__);
1298                 ret = -ENOENT;
1299                 goto exit;
1300         }
1301 #ifdef CONFIG_DEBUG_CFG80211
1302         DBG_8723A(FUNC_NDEV_FMT " mac =" MAC_FMT "\n", FUNC_NDEV_ARG(ndev),
1303                   MAC_ARG(mac));
1304 #endif
1305
1306         /* for infra./P2PClient mode */
1307         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
1308             check_fwstate(pmlmepriv, _FW_LINKED)) {
1309                 struct wlan_network *cur_network = &pmlmepriv->cur_network;
1310
1311                 if (memcmp(mac, cur_network->network.MacAddress, ETH_ALEN)) {
1312                         DBG_8723A("%s, mismatch bssid =" MAC_FMT "\n", __func__,
1313                                   MAC_ARG(cur_network->network.MacAddress));
1314                         ret = -ENOENT;
1315                         goto exit;
1316                 }
1317
1318                 sinfo->filled |= STATION_INFO_SIGNAL;
1319                 sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.
1320                                                             signal_strength);
1321
1322                 sinfo->filled |= STATION_INFO_TX_BITRATE;
1323                 sinfo->txrate.legacy = rtw_get_cur_max_rate23a(padapter);
1324
1325                 sinfo->filled |= STATION_INFO_RX_PACKETS;
1326                 sinfo->rx_packets = sta_rx_data_pkts(psta);
1327
1328                 sinfo->filled |= STATION_INFO_TX_PACKETS;
1329                 sinfo->tx_packets = psta->sta_stats.tx_pkts;
1330         }
1331
1332         /* for Ad-Hoc/AP mode */
1333         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
1334              check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) ||
1335              check_fwstate(pmlmepriv, WIFI_AP_STATE)) &&
1336             check_fwstate(pmlmepriv, _FW_LINKED)
1337             ) {
1338                 /* TODO: should acquire station info... */
1339         }
1340
1341 exit:
1342         return ret;
1343 }
1344
1345 static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
1346                                      struct net_device *ndev,
1347                                      enum nl80211_iftype type, u32 *flags,
1348                                      struct vif_params *params)
1349 {
1350         enum nl80211_iftype old_type;
1351         enum ndis_802_11_net_infra networkType;
1352         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
1353         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1354         struct wireless_dev *rtw_wdev = wiphy_to_wdev(wiphy);
1355 #ifdef CONFIG_8723AU_P2P
1356         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1357 #endif
1358         int ret = 0;
1359         u8 change = false;
1360
1361         DBG_8723A(FUNC_NDEV_FMT " call netdev_open23a\n", FUNC_NDEV_ARG(ndev));
1362         if (netdev_open23a(ndev) != 0) {
1363                 ret = -EPERM;
1364                 goto exit;
1365         }
1366
1367         if (_FAIL == rtw_pwr_wakeup(padapter)) {
1368                 ret = -EPERM;
1369                 goto exit;
1370         }
1371
1372         old_type = rtw_wdev->iftype;
1373         DBG_8723A(FUNC_NDEV_FMT " old_iftype =%d, new_iftype =%d\n",
1374                   FUNC_NDEV_ARG(ndev), old_type, type);
1375
1376         if (old_type != type) {
1377                 change = true;
1378                 pmlmeext->action_public_rxseq = 0xffff;
1379                 pmlmeext->action_public_dialog_token = 0xff;
1380         }
1381
1382         switch (type) {
1383         case NL80211_IFTYPE_ADHOC:
1384                 networkType = Ndis802_11IBSS;
1385                 break;
1386         case NL80211_IFTYPE_P2P_CLIENT:
1387         case NL80211_IFTYPE_STATION:
1388                 networkType = Ndis802_11Infrastructure;
1389 #ifdef CONFIG_8723AU_P2P
1390                 if (change && rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
1391                         del_timer_sync(&pwdinfo->find_phase_timer);
1392                         del_timer_sync(&pwdinfo->restore_p2p_state_timer);
1393                         del_timer_sync(&pwdinfo->pre_tx_scan_timer);
1394
1395                         /* it means remove GO and change mode from AP(GO)
1396                            to station(P2P DEVICE) */
1397                         rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1398                         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
1399
1400                         DBG_8723A("%s, role =%d, p2p_state =%d, pre_p2p_state ="
1401                                   "%d\n", __func__, rtw_p2p_role(pwdinfo),
1402                                   rtw_p2p_state(pwdinfo),
1403                                   rtw_p2p_pre_state(pwdinfo));
1404                 }
1405 #endif /* CONFIG_8723AU_P2P */
1406                 break;
1407         case NL80211_IFTYPE_P2P_GO:
1408         case NL80211_IFTYPE_AP:
1409                 networkType = Ndis802_11APMode;
1410 #ifdef CONFIG_8723AU_P2P
1411                 if (change && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
1412                         /* it means P2P Group created, we will be GO
1413                            and change mode from  P2P DEVICE to AP(GO) */
1414                         rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
1415                 }
1416 #endif /* CONFIG_8723AU_P2P */
1417                 break;
1418         default:
1419                 return -EOPNOTSUPP;
1420         }
1421
1422         rtw_wdev->iftype = type;
1423
1424         if (rtw_set_802_11_infrastructure_mode23a(padapter, networkType) == false) {
1425                 rtw_wdev->iftype = old_type;
1426                 ret = -EPERM;
1427                 goto exit;
1428         }
1429
1430         rtw_setopmode_cmd23a(padapter, networkType);
1431
1432 exit:
1433         return ret;
1434 }
1435
1436 void rtw_cfg80211_indicate_scan_done(struct rtw_wdev_priv *pwdev_priv,
1437                                      bool aborted)
1438 {
1439         spin_lock_bh(&pwdev_priv->scan_req_lock);
1440         if (pwdev_priv->scan_request != NULL) {
1441 #ifdef CONFIG_DEBUG_CFG80211
1442                 DBG_8723A("%s with scan req\n", __func__);
1443 #endif
1444                 if (pwdev_priv->scan_request->wiphy !=
1445                     pwdev_priv->rtw_wdev->wiphy)
1446                         DBG_8723A("error wiphy compare\n");
1447                 else
1448                         cfg80211_scan_done(pwdev_priv->scan_request, aborted);
1449
1450                 pwdev_priv->scan_request = NULL;
1451         } else {
1452 #ifdef CONFIG_DEBUG_CFG80211
1453                 DBG_8723A("%s without scan req\n", __func__);
1454 #endif
1455         }
1456         spin_unlock_bh(&pwdev_priv->scan_req_lock);
1457 }
1458
1459 void rtw_cfg80211_surveydone_event_callback(struct rtw_adapter *padapter)
1460 {
1461         struct list_head *plist, *phead, *ptmp;
1462         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1463         struct rtw_queue *queue = &pmlmepriv->scanned_queue;
1464         struct wlan_network *pnetwork;
1465
1466 #ifdef CONFIG_DEBUG_CFG80211
1467         DBG_8723A("%s\n", __func__);
1468 #endif
1469
1470         spin_lock_bh(&pmlmepriv->scanned_queue.lock);
1471
1472         phead = get_list_head(queue);
1473
1474         list_for_each_safe(plist, ptmp, phead) {
1475                 pnetwork = container_of(plist, struct wlan_network, list);
1476
1477                 /* report network only if the current channel set
1478                    contains the channel to which this network belongs */
1479                 if (rtw_ch_set_search_ch23a
1480                     (padapter->mlmeextpriv.channel_set,
1481                      pnetwork->network.Configuration.DSConfig) >= 0)
1482                         rtw_cfg80211_inform_bss(padapter, pnetwork);
1483         }
1484
1485         spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
1486
1487         /* call this after other things have been done */
1488         rtw_cfg80211_indicate_scan_done(wdev_to_priv(padapter->rtw_wdev),
1489                                         false);
1490 }
1491
1492 static int rtw_cfg80211_set_probe_req_wpsp2pie(struct rtw_adapter *padapter,
1493                                                char *buf, int len)
1494 {
1495         int ret = 0;
1496         uint wps_ielen = 0;
1497         u8 *wps_ie;
1498 #ifdef CONFIG_8723AU_P2P
1499         u32 p2p_ielen = 0;
1500         u8 *p2p_ie;
1501         u32 wfd_ielen = 0;
1502 #endif
1503         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1504
1505 #ifdef CONFIG_DEBUG_CFG80211
1506         DBG_8723A("%s, ielen =%d\n", __func__, len);
1507 #endif
1508
1509         if (len > 0) {
1510                 wps_ie = rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen);
1511                 if (wps_ie) {
1512 #ifdef CONFIG_DEBUG_CFG80211
1513                         DBG_8723A("probe_req_wps_ielen =%d\n", wps_ielen);
1514 #endif
1515                         if (pmlmepriv->wps_probe_req_ie) {
1516                                 pmlmepriv->wps_probe_req_ie_len = 0;
1517                                 kfree(pmlmepriv->wps_probe_req_ie);
1518                                 pmlmepriv->wps_probe_req_ie = NULL;
1519                         }
1520
1521                         pmlmepriv->wps_probe_req_ie =
1522                                 kmalloc(wps_ielen, GFP_KERNEL);
1523                         if (pmlmepriv->wps_probe_req_ie == NULL) {
1524                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
1525                                           __func__, __LINE__);
1526                                 return -EINVAL;
1527                         }
1528                         memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
1529                         pmlmepriv->wps_probe_req_ie_len = wps_ielen;
1530                 }
1531 #ifdef CONFIG_8723AU_P2P
1532                 p2p_ie = rtw_get_p2p_ie23a(buf, len, NULL, &p2p_ielen);
1533                 if (p2p_ie) {
1534 #ifdef CONFIG_DEBUG_CFG80211
1535                         DBG_8723A("probe_req_p2p_ielen =%d\n", p2p_ielen);
1536 #endif
1537
1538                         if (pmlmepriv->p2p_probe_req_ie) {
1539                                 pmlmepriv->p2p_probe_req_ie_len = 0;
1540                                 kfree(pmlmepriv->p2p_probe_req_ie);
1541                                 pmlmepriv->p2p_probe_req_ie = NULL;
1542                         }
1543
1544                         pmlmepriv->p2p_probe_req_ie =
1545                                 kmalloc(p2p_ielen, GFP_KERNEL);
1546                         if (pmlmepriv->p2p_probe_req_ie == NULL) {
1547                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
1548                                           __func__, __LINE__);
1549                                 return -EINVAL;
1550
1551                         }
1552                         memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
1553                         pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
1554                 }
1555 #endif /* CONFIG_8723AU_P2P */
1556
1557                 /* buf += p2p_ielen; */
1558                 /* len -= p2p_ielen; */
1559
1560 #ifdef CONFIG_8723AU_P2P
1561                 if (rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) {
1562 #ifdef CONFIG_DEBUG_CFG80211
1563                         DBG_8723A("probe_req_wfd_ielen =%d\n", wfd_ielen);
1564 #endif
1565
1566                         if (pmlmepriv->wfd_probe_req_ie) {
1567                                 pmlmepriv->wfd_probe_req_ie_len = 0;
1568                                 kfree(pmlmepriv->wfd_probe_req_ie);
1569                                 pmlmepriv->wfd_probe_req_ie = NULL;
1570                         }
1571
1572                         pmlmepriv->wfd_probe_req_ie =
1573                                 kmalloc(wfd_ielen, GFP_KERNEL);
1574                         if (pmlmepriv->wfd_probe_req_ie == NULL) {
1575                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
1576                                           __func__, __LINE__);
1577                                 return -EINVAL;
1578
1579                         }
1580                         rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie,
1581                                        &pmlmepriv->wfd_probe_req_ie_len);
1582                 }
1583 #endif /* CONFIG_8723AU_P2P */
1584
1585         }
1586
1587         return ret;
1588 }
1589
1590 static int cfg80211_rtw_scan(struct wiphy *wiphy,
1591                              struct cfg80211_scan_request *request)
1592 {
1593         int i;
1594         u8 _status = false;
1595         int ret = 0;
1596         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
1597         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1598         struct cfg80211_ssid ssid[RTW_SSID_SCAN_AMOUNT];
1599         struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
1600         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
1601         struct cfg80211_ssid *ssids = request->ssids;
1602 #ifdef CONFIG_8723AU_P2P
1603         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1604         int social_channel = 0;
1605 #endif /* CONFIG_8723AU_P2P */
1606         bool need_indicate_scan_done = false;
1607
1608 #ifdef CONFIG_DEBUG_CFG80211
1609         DBG_8723A(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter));
1610 #endif
1611
1612         spin_lock_bh(&pwdev_priv->scan_req_lock);
1613         pwdev_priv->scan_request = request;
1614         spin_unlock_bh(&pwdev_priv->scan_req_lock);
1615
1616         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1617
1618 #ifdef CONFIG_DEBUG_CFG80211
1619                 DBG_8723A("%s under WIFI_AP_STATE\n", __func__);
1620 #endif
1621                 /* need_indicate_scan_done = true; */
1622                 /* goto check_need_indicate_scan_done; */
1623         }
1624
1625         if (rtw_pwr_wakeup(padapter) == _FAIL) {
1626                 need_indicate_scan_done = true;
1627                 goto check_need_indicate_scan_done;
1628         }
1629 #ifdef CONFIG_8723AU_P2P
1630         if (!memcmp(ssids->ssid, "DIRECT-", 7) &&
1631             rtw_get_p2p_ie23a((u8 *) request->ie, request->ie_len, NULL, NULL)) {
1632                 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
1633                         rtw_p2p_enable23a(padapter, P2P_ROLE_DEVICE);
1634                         wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = true;
1635                 } else {
1636                         rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
1637 #ifdef CONFIG_DEBUG_CFG80211
1638                         DBG_8723A("%s, role =%d, p2p_state =%d\n", __func__,
1639                                   rtw_p2p_role(pwdinfo),
1640                                   rtw_p2p_state(pwdinfo));
1641 #endif
1642                 }
1643                 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
1644
1645                 if (request->n_channels == 3 &&
1646                     request->channels[0]->hw_value == 1 &&
1647                     request->channels[1]->hw_value == 6 &&
1648                     request->channels[2]->hw_value == 11)
1649                         social_channel = 1;
1650         }
1651 #endif /* CONFIG_8723AU_P2P */
1652
1653         if (request->ie && request->ie_len > 0) {
1654                 rtw_cfg80211_set_probe_req_wpsp2pie(padapter,
1655                                                     (u8 *) request->ie,
1656                                                     request->ie_len);
1657         }
1658
1659         if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true) {
1660                 DBG_8723A("%s, bBusyTraffic == true\n", __func__);
1661                 need_indicate_scan_done = true;
1662                 goto check_need_indicate_scan_done;
1663         }
1664         if (rtw_is_scan_deny(padapter)) {
1665                 DBG_8723A(FUNC_ADPT_FMT ": scan deny\n",
1666                           FUNC_ADPT_ARG(padapter));
1667                 need_indicate_scan_done = true;
1668                 goto check_need_indicate_scan_done;
1669         }
1670
1671         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) ==
1672             true) {
1673                 DBG_8723A("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
1674                 need_indicate_scan_done = true;
1675                 goto check_need_indicate_scan_done;
1676         }
1677 #ifdef CONFIG_8723AU_P2P
1678         if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
1679             !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
1680                 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
1681                 rtw_free_network_queue23a(padapter, true);
1682
1683                 if (social_channel == 0)
1684                         rtw_p2p_findphase_ex_set(pwdinfo,
1685                                                  P2P_FINDPHASE_EX_NONE);
1686                 else
1687                         rtw_p2p_findphase_ex_set(pwdinfo,
1688                                                  P2P_FINDPHASE_EX_SOCIAL_LAST);
1689         }
1690 #endif /* CONFIG_8723AU_P2P */
1691
1692         memset(ssid, 0, sizeof(struct cfg80211_ssid) * RTW_SSID_SCAN_AMOUNT);
1693         /* parsing request ssids, n_ssids */
1694         for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
1695 #ifdef CONFIG_DEBUG_CFG80211
1696                 DBG_8723A("ssid =%s, len =%d\n", ssids[i].ssid,
1697                           ssids[i].ssid_len);
1698 #endif
1699                 memcpy(ssid[i].ssid, ssids[i].ssid, ssids[i].ssid_len);
1700                 ssid[i].ssid_len = ssids[i].ssid_len;
1701         }
1702
1703         /* parsing channels, n_channels */
1704         memset(ch, 0,
1705                sizeof(struct rtw_ieee80211_channel) * RTW_CHANNEL_SCAN_AMOUNT);
1706
1707         if (request->n_channels == 1) {
1708                 for (i = 0; i < request->n_channels &&
1709                      i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
1710 #ifdef CONFIG_DEBUG_CFG80211
1711                         DBG_8723A(FUNC_ADPT_FMT CHAN_FMT "\n",
1712                                   FUNC_ADPT_ARG(padapter),
1713                                   CHAN_ARG(request->channels[i]));
1714 #endif
1715                         ch[i].hw_value = request->channels[i]->hw_value;
1716                         ch[i].flags = request->channels[i]->flags;
1717                 }
1718         }
1719
1720         spin_lock_bh(&pmlmepriv->lock);
1721         if (request->n_channels == 1) {
1722                 memcpy(&ch[1], &ch[0], sizeof(struct rtw_ieee80211_channel));
1723                 memcpy(&ch[2], &ch[0], sizeof(struct rtw_ieee80211_channel));
1724                 _status = rtw_sitesurvey_cmd23a(padapter, ssid,
1725                                              RTW_SSID_SCAN_AMOUNT, ch, 3);
1726         } else {
1727                 _status = rtw_sitesurvey_cmd23a(padapter, ssid,
1728                                              RTW_SSID_SCAN_AMOUNT, NULL, 0);
1729         }
1730         spin_unlock_bh(&pmlmepriv->lock);
1731
1732         if (_status == false)
1733                 ret = -1;
1734
1735 check_need_indicate_scan_done:
1736         if (need_indicate_scan_done)
1737                 rtw_cfg80211_surveydone_event_callback(padapter);
1738         return ret;
1739 }
1740
1741 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1742 {
1743         DBG_8723A("%s\n", __func__);
1744         return 0;
1745 }
1746
1747 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1748                                   struct cfg80211_ibss_params *params)
1749 {
1750         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
1751         return 0;
1752 }
1753
1754 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1755 {
1756         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
1757         return 0;
1758 }
1759
1760 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv,
1761                                         u32 wpa_version)
1762 {
1763         DBG_8723A("%s, wpa_version =%d\n", __func__, wpa_version);
1764
1765         if (!wpa_version) {
1766                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
1767                 return 0;
1768         }
1769
1770         if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) {
1771                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
1772         }
1773
1774 /*
1775         if (wpa_version & NL80211_WPA_VERSION_2)
1776         {
1777                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
1778         }
1779 */
1780
1781         return 0;
1782 }
1783
1784 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
1785                                       enum nl80211_auth_type sme_auth_type)
1786 {
1787         DBG_8723A("%s, nl80211_auth_type =%d\n", __func__, sme_auth_type);
1788
1789         switch (sme_auth_type) {
1790         case NL80211_AUTHTYPE_AUTOMATIC:
1791                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1792
1793                 break;
1794         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1795                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1796
1797                 if (psecuritypriv->ndisauthtype > Ndis802_11AuthModeWPA)
1798                         psecuritypriv->dot11AuthAlgrthm =
1799                                 dot11AuthAlgrthm_8021X;
1800                 break;
1801         case NL80211_AUTHTYPE_SHARED_KEY:
1802                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1803
1804                 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1805                 break;
1806         default:
1807                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1808                 /* return -ENOTSUPP; */
1809         }
1810
1811         return 0;
1812 }
1813
1814 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv,
1815                                    u32 cipher, bool ucast)
1816 {
1817         u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
1818
1819         u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
1820             &psecuritypriv->dot118021XGrpPrivacy;
1821
1822         DBG_8723A("%s, ucast =%d, cipher = 0x%x\n", __func__, ucast, cipher);
1823
1824         if (!cipher) {
1825                 *profile_cipher = _NO_PRIVACY_;
1826                 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
1827                 return 0;
1828         }
1829
1830         switch (cipher) {
1831         case IW_AUTH_CIPHER_NONE:
1832                 *profile_cipher = _NO_PRIVACY_;
1833                 ndisencryptstatus = Ndis802_11EncryptionDisabled;
1834                 break;
1835         case WLAN_CIPHER_SUITE_WEP40:
1836                 *profile_cipher = _WEP40_;
1837                 ndisencryptstatus = Ndis802_11Encryption1Enabled;
1838                 break;
1839         case WLAN_CIPHER_SUITE_WEP104:
1840                 *profile_cipher = _WEP104_;
1841                 ndisencryptstatus = Ndis802_11Encryption1Enabled;
1842                 break;
1843         case WLAN_CIPHER_SUITE_TKIP:
1844                 *profile_cipher = _TKIP_;
1845                 ndisencryptstatus = Ndis802_11Encryption2Enabled;
1846                 break;
1847         case WLAN_CIPHER_SUITE_CCMP:
1848                 *profile_cipher = _AES_;
1849                 ndisencryptstatus = Ndis802_11Encryption3Enabled;
1850                 break;
1851         default:
1852                 DBG_8723A("Unsupported cipher: 0x%x\n", cipher);
1853                 return -ENOTSUPP;
1854         }
1855
1856         if (ucast)
1857                 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
1858
1859         return 0;
1860 }
1861
1862 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv,
1863                                     u32 key_mgt)
1864 {
1865         DBG_8723A("%s, key_mgt = 0x%x\n", __func__, key_mgt);
1866
1867         if (key_mgt == WLAN_AKM_SUITE_8021X)
1868                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1869         else if (key_mgt == WLAN_AKM_SUITE_PSK)
1870                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1871         else
1872                 DBG_8723A("Invalid key mgt: 0x%x\n", key_mgt);
1873
1874         return 0;
1875 }
1876
1877 static int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie,
1878                                    size_t ielen)
1879 {
1880         u8 *buf = NULL, *pos = NULL;
1881         int group_cipher = 0, pairwise_cipher = 0;
1882         int ret = 0;
1883         int wpa_ielen = 0;
1884         int wpa2_ielen = 0;
1885         u8 *pwpa, *pwpa2;
1886         u8 null_addr[] = { 0, 0, 0, 0, 0, 0 };
1887         int i;
1888
1889         if (!pie || !ielen) {
1890                 /* Treat this as normal case, but need to clear
1891                    WIFI_UNDER_WPS */
1892                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1893                 goto exit;
1894         }
1895         if (ielen > MAX_WPA_IE_LEN + MAX_WPS_IE_LEN + MAX_P2P_IE_LEN) {
1896                 ret = -EINVAL;
1897                 goto exit;
1898         }
1899         buf = kzalloc(ielen, GFP_KERNEL);
1900         if (buf == NULL) {
1901                 ret = -ENOMEM;
1902                 goto exit;
1903         }
1904         memcpy(buf, pie, ielen);
1905
1906         /* dump */
1907         DBG_8723A("set wpa_ie(length:%zu):\n", ielen);
1908         for (i = 0; i < ielen; i = i + 8)
1909                 DBG_8723A("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
1910                           buf[i], buf[i + 1],
1911                           buf[i + 2], buf[i + 3], buf[i + 4],
1912                           buf[i + 5], buf[i + 6], buf[i + 7]);
1913         pos = buf;
1914         if (ielen < RSN_HEADER_LEN) {
1915                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
1916                          ("Ie len too short %d\n", (int)ielen));
1917                 ret = -1;
1918                 goto exit;
1919         }
1920
1921         pwpa = rtw_get_wpa_ie23a(buf, &wpa_ielen, ielen);
1922         if (pwpa && wpa_ielen > 0) {
1923                 if (rtw_parse_wpa_ie23a(pwpa, wpa_ielen + 2, &group_cipher,
1924                                      &pairwise_cipher, NULL) == _SUCCESS) {
1925                         padapter->securitypriv.dot11AuthAlgrthm =
1926                                 dot11AuthAlgrthm_8021X;
1927                         padapter->securitypriv.ndisauthtype =
1928                                 Ndis802_11AuthModeWPAPSK;
1929                         memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0],
1930                                wpa_ielen + 2);
1931
1932                         DBG_8723A("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
1933                 }
1934         }
1935
1936         pwpa2 = rtw_get_wpa2_ie23a(buf, &wpa2_ielen, ielen);
1937         if (pwpa2 && wpa2_ielen > 0) {
1938                 if (rtw_parse_wpa2_ie23a (pwpa2, wpa2_ielen + 2, &group_cipher,
1939                                        &pairwise_cipher, NULL) == _SUCCESS) {
1940                         padapter->securitypriv.dot11AuthAlgrthm =
1941                                 dot11AuthAlgrthm_8021X;
1942                         padapter->securitypriv.ndisauthtype =
1943                                 Ndis802_11AuthModeWPA2PSK;
1944                         memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0],
1945                                wpa2_ielen + 2);
1946
1947                         DBG_8723A("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
1948                 }
1949         }
1950
1951         if (group_cipher == 0) {
1952                 group_cipher = WPA_CIPHER_NONE;
1953         }
1954         if (pairwise_cipher == 0) {
1955                 pairwise_cipher = WPA_CIPHER_NONE;
1956         }
1957
1958         switch (group_cipher) {
1959         case WPA_CIPHER_NONE:
1960                 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1961                 padapter->securitypriv.ndisencryptstatus =
1962                         Ndis802_11EncryptionDisabled;
1963                 break;
1964         case WPA_CIPHER_WEP40:
1965                 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1966                 padapter->securitypriv.ndisencryptstatus =
1967                         Ndis802_11Encryption1Enabled;
1968                 break;
1969         case WPA_CIPHER_TKIP:
1970                 padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
1971                 padapter->securitypriv.ndisencryptstatus =
1972                         Ndis802_11Encryption2Enabled;
1973                 break;
1974         case WPA_CIPHER_CCMP:
1975                 padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
1976                 padapter->securitypriv.ndisencryptstatus =
1977                         Ndis802_11Encryption3Enabled;
1978                 break;
1979         case WPA_CIPHER_WEP104:
1980                 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
1981                 padapter->securitypriv.ndisencryptstatus =
1982                         Ndis802_11Encryption1Enabled;
1983                 break;
1984         }
1985
1986         switch (pairwise_cipher) {
1987         case WPA_CIPHER_NONE:
1988                 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1989                 padapter->securitypriv.ndisencryptstatus =
1990                         Ndis802_11EncryptionDisabled;
1991                 break;
1992         case WPA_CIPHER_WEP40:
1993                 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1994                 padapter->securitypriv.ndisencryptstatus =
1995                         Ndis802_11Encryption1Enabled;
1996                 break;
1997         case WPA_CIPHER_TKIP:
1998                 padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
1999                 padapter->securitypriv.ndisencryptstatus =
2000                         Ndis802_11Encryption2Enabled;
2001                 break;
2002         case WPA_CIPHER_CCMP:
2003                 padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
2004                 padapter->securitypriv.ndisencryptstatus =
2005                         Ndis802_11Encryption3Enabled;
2006                 break;
2007         case WPA_CIPHER_WEP104:
2008                 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
2009                 padapter->securitypriv.ndisencryptstatus =
2010                         Ndis802_11Encryption1Enabled;
2011                 break;
2012         }
2013
2014         {                       /* handle wps_ie */
2015                 uint wps_ielen;
2016                 u8 *wps_ie;
2017
2018                 wps_ie = rtw_get_wps_ie23a(buf, ielen, NULL, &wps_ielen);
2019                 if (wps_ie && wps_ielen > 0) {
2020                         DBG_8723A("got wps_ie, wps_ielen:%u\n", wps_ielen);
2021                         padapter->securitypriv.wps_ie_len =
2022                                 wps_ielen <
2023                                 MAX_WPS_IE_LEN ? wps_ielen : MAX_WPS_IE_LEN;
2024                         memcpy(padapter->securitypriv.wps_ie, wps_ie,
2025                                padapter->securitypriv.wps_ie_len);
2026                         set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
2027                 } else {
2028                         _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2029                 }
2030         }
2031
2032 #ifdef CONFIG_8723AU_P2P
2033         {                       /* check p2p_ie for assoc req; */
2034                 uint p2p_ielen = 0;
2035                 u8 *p2p_ie;
2036                 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2037
2038                 p2p_ie = rtw_get_p2p_ie23a(buf, ielen, NULL, &p2p_ielen);
2039                 if (p2p_ie) {
2040 #ifdef CONFIG_DEBUG_CFG80211
2041                         DBG_8723A("%s p2p_assoc_req_ielen =%d\n", __func__,
2042                                   p2p_ielen);
2043 #endif
2044
2045                         if (pmlmepriv->p2p_assoc_req_ie) {
2046                                 pmlmepriv->p2p_assoc_req_ie_len = 0;
2047                                 kfree(pmlmepriv->p2p_assoc_req_ie);
2048                                 pmlmepriv->p2p_assoc_req_ie = NULL;
2049                         }
2050
2051                         pmlmepriv->p2p_assoc_req_ie =
2052                                 kmalloc(p2p_ielen, GFP_KERNEL);
2053                         if (pmlmepriv->p2p_assoc_req_ie == NULL) {
2054                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
2055                                           __func__, __LINE__);
2056                                 goto exit;
2057                         }
2058                         memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
2059                         pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
2060                 }
2061         }
2062 #endif /* CONFIG_8723AU_P2P */
2063
2064 #ifdef CONFIG_8723AU_P2P
2065         {                       /* check wfd_ie for assoc req; */
2066                 uint wfd_ielen = 0;
2067                 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2068
2069                 if (rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen)) {
2070 #ifdef CONFIG_DEBUG_CFG80211
2071                         DBG_8723A("%s wfd_assoc_req_ielen =%d\n", __func__,
2072                                   wfd_ielen);
2073 #endif
2074
2075                         if (pmlmepriv->wfd_assoc_req_ie) {
2076                                 pmlmepriv->wfd_assoc_req_ie_len = 0;
2077                                 kfree(pmlmepriv->wfd_assoc_req_ie);
2078                                 pmlmepriv->wfd_assoc_req_ie = NULL;
2079                         }
2080
2081                         pmlmepriv->wfd_assoc_req_ie =
2082                                 kmalloc(wfd_ielen, GFP_KERNEL);
2083                         if (pmlmepriv->wfd_assoc_req_ie == NULL) {
2084                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
2085                                           __func__, __LINE__);
2086                                 goto exit;
2087                         }
2088                         rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie,
2089                                        &pmlmepriv->wfd_assoc_req_ie_len);
2090                 }
2091         }
2092 #endif /* CONFIG_8723AU_P2P */
2093
2094         /* TKIP and AES disallow multicast packets until installing group key */
2095         if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_ ||
2096             padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_ ||
2097             padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
2098                 /* WPS open need to enable multicast */
2099                 /* check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true)*/
2100                 rtw_hal_set_hwreg23a(padapter, HW_VAR_OFF_RCR_AM, null_addr);
2101
2102         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2103                  ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->"
2104                   "securitypriv.ndisencryptstatus =%d padapter->"
2105                   "securitypriv.ndisauthtype =%d\n", pairwise_cipher,
2106                   padapter->securitypriv.ndisencryptstatus,
2107                   padapter->securitypriv.ndisauthtype));
2108
2109 exit:
2110         kfree(buf);
2111         if (ret)
2112                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2113         return ret;
2114 }
2115
2116 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
2117                                 struct cfg80211_connect_params *sme)
2118 {
2119         int ret = 0;
2120         struct list_head *phead, *plist, *ptmp;
2121         struct wlan_network *pnetwork = NULL;
2122         enum ndis_802_11_auth_mode authmode;
2123         struct cfg80211_ssid ndis_ssid;
2124         u8 *dst_ssid;
2125         u8 *src_ssid;
2126         u8 *dst_bssid;
2127         const u8 *src_bssid;
2128         /* u8 matched_by_bssid = false; */
2129         /* u8 matched_by_ssid = false; */
2130         u8 matched = false;
2131         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2132         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2133         struct security_priv *psecuritypriv = &padapter->securitypriv;
2134         struct rtw_queue *queue = &pmlmepriv->scanned_queue;
2135
2136         DBG_8723A("=>" FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
2137         DBG_8723A("privacy =%d, key =%p, key_len =%d, key_idx =%d\n",
2138                   sme->privacy, sme->key, sme->key_len, sme->key_idx);
2139
2140         if (wdev_to_priv(padapter->rtw_wdev)->block) {
2141                 ret = -EBUSY;
2142                 DBG_8723A("%s wdev_priv.block is set\n", __func__);
2143                 goto exit;
2144         }
2145
2146         if (_FAIL == rtw_pwr_wakeup(padapter)) {
2147                 ret = -EPERM;
2148                 goto exit;
2149         }
2150
2151         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2152                 ret = -EPERM;
2153                 goto exit;
2154         }
2155
2156         if (!sme->ssid || !sme->ssid_len) {
2157                 ret = -EINVAL;
2158                 goto exit;
2159         }
2160
2161         if (sme->ssid_len > IW_ESSID_MAX_SIZE) {
2162                 ret = -E2BIG;
2163                 goto exit;
2164         }
2165
2166         memset(&ndis_ssid, 0, sizeof(struct cfg80211_ssid));
2167         ndis_ssid.ssid_len = sme->ssid_len;
2168         memcpy(ndis_ssid.ssid, sme->ssid, sme->ssid_len);
2169
2170         DBG_8723A("ssid =%s, len =%zu\n", ndis_ssid.ssid, sme->ssid_len);
2171
2172         if (sme->bssid)
2173                 DBG_8723A("bssid =" MAC_FMT "\n", MAC_ARG(sme->bssid));
2174
2175         if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
2176                 ret = -EBUSY;
2177                 DBG_8723A("%s, fw_state = 0x%x, goto exit\n", __func__,
2178                           pmlmepriv->fw_state);
2179                 goto exit;
2180         }
2181         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
2182                 rtw_scan_abort23a(padapter);
2183         }
2184
2185         spin_lock_bh(&queue->lock);
2186
2187         phead = get_list_head(queue);
2188
2189         list_for_each_safe(plist, ptmp, phead) {
2190                 pnetwork = container_of(plist, struct wlan_network, list);
2191
2192                 dst_ssid = pnetwork->network.Ssid.ssid;
2193                 dst_bssid = pnetwork->network.MacAddress;
2194
2195                 if (sme->bssid) {
2196                         if (memcmp(pnetwork->network.MacAddress,
2197                                    sme->bssid, ETH_ALEN))
2198                                 continue;
2199                 }
2200
2201                 if (sme->ssid && sme->ssid_len) {
2202                         if (pnetwork->network.Ssid.ssid_len != sme->ssid_len ||
2203                             memcmp(pnetwork->network.Ssid.ssid, sme->ssid,
2204                                    sme->ssid_len))
2205                                 continue;
2206                 }
2207
2208                 if (sme->bssid) {
2209                         src_bssid = sme->bssid;
2210
2211                         if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) {
2212                                 DBG_8723A("matched by bssid\n");
2213
2214                                 ndis_ssid.ssid_len =
2215                                     pnetwork->network.Ssid.ssid_len;
2216                                 memcpy(ndis_ssid.ssid,
2217                                        pnetwork->network.Ssid.ssid,
2218                                        pnetwork->network.Ssid.ssid_len);
2219
2220                                 matched = true;
2221                                 break;
2222                         }
2223
2224                 } else if (sme->ssid && sme->ssid_len) {
2225                         src_ssid = ndis_ssid.ssid;
2226
2227                         if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.ssid_len)) &&
2228                             (pnetwork->network.Ssid.ssid_len ==
2229                              ndis_ssid.ssid_len)) {
2230                                 DBG_8723A("matched by ssid\n");
2231                                 matched = true;
2232                                 break;
2233                         }
2234                 }
2235         }
2236
2237         spin_unlock_bh(&queue->lock);
2238
2239         if (!matched || (pnetwork == NULL)) {
2240                 ret = -ENOENT;
2241                 DBG_8723A("connect, matched == false, goto exit\n");
2242                 goto exit;
2243         }
2244
2245         if (rtw_set_802_11_infrastructure_mode23a
2246             (padapter, pnetwork->network.InfrastructureMode) == false) {
2247                 ret = -EPERM;
2248                 goto exit;
2249         }
2250
2251         psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
2252         psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
2253         psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2254         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2255         psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2256
2257         ret =
2258             rtw_cfg80211_set_wpa_version(psecuritypriv,
2259                                          sme->crypto.wpa_versions);
2260         if (ret < 0)
2261                 goto exit;
2262
2263         ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
2264
2265         if (ret < 0)
2266                 goto exit;
2267
2268         DBG_8723A("%s, ie_len =%zu\n", __func__, sme->ie_len);
2269
2270         ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len);
2271         if (ret < 0)
2272                 goto exit;
2273
2274         if (sme->crypto.n_ciphers_pairwise) {
2275                 ret = rtw_cfg80211_set_cipher(psecuritypriv,
2276                                               sme->crypto.ciphers_pairwise[0],
2277                                               true);
2278                 if (ret < 0)
2279                         goto exit;
2280         }
2281
2282         /* For WEP Shared auth */
2283         if ((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared ||
2284              psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) &&
2285             sme->key) {
2286                 u32 wep_key_idx, wep_key_len, wep_total_len;
2287                 struct ndis_802_11_wep *pwep = NULL;
2288                 DBG_8723A("%s(): Shared/Auto WEP\n", __func__);
2289
2290                 wep_key_idx = sme->key_idx;
2291                 wep_key_len = sme->key_len;
2292
2293                 if (sme->key_idx > WEP_KEYS) {
2294                         ret = -EINVAL;
2295                         goto exit;
2296                 }
2297
2298                 if (wep_key_len > 0) {
2299                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
2300                         wep_total_len =
2301                                 wep_key_len +
2302                                 offsetof(struct ndis_802_11_wep, KeyMaterial);
2303                         pwep = (struct ndis_802_11_wep *)kmalloc(wep_total_len,
2304                                                                  GFP_KERNEL);
2305                         if (pwep == NULL) {
2306                                 DBG_8723A(" wpa_set_encryption: pwep "
2307                                           "allocate fail !!!\n");
2308                                 ret = -ENOMEM;
2309                                 goto exit;
2310                         }
2311
2312                         memset(pwep, 0, wep_total_len);
2313
2314                         pwep->KeyLength = wep_key_len;
2315                         pwep->Length = wep_total_len;
2316
2317                         if (wep_key_len == 13) {
2318                                 padapter->securitypriv.dot11PrivacyAlgrthm =
2319                                     _WEP104_;
2320                                 padapter->securitypriv.dot118021XGrpPrivacy =
2321                                     _WEP104_;
2322                         }
2323                 } else {
2324                         ret = -EINVAL;
2325                         goto exit;
2326                 }
2327
2328                 pwep->KeyIndex = wep_key_idx;
2329                 pwep->KeyIndex |= 0x80000000;
2330
2331                 memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
2332
2333                 if (rtw_set_802_11_add_wep23a(padapter, pwep) == (u8) _FAIL) {
2334                         ret = -EOPNOTSUPP;
2335                 }
2336
2337                 kfree(pwep);
2338
2339                 if (ret < 0)
2340                         goto exit;
2341         }
2342
2343         ret = rtw_cfg80211_set_cipher(psecuritypriv,
2344                                       sme->crypto.cipher_group, false);
2345         if (ret < 0)
2346                 return ret;
2347
2348         if (sme->crypto.n_akm_suites) {
2349                 ret = rtw_cfg80211_set_key_mgt(psecuritypriv,
2350                                                sme->crypto.akm_suites[0]);
2351                 if (ret < 0)
2352                         goto exit;
2353         }
2354
2355         authmode = psecuritypriv->ndisauthtype;
2356         rtw_set_802_11_authentication_mode23a(padapter, authmode);
2357
2358         /* rtw_set_802_11_encryption_mode(padapter,
2359            padapter->securitypriv.ndisencryptstatus); */
2360
2361         if (rtw_set_802_11_ssid23a(padapter, &ndis_ssid) == false) {
2362                 ret = -1;
2363                 goto exit;
2364         }
2365
2366         DBG_8723A("set ssid:dot11AuthAlgrthm =%d, dot11PrivacyAlgrthm =%d, "
2367                   "dot118021XGrpPrivacy =%d\n", psecuritypriv->dot11AuthAlgrthm,
2368                   psecuritypriv->dot11PrivacyAlgrthm,
2369                   psecuritypriv->dot118021XGrpPrivacy);
2370
2371 exit:
2372
2373         DBG_8723A("<=%s, ret %d\n", __func__, ret);
2374
2375         return ret;
2376 }
2377
2378 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2379                                    u16 reason_code)
2380 {
2381         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2382
2383         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
2384
2385         rtw_set_roaming(padapter, 0);
2386
2387         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
2388                 rtw_scan_abort23a(padapter);
2389                 LeaveAllPowerSaveMode23a(padapter);
2390                 rtw_disassoc_cmd23a(padapter, 500, false);
2391
2392                 DBG_8723A("%s...call rtw_indicate_disconnect23a\n", __func__);
2393
2394                 padapter->mlmepriv.not_indic_disco = true;
2395                 rtw_indicate_disconnect23a(padapter);
2396                 padapter->mlmepriv.not_indic_disco = false;
2397
2398                 rtw_free_assoc_resources23a(padapter, 1);
2399         }
2400
2401         return 0;
2402 }
2403
2404 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
2405                                     struct wireless_dev *wdev,
2406                                     enum nl80211_tx_power_setting type, int mbm)
2407 {
2408         DBG_8723A("%s\n", __func__);
2409         return 0;
2410 }
2411
2412 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
2413                                     struct wireless_dev *wdev, int *dbm)
2414 {
2415         DBG_8723A("%s\n", __func__);
2416         *dbm = (12);
2417         return 0;
2418 }
2419
2420 inline bool rtw_cfg80211_pwr_mgmt(struct rtw_adapter *adapter)
2421 {
2422         struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(adapter->rtw_wdev);
2423         return rtw_wdev_priv->power_mgmt;
2424 }
2425
2426 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
2427                                        struct net_device *ndev,
2428                                        bool enabled, int timeout)
2429 {
2430         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2431         struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(padapter->rtw_wdev);
2432
2433         DBG_8723A(FUNC_NDEV_FMT " enabled:%u, timeout:%d\n",
2434                   FUNC_NDEV_ARG(ndev), enabled, timeout);
2435
2436         rtw_wdev_priv->power_mgmt = enabled;
2437
2438         if (!enabled)
2439                 LPS_Leave23a(padapter);
2440
2441         return 0;
2442 }
2443
2444 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
2445                                   struct net_device *netdev,
2446                                   struct cfg80211_pmksa *pmksa)
2447 {
2448         u8 index, blInserted = false;
2449         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2450         struct security_priv *psecuritypriv = &padapter->securitypriv;
2451         u8 strZeroMacAddress[ETH_ALEN] = { 0x00 };
2452
2453         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(netdev));
2454
2455         if (!memcmp(pmksa->bssid, strZeroMacAddress, ETH_ALEN)) {
2456                 return -EINVAL;
2457         }
2458
2459         blInserted = false;
2460
2461         /* overwrite PMKID */
2462         for (index = 0; index < NUM_PMKID_CACHE; index++) {
2463                 if (!memcmp(psecuritypriv->PMKIDList[index].Bssid,
2464                             pmksa->bssid, ETH_ALEN)) {
2465                         /* BSSID is matched, the same AP => rewrite with
2466                            new PMKID. */
2467                         DBG_8723A(FUNC_NDEV_FMT
2468                                   " BSSID exists in the PMKList.\n",
2469                                   FUNC_NDEV_ARG(netdev));
2470
2471                         memcpy(psecuritypriv->PMKIDList[index].PMKID,
2472                                pmksa->pmkid, WLAN_PMKID_LEN);
2473                         psecuritypriv->PMKIDList[index].bUsed = true;
2474                         psecuritypriv->PMKIDIndex = index + 1;
2475                         blInserted = true;
2476                         break;
2477                 }
2478         }
2479
2480         if (!blInserted) {
2481                 /*  Find a new entry */
2482                 DBG_8723A(FUNC_NDEV_FMT
2483                           " Use the new entry index = %d for this PMKID.\n",
2484                           FUNC_NDEV_ARG(netdev), psecuritypriv->PMKIDIndex);
2485
2486                 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
2487                        Bssid, pmksa->bssid, ETH_ALEN);
2488                 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
2489                        PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2490
2491                 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed =
2492                         true;
2493                 psecuritypriv->PMKIDIndex++;
2494                 if (psecuritypriv->PMKIDIndex == 16) {
2495                         psecuritypriv->PMKIDIndex = 0;
2496                 }
2497         }
2498
2499         return 0;
2500 }
2501
2502 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
2503                                   struct net_device *netdev,
2504                                   struct cfg80211_pmksa *pmksa)
2505 {
2506         u8 index, bMatched = false;
2507         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2508         struct security_priv *psecuritypriv = &padapter->securitypriv;
2509
2510         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(netdev));
2511
2512         for (index = 0; index < NUM_PMKID_CACHE; index++) {
2513                 if (!memcmp(psecuritypriv->PMKIDList[index].Bssid,
2514                             pmksa->bssid, ETH_ALEN)) {
2515                         /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
2516                         memset(psecuritypriv->PMKIDList[index].Bssid, 0x00,
2517                                ETH_ALEN);
2518                         memset(psecuritypriv->PMKIDList[index].PMKID, 0x00,
2519                                WLAN_PMKID_LEN);
2520                         psecuritypriv->PMKIDList[index].bUsed = false;
2521                         bMatched = true;
2522                         break;
2523                 }
2524         }
2525
2526         if (false == bMatched) {
2527                 DBG_8723A(FUNC_NDEV_FMT " do not have matched BSSID\n",
2528                           FUNC_NDEV_ARG(netdev));
2529                 return -EINVAL;
2530         }
2531
2532         return 0;
2533 }
2534
2535 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
2536                                     struct net_device *netdev)
2537 {
2538         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2539         struct security_priv *psecuritypriv = &padapter->securitypriv;
2540
2541         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(netdev));
2542
2543         memset(&psecuritypriv->PMKIDList[0], 0x00,
2544                sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
2545         psecuritypriv->PMKIDIndex = 0;
2546
2547         return 0;
2548 }
2549
2550 #ifdef CONFIG_8723AU_AP_MODE
2551 void rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter,
2552                                      u8 *pmgmt_frame, uint frame_len)
2553 {
2554         s32 freq;
2555         int channel;
2556         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2557         struct net_device *ndev = padapter->pnetdev;
2558
2559         DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name);
2560
2561 #if defined(RTW_USE_CFG80211_STA_EVENT)
2562         {
2563                 struct station_info sinfo;
2564                 u8 ie_offset;
2565                 if (ieee80211_is_assoc_req(hdr->frame_control))
2566                         ie_offset = _ASOCREQ_IE_OFFSET_;
2567                 else            /*  WIFI_REASSOCREQ */
2568                         ie_offset = _REASOCREQ_IE_OFFSET_;
2569
2570                 sinfo.filled = 0;
2571                 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
2572                 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
2573                 sinfo.assoc_req_ies_len =
2574                         frame_len - WLAN_HDR_A3_LEN - ie_offset;
2575                 cfg80211_new_sta(ndev, hdr->addr2, &sinfo, GFP_ATOMIC);
2576         }
2577 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
2578         channel = pmlmeext->cur_channel;
2579         if (channel <= RTW_CH_MAX_2G_CHANNEL)
2580                 freq = ieee80211_channel_to_frequency(channel,
2581                                                       IEEE80211_BAND_2GHZ);
2582         else
2583                 freq = ieee80211_channel_to_frequency(channel,
2584                                                       IEEE80211_BAND_5GHZ);
2585
2586         rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len,
2587                              GFP_ATOMIC);
2588 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
2589 }
2590
2591 void rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter,
2592                                         unsigned char *da,
2593                                         unsigned short reason)
2594 {
2595         s32 freq;
2596         int channel;
2597         u8 *pmgmt_frame;
2598         uint frame_len;
2599         struct ieee80211_hdr *pwlanhdr;
2600         unsigned short *fctrl;
2601         u8 mgmt_buf[128] = { 0 };
2602         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2603         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2604         struct net_device *ndev = padapter->pnetdev;
2605
2606         DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name);
2607
2608 #if defined(RTW_USE_CFG80211_STA_EVENT)
2609         cfg80211_del_sta(ndev, da, GFP_ATOMIC);
2610 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
2611         channel = pmlmeext->cur_channel;
2612         if (channel <= RTW_CH_MAX_2G_CHANNEL)
2613                 freq = ieee80211_channel_to_frequency(channel,
2614                                                       IEEE80211_BAND_2GHZ);
2615         else
2616                 freq = ieee80211_channel_to_frequency(channel,
2617                                                       IEEE80211_BAND_5GHZ);
2618
2619         pmgmt_frame = mgmt_buf;
2620         pwlanhdr = (struct ieee80211_hdr *)pmgmt_frame;
2621
2622         fctrl = &pwlanhdr->frame_control;
2623         *(fctrl) = 0;
2624
2625         memcpy(pwlanhdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN);
2626         memcpy(pwlanhdr->addr2, da, ETH_ALEN);
2627         memcpy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN);
2628
2629         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2630         pmlmeext->mgnt_seq++;
2631         SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
2632
2633         pmgmt_frame += sizeof(struct ieee80211_hdr_3addr);
2634         frame_len = sizeof(struct ieee80211_hdr_3addr);
2635
2636         reason = cpu_to_le16(reason);
2637         pmgmt_frame = rtw_set_fixed_ie23a(pmgmt_frame,
2638                                        WLAN_REASON_PREV_AUTH_NOT_VALID,
2639                                        (unsigned char *)&reason, &frame_len);
2640
2641         rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len,
2642                              GFP_ATOMIC);
2643 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
2644 }
2645
2646 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
2647 {
2648         int ret = 0;
2649
2650         DBG_8723A("%s\n", __func__);
2651
2652         return ret;
2653 }
2654
2655 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
2656 {
2657         int ret = 0;
2658
2659         DBG_8723A("%s\n", __func__);
2660
2661         return ret;
2662 }
2663
2664 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb,
2665                                               struct net_device *ndev)
2666 {
2667         int ret = 0;
2668         int rtap_len;
2669         int qos_len = 0;
2670         int dot11_hdr_len = 24;
2671         int snap_len = 6;
2672         unsigned char *pdata;
2673         unsigned char src_mac_addr[6];
2674         unsigned char dst_mac_addr[6];
2675         struct ieee80211_hdr *dot11_hdr;
2676         struct ieee80211_radiotap_header *rtap_hdr;
2677         struct rtw_adapter *padapter = netdev_priv(ndev);
2678
2679         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
2680
2681         if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
2682                 goto fail;
2683
2684         rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
2685         if (unlikely(rtap_hdr->it_version))
2686                 goto fail;
2687
2688         rtap_len = ieee80211_get_radiotap_len(skb->data);
2689         if (unlikely(skb->len < rtap_len))
2690                 goto fail;
2691
2692         if (rtap_len != 14) {
2693                 DBG_8723A("radiotap len (should be 14): %d\n", rtap_len);
2694                 goto fail;
2695         }
2696
2697         /* Skip the ratio tap header */
2698         skb_pull(skb, rtap_len);
2699
2700         dot11_hdr = (struct ieee80211_hdr *)skb->data;
2701         /* Check if the QoS bit is set */
2702         if (ieee80211_is_data(dot11_hdr->frame_control)) {
2703                 /* Check if this ia a Wireless Distribution System (WDS) frame
2704                  * which has 4 MAC addresses
2705                  */
2706                 if (ieee80211_is_data_qos(dot11_hdr->frame_control))
2707                         qos_len = IEEE80211_QOS_CTL_LEN;
2708                 if (ieee80211_has_a4(dot11_hdr->frame_control))
2709                         dot11_hdr_len += 6;
2710
2711                 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
2712                 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
2713
2714                 /*
2715                  * Skip the 802.11 header, QoS (if any) and SNAP,
2716                  * but leave spaces for two MAC addresses
2717                  */
2718                 skb_pull(skb, dot11_hdr_len + qos_len + snap_len -
2719                          ETH_ALEN * 2);
2720                 pdata = (unsigned char *)skb->data;
2721                 memcpy(pdata, dst_mac_addr, ETH_ALEN);
2722                 memcpy(pdata + ETH_ALEN, src_mac_addr, ETH_ALEN);
2723
2724                 DBG_8723A("should be eapol packet\n");
2725
2726                 /* Use the real net device to transmit the packet */
2727                 ret = rtw_xmit23a_entry23a(skb, padapter->pnetdev);
2728
2729                 return ret;
2730
2731         } else if (ieee80211_is_action(dot11_hdr->frame_control)) {
2732                 /* only for action frames */
2733                 struct xmit_frame *pmgntframe;
2734                 struct pkt_attrib *pattrib;
2735                 unsigned char *pframe;
2736                 /* u8 category, action, OUI_Subtype, dialogToken = 0; */
2737                 /* unsigned char        *frame_body; */
2738                 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2739                 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2740                 u32 len = skb->len;
2741                 u8 category, action;
2742 #ifdef CONFIG_8723AU_P2P
2743                 int type = -1;
2744 #endif
2745
2746                 if (rtw_action_frame_parse23a(skb->data, len, &category,
2747                                            &action) == false) {
2748                         DBG_8723A(FUNC_NDEV_FMT " frame_control:0x%x\n",
2749                                   FUNC_NDEV_ARG(ndev),
2750                                   le16_to_cpu(dot11_hdr->frame_control));
2751                         goto fail;
2752                 }
2753
2754                 DBG_8723A("RTW_Tx:da =" MAC_FMT " via " FUNC_NDEV_FMT "\n",
2755                           MAC_ARG(dot11_hdr->addr1), FUNC_NDEV_ARG(ndev));
2756 #ifdef CONFIG_8723AU_P2P
2757                 type = rtw_p2p_check_frames(padapter, skb->data, len, true);
2758                 if (type >= 0)
2759                         goto dump;
2760 #endif
2761                 if (category == WLAN_CATEGORY_PUBLIC)
2762                         DBG_8723A("RTW_Tx:%s\n", action_public_str23a(action));
2763                 else
2764                         DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category,
2765                                   action);
2766 #ifdef CONFIG_8723AU_P2P
2767 dump:
2768 #endif
2769                 /* starting alloc mgmt frame to dump it */
2770                 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2771                 if (pmgntframe == NULL)
2772                         goto fail;
2773
2774                 /* update attribute */
2775                 pattrib = &pmgntframe->attrib;
2776                 update_mgntframe_attrib23a(padapter, pattrib);
2777                 pattrib->retry_ctrl = false;
2778
2779                 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2780
2781                 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2782
2783                 memcpy(pframe, skb->data, len);
2784 #ifdef CONFIG_8723AU_P2P
2785                 if (type >= 0) {
2786                         struct wifi_display_info *pwfd_info;
2787
2788                         pwfd_info = padapter->wdinfo.wfd_info;
2789
2790                         if (pwfd_info->wfd_enable)
2791                                 rtw_append_wfd_ie(padapter, pframe, &len);
2792                 }
2793 #endif /*  CONFIG_8723AU_P2P */
2794                 pattrib->pktlen = len;
2795
2796                 /* update seq number */
2797                 pmlmeext->mgnt_seq = le16_to_cpu(dot11_hdr->seq_ctrl) >> 4;
2798                 pattrib->seqnum = pmlmeext->mgnt_seq;
2799                 pmlmeext->mgnt_seq++;
2800
2801                 pattrib->last_txcmdsz = pattrib->pktlen;
2802
2803                 dump_mgntframe23a(padapter, pmgntframe);
2804         }
2805
2806 fail:
2807
2808         dev_kfree_skb(skb);
2809
2810         return 0;
2811 }
2812
2813 static int
2814 rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
2815 {
2816         int ret = 0;
2817
2818         DBG_8723A("%s\n", __func__);
2819
2820         return ret;
2821 }
2822
2823 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
2824         .ndo_open = rtw_cfg80211_monitor_if_open,
2825         .ndo_stop = rtw_cfg80211_monitor_if_close,
2826         .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
2827         .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
2828 };
2829
2830 static int rtw_cfg80211_add_monitor_if(struct rtw_adapter *padapter, char *name,
2831                                        struct net_device **ndev)
2832 {
2833         int ret = 0;
2834         struct net_device *mon_ndev = NULL;
2835         struct wireless_dev *mon_wdev = NULL;
2836         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
2837
2838         if (!name) {
2839                 DBG_8723A(FUNC_ADPT_FMT " without specific name\n",
2840                           FUNC_ADPT_ARG(padapter));
2841                 ret = -EINVAL;
2842                 goto out;
2843         }
2844
2845         if (pwdev_priv->pmon_ndev) {
2846                 DBG_8723A(FUNC_ADPT_FMT " monitor interface exist: " NDEV_FMT
2847                           "\n", FUNC_ADPT_ARG(padapter),
2848                           NDEV_ARG(pwdev_priv->pmon_ndev));
2849                 ret = -EBUSY;
2850                 goto out;
2851         }
2852
2853         mon_ndev = alloc_etherdev(sizeof(struct rtw_adapter));
2854         if (!mon_ndev) {
2855                 DBG_8723A(FUNC_ADPT_FMT " allocate ndev fail\n",
2856                           FUNC_ADPT_ARG(padapter));
2857                 ret = -ENOMEM;
2858                 goto out;
2859         }
2860
2861         mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
2862         strncpy(mon_ndev->name, name, IFNAMSIZ);
2863         mon_ndev->name[IFNAMSIZ - 1] = 0;
2864         mon_ndev->destructor = rtw_ndev_destructor;
2865
2866         mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
2867
2868         /*  wdev */
2869         mon_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2870         if (!mon_wdev) {
2871                 DBG_8723A(FUNC_ADPT_FMT " allocate mon_wdev fail\n",
2872                           FUNC_ADPT_ARG(padapter));
2873                 ret = -ENOMEM;
2874                 goto out;
2875         }
2876
2877         mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
2878         mon_wdev->netdev = mon_ndev;
2879         mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
2880         mon_ndev->ieee80211_ptr = mon_wdev;
2881
2882         ret = register_netdevice(mon_ndev);
2883         if (ret) {
2884                 goto out;
2885         }
2886
2887         *ndev = pwdev_priv->pmon_ndev = mon_ndev;
2888         memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ + 1);
2889
2890 out:
2891         if (ret) {
2892                 kfree(mon_wdev);
2893                 mon_wdev = NULL;
2894         }
2895
2896         if (ret && mon_ndev) {
2897                 free_netdev(mon_ndev);
2898                 *ndev = mon_ndev = NULL;
2899         }
2900
2901         return ret;
2902 }
2903
2904 static struct wireless_dev *
2905 cfg80211_rtw_add_virtual_intf(struct wiphy *wiphy, const char *name,
2906                               enum nl80211_iftype type, u32 *flags,
2907                               struct vif_params *params)
2908 {
2909         int ret = 0;
2910         struct net_device *ndev = NULL;
2911         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2912
2913         DBG_8723A(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
2914                   FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
2915
2916         switch (type) {
2917         case NL80211_IFTYPE_ADHOC:
2918         case NL80211_IFTYPE_AP_VLAN:
2919         case NL80211_IFTYPE_WDS:
2920         case NL80211_IFTYPE_MESH_POINT:
2921                 ret = -ENODEV;
2922                 break;
2923         case NL80211_IFTYPE_MONITOR:
2924                 ret =
2925                     rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
2926                 break;
2927
2928         case NL80211_IFTYPE_P2P_CLIENT:
2929         case NL80211_IFTYPE_STATION:
2930                 ret = -ENODEV;
2931                 break;
2932
2933         case NL80211_IFTYPE_P2P_GO:
2934         case NL80211_IFTYPE_AP:
2935                 ret = -ENODEV;
2936                 break;
2937         default:
2938                 ret = -ENODEV;
2939                 DBG_8723A("Unsupported interface type\n");
2940                 break;
2941         }
2942
2943         DBG_8723A(FUNC_ADPT_FMT " ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter),
2944                   ndev, ret);
2945
2946         return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
2947 }
2948
2949 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
2950                                          struct wireless_dev *wdev)
2951 {
2952         struct rtw_wdev_priv *pwdev_priv =
2953             (struct rtw_wdev_priv *)wiphy_priv(wiphy);
2954         struct net_device *ndev;
2955         ndev = wdev ? wdev->netdev : NULL;
2956
2957         if (!ndev)
2958                 goto exit;
2959
2960         unregister_netdevice(ndev);
2961
2962         if (ndev == pwdev_priv->pmon_ndev) {
2963                 pwdev_priv->pmon_ndev = NULL;
2964                 pwdev_priv->ifname_mon[0] = '\0';
2965                 DBG_8723A(FUNC_NDEV_FMT " remove monitor interface\n",
2966                           FUNC_NDEV_ARG(ndev));
2967         }
2968
2969 exit:
2970         return 0;
2971 }
2972
2973 static int rtw_add_beacon(struct rtw_adapter *adapter, const u8 *head,
2974                           size_t head_len, const u8 *tail, size_t tail_len)
2975 {
2976         int ret = 0;
2977         u8 *pbuf = NULL;
2978         uint len, wps_ielen = 0;
2979 #ifdef CONFIG_8723AU_P2P
2980         uint p2p_ielen = 0;
2981         u8 got_p2p_ie = false;
2982 #endif
2983         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2984         /* struct sta_priv *pstapriv = &padapter->stapriv; */
2985
2986         DBG_8723A("%s beacon_head_len =%zu, beacon_tail_len =%zu\n",
2987                   __func__, head_len, tail_len);
2988
2989         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2990                 return -EINVAL;
2991
2992         if (head_len < 24)
2993                 return -EINVAL;
2994
2995         pbuf = kzalloc(head_len + tail_len, GFP_KERNEL);
2996         if (!pbuf)
2997                 return -ENOMEM;
2998         /*  24 = beacon header len. */
2999         memcpy(pbuf, (void *)head + 24, head_len - 24);
3000         memcpy(pbuf + head_len - 24, (void *)tail, tail_len);
3001
3002         len = head_len + tail_len - 24;
3003
3004         /* check wps ie if inclued */
3005         if (rtw_get_wps_ie23a
3006             (pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL,
3007              &wps_ielen))
3008                 DBG_8723A("add bcn, wps_ielen =%d\n", wps_ielen);
3009
3010 #ifdef CONFIG_8723AU_P2P
3011         /* check p2p ie if inclued */
3012         if (rtw_get_p2p_ie23a
3013             (pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL,
3014              &p2p_ielen)) {
3015                 DBG_8723A("got p2p_ie, len =%d\n", p2p_ielen);
3016                 got_p2p_ie = true;
3017         }
3018 #endif
3019
3020         /* pbss_network->IEs will not include p2p_ie, wfd ie */
3021         rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_,
3022                           P2P_OUI23A, 4);
3023         rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_,
3024                           WFD_OUI23A, 4);
3025
3026         if (rtw_check_beacon_data23a(adapter, pbuf, len) == _SUCCESS) {
3027 #ifdef CONFIG_8723AU_P2P
3028                 /* check p2p if enable */
3029                 if (got_p2p_ie == true) {
3030                         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3031                         struct wifidirect_info *pwdinfo = &adapter->wdinfo;
3032
3033                         if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
3034                                 DBG_8723A("Enable P2P function for the first "
3035                                           "time\n");
3036                                 rtw_p2p_enable23a(adapter, P2P_ROLE_GO);
3037                                 wdev_to_priv(adapter->rtw_wdev)->p2p_enabled =
3038                                         true;
3039                         } else {
3040                                 del_timer_sync(&pwdinfo->find_phase_timer);
3041                                 del_timer_sync(&pwdinfo->
3042                                                restore_p2p_state_timer);
3043                                 del_timer_sync(&pwdinfo->pre_tx_scan_timer);
3044
3045                                 DBG_8723A("enter GO Mode, p2p_ielen =%d\n",
3046                                           p2p_ielen);
3047
3048                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
3049                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
3050                                 pwdinfo->intent = 15;
3051                         }
3052
3053                         pwdinfo->operating_channel = pmlmeext->cur_channel;
3054                 }
3055 #endif /* CONFIG_8723AU_P2P */
3056
3057                 ret = 0;
3058
3059         } else {
3060                 ret = -EINVAL;
3061         }
3062
3063         kfree(pbuf);
3064
3065         return ret;
3066 }
3067
3068 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3069                                  struct cfg80211_ap_settings *settings)
3070 {
3071         int ret = 0;
3072         struct rtw_adapter *adapter = wiphy_to_adapter(wiphy);
3073
3074         DBG_8723A(FUNC_NDEV_FMT " hidden_ssid:%d, auth_type:%d\n",
3075                   FUNC_NDEV_ARG(ndev), settings->hidden_ssid,
3076                   settings->auth_type);
3077
3078         ret = rtw_add_beacon(adapter, settings->beacon.head,
3079                              settings->beacon.head_len, settings->beacon.tail,
3080                              settings->beacon.tail_len);
3081
3082         adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode =
3083                 settings->hidden_ssid;
3084
3085         if (settings->ssid && settings->ssid_len) {
3086                 struct wlan_bssid_ex *pbss_network =
3087                         &adapter->mlmepriv.cur_network.network;
3088                 struct wlan_bssid_ex *pbss_network_ext =
3089                         &adapter->mlmeextpriv.mlmext_info.network;
3090
3091                 if (0)
3092                         DBG_8723A(FUNC_ADPT_FMT
3093                                   " ssid:(%s,%d), from ie:(%s,%d)\n",
3094                                   FUNC_ADPT_ARG(adapter), settings->ssid,
3095                                   (int)settings->ssid_len,
3096                                   pbss_network->Ssid.ssid,
3097                                   pbss_network->Ssid.ssid_len);
3098
3099                 memcpy(pbss_network->Ssid.ssid, (void *)settings->ssid,
3100                        settings->ssid_len);
3101                 pbss_network->Ssid.ssid_len = settings->ssid_len;
3102                 memcpy(pbss_network_ext->Ssid.ssid, (void *)settings->ssid,
3103                        settings->ssid_len);
3104                 pbss_network_ext->Ssid.ssid_len = settings->ssid_len;
3105
3106                 if (0)
3107                         DBG_8723A(FUNC_ADPT_FMT
3108                                   " after ssid:(%s,%d), (%s,%d)\n",
3109                                   FUNC_ADPT_ARG(adapter),
3110                                   pbss_network->Ssid.ssid,
3111                                   pbss_network->Ssid.ssid_len,
3112                                   pbss_network_ext->Ssid.ssid,
3113                                   pbss_network_ext->Ssid.ssid_len);
3114         }
3115
3116         return ret;
3117 }
3118
3119 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy,
3120                                       struct net_device *ndev,
3121                                       struct cfg80211_beacon_data *info)
3122 {
3123         int ret = 0;
3124         struct rtw_adapter *adapter = wiphy_to_adapter(wiphy);
3125
3126         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3127
3128         ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail,
3129                              info->tail_len);
3130
3131         return ret;
3132 }
3133
3134 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3135 {
3136         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3137         return 0;
3138 }
3139
3140 static int cfg80211_rtw_add_station(struct wiphy *wiphy,
3141                                     struct net_device *ndev, u8 *mac,
3142                                     struct station_parameters *params)
3143 {
3144         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3145
3146         return 0;
3147 }
3148
3149 static int cfg80211_rtw_del_station(struct wiphy *wiphy,
3150                                     struct net_device *ndev, u8 *mac)
3151 {
3152         int ret = 0;
3153         struct list_head *phead, *plist, *ptmp;
3154         u8 updated = 0;
3155         struct sta_info *psta;
3156         struct rtw_adapter *padapter = netdev_priv(ndev);
3157         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3158         struct sta_priv *pstapriv = &padapter->stapriv;
3159
3160         DBG_8723A("+" FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3161
3162         if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != true) {
3163                 DBG_8723A("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n",
3164                           __func__);
3165                 return -EINVAL;
3166         }
3167
3168         if (!mac) {
3169                 DBG_8723A("flush all sta, and cam_entry\n");
3170
3171                 flush_all_cam_entry23a(padapter);       /* clear CAM */
3172
3173                 ret = rtw_sta_flush23a(padapter);
3174
3175                 return ret;
3176         }
3177
3178         DBG_8723A("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
3179
3180         if (is_broadcast_ether_addr(mac))
3181                 return -EINVAL;
3182
3183         spin_lock_bh(&pstapriv->asoc_list_lock);
3184
3185         phead = &pstapriv->asoc_list;
3186
3187         /* check asoc_queue */
3188         list_for_each_safe(plist, ptmp, phead) {
3189                 psta = container_of(plist, struct sta_info, asoc_list);
3190
3191                 if (!memcmp(mac, psta->hwaddr, ETH_ALEN)) {
3192                         if (psta->dot8021xalg == 1 &&
3193                             psta->bpairwise_key_installed == false) {
3194                                 DBG_8723A("%s, sta's dot8021xalg = 1 and "
3195                                           "key_installed = false\n", __func__);
3196                         } else {
3197                                 DBG_8723A("free psta =%p, aid =%d\n", psta,
3198                                           psta->aid);
3199
3200                                 list_del_init(&psta->asoc_list);
3201                                 pstapriv->asoc_list_cnt--;
3202
3203                                 /* spin_unlock_bh(&pstapriv->asoc_list_lock); */
3204                                 updated =
3205                                     ap_free_sta23a(padapter, psta, true,
3206                                                 WLAN_REASON_DEAUTH_LEAVING);
3207                                 /* spin_lock_bh(&pstapriv->asoc_list_lock); */
3208
3209                                 psta = NULL;
3210
3211                                 break;
3212                         }
3213                 }
3214         }
3215
3216         spin_unlock_bh(&pstapriv->asoc_list_lock);
3217
3218         associated_clients_update23a(padapter, updated);
3219
3220         DBG_8723A("-" FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3221
3222         return ret;
3223 }
3224
3225 static int cfg80211_rtw_change_station(struct wiphy *wiphy,
3226                                        struct net_device *ndev, u8 *mac,
3227                                        struct station_parameters *params)
3228 {
3229         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3230         return 0;
3231 }
3232
3233 static int cfg80211_rtw_dump_station(struct wiphy *wiphy,
3234                                      struct net_device *ndev, int idx, u8 *mac,
3235                                      struct station_info *sinfo)
3236 {
3237         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3238
3239         /* TODO: dump scanned queue */
3240
3241         return -ENOENT;
3242 }
3243
3244 static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
3245                                    struct bss_parameters *params)
3246 {
3247         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3248         return 0;
3249 }
3250 #endif /* CONFIG_8723AU_AP_MODE */
3251
3252 void rtw_cfg80211_rx_action_p2p(struct rtw_adapter *padapter, u8 *pmgmt_frame,
3253                                 uint frame_len)
3254 {
3255 #ifdef CONFIG_8723AU_P2P
3256         int type;
3257 #endif
3258         s32 freq;
3259         int channel;
3260         u8 category, action;
3261
3262         channel = rtw_get_oper_ch23a(padapter);
3263
3264         DBG_8723A("RTW_Rx:cur_ch =%d\n", channel);
3265 #ifdef CONFIG_8723AU_P2P
3266         type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, false);
3267         if (type >= 0)
3268                 goto indicate;
3269 #endif
3270         rtw_action_frame_parse23a(pmgmt_frame, frame_len, &category, &action);
3271         DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action);
3272
3273 #ifdef CONFIG_8723AU_P2P
3274 indicate:
3275 #endif
3276         if (channel <= RTW_CH_MAX_2G_CHANNEL)
3277                 freq = ieee80211_channel_to_frequency(channel,
3278                                                       IEEE80211_BAND_2GHZ);
3279         else
3280                 freq = ieee80211_channel_to_frequency(channel,
3281                                                       IEEE80211_BAND_5GHZ);
3282
3283         rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len,
3284                              GFP_ATOMIC);
3285 }
3286
3287 void rtw_cfg80211_rx_p2p_action_public(struct rtw_adapter *padapter,
3288                                        u8 *pmgmt_frame, uint frame_len)
3289 {
3290 #ifdef CONFIG_8723AU_P2P
3291         int type;
3292 #endif
3293         s32 freq;
3294         int channel;
3295         u8 category, action;
3296
3297         channel = rtw_get_oper_ch23a(padapter);
3298
3299         DBG_8723A("RTW_Rx:cur_ch =%d\n", channel);
3300 #ifdef CONFIG_8723AU_P2P
3301         type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, false);
3302         if (type >= 0) {
3303                 switch (type) {
3304                 case P2P_GO_NEGO_CONF:
3305                 case P2P_PROVISION_DISC_RESP:
3306                         rtw_clear_scan_deny(padapter);
3307                 }
3308                 goto indicate;
3309         }
3310 #endif
3311         rtw_action_frame_parse23a(pmgmt_frame, frame_len, &category, &action);
3312         DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action);
3313
3314 #ifdef CONFIG_8723AU_P2P
3315 indicate:
3316 #endif
3317         if (channel <= RTW_CH_MAX_2G_CHANNEL)
3318                 freq = ieee80211_channel_to_frequency(channel,
3319                                                       IEEE80211_BAND_2GHZ);
3320         else
3321                 freq = ieee80211_channel_to_frequency(channel,
3322                                                       IEEE80211_BAND_5GHZ);
3323
3324         rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len,
3325                              GFP_ATOMIC);
3326 }
3327
3328 void rtw_cfg80211_rx_action(struct rtw_adapter *adapter, u8 *frame,
3329                             uint frame_len, const char *msg)
3330 {
3331         s32 freq;
3332         int channel;
3333         u8 category, action;
3334
3335         channel = rtw_get_oper_ch23a(adapter);
3336
3337         rtw_action_frame_parse23a(frame, frame_len, &category, &action);
3338
3339         DBG_8723A("RTW_Rx:cur_ch =%d\n", channel);
3340         if (msg)
3341                 DBG_8723A("RTW_Rx:%s\n", msg);
3342         else
3343                 DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category,
3344                           action);
3345
3346         if (channel <= RTW_CH_MAX_2G_CHANNEL)
3347                 freq = ieee80211_channel_to_frequency(channel,
3348                                                       IEEE80211_BAND_2GHZ);
3349         else
3350                 freq = ieee80211_channel_to_frequency(channel,
3351                                                       IEEE80211_BAND_5GHZ);
3352
3353         rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
3354 }
3355
3356 #ifdef CONFIG_8723AU_P2P
3357 void rtw_cfg80211_issue_p2p_provision_request23a(struct rtw_adapter *padapter,
3358                                               const u8 *buf, size_t len)
3359 {
3360         u16 wps_devicepassword_id = 0x0000;
3361         uint wps_devicepassword_id_len = 0;
3362         u8 wpsie[255] = { 0x00 }, p2p_ie[255] = { 0x00 };
3363         uint p2p_ielen = 0;
3364         uint wpsielen = 0;
3365         u32 devinfo_contentlen = 0;
3366         u8 devinfo_content[64] = { 0x00 };
3367         u16 capability = 0;
3368         uint capability_len = 0;
3369
3370         unsigned char category = WLAN_CATEGORY_PUBLIC;
3371         u8 action = P2P_PUB_ACTION_ACTION;
3372         u8 dialogToken = 1;
3373         u32 p2poui = cpu_to_be32(P2POUI);
3374         u8 oui_subtype = P2P_PROVISION_DISC_REQ;
3375         u32 p2pielen = 0;
3376 #ifdef CONFIG_8723AU_P2P
3377         u32 wfdielen = 0;
3378 #endif /* CONFIG_8723AU_P2P */
3379
3380         struct xmit_frame *pmgntframe;
3381         struct pkt_attrib *pattrib;
3382         unsigned char *pframe;
3383         struct ieee80211_hdr *pwlanhdr, *hdr;
3384         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3385         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3386
3387         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3388         u8 *frame_body =
3389             (unsigned char *)(buf + sizeof(struct ieee80211_hdr_3addr));
3390         size_t frame_body_len = len - sizeof(struct ieee80211_hdr_3addr);
3391
3392         DBG_8723A("[%s] In\n", __func__);
3393
3394         hdr = (struct ieee80211_hdr *)buf;
3395         /* prepare for building provision_request frame */
3396         memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, hdr->addr1, ETH_ALEN);
3397         memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, hdr->addr1, ETH_ALEN);
3398
3399         pwdinfo->tx_prov_disc_info.wps_config_method_request =
3400             WPS_CM_PUSH_BUTTON;
3401
3402         rtw_get_wps_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_,
3403                        frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie,
3404                        &wpsielen);
3405         rtw_get_wps_attr_content23a(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID,
3406                                     (u8 *)&wps_devicepassword_id,
3407                                     &wps_devicepassword_id_len);
3408         wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
3409
3410         switch (wps_devicepassword_id) {
3411         case WPS_DPID_PIN:
3412                 pwdinfo->tx_prov_disc_info.wps_config_method_request =
3413                         WPS_CM_LABEL;
3414                 break;
3415         case WPS_DPID_USER_SPEC:
3416                 pwdinfo->tx_prov_disc_info.wps_config_method_request =
3417                         WPS_CM_DISPLYA;
3418                 break;
3419         case WPS_DPID_MACHINE_SPEC:
3420                 break;
3421         case WPS_DPID_REKEY:
3422                 break;
3423         case WPS_DPID_PBC:
3424                 pwdinfo->tx_prov_disc_info.wps_config_method_request =
3425                         WPS_CM_PUSH_BUTTON;
3426                 break;
3427         case WPS_DPID_REGISTRAR_SPEC:
3428                 pwdinfo->tx_prov_disc_info.wps_config_method_request =
3429                         WPS_CM_KEYPAD;
3430                 break;
3431         default:
3432                 break;
3433         }
3434
3435         if (rtw_get_p2p_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_,
3436                            frame_body_len - _PUBLIC_ACTION_IE_OFFSET_,
3437                            p2p_ie, &p2p_ielen)) {
3438                 rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen,
3439                                          P2P_ATTR_DEVICE_INFO, devinfo_content,
3440                                          &devinfo_contentlen);
3441                 rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY,
3442                                          (u8 *)&capability, &capability_len);
3443         }
3444
3445         /* start to build provision_request frame */
3446         memset(wpsie, 0, sizeof(wpsie));
3447         memset(p2p_ie, 0, sizeof(p2p_ie));
3448         p2p_ielen = 0;
3449
3450         pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3451         if (pmgntframe == NULL)
3452                 return;
3453         /* update attribute */
3454         pattrib = &pmgntframe->attrib;
3455         update_mgntframe_attrib23a(padapter, pattrib);
3456
3457         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3458
3459         pframe = (u8 *) (pmgntframe->buf_addr) + TXDESC_OFFSET;
3460         pwlanhdr = (struct ieee80211_hdr *)pframe;
3461
3462         pwlanhdr->frame_control = 0;
3463
3464         memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr,
3465                ETH_ALEN);
3466         memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
3467         memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr,
3468                ETH_ALEN);
3469
3470         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3471         pmlmeext->mgnt_seq++;
3472         SetFrameSubType(pframe, WIFI_ACTION);
3473
3474         pframe += sizeof(struct ieee80211_hdr_3addr);
3475         pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3476
3477         pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
3478         pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
3479         pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *)&p2poui,
3480                                   &pattrib->pktlen);
3481         pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
3482         pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
3483
3484         /* build_prov_disc_request_p2p_ie23a */
3485         /*      P2P OUI */
3486         p2pielen = 0;
3487         p2p_ie[p2pielen++] = 0x50;
3488         p2p_ie[p2pielen++] = 0x6F;
3489         p2p_ie[p2pielen++] = 0x9A;
3490         p2p_ie[p2pielen++] = 0x09;      /*      WFA P2P v1.0 */
3491
3492         /*      Commented by Albert 20110301 */
3493         /*      According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes */
3494         /*      1. P2P Capability */
3495         /*      2. Device Info */
3496         /*      3. Group ID ( When joining an operating P2P Group ) */
3497
3498         /*      P2P Capability ATTR */
3499         /*      Type: */
3500         p2p_ie[p2pielen++] = P2P_ATTR_CAPABILITY;
3501
3502         /*      Length: */
3503         put_unaligned_le16(0x0002, p2p_ie + p2pielen);
3504         p2pielen += 2;
3505
3506         /*      Value: */
3507         /*      Device Capability Bitmap, 1 byte */
3508         /*      Group Capability Bitmap, 1 byte */
3509         memcpy(p2p_ie + p2pielen, &capability, 2);
3510         p2pielen += 2;
3511
3512         /*      Device Info ATTR */
3513         /*      Type: */
3514         p2p_ie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
3515
3516         /*      Length: */
3517         put_unaligned_le16(devinfo_contentlen, p2p_ie + p2pielen);
3518         p2pielen += 2;
3519
3520         /*      Value: */
3521         memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
3522         p2pielen += devinfo_contentlen;
3523
3524         pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
3525                             (unsigned char *)p2p_ie, &p2p_ielen);
3526         pattrib->pktlen += p2p_ielen;
3527
3528         wpsielen = 0;
3529         /*      WPS OUI */
3530         *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
3531         wpsielen += 4;
3532
3533         /*      WPS version */
3534         /*      Type: */
3535         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
3536         wpsielen += 2;
3537
3538         /*      Length: */
3539         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
3540         wpsielen += 2;
3541
3542         /*      Value: */
3543         wpsie[wpsielen++] = WPS_VERSION_1;      /*      Version 1.0 */
3544
3545         /*      Config Method */
3546         /*      Type: */
3547         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
3548         wpsielen += 2;
3549
3550         /*      Length: */
3551         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
3552         wpsielen += 2;
3553
3554         /*      Value: */
3555         *(u16 *)(wpsie + wpsielen) =
3556             cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
3557         wpsielen += 2;
3558
3559         pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen,
3560                             (unsigned char *)wpsie, &pattrib->pktlen);
3561
3562 #ifdef CONFIG_8723AU_P2P
3563         wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
3564         pframe += wfdielen;
3565         pattrib->pktlen += wfdielen;
3566 #endif /* CONFIG_8723AU_P2P */
3567
3568         pattrib->last_txcmdsz = pattrib->pktlen;
3569
3570         /* dump_mgntframe23a(padapter, pmgntframe); */
3571         if (dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe) != _SUCCESS)
3572                 DBG_8723A("%s, ack to\n", __func__);
3573 }
3574
3575 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
3576                                           struct wireless_dev *wdev,
3577                                           struct ieee80211_channel *channel,
3578                                           unsigned int duration, u64 *cookie)
3579 {
3580         s32 err = 0;
3581         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
3582         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3583         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3584         struct cfg80211_wifidirect_info *pcfg80211_wdinfo =
3585             &padapter->cfg80211_wdinfo;
3586         u8 remain_ch =
3587                 (u8) ieee80211_frequency_to_channel(channel->center_freq);
3588         u8 ready_on_channel = false;
3589
3590         DBG_8723A(FUNC_ADPT_FMT " ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter),
3591                   remain_ch, duration);
3592
3593         if (pcfg80211_wdinfo->is_ro_ch == true) {
3594                 DBG_8723A("%s, cancel ro ch timer\n", __func__);
3595
3596                 del_timer_sync(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
3597
3598 #ifdef CONFIG_8723AU_P2P
3599                 p2p_protocol_wk_hdl23a(padapter, P2P_RO_CH_WK);
3600 #endif
3601         }
3602
3603         pcfg80211_wdinfo->is_ro_ch = true;
3604
3605         if (_FAIL == rtw_pwr_wakeup(padapter)) {
3606                 err = -EFAULT;
3607                 goto exit;
3608         }
3609
3610         memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel,
3611                sizeof(struct ieee80211_channel));
3612         pcfg80211_wdinfo->remain_on_ch_cookie = *cookie;
3613
3614         rtw_scan_abort23a(padapter);
3615         if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
3616                 rtw_p2p_enable23a(padapter, P2P_ROLE_DEVICE);
3617                 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = true;
3618         } else {
3619                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
3620 #ifdef CONFIG_DEBUG_CFG80211
3621                 DBG_8723A("%s, role =%d, p2p_state =%d\n", __func__,
3622                           rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
3623 #endif
3624         }
3625
3626         rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
3627
3628         if (duration < 400)
3629                 duration = duration * 3;        /* extend from exper. */
3630
3631         pcfg80211_wdinfo->restore_channel = pmlmeext->cur_channel;
3632
3633         if (rtw_ch_set_search_ch23a(pmlmeext->channel_set, remain_ch) >= 0) {
3634                 if (remain_ch != pmlmeext->cur_channel) {
3635                         ready_on_channel = true;
3636                 }
3637         } else {
3638                 DBG_8723A("%s remain_ch:%u not in channel plan!!!!\n",
3639                           __func__, remain_ch);
3640         }
3641
3642         /* call this after other things have been done */
3643         if (ready_on_channel == true) {
3644                 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
3645                         pmlmeext->cur_channel = remain_ch;
3646
3647                         set_channel_bwmode23a(padapter, remain_ch,
3648                                            HAL_PRIME_CHNL_OFFSET_DONT_CARE,
3649                                            HT_CHANNEL_WIDTH_20);
3650                 }
3651         }
3652         DBG_8723A("%s, set ro ch timer, duration =%d\n", __func__, duration);
3653         mod_timer(&pcfg80211_wdinfo->remain_on_ch_timer,
3654                   jiffies + msecs_to_jiffies(duration));
3655
3656         rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type,
3657                                       duration, GFP_KERNEL);
3658
3659         pwdinfo->listen_channel = pmlmeext->cur_channel;
3660
3661 exit:
3662         if (err)
3663                 pcfg80211_wdinfo->is_ro_ch = false;
3664
3665         return err;
3666 }
3667
3668 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
3669                                                  struct wireless_dev *wdev,
3670                                                  u64 cookie)
3671 {
3672         s32 err = 0;
3673         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
3674         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3675         struct cfg80211_wifidirect_info *pcfg80211_wdinfo =
3676             &padapter->cfg80211_wdinfo;
3677
3678         DBG_8723A(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter));
3679
3680         if (pcfg80211_wdinfo->is_ro_ch == true) {
3681                 DBG_8723A("%s, cancel ro ch timer\n", __func__);
3682                 del_timer_sync(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
3683 #ifdef CONFIG_8723AU_P2P
3684                 p2p_protocol_wk_hdl23a(padapter, P2P_RO_CH_WK);
3685 #endif
3686         }
3687
3688         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
3689 #ifdef CONFIG_DEBUG_CFG80211
3690         DBG_8723A("%s, role =%d, p2p_state =%d\n", __func__,
3691                   rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
3692 #endif
3693         pcfg80211_wdinfo->is_ro_ch = false;
3694
3695         return err;
3696 }
3697
3698 #endif /* CONFIG_8723AU_P2P */
3699
3700 static int _cfg80211_rtw_mgmt_tx(struct rtw_adapter *padapter, u8 tx_ch,
3701                                  const u8 *buf, size_t len)
3702 {
3703         struct xmit_frame *pmgntframe;
3704         struct pkt_attrib *pattrib;
3705         unsigned char *pframe;
3706         int ret = _FAIL;
3707         bool ack = true;
3708         struct ieee80211_hdr *pwlanhdr;
3709         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3710         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3711         /* struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; */
3712
3713         if (_FAIL == rtw_pwr_wakeup(padapter)) {
3714                 ret = -EFAULT;
3715                 goto exit;
3716         }
3717
3718         rtw_set_scan_deny(padapter, 1000);
3719
3720         rtw_scan_abort23a(padapter);
3721
3722         if (tx_ch != rtw_get_oper_ch23a(padapter)) {
3723                 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
3724                         pmlmeext->cur_channel = tx_ch;
3725                 set_channel_bwmode23a(padapter, tx_ch,
3726                                    HAL_PRIME_CHNL_OFFSET_DONT_CARE,
3727                                    HT_CHANNEL_WIDTH_20);
3728         }
3729
3730         /* starting alloc mgmt frame to dump it */
3731         pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3732         if (pmgntframe == NULL) {
3733                 /* ret = -ENOMEM; */
3734                 ret = _FAIL;
3735                 goto exit;
3736         }
3737
3738         /* update attribute */
3739         pattrib = &pmgntframe->attrib;
3740         update_mgntframe_attrib23a(padapter, pattrib);
3741         pattrib->retry_ctrl = false;
3742
3743         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3744
3745         pframe = (u8 *) (pmgntframe->buf_addr) + TXDESC_OFFSET;
3746
3747         memcpy(pframe, (void *)buf, len);
3748         pattrib->pktlen = len;
3749
3750         pwlanhdr = (struct ieee80211_hdr *)pframe;
3751         /* update seq number */
3752         pmlmeext->mgnt_seq = le16_to_cpu(pwlanhdr->seq_ctrl) >> 4;
3753         pattrib->seqnum = pmlmeext->mgnt_seq;
3754         pmlmeext->mgnt_seq++;
3755
3756 #ifdef CONFIG_8723AU_P2P
3757         {
3758                 struct wifi_display_info *pwfd_info;
3759
3760                 pwfd_info = padapter->wdinfo.wfd_info;
3761
3762                 if (true == pwfd_info->wfd_enable) {
3763                         rtw_append_wfd_ie(padapter, pframe, &pattrib->pktlen);
3764                 }
3765         }
3766 #endif /*  CONFIG_8723AU_P2P */
3767
3768         pattrib->last_txcmdsz = pattrib->pktlen;
3769
3770         if (dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe) != _SUCCESS) {
3771                 ack = false;
3772                 ret = _FAIL;
3773
3774 #ifdef CONFIG_DEBUG_CFG80211
3775                 DBG_8723A("%s, ack == _FAIL\n", __func__);
3776 #endif
3777         } else {
3778 #ifdef CONFIG_DEBUG_CFG80211
3779                 DBG_8723A("%s, ack =%d, ok!\n", __func__, ack);
3780 #endif
3781                 ret = _SUCCESS;
3782         }
3783
3784 exit:
3785
3786 #ifdef CONFIG_DEBUG_CFG80211
3787         DBG_8723A("%s, ret =%d\n", __func__, ret);
3788 #endif
3789
3790         return ret;
3791 }
3792
3793 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3794 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
3795                                 struct ieee80211_channel *chan,
3796                                 bool offchan,
3797                                 unsigned int wait,
3798                                 const u8 *buf, size_t len,
3799                                 bool no_cck, bool dont_wait_for_ack,
3800 #else
3801                                 struct cfg80211_mgmt_tx_params *params,
3802 #endif
3803                                 u64 *cookie)
3804 {
3805         struct rtw_adapter *padapter =
3806                 (struct rtw_adapter *)wiphy_to_adapter(wiphy);
3807         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
3808         int ret = 0;
3809         int tx_ret;
3810         u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
3811         u32 dump_cnt = 0;
3812         bool ack = true;
3813         u8 category, action;
3814         int type = (-1);
3815         unsigned long start = jiffies;
3816 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
3817         size_t len = params->len;
3818         struct ieee80211_channel *chan = params->chan;
3819         const u8 *buf = params->buf;
3820 #endif
3821         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)buf;
3822         u8 tx_ch = (u8) ieee80211_frequency_to_channel(chan->center_freq);
3823
3824         /* cookie generation */
3825         *cookie = (unsigned long)buf;
3826
3827 #ifdef CONFIG_DEBUG_CFG80211
3828         DBG_8723A(FUNC_ADPT_FMT " len =%zu, ch =%d"
3829                   "\n", FUNC_ADPT_ARG(padapter), len, tx_ch);
3830 #endif /* CONFIG_DEBUG_CFG80211 */
3831
3832         /* indicate ack before issue frame to avoid racing with rsp frame */
3833         rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack,
3834                                     GFP_KERNEL);
3835
3836         if (rtw_action_frame_parse23a(buf, len, &category, &action) == false) {
3837                 DBG_8723A(FUNC_ADPT_FMT " frame_control:0x%x\n",
3838                           FUNC_ADPT_ARG(padapter),
3839                           le16_to_cpu(hdr->frame_control));
3840                 goto exit;
3841         }
3842
3843         DBG_8723A("RTW_Tx:tx_ch =%d, da =" MAC_FMT "\n", tx_ch,
3844                   MAC_ARG(hdr->addr1));
3845 #ifdef CONFIG_8723AU_P2P
3846         type = rtw_p2p_check_frames(padapter, buf, len, true);
3847         if (type >= 0)
3848                 goto dump;
3849 #endif
3850         if (category == WLAN_CATEGORY_PUBLIC)
3851                 DBG_8723A("RTW_Tx:%s\n", action_public_str23a(action));
3852         else
3853                 DBG_8723A("RTW_Tx:category(%u), action(%u)\n",
3854                           category, action);
3855
3856 #ifdef CONFIG_8723AU_P2P
3857 dump:
3858 #endif
3859         do {
3860                 dump_cnt++;
3861                 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
3862         } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
3863
3864         if (tx_ret != _SUCCESS || dump_cnt > 1) {
3865                 DBG_8723A(FUNC_ADPT_FMT " %s (%d/%d) in %d ms\n",
3866                           FUNC_ADPT_ARG(padapter),
3867                           tx_ret == _SUCCESS ? "OK" : "FAIL", dump_cnt,
3868                           dump_limit, jiffies_to_msecs(jiffies - start));
3869         }
3870
3871         switch (type) {
3872         case P2P_GO_NEGO_CONF:
3873                 rtw_clear_scan_deny(padapter);
3874                 break;
3875         case P2P_INVIT_RESP:
3876                 if (pwdev_priv->invit_info.flags & BIT(0)
3877                     && pwdev_priv->invit_info.status == 0) {
3878                         DBG_8723A(FUNC_ADPT_FMT " agree with invitation of "
3879                                   "persistent group\n",
3880                                   FUNC_ADPT_ARG(padapter));
3881                         rtw_set_scan_deny(padapter, 5000);
3882                         rtw_pwr_wakeup_ex(padapter, 5000);
3883                         rtw_clear_scan_deny(padapter);
3884                 }
3885                 break;
3886         }
3887
3888 exit:
3889         return ret;
3890 }
3891
3892 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
3893                                              struct wireless_dev *wdev,
3894                                              u16 frame_type, bool reg)
3895 {
3896
3897 #ifdef CONFIG_DEBUG_CFG80211
3898         DBG_8723A(FUNC_ADPT_FMT " frame_type:%x, reg:%d\n",
3899                   FUNC_ADPT_ARG(adapter), frame_type, reg);
3900 #endif
3901
3902         if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
3903                 return;
3904
3905         return;
3906 }
3907
3908 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf,
3909                                             int len)
3910 {
3911         int ret = 0;
3912         uint wps_ielen = 0;
3913         u8 *wps_ie;
3914 #ifdef CONFIG_8723AU_P2P
3915         u32 p2p_ielen = 0;
3916         u32 wfd_ielen = 0;
3917         u8 *p2p_ie;
3918 #endif
3919 #ifdef CONFIG_8723AU_AP_MODE
3920         u8 wps_oui[8] = { 0x0, 0x50, 0xf2, 0x04 };
3921 #endif
3922         struct rtw_adapter *padapter = netdev_priv(ndev);
3923         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3924         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3925
3926         DBG_8723A(FUNC_NDEV_FMT " ielen =%d\n", FUNC_NDEV_ARG(ndev), len);
3927
3928         if (len > 0) {
3929                 wps_ie = rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen);
3930                 if (wps_ie) {
3931 #ifdef CONFIG_DEBUG_CFG80211
3932                         DBG_8723A("bcn_wps_ielen =%d\n", wps_ielen);
3933 #endif
3934
3935                         if (pmlmepriv->wps_beacon_ie) {
3936                                 pmlmepriv->wps_beacon_ie_len = 0;
3937                                 kfree(pmlmepriv->wps_beacon_ie);
3938                                 pmlmepriv->wps_beacon_ie = NULL;
3939                         }
3940
3941                         pmlmepriv->wps_beacon_ie =
3942                                 kmalloc(wps_ielen, GFP_KERNEL);
3943                         if (pmlmepriv->wps_beacon_ie == NULL) {
3944                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
3945                                           __func__, __LINE__);
3946                                 return -EINVAL;
3947                         }
3948                         memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
3949                         pmlmepriv->wps_beacon_ie_len = wps_ielen;
3950
3951 #ifdef CONFIG_8723AU_AP_MODE
3952                         update_beacon23a(padapter, _VENDOR_SPECIFIC_IE_, wps_oui,
3953                                       true);
3954 #endif
3955                 }
3956 #ifdef CONFIG_8723AU_P2P
3957                 p2p_ie = rtw_get_p2p_ie23a(buf, len, NULL, &p2p_ielen);
3958                 if (p2p_ie) {
3959 #ifdef CONFIG_DEBUG_CFG80211
3960                         DBG_8723A("bcn_p2p_ielen =%d\n", p2p_ielen);
3961 #endif
3962
3963                         if (pmlmepriv->p2p_beacon_ie) {
3964                                 pmlmepriv->p2p_beacon_ie_len = 0;
3965                                 kfree(pmlmepriv->p2p_beacon_ie);
3966                                 pmlmepriv->p2p_beacon_ie = NULL;
3967                         }
3968
3969                         pmlmepriv->p2p_beacon_ie =
3970                                 kmalloc(p2p_ielen, GFP_KERNEL);
3971                         if (pmlmepriv->p2p_beacon_ie == NULL) {
3972                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
3973                                           __func__, __LINE__);
3974                                 return -EINVAL;
3975                         }
3976
3977                         memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
3978                         pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
3979                 }
3980 #endif /* CONFIG_8723AU_P2P */
3981
3982                 /* buf += p2p_ielen; */
3983                 /* len -= p2p_ielen; */
3984
3985 #ifdef CONFIG_8723AU_P2P
3986                 if (rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) {
3987 #ifdef CONFIG_DEBUG_CFG80211
3988                         DBG_8723A("bcn_wfd_ielen =%d\n", wfd_ielen);
3989 #endif
3990
3991                         if (pmlmepriv->wfd_beacon_ie) {
3992                                 pmlmepriv->wfd_beacon_ie_len = 0;
3993                                 kfree(pmlmepriv->wfd_beacon_ie);
3994                                 pmlmepriv->wfd_beacon_ie = NULL;
3995                         }
3996
3997                         pmlmepriv->wfd_beacon_ie =
3998                                 kmalloc(wfd_ielen, GFP_KERNEL);
3999                         if (pmlmepriv->wfd_beacon_ie == NULL) {
4000                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
4001                                           __func__, __LINE__);
4002                                 return -EINVAL;
4003
4004                         }
4005                         rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie,
4006                                        &pmlmepriv->wfd_beacon_ie_len);
4007                 }
4008 #endif /* CONFIG_8723AU_P2P */
4009
4010                 pmlmeext->bstart_bss = true;
4011
4012         }
4013
4014         return ret;
4015 }
4016
4017 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net,
4018                                                 char *buf, int len)
4019 {
4020         struct rtw_adapter *padapter = netdev_priv(net);
4021         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4022 #ifdef CONFIG_8723AU_P2P
4023         u32 p2p_ielen = 0;
4024         u8 *p2p_ie;
4025         u32 wfd_ielen = 0;
4026 #endif
4027         int ret = 0;
4028         uint wps_ielen = 0;
4029         u8 *wps_ie;
4030
4031         if (len > 0) {
4032                 wps_ie = rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen);
4033                 if (wps_ie) {
4034                         uint attr_contentlen = 0;
4035                         u16 uconfig_method, *puconfig_method = NULL;
4036
4037                         if (pmlmepriv->wps_probe_resp_ie) {
4038                                 pmlmepriv->wps_probe_resp_ie_len = 0;
4039                                 kfree(pmlmepriv->wps_probe_resp_ie);
4040                                 pmlmepriv->wps_probe_resp_ie = NULL;
4041                         }
4042
4043                         pmlmepriv->wps_probe_resp_ie =
4044                                 kmalloc(wps_ielen, GFP_KERNEL);
4045                         if (pmlmepriv->wps_probe_resp_ie == NULL) {
4046                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
4047                                           __func__, __LINE__);
4048                                 return -EINVAL;
4049
4050                         }
4051
4052                         /* add PUSH_BUTTON config_method by driver self in
4053                            wpsie of probe_resp at GO Mode */
4054                         puconfig_method = (u16 *)rtw_get_wps_attr_content23a(wps_ie, wps_ielen,
4055                                                               WPS_ATTR_CONF_METHOD,
4056                                                               NULL,
4057                                                               &attr_contentlen);
4058                         if (puconfig_method) {
4059                                 uconfig_method = WPS_CM_PUSH_BUTTON;
4060                                 uconfig_method = cpu_to_be16(uconfig_method);
4061
4062                                 *puconfig_method |= uconfig_method;
4063                         }
4064
4065                         memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
4066                         pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
4067
4068                 }
4069
4070                 /* buf += wps_ielen; */
4071                 /* len -= wps_ielen; */
4072
4073 #ifdef CONFIG_8723AU_P2P
4074                 p2p_ie = rtw_get_p2p_ie23a(buf, len, NULL, &p2p_ielen);
4075                 if (p2p_ie) {
4076                         u8 is_GO = false;
4077                         u32 attr_contentlen = 0;
4078                         u16 cap_attr = 0;
4079
4080 #ifdef CONFIG_DEBUG_CFG80211
4081                         DBG_8723A("probe_resp_p2p_ielen =%d\n", p2p_ielen);
4082 #endif
4083
4084                         /* Check P2P Capability ATTR */
4085                         if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen,
4086                                                      P2P_ATTR_CAPABILITY,
4087                                                      (u8 *) &cap_attr,
4088                                                      (uint *) &attr_contentlen)) {
4089                                 u8 grp_cap = 0;
4090                                 /* DBG_8723A( "[%s] Got P2P Capability Attr!!\n", __func__ ); */
4091                                 cap_attr = le16_to_cpu(cap_attr);
4092                                 grp_cap = (u8) ((cap_attr >> 8) & 0xff);
4093
4094                                 is_GO = (grp_cap & BIT(0)) ? true : false;
4095
4096                                 if (is_GO)
4097                                         DBG_8723A
4098                                             ("Got P2P Capability Attr, grp_cap"
4099                                              "= 0x%x, is_GO\n", grp_cap);
4100                         }
4101
4102                         if (is_GO == false) {
4103                                 if (pmlmepriv->p2p_probe_resp_ie) {
4104                                         pmlmepriv->p2p_probe_resp_ie_len = 0;
4105                                         kfree(pmlmepriv->p2p_probe_resp_ie);
4106                                         pmlmepriv->p2p_probe_resp_ie = NULL;
4107                                 }
4108
4109                                 pmlmepriv->p2p_probe_resp_ie =
4110                                     kmalloc(p2p_ielen, GFP_KERNEL);
4111                                 if (pmlmepriv->p2p_probe_resp_ie == NULL) {
4112                                         DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
4113                                                   __func__, __LINE__);
4114                                         return -EINVAL;
4115                                 }
4116                                 memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie,
4117                                        p2p_ielen);
4118                                 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
4119                         } else {
4120                                 if (pmlmepriv->p2p_go_probe_resp_ie) {
4121                                         pmlmepriv->p2p_go_probe_resp_ie_len = 0;
4122                                         kfree(pmlmepriv->p2p_go_probe_resp_ie);
4123                                         pmlmepriv->p2p_go_probe_resp_ie = NULL;
4124                                 }
4125
4126                                 pmlmepriv->p2p_go_probe_resp_ie =
4127                                     kmalloc(p2p_ielen, GFP_KERNEL);
4128                                 if (pmlmepriv->p2p_go_probe_resp_ie == NULL) {
4129                                         DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
4130                                                   __func__, __LINE__);
4131                                         return -EINVAL;
4132
4133                                 }
4134                                 memcpy(pmlmepriv->p2p_go_probe_resp_ie,
4135                                        p2p_ie, p2p_ielen);
4136                                 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
4137                         }
4138                 }
4139 #endif /* CONFIG_8723AU_P2P */
4140
4141                 /* buf += p2p_ielen; */
4142                 /* len -= p2p_ielen; */
4143
4144 #ifdef CONFIG_8723AU_P2P
4145                 if (rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) {
4146 #ifdef CONFIG_DEBUG_CFG80211
4147                         DBG_8723A("probe_resp_wfd_ielen =%d\n", wfd_ielen);
4148 #endif
4149
4150                         if (pmlmepriv->wfd_probe_resp_ie) {
4151                                 pmlmepriv->wfd_probe_resp_ie_len = 0;
4152                                 kfree(pmlmepriv->wfd_probe_resp_ie);
4153                                 pmlmepriv->wfd_probe_resp_ie = NULL;
4154                         }
4155
4156                         pmlmepriv->wfd_probe_resp_ie =
4157                             kmalloc(wfd_ielen, GFP_KERNEL);
4158                         if (pmlmepriv->wfd_probe_resp_ie == NULL) {
4159                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
4160                                           __func__, __LINE__);
4161                                 return -EINVAL;
4162
4163                         }
4164                         rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie,
4165                                        &pmlmepriv->wfd_probe_resp_ie_len);
4166                 }
4167 #endif /* CONFIG_8723AU_P2P */
4168         }
4169
4170         return ret;
4171 }
4172
4173 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net,
4174                                                 char *buf, int len)
4175 {
4176         int ret = 0;
4177         struct rtw_adapter *padapter = netdev_priv(net);
4178         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4179
4180         DBG_8723A("%s, ielen =%d\n", __func__, len);
4181
4182         if (len > 0) {
4183                 if (pmlmepriv->wps_assoc_resp_ie) {
4184                         pmlmepriv->wps_assoc_resp_ie_len = 0;
4185                         kfree(pmlmepriv->wps_assoc_resp_ie);
4186                         pmlmepriv->wps_assoc_resp_ie = NULL;
4187                 }
4188
4189                 pmlmepriv->wps_assoc_resp_ie = kmalloc(len, GFP_KERNEL);
4190                 if (pmlmepriv->wps_assoc_resp_ie == NULL) {
4191                         DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
4192                                   __func__, __LINE__);
4193                         return -EINVAL;
4194
4195                 }
4196                 memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len);
4197                 pmlmepriv->wps_assoc_resp_ie_len = len;
4198         }
4199
4200         return ret;
4201 }
4202
4203 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
4204                                    int type)
4205 {
4206         int ret = 0;
4207         uint wps_ielen = 0;
4208 #ifdef CONFIG_8723AU_P2P
4209         u32 p2p_ielen = 0;
4210 #endif
4211
4212 #ifdef CONFIG_DEBUG_CFG80211
4213         DBG_8723A("%s, ielen =%d\n", __func__, len);
4214 #endif
4215
4216         if ((rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen) && (wps_ielen > 0))
4217 #ifdef CONFIG_8723AU_P2P
4218             || (rtw_get_p2p_ie23a(buf, len, NULL, &p2p_ielen) && (p2p_ielen > 0))
4219 #endif
4220             ) {
4221                 if (net) {
4222                         switch (type) {
4223                         case 0x1:       /* BEACON */
4224                                 ret =
4225                                     rtw_cfg80211_set_beacon_wpsp2pie(net, buf,
4226                                                                      len);
4227                                 break;
4228                         case 0x2:       /* PROBE_RESP */
4229                                 ret =
4230                                     rtw_cfg80211_set_probe_resp_wpsp2pie(net,
4231                                                                          buf,
4232                                                                          len);
4233                                 break;
4234                         case 0x4:       /* ASSOC_RESP */
4235                                 ret =
4236                                     rtw_cfg80211_set_assoc_resp_wpsp2pie(net,
4237                                                                          buf,
4238                                                                          len);
4239                                 break;
4240                         }
4241                 }
4242         }
4243
4244         return ret;
4245
4246 }
4247
4248 static struct cfg80211_ops rtw_cfg80211_ops = {
4249         .change_virtual_intf = cfg80211_rtw_change_iface,
4250         .add_key = cfg80211_rtw_add_key,
4251         .get_key = cfg80211_rtw_get_key,
4252         .del_key = cfg80211_rtw_del_key,
4253         .set_default_key = cfg80211_rtw_set_default_key,
4254         .get_station = cfg80211_rtw_get_station,
4255         .scan = cfg80211_rtw_scan,
4256         .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
4257         .connect = cfg80211_rtw_connect,
4258         .disconnect = cfg80211_rtw_disconnect,
4259         .join_ibss = cfg80211_rtw_join_ibss,
4260         .leave_ibss = cfg80211_rtw_leave_ibss,
4261         .set_tx_power = cfg80211_rtw_set_txpower,
4262         .get_tx_power = cfg80211_rtw_get_txpower,
4263         .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
4264         .set_pmksa = cfg80211_rtw_set_pmksa,
4265         .del_pmksa = cfg80211_rtw_del_pmksa,
4266         .flush_pmksa = cfg80211_rtw_flush_pmksa,
4267
4268 #ifdef CONFIG_8723AU_AP_MODE
4269         .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
4270         .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
4271
4272         .start_ap = cfg80211_rtw_start_ap,
4273         .change_beacon = cfg80211_rtw_change_beacon,
4274         .stop_ap = cfg80211_rtw_stop_ap,
4275
4276         .add_station = cfg80211_rtw_add_station,
4277         .del_station = cfg80211_rtw_del_station,
4278         .change_station = cfg80211_rtw_change_station,
4279         .dump_station = cfg80211_rtw_dump_station,
4280         .change_bss = cfg80211_rtw_change_bss,
4281 #endif /* CONFIG_8723AU_AP_MODE */
4282
4283 #ifdef CONFIG_8723AU_P2P
4284         .remain_on_channel = cfg80211_rtw_remain_on_channel,
4285         .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
4286 #endif
4287
4288         .mgmt_tx = cfg80211_rtw_mgmt_tx,
4289         .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
4290 };
4291
4292 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap,
4293                                        enum ieee80211_band band, u8 rf_type)
4294 {
4295
4296 #define MAX_BIT_RATE_40MHZ_MCS15        300     /* Mbps */
4297 #define MAX_BIT_RATE_40MHZ_MCS7         150     /* Mbps */
4298
4299         ht_cap->ht_supported = true;
4300
4301         ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
4302             IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
4303             IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
4304
4305         /*
4306          *Maximum length of AMPDU that the STA can receive.
4307          *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
4308          */
4309         ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4310
4311         /*Minimum MPDU start spacing , */
4312         ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
4313
4314         ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
4315
4316         /*
4317          *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
4318          *base on ant_num
4319          *rx_mask: RX mask
4320          *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7
4321          *if rx_ant = 2 rx_mask[1]= 0xff;==>MCS8-MCS15
4322          *if rx_ant >= 3 rx_mask[2]= 0xff;
4323          *if BW_40 rx_mask[4]= 0x01;
4324          *highest supported RX rate
4325          */
4326         if (rf_type == RF_1T1R) {
4327                 ht_cap->mcs.rx_mask[0] = 0xFF;
4328                 ht_cap->mcs.rx_mask[1] = 0x00;
4329                 ht_cap->mcs.rx_mask[4] = 0x01;
4330
4331                 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
4332         } else if ((rf_type == RF_1T2R) || (rf_type == RF_2T2R)) {
4333                 ht_cap->mcs.rx_mask[0] = 0xFF;
4334                 ht_cap->mcs.rx_mask[1] = 0xFF;
4335                 ht_cap->mcs.rx_mask[4] = 0x01;
4336
4337                 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
4338         } else {
4339                 DBG_8723A("%s, error rf_type =%d\n", __func__, rf_type);
4340         }
4341
4342 }
4343
4344 void rtw_cfg80211_init_wiphy(struct rtw_adapter *padapter)
4345 {
4346         u8 rf_type;
4347         struct ieee80211_supported_band *bands;
4348         struct wireless_dev *pwdev = padapter->rtw_wdev;
4349         struct wiphy *wiphy = pwdev->wiphy;
4350
4351         rtw23a_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
4352
4353         DBG_8723A("%s:rf_type =%d\n", __func__, rf_type);
4354
4355         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
4356         {
4357                 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
4358                 if (bands)
4359                         rtw_cfg80211_init_ht_capab(&bands->ht_cap,
4360                                                    IEEE80211_BAND_2GHZ,
4361                                                    rf_type);
4362         }
4363
4364         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
4365         {
4366                 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
4367                 if (bands)
4368                         rtw_cfg80211_init_ht_capab(&bands->ht_cap,
4369                                                    IEEE80211_BAND_5GHZ,
4370                                                    rf_type);
4371         }
4372 }
4373
4374 static void rtw_cfg80211_preinit_wiphy(struct rtw_adapter *padapter,
4375                                        struct wiphy *wiphy)
4376 {
4377         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4378
4379         wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
4380         wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
4381         wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
4382
4383         wiphy->max_remain_on_channel_duration =
4384             RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
4385
4386         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4387             BIT(NL80211_IFTYPE_ADHOC) |
4388 #ifdef CONFIG_8723AU_AP_MODE
4389             BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) |
4390 #endif
4391 #if defined(CONFIG_8723AU_P2P)
4392             BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) |
4393 #endif
4394             0;
4395
4396 #ifdef CONFIG_8723AU_AP_MODE
4397         wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
4398 #endif /* CONFIG_8723AU_AP_MODE */
4399
4400         wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
4401
4402         /*
4403            wiphy->iface_combinations = &rtw_combinations;
4404            wiphy->n_iface_combinations = 1;
4405          */
4406
4407         wiphy->cipher_suites = rtw_cipher_suites;
4408         wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
4409
4410         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
4411         wiphy->bands[IEEE80211_BAND_2GHZ] =
4412             rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
4413         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
4414         wiphy->bands[IEEE80211_BAND_5GHZ] =
4415             rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
4416
4417         wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
4418         wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
4419
4420         if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
4421                 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
4422         else
4423                 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
4424 }
4425
4426 int rtw_wdev_alloc(struct rtw_adapter *padapter, struct device *dev)
4427 {
4428         int ret = 0;
4429         struct wiphy *wiphy;
4430         struct wireless_dev *wdev;
4431         struct rtw_wdev_priv *pwdev_priv;
4432         struct net_device *pnetdev = padapter->pnetdev;
4433
4434         DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
4435
4436         /* wiphy */
4437         wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wdev_priv));
4438         if (!wiphy) {
4439                 DBG_8723A("Couldn't allocate wiphy device\n");
4440                 ret = -ENOMEM;
4441                 goto exit;
4442         }
4443         set_wiphy_dev(wiphy, dev);
4444         rtw_cfg80211_preinit_wiphy(padapter, wiphy);
4445
4446         ret = wiphy_register(wiphy);
4447         if (ret < 0) {
4448                 DBG_8723A("Couldn't register wiphy device\n");
4449                 goto free_wiphy;
4450         }
4451
4452         /*  wdev */
4453         wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
4454         if (!wdev) {
4455                 DBG_8723A("Couldn't allocate wireless device\n");
4456                 ret = -ENOMEM;
4457                 goto unregister_wiphy;
4458         }
4459         wdev->wiphy = wiphy;
4460         wdev->netdev = pnetdev;
4461         /* wdev->iftype = NL80211_IFTYPE_STATION; */
4462         /*  for rtw_setopmode_cmd23a() in cfg80211_rtw_change_iface() */
4463         wdev->iftype = NL80211_IFTYPE_MONITOR;
4464         padapter->rtw_wdev = wdev;
4465         pnetdev->ieee80211_ptr = wdev;
4466
4467         /* init pwdev_priv */
4468         pwdev_priv = wdev_to_priv(wdev);
4469         pwdev_priv->rtw_wdev = wdev;
4470         pwdev_priv->pmon_ndev = NULL;
4471         pwdev_priv->ifname_mon[0] = '\0';
4472         pwdev_priv->padapter = padapter;
4473         pwdev_priv->scan_request = NULL;
4474         spin_lock_init(&pwdev_priv->scan_req_lock);
4475
4476         pwdev_priv->p2p_enabled = false;
4477         pwdev_priv->provdisc_req_issued = false;
4478         rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
4479
4480         if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
4481                 pwdev_priv->power_mgmt = true;
4482         else
4483                 pwdev_priv->power_mgmt = false;
4484
4485         return ret;
4486 unregister_wiphy:
4487         wiphy_unregister(wiphy);
4488 free_wiphy:
4489         wiphy_free(wiphy);
4490 exit:
4491         return ret;
4492 }
4493
4494 void rtw_wdev_free(struct wireless_dev *wdev)
4495 {
4496         struct rtw_wdev_priv *pwdev_priv;
4497
4498         DBG_8723A("%s(wdev =%p)\n", __func__, wdev);
4499
4500         if (!wdev)
4501                 return;
4502
4503         pwdev_priv = wdev_to_priv(wdev);
4504
4505         kfree(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
4506         kfree(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
4507
4508         wiphy_free(wdev->wiphy);
4509
4510         kfree(wdev);
4511 }
4512
4513 void rtw_wdev_unregister(struct wireless_dev *wdev)
4514 {
4515         struct rtw_wdev_priv *pwdev_priv;
4516
4517         DBG_8723A("%s(wdev =%p)\n", __func__, wdev);
4518
4519         if (!wdev)
4520                 return;
4521
4522         pwdev_priv = wdev_to_priv(wdev);
4523
4524         rtw_cfg80211_indicate_scan_done(pwdev_priv, true);
4525
4526         if (pwdev_priv->pmon_ndev) {
4527                 DBG_8723A("%s, unregister monitor interface\n", __func__);
4528                 unregister_netdev(pwdev_priv->pmon_ndev);
4529         }
4530
4531         wiphy_unregister(wdev->wiphy);
4532 }