staging: r8723au: Add source files for new driver - part 3
[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         u32 p2p_ielen = 0;
1499         u8 *p2p_ie;
1500         u32 wfd_ielen = 0;
1501         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1502
1503 #ifdef CONFIG_DEBUG_CFG80211
1504         DBG_8723A("%s, ielen =%d\n", __func__, len);
1505 #endif
1506
1507         if (len > 0) {
1508                 wps_ie = rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen);
1509                 if (wps_ie) {
1510 #ifdef CONFIG_DEBUG_CFG80211
1511                         DBG_8723A("probe_req_wps_ielen =%d\n", wps_ielen);
1512 #endif
1513                         if (pmlmepriv->wps_probe_req_ie) {
1514                                 pmlmepriv->wps_probe_req_ie_len = 0;
1515                                 kfree(pmlmepriv->wps_probe_req_ie);
1516                                 pmlmepriv->wps_probe_req_ie = NULL;
1517                         }
1518
1519                         pmlmepriv->wps_probe_req_ie =
1520                                 kmalloc(wps_ielen, GFP_KERNEL);
1521                         if (pmlmepriv->wps_probe_req_ie == NULL) {
1522                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
1523                                           __func__, __LINE__);
1524                                 return -EINVAL;
1525                         }
1526                         memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
1527                         pmlmepriv->wps_probe_req_ie_len = wps_ielen;
1528                 }
1529 #ifdef CONFIG_8723AU_P2P
1530                 p2p_ie = rtw_get_p2p_ie23a(buf, len, NULL, &p2p_ielen);
1531                 if (p2p_ie) {
1532 #ifdef CONFIG_DEBUG_CFG80211
1533                         DBG_8723A("probe_req_p2p_ielen =%d\n", p2p_ielen);
1534 #endif
1535
1536                         if (pmlmepriv->p2p_probe_req_ie) {
1537                                 pmlmepriv->p2p_probe_req_ie_len = 0;
1538                                 kfree(pmlmepriv->p2p_probe_req_ie);
1539                                 pmlmepriv->p2p_probe_req_ie = NULL;
1540                         }
1541
1542                         pmlmepriv->p2p_probe_req_ie =
1543                                 kmalloc(p2p_ielen, GFP_KERNEL);
1544                         if (pmlmepriv->p2p_probe_req_ie == NULL) {
1545                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
1546                                           __func__, __LINE__);
1547                                 return -EINVAL;
1548
1549                         }
1550                         memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
1551                         pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
1552                 }
1553 #endif /* CONFIG_8723AU_P2P */
1554
1555                 /* buf += p2p_ielen; */
1556                 /* len -= p2p_ielen; */
1557
1558 #ifdef CONFIG_8723AU_P2P
1559                 if (rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) {
1560 #ifdef CONFIG_DEBUG_CFG80211
1561                         DBG_8723A("probe_req_wfd_ielen =%d\n", wfd_ielen);
1562 #endif
1563
1564                         if (pmlmepriv->wfd_probe_req_ie) {
1565                                 pmlmepriv->wfd_probe_req_ie_len = 0;
1566                                 kfree(pmlmepriv->wfd_probe_req_ie);
1567                                 pmlmepriv->wfd_probe_req_ie = NULL;
1568                         }
1569
1570                         pmlmepriv->wfd_probe_req_ie =
1571                                 kmalloc(wfd_ielen, GFP_KERNEL);
1572                         if (pmlmepriv->wfd_probe_req_ie == NULL) {
1573                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
1574                                           __func__, __LINE__);
1575                                 return -EINVAL;
1576
1577                         }
1578                         rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_req_ie,
1579                                        &pmlmepriv->wfd_probe_req_ie_len);
1580                 }
1581 #endif /* CONFIG_8723AU_P2P */
1582
1583         }
1584
1585         return ret;
1586 }
1587
1588 static int cfg80211_rtw_scan(struct wiphy *wiphy,
1589                              struct cfg80211_scan_request *request)
1590 {
1591         int i;
1592         u8 _status = false;
1593         int ret = 0;
1594         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
1595         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1596         struct cfg80211_ssid ssid[RTW_SSID_SCAN_AMOUNT];
1597         struct rtw_ieee80211_channel ch[RTW_CHANNEL_SCAN_AMOUNT];
1598 #ifdef CONFIG_8723AU_P2P
1599         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1600 #endif /* CONFIG_8723AU_P2P */
1601         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
1602         struct cfg80211_ssid *ssids = request->ssids;
1603         int social_channel = 0;
1604         bool need_indicate_scan_done = false;
1605
1606 #ifdef CONFIG_DEBUG_CFG80211
1607         DBG_8723A(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter));
1608 #endif
1609
1610         spin_lock_bh(&pwdev_priv->scan_req_lock);
1611         pwdev_priv->scan_request = request;
1612         spin_unlock_bh(&pwdev_priv->scan_req_lock);
1613
1614         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1615
1616 #ifdef CONFIG_DEBUG_CFG80211
1617                 DBG_8723A("%s under WIFI_AP_STATE\n", __func__);
1618 #endif
1619                 /* need_indicate_scan_done = true; */
1620                 /* goto check_need_indicate_scan_done; */
1621         }
1622
1623         if (rtw_pwr_wakeup(padapter) == _FAIL) {
1624                 need_indicate_scan_done = true;
1625                 goto check_need_indicate_scan_done;
1626         }
1627 #ifdef CONFIG_8723AU_P2P
1628         if (ssids->ssid != NULL &&
1629             !memcmp(ssids->ssid, "DIRECT-", 7) &&
1630             rtw_get_p2p_ie23a((u8 *) request->ie, request->ie_len, NULL, NULL)) {
1631                 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
1632                         rtw_p2p_enable23a(padapter, P2P_ROLE_DEVICE);
1633                         wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = true;
1634                 } else {
1635                         rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
1636 #ifdef CONFIG_DEBUG_CFG80211
1637                         DBG_8723A("%s, role =%d, p2p_state =%d\n", __func__,
1638                                   rtw_p2p_role(pwdinfo),
1639                                   rtw_p2p_state(pwdinfo));
1640 #endif
1641                 }
1642                 rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
1643
1644                 if (request->n_channels == 3 &&
1645                     request->channels[0]->hw_value == 1 &&
1646                     request->channels[1]->hw_value == 6 &&
1647                     request->channels[2]->hw_value == 11)
1648                         social_channel = 1;
1649         }
1650 #endif /* CONFIG_8723AU_P2P */
1651
1652         if (request->ie && request->ie_len > 0) {
1653                 rtw_cfg80211_set_probe_req_wpsp2pie(padapter,
1654                                                     (u8 *) request->ie,
1655                                                     request->ie_len);
1656         }
1657
1658         if (pmlmepriv->LinkDetectInfo.bBusyTraffic == true) {
1659                 DBG_8723A("%s, bBusyTraffic == true\n", __func__);
1660                 need_indicate_scan_done = true;
1661                 goto check_need_indicate_scan_done;
1662         }
1663         if (rtw_is_scan_deny(padapter)) {
1664                 DBG_8723A(FUNC_ADPT_FMT ": scan deny\n",
1665                           FUNC_ADPT_ARG(padapter));
1666                 need_indicate_scan_done = true;
1667                 goto check_need_indicate_scan_done;
1668         }
1669
1670         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) ==
1671             true) {
1672                 DBG_8723A("%s, fwstate = 0x%x\n", __func__, pmlmepriv->fw_state);
1673                 need_indicate_scan_done = true;
1674                 goto check_need_indicate_scan_done;
1675         }
1676 #ifdef CONFIG_8723AU_P2P
1677         if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
1678             !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
1679                 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
1680                 rtw_free_network_queue23a(padapter, true);
1681
1682                 if (social_channel == 0)
1683                         rtw_p2p_findphase_ex_set(pwdinfo,
1684                                                  P2P_FINDPHASE_EX_NONE);
1685                 else
1686                         rtw_p2p_findphase_ex_set(pwdinfo,
1687                                                  P2P_FINDPHASE_EX_SOCIAL_LAST);
1688         }
1689 #endif /* CONFIG_8723AU_P2P */
1690
1691         memset(ssid, 0, sizeof(struct cfg80211_ssid) * RTW_SSID_SCAN_AMOUNT);
1692         /* parsing request ssids, n_ssids */
1693         for (i = 0; i < request->n_ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
1694 #ifdef CONFIG_DEBUG_CFG80211
1695                 DBG_8723A("ssid =%s, len =%d\n", ssids[i].ssid,
1696                           ssids[i].ssid_len);
1697 #endif
1698                 memcpy(ssid[i].ssid, ssids[i].ssid, ssids[i].ssid_len);
1699                 ssid[i].ssid_len = ssids[i].ssid_len;
1700         }
1701
1702         /* parsing channels, n_channels */
1703         memset(ch, 0,
1704                sizeof(struct rtw_ieee80211_channel) * RTW_CHANNEL_SCAN_AMOUNT);
1705
1706         if (request->n_channels == 1) {
1707                 for (i = 0; i < request->n_channels &&
1708                      i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
1709 #ifdef CONFIG_DEBUG_CFG80211
1710                         DBG_8723A(FUNC_ADPT_FMT CHAN_FMT "\n",
1711                                   FUNC_ADPT_ARG(padapter),
1712                                   CHAN_ARG(request->channels[i]));
1713 #endif
1714                         ch[i].hw_value = request->channels[i]->hw_value;
1715                         ch[i].flags = request->channels[i]->flags;
1716                 }
1717         }
1718
1719         spin_lock_bh(&pmlmepriv->lock);
1720         if (request->n_channels == 1) {
1721                 memcpy(&ch[1], &ch[0], sizeof(struct rtw_ieee80211_channel));
1722                 memcpy(&ch[2], &ch[0], sizeof(struct rtw_ieee80211_channel));
1723                 _status = rtw_sitesurvey_cmd23a(padapter, ssid,
1724                                              RTW_SSID_SCAN_AMOUNT, ch, 3);
1725         } else {
1726                 _status = rtw_sitesurvey_cmd23a(padapter, ssid,
1727                                              RTW_SSID_SCAN_AMOUNT, NULL, 0);
1728         }
1729         spin_unlock_bh(&pmlmepriv->lock);
1730
1731         if (_status == false)
1732                 ret = -1;
1733
1734 check_need_indicate_scan_done:
1735         if (need_indicate_scan_done)
1736                 rtw_cfg80211_surveydone_event_callback(padapter);
1737         return ret;
1738 }
1739
1740 static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1741 {
1742         DBG_8723A("%s\n", __func__);
1743         return 0;
1744 }
1745
1746 static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1747                                   struct cfg80211_ibss_params *params)
1748 {
1749         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
1750         return 0;
1751 }
1752
1753 static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1754 {
1755         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
1756         return 0;
1757 }
1758
1759 static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv,
1760                                         u32 wpa_version)
1761 {
1762         DBG_8723A("%s, wpa_version =%d\n", __func__, wpa_version);
1763
1764         if (!wpa_version) {
1765                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
1766                 return 0;
1767         }
1768
1769         if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) {
1770                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
1771         }
1772
1773 /*
1774         if (wpa_version & NL80211_WPA_VERSION_2)
1775         {
1776                 psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
1777         }
1778 */
1779
1780         return 0;
1781 }
1782
1783 static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
1784                                       enum nl80211_auth_type sme_auth_type)
1785 {
1786         DBG_8723A("%s, nl80211_auth_type =%d\n", __func__, sme_auth_type);
1787
1788         switch (sme_auth_type) {
1789         case NL80211_AUTHTYPE_AUTOMATIC:
1790                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1791
1792                 break;
1793         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1794                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1795
1796                 if (psecuritypriv->ndisauthtype > Ndis802_11AuthModeWPA)
1797                         psecuritypriv->dot11AuthAlgrthm =
1798                                 dot11AuthAlgrthm_8021X;
1799                 break;
1800         case NL80211_AUTHTYPE_SHARED_KEY:
1801                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
1802
1803                 psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1804                 break;
1805         default:
1806                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
1807                 /* return -ENOTSUPP; */
1808         }
1809
1810         return 0;
1811 }
1812
1813 static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv,
1814                                    u32 cipher, bool ucast)
1815 {
1816         u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
1817
1818         u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
1819             &psecuritypriv->dot118021XGrpPrivacy;
1820
1821         DBG_8723A("%s, ucast =%d, cipher = 0x%x\n", __func__, ucast, cipher);
1822
1823         if (!cipher) {
1824                 *profile_cipher = _NO_PRIVACY_;
1825                 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
1826                 return 0;
1827         }
1828
1829         switch (cipher) {
1830         case IW_AUTH_CIPHER_NONE:
1831                 *profile_cipher = _NO_PRIVACY_;
1832                 ndisencryptstatus = Ndis802_11EncryptionDisabled;
1833                 break;
1834         case WLAN_CIPHER_SUITE_WEP40:
1835                 *profile_cipher = _WEP40_;
1836                 ndisencryptstatus = Ndis802_11Encryption1Enabled;
1837                 break;
1838         case WLAN_CIPHER_SUITE_WEP104:
1839                 *profile_cipher = _WEP104_;
1840                 ndisencryptstatus = Ndis802_11Encryption1Enabled;
1841                 break;
1842         case WLAN_CIPHER_SUITE_TKIP:
1843                 *profile_cipher = _TKIP_;
1844                 ndisencryptstatus = Ndis802_11Encryption2Enabled;
1845                 break;
1846         case WLAN_CIPHER_SUITE_CCMP:
1847                 *profile_cipher = _AES_;
1848                 ndisencryptstatus = Ndis802_11Encryption3Enabled;
1849                 break;
1850         default:
1851                 DBG_8723A("Unsupported cipher: 0x%x\n", cipher);
1852                 return -ENOTSUPP;
1853         }
1854
1855         if (ucast)
1856                 psecuritypriv->ndisencryptstatus = ndisencryptstatus;
1857
1858         return 0;
1859 }
1860
1861 static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv,
1862                                     u32 key_mgt)
1863 {
1864         DBG_8723A("%s, key_mgt = 0x%x\n", __func__, key_mgt);
1865
1866         if (key_mgt == WLAN_AKM_SUITE_8021X)
1867                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1868         else if (key_mgt == WLAN_AKM_SUITE_PSK)
1869                 psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1870         else
1871                 DBG_8723A("Invalid key mgt: 0x%x\n", key_mgt);
1872
1873         return 0;
1874 }
1875
1876 static int rtw_cfg80211_set_wpa_ie(struct rtw_adapter *padapter, const u8 *pie,
1877                                    size_t ielen)
1878 {
1879         u8 *buf = NULL, *pos = NULL;
1880         int group_cipher = 0, pairwise_cipher = 0;
1881         int ret = 0;
1882         int wpa_ielen = 0;
1883         int wpa2_ielen = 0;
1884         u8 *pwpa, *pwpa2;
1885         u8 null_addr[] = { 0, 0, 0, 0, 0, 0 };
1886         int i;
1887
1888         if (!pie || !ielen) {
1889                 /* Treat this as normal case, but need to clear
1890                    WIFI_UNDER_WPS */
1891                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1892                 goto exit;
1893         }
1894         if (ielen > MAX_WPA_IE_LEN + MAX_WPS_IE_LEN + MAX_P2P_IE_LEN) {
1895                 ret = -EINVAL;
1896                 goto exit;
1897         }
1898         buf = kzalloc(ielen, GFP_KERNEL);
1899         if (buf == NULL) {
1900                 ret = -ENOMEM;
1901                 goto exit;
1902         }
1903         memcpy(buf, pie, ielen);
1904
1905         /* dump */
1906         DBG_8723A("set wpa_ie(length:%zu):\n", ielen);
1907         for (i = 0; i < ielen; i = i + 8)
1908                 DBG_8723A("0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
1909                           buf[i], buf[i + 1],
1910                           buf[i + 2], buf[i + 3], buf[i + 4],
1911                           buf[i + 5], buf[i + 6], buf[i + 7]);
1912         pos = buf;
1913         if (ielen < RSN_HEADER_LEN) {
1914                 RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_err_,
1915                          ("Ie len too short %d\n", (int)ielen));
1916                 ret = -1;
1917                 goto exit;
1918         }
1919
1920         pwpa = rtw_get_wpa_ie23a(buf, &wpa_ielen, ielen);
1921         if (pwpa && wpa_ielen > 0) {
1922                 if (rtw_parse_wpa_ie23a(pwpa, wpa_ielen + 2, &group_cipher,
1923                                      &pairwise_cipher, NULL) == _SUCCESS) {
1924                         padapter->securitypriv.dot11AuthAlgrthm =
1925                                 dot11AuthAlgrthm_8021X;
1926                         padapter->securitypriv.ndisauthtype =
1927                                 Ndis802_11AuthModeWPAPSK;
1928                         memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0],
1929                                wpa_ielen + 2);
1930
1931                         DBG_8723A("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
1932                 }
1933         }
1934
1935         pwpa2 = rtw_get_wpa2_ie23a(buf, &wpa2_ielen, ielen);
1936         if (pwpa2 && wpa2_ielen > 0) {
1937                 if (rtw_parse_wpa2_ie23a (pwpa2, wpa2_ielen + 2, &group_cipher,
1938                                        &pairwise_cipher, NULL) == _SUCCESS) {
1939                         padapter->securitypriv.dot11AuthAlgrthm =
1940                                 dot11AuthAlgrthm_8021X;
1941                         padapter->securitypriv.ndisauthtype =
1942                                 Ndis802_11AuthModeWPA2PSK;
1943                         memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0],
1944                                wpa2_ielen + 2);
1945
1946                         DBG_8723A("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
1947                 }
1948         }
1949
1950         if (group_cipher == 0) {
1951                 group_cipher = WPA_CIPHER_NONE;
1952         }
1953         if (pairwise_cipher == 0) {
1954                 pairwise_cipher = WPA_CIPHER_NONE;
1955         }
1956
1957         switch (group_cipher) {
1958         case WPA_CIPHER_NONE:
1959                 padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1960                 padapter->securitypriv.ndisencryptstatus =
1961                         Ndis802_11EncryptionDisabled;
1962                 break;
1963         case WPA_CIPHER_WEP40:
1964                 padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1965                 padapter->securitypriv.ndisencryptstatus =
1966                         Ndis802_11Encryption1Enabled;
1967                 break;
1968         case WPA_CIPHER_TKIP:
1969                 padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
1970                 padapter->securitypriv.ndisencryptstatus =
1971                         Ndis802_11Encryption2Enabled;
1972                 break;
1973         case WPA_CIPHER_CCMP:
1974                 padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
1975                 padapter->securitypriv.ndisencryptstatus =
1976                         Ndis802_11Encryption3Enabled;
1977                 break;
1978         case WPA_CIPHER_WEP104:
1979                 padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
1980                 padapter->securitypriv.ndisencryptstatus =
1981                         Ndis802_11Encryption1Enabled;
1982                 break;
1983         }
1984
1985         switch (pairwise_cipher) {
1986         case WPA_CIPHER_NONE:
1987                 padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1988                 padapter->securitypriv.ndisencryptstatus =
1989                         Ndis802_11EncryptionDisabled;
1990                 break;
1991         case WPA_CIPHER_WEP40:
1992                 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1993                 padapter->securitypriv.ndisencryptstatus =
1994                         Ndis802_11Encryption1Enabled;
1995                 break;
1996         case WPA_CIPHER_TKIP:
1997                 padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
1998                 padapter->securitypriv.ndisencryptstatus =
1999                         Ndis802_11Encryption2Enabled;
2000                 break;
2001         case WPA_CIPHER_CCMP:
2002                 padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
2003                 padapter->securitypriv.ndisencryptstatus =
2004                         Ndis802_11Encryption3Enabled;
2005                 break;
2006         case WPA_CIPHER_WEP104:
2007                 padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
2008                 padapter->securitypriv.ndisencryptstatus =
2009                         Ndis802_11Encryption1Enabled;
2010                 break;
2011         }
2012
2013         {                       /* handle wps_ie */
2014                 uint wps_ielen;
2015                 u8 *wps_ie;
2016
2017                 wps_ie = rtw_get_wps_ie23a(buf, ielen, NULL, &wps_ielen);
2018                 if (wps_ie && wps_ielen > 0) {
2019                         DBG_8723A("got wps_ie, wps_ielen:%u\n", wps_ielen);
2020                         padapter->securitypriv.wps_ie_len =
2021                                 wps_ielen <
2022                                 MAX_WPS_IE_LEN ? wps_ielen : MAX_WPS_IE_LEN;
2023                         memcpy(padapter->securitypriv.wps_ie, wps_ie,
2024                                padapter->securitypriv.wps_ie_len);
2025                         set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
2026                 } else {
2027                         _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2028                 }
2029         }
2030
2031 #ifdef CONFIG_8723AU_P2P
2032         {                       /* check p2p_ie for assoc req; */
2033                 uint p2p_ielen = 0;
2034                 u8 *p2p_ie;
2035                 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2036
2037                 p2p_ie = rtw_get_p2p_ie23a(buf, ielen, NULL, &p2p_ielen);
2038                 if (p2p_ie) {
2039 #ifdef CONFIG_DEBUG_CFG80211
2040                         DBG_8723A("%s p2p_assoc_req_ielen =%d\n", __func__,
2041                                   p2p_ielen);
2042 #endif
2043
2044                         if (pmlmepriv->p2p_assoc_req_ie) {
2045                                 pmlmepriv->p2p_assoc_req_ie_len = 0;
2046                                 kfree(pmlmepriv->p2p_assoc_req_ie);
2047                                 pmlmepriv->p2p_assoc_req_ie = NULL;
2048                         }
2049
2050                         pmlmepriv->p2p_assoc_req_ie =
2051                                 kmalloc(p2p_ielen, GFP_KERNEL);
2052                         if (pmlmepriv->p2p_assoc_req_ie == NULL) {
2053                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
2054                                           __func__, __LINE__);
2055                                 goto exit;
2056                         }
2057                         memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
2058                         pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
2059                 }
2060         }
2061 #endif /* CONFIG_8723AU_P2P */
2062
2063 #ifdef CONFIG_8723AU_P2P
2064         {                       /* check wfd_ie for assoc req; */
2065                 uint wfd_ielen = 0;
2066                 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2067
2068                 if (rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen)) {
2069 #ifdef CONFIG_DEBUG_CFG80211
2070                         DBG_8723A("%s wfd_assoc_req_ielen =%d\n", __func__,
2071                                   wfd_ielen);
2072 #endif
2073
2074                         if (pmlmepriv->wfd_assoc_req_ie) {
2075                                 pmlmepriv->wfd_assoc_req_ie_len = 0;
2076                                 kfree(pmlmepriv->wfd_assoc_req_ie);
2077                                 pmlmepriv->wfd_assoc_req_ie = NULL;
2078                         }
2079
2080                         pmlmepriv->wfd_assoc_req_ie =
2081                                 kmalloc(wfd_ielen, GFP_KERNEL);
2082                         if (pmlmepriv->wfd_assoc_req_ie == NULL) {
2083                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
2084                                           __func__, __LINE__);
2085                                 goto exit;
2086                         }
2087                         rtw_get_wfd_ie(buf, ielen, pmlmepriv->wfd_assoc_req_ie,
2088                                        &pmlmepriv->wfd_assoc_req_ie_len);
2089                 }
2090         }
2091 #endif /* CONFIG_8723AU_P2P */
2092
2093         /* TKIP and AES disallow multicast packets until installing group key */
2094         if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_ ||
2095             padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_ ||
2096             padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
2097                 /* WPS open need to enable multicast */
2098                 /* check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == true)*/
2099                 rtw_hal_set_hwreg23a(padapter, HW_VAR_OFF_RCR_AM, null_addr);
2100
2101         RT_TRACE(_module_rtl871x_ioctl_os_c, _drv_info_,
2102                  ("rtw_set_wpa_ie: pairwise_cipher = 0x%08x padapter->"
2103                   "securitypriv.ndisencryptstatus =%d padapter->"
2104                   "securitypriv.ndisauthtype =%d\n", pairwise_cipher,
2105                   padapter->securitypriv.ndisencryptstatus,
2106                   padapter->securitypriv.ndisauthtype));
2107
2108 exit:
2109         kfree(buf);
2110         if (ret)
2111                 _clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
2112         return ret;
2113 }
2114
2115 static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
2116                                 struct cfg80211_connect_params *sme)
2117 {
2118         int ret = 0;
2119         struct list_head *phead, *plist, *ptmp;
2120         struct wlan_network *pnetwork = NULL;
2121         enum ndis_802_11_auth_mode authmode;
2122         struct cfg80211_ssid ndis_ssid;
2123         u8 *dst_ssid;
2124         u8 *src_ssid;
2125         u8 *dst_bssid;
2126         const u8 *src_bssid;
2127         /* u8 matched_by_bssid = false; */
2128         /* u8 matched_by_ssid = false; */
2129         u8 matched = false;
2130         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2131         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2132         struct security_priv *psecuritypriv = &padapter->securitypriv;
2133         struct rtw_queue *queue = &pmlmepriv->scanned_queue;
2134
2135         DBG_8723A("=>" FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
2136         DBG_8723A("privacy =%d, key =%p, key_len =%d, key_idx =%d\n",
2137                   sme->privacy, sme->key, sme->key_len, sme->key_idx);
2138
2139         if (wdev_to_priv(padapter->rtw_wdev)->block) {
2140                 ret = -EBUSY;
2141                 DBG_8723A("%s wdev_priv.block is set\n", __func__);
2142                 goto exit;
2143         }
2144
2145         if (_FAIL == rtw_pwr_wakeup(padapter)) {
2146                 ret = -EPERM;
2147                 goto exit;
2148         }
2149
2150         if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2151                 ret = -EPERM;
2152                 goto exit;
2153         }
2154
2155         if (!sme->ssid || !sme->ssid_len) {
2156                 ret = -EINVAL;
2157                 goto exit;
2158         }
2159
2160         if (sme->ssid_len > IW_ESSID_MAX_SIZE) {
2161                 ret = -E2BIG;
2162                 goto exit;
2163         }
2164
2165         memset(&ndis_ssid, 0, sizeof(struct cfg80211_ssid));
2166         ndis_ssid.ssid_len = sme->ssid_len;
2167         memcpy(ndis_ssid.ssid, sme->ssid, sme->ssid_len);
2168
2169         DBG_8723A("ssid =%s, len =%zu\n", ndis_ssid.ssid, sme->ssid_len);
2170
2171         if (sme->bssid)
2172                 DBG_8723A("bssid =" MAC_FMT "\n", MAC_ARG(sme->bssid));
2173
2174         if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) {
2175                 ret = -EBUSY;
2176                 DBG_8723A("%s, fw_state = 0x%x, goto exit\n", __func__,
2177                           pmlmepriv->fw_state);
2178                 goto exit;
2179         }
2180         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
2181                 rtw_scan_abort23a(padapter);
2182         }
2183
2184         spin_lock_bh(&queue->lock);
2185
2186         phead = get_list_head(queue);
2187
2188         list_for_each_safe(plist, ptmp, phead) {
2189                 pnetwork = container_of(plist, struct wlan_network, list);
2190
2191                 dst_ssid = pnetwork->network.Ssid.ssid;
2192                 dst_bssid = pnetwork->network.MacAddress;
2193
2194                 if (sme->bssid) {
2195                         if (memcmp(pnetwork->network.MacAddress,
2196                                    sme->bssid, ETH_ALEN))
2197                                 continue;
2198                 }
2199
2200                 if (sme->ssid && sme->ssid_len) {
2201                         if (pnetwork->network.Ssid.ssid_len != sme->ssid_len ||
2202                             memcmp(pnetwork->network.Ssid.ssid, sme->ssid,
2203                                    sme->ssid_len))
2204                                 continue;
2205                 }
2206
2207                 if (sme->bssid) {
2208                         src_bssid = sme->bssid;
2209
2210                         if ((!memcmp(dst_bssid, src_bssid, ETH_ALEN))) {
2211                                 DBG_8723A("matched by bssid\n");
2212
2213                                 ndis_ssid.ssid_len =
2214                                     pnetwork->network.Ssid.ssid_len;
2215                                 memcpy(ndis_ssid.ssid,
2216                                        pnetwork->network.Ssid.ssid,
2217                                        pnetwork->network.Ssid.ssid_len);
2218
2219                                 matched = true;
2220                                 break;
2221                         }
2222
2223                 } else if (sme->ssid && sme->ssid_len) {
2224                         src_ssid = ndis_ssid.ssid;
2225
2226                         if ((!memcmp(dst_ssid, src_ssid, ndis_ssid.ssid_len)) &&
2227                             (pnetwork->network.Ssid.ssid_len ==
2228                              ndis_ssid.ssid_len)) {
2229                                 DBG_8723A("matched by ssid\n");
2230                                 matched = true;
2231                                 break;
2232                         }
2233                 }
2234         }
2235
2236         spin_unlock_bh(&queue->lock);
2237
2238         if (!matched || (pnetwork == NULL)) {
2239                 ret = -ENOENT;
2240                 DBG_8723A("connect, matched == false, goto exit\n");
2241                 goto exit;
2242         }
2243
2244         if (rtw_set_802_11_infrastructure_mode23a
2245             (padapter, pnetwork->network.InfrastructureMode) == false) {
2246                 ret = -EPERM;
2247                 goto exit;
2248         }
2249
2250         psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
2251         psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
2252         psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
2253         psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2254         psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
2255
2256         ret =
2257             rtw_cfg80211_set_wpa_version(psecuritypriv,
2258                                          sme->crypto.wpa_versions);
2259         if (ret < 0)
2260                 goto exit;
2261
2262         ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
2263
2264         if (ret < 0)
2265                 goto exit;
2266
2267         DBG_8723A("%s, ie_len =%zu\n", __func__, sme->ie_len);
2268
2269         ret = rtw_cfg80211_set_wpa_ie(padapter, sme->ie, sme->ie_len);
2270         if (ret < 0)
2271                 goto exit;
2272
2273         if (sme->crypto.n_ciphers_pairwise) {
2274                 ret = rtw_cfg80211_set_cipher(psecuritypriv,
2275                                               sme->crypto.ciphers_pairwise[0],
2276                                               true);
2277                 if (ret < 0)
2278                         goto exit;
2279         }
2280
2281         /* For WEP Shared auth */
2282         if ((psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Shared ||
2283              psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_Auto) &&
2284             sme->key) {
2285                 u32 wep_key_idx, wep_key_len, wep_total_len;
2286                 struct ndis_802_11_wep *pwep = NULL;
2287                 DBG_8723A("%s(): Shared/Auto WEP\n", __func__);
2288
2289                 wep_key_idx = sme->key_idx;
2290                 wep_key_len = sme->key_len;
2291
2292                 if (sme->key_idx > WEP_KEYS) {
2293                         ret = -EINVAL;
2294                         goto exit;
2295                 }
2296
2297                 if (wep_key_len > 0) {
2298                         wep_key_len = wep_key_len <= 5 ? 5 : 13;
2299                         wep_total_len =
2300                                 wep_key_len +
2301                                 offsetof(struct ndis_802_11_wep, KeyMaterial);
2302                         pwep = (struct ndis_802_11_wep *)kmalloc(wep_total_len,
2303                                                                  GFP_KERNEL);
2304                         if (pwep == NULL) {
2305                                 DBG_8723A(" wpa_set_encryption: pwep "
2306                                           "allocate fail !!!\n");
2307                                 ret = -ENOMEM;
2308                                 goto exit;
2309                         }
2310
2311                         memset(pwep, 0, wep_total_len);
2312
2313                         pwep->KeyLength = wep_key_len;
2314                         pwep->Length = wep_total_len;
2315
2316                         if (wep_key_len == 13) {
2317                                 padapter->securitypriv.dot11PrivacyAlgrthm =
2318                                     _WEP104_;
2319                                 padapter->securitypriv.dot118021XGrpPrivacy =
2320                                     _WEP104_;
2321                         }
2322                 } else {
2323                         ret = -EINVAL;
2324                         goto exit;
2325                 }
2326
2327                 pwep->KeyIndex = wep_key_idx;
2328                 pwep->KeyIndex |= 0x80000000;
2329
2330                 memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
2331
2332                 if (rtw_set_802_11_add_wep23a(padapter, pwep) == (u8) _FAIL) {
2333                         ret = -EOPNOTSUPP;
2334                 }
2335
2336                 kfree(pwep);
2337
2338                 if (ret < 0)
2339                         goto exit;
2340         }
2341
2342         ret = rtw_cfg80211_set_cipher(psecuritypriv,
2343                                       sme->crypto.cipher_group, false);
2344         if (ret < 0)
2345                 return ret;
2346
2347         if (sme->crypto.n_akm_suites) {
2348                 ret = rtw_cfg80211_set_key_mgt(psecuritypriv,
2349                                                sme->crypto.akm_suites[0]);
2350                 if (ret < 0)
2351                         goto exit;
2352         }
2353
2354         authmode = psecuritypriv->ndisauthtype;
2355         rtw_set_802_11_authentication_mode23a(padapter, authmode);
2356
2357         /* rtw_set_802_11_encryption_mode(padapter,
2358            padapter->securitypriv.ndisencryptstatus); */
2359
2360         if (rtw_set_802_11_ssid23a(padapter, &ndis_ssid) == false) {
2361                 ret = -1;
2362                 goto exit;
2363         }
2364
2365         DBG_8723A("set ssid:dot11AuthAlgrthm =%d, dot11PrivacyAlgrthm =%d, "
2366                   "dot118021XGrpPrivacy =%d\n", psecuritypriv->dot11AuthAlgrthm,
2367                   psecuritypriv->dot11PrivacyAlgrthm,
2368                   psecuritypriv->dot118021XGrpPrivacy);
2369
2370 exit:
2371
2372         DBG_8723A("<=%s, ret %d\n", __func__, ret);
2373
2374         return ret;
2375 }
2376
2377 static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2378                                    u16 reason_code)
2379 {
2380         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2381
2382         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
2383
2384         rtw_set_roaming(padapter, 0);
2385
2386         if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
2387                 rtw_scan_abort23a(padapter);
2388                 LeaveAllPowerSaveMode23a(padapter);
2389                 rtw_disassoc_cmd23a(padapter, 500, false);
2390
2391                 DBG_8723A("%s...call rtw_indicate_disconnect23a\n", __func__);
2392
2393                 padapter->mlmepriv.not_indic_disco = true;
2394                 rtw_indicate_disconnect23a(padapter);
2395                 padapter->mlmepriv.not_indic_disco = false;
2396
2397                 rtw_free_assoc_resources23a(padapter, 1);
2398         }
2399
2400         return 0;
2401 }
2402
2403 static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
2404                                     struct wireless_dev *wdev,
2405                                     enum nl80211_tx_power_setting type, int mbm)
2406 {
2407         DBG_8723A("%s\n", __func__);
2408         return 0;
2409 }
2410
2411 static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
2412                                     struct wireless_dev *wdev, int *dbm)
2413 {
2414         DBG_8723A("%s\n", __func__);
2415         *dbm = (12);
2416         return 0;
2417 }
2418
2419 inline bool rtw_cfg80211_pwr_mgmt(struct rtw_adapter *adapter)
2420 {
2421         struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(adapter->rtw_wdev);
2422         return rtw_wdev_priv->power_mgmt;
2423 }
2424
2425 static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
2426                                        struct net_device *ndev,
2427                                        bool enabled, int timeout)
2428 {
2429         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2430         struct rtw_wdev_priv *rtw_wdev_priv = wdev_to_priv(padapter->rtw_wdev);
2431
2432         DBG_8723A(FUNC_NDEV_FMT " enabled:%u, timeout:%d\n",
2433                   FUNC_NDEV_ARG(ndev), enabled, timeout);
2434
2435         rtw_wdev_priv->power_mgmt = enabled;
2436
2437         if (!enabled)
2438                 LPS_Leave23a(padapter);
2439
2440         return 0;
2441 }
2442
2443 static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
2444                                   struct net_device *netdev,
2445                                   struct cfg80211_pmksa *pmksa)
2446 {
2447         u8 index, blInserted = false;
2448         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2449         struct security_priv *psecuritypriv = &padapter->securitypriv;
2450         u8 strZeroMacAddress[ETH_ALEN] = { 0x00 };
2451
2452         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(netdev));
2453
2454         if (!memcmp(pmksa->bssid, strZeroMacAddress, ETH_ALEN)) {
2455                 return -EINVAL;
2456         }
2457
2458         blInserted = false;
2459
2460         /* overwrite PMKID */
2461         for (index = 0; index < NUM_PMKID_CACHE; index++) {
2462                 if (!memcmp(psecuritypriv->PMKIDList[index].Bssid,
2463                             pmksa->bssid, ETH_ALEN)) {
2464                         /* BSSID is matched, the same AP => rewrite with
2465                            new PMKID. */
2466                         DBG_8723A(FUNC_NDEV_FMT
2467                                   " BSSID exists in the PMKList.\n",
2468                                   FUNC_NDEV_ARG(netdev));
2469
2470                         memcpy(psecuritypriv->PMKIDList[index].PMKID,
2471                                pmksa->pmkid, WLAN_PMKID_LEN);
2472                         psecuritypriv->PMKIDList[index].bUsed = true;
2473                         psecuritypriv->PMKIDIndex = index + 1;
2474                         blInserted = true;
2475                         break;
2476                 }
2477         }
2478
2479         if (!blInserted) {
2480                 /*  Find a new entry */
2481                 DBG_8723A(FUNC_NDEV_FMT
2482                           " Use the new entry index = %d for this PMKID.\n",
2483                           FUNC_NDEV_ARG(netdev), psecuritypriv->PMKIDIndex);
2484
2485                 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
2486                        Bssid, pmksa->bssid, ETH_ALEN);
2487                 memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].
2488                        PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2489
2490                 psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed =
2491                         true;
2492                 psecuritypriv->PMKIDIndex++;
2493                 if (psecuritypriv->PMKIDIndex == 16) {
2494                         psecuritypriv->PMKIDIndex = 0;
2495                 }
2496         }
2497
2498         return 0;
2499 }
2500
2501 static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
2502                                   struct net_device *netdev,
2503                                   struct cfg80211_pmksa *pmksa)
2504 {
2505         u8 index, bMatched = false;
2506         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2507         struct security_priv *psecuritypriv = &padapter->securitypriv;
2508
2509         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(netdev));
2510
2511         for (index = 0; index < NUM_PMKID_CACHE; index++) {
2512                 if (!memcmp(psecuritypriv->PMKIDList[index].Bssid,
2513                             pmksa->bssid, ETH_ALEN)) {
2514                         /* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
2515                         memset(psecuritypriv->PMKIDList[index].Bssid, 0x00,
2516                                ETH_ALEN);
2517                         memset(psecuritypriv->PMKIDList[index].PMKID, 0x00,
2518                                WLAN_PMKID_LEN);
2519                         psecuritypriv->PMKIDList[index].bUsed = false;
2520                         bMatched = true;
2521                         break;
2522                 }
2523         }
2524
2525         if (false == bMatched) {
2526                 DBG_8723A(FUNC_NDEV_FMT " do not have matched BSSID\n",
2527                           FUNC_NDEV_ARG(netdev));
2528                 return -EINVAL;
2529         }
2530
2531         return 0;
2532 }
2533
2534 static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
2535                                     struct net_device *netdev)
2536 {
2537         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2538         struct security_priv *psecuritypriv = &padapter->securitypriv;
2539
2540         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(netdev));
2541
2542         memset(&psecuritypriv->PMKIDList[0], 0x00,
2543                sizeof(struct rt_pmkid_list) * NUM_PMKID_CACHE);
2544         psecuritypriv->PMKIDIndex = 0;
2545
2546         return 0;
2547 }
2548
2549 #ifdef CONFIG_8723AU_AP_MODE
2550 void rtw_cfg80211_indicate_sta_assoc(struct rtw_adapter *padapter,
2551                                      u8 *pmgmt_frame, uint frame_len)
2552 {
2553         s32 freq;
2554         int channel;
2555         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2556         struct net_device *ndev = padapter->pnetdev;
2557
2558         DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name);
2559
2560 #if defined(RTW_USE_CFG80211_STA_EVENT)
2561         {
2562                 struct station_info sinfo;
2563                 u8 ie_offset;
2564                 if (ieee80211_is_assoc_req(hdr->frame_control))
2565                         ie_offset = _ASOCREQ_IE_OFFSET_;
2566                 else            /*  WIFI_REASSOCREQ */
2567                         ie_offset = _REASOCREQ_IE_OFFSET_;
2568
2569                 sinfo.filled = 0;
2570                 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
2571                 sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
2572                 sinfo.assoc_req_ies_len =
2573                         frame_len - WLAN_HDR_A3_LEN - ie_offset;
2574                 cfg80211_new_sta(ndev, hdr->addr2, &sinfo, GFP_ATOMIC);
2575         }
2576 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
2577         channel = pmlmeext->cur_channel;
2578         if (channel <= RTW_CH_MAX_2G_CHANNEL)
2579                 freq = ieee80211_channel_to_frequency(channel,
2580                                                       IEEE80211_BAND_2GHZ);
2581         else
2582                 freq = ieee80211_channel_to_frequency(channel,
2583                                                       IEEE80211_BAND_5GHZ);
2584
2585         rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len,
2586                              GFP_ATOMIC);
2587 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
2588 }
2589
2590 void rtw_cfg80211_indicate_sta_disassoc(struct rtw_adapter *padapter,
2591                                         unsigned char *da,
2592                                         unsigned short reason)
2593 {
2594         s32 freq;
2595         int channel;
2596         u8 *pmgmt_frame;
2597         uint frame_len;
2598         struct ieee80211_hdr *pwlanhdr;
2599         unsigned short *fctrl;
2600         u8 mgmt_buf[128] = { 0 };
2601         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2602         struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2603         struct net_device *ndev = padapter->pnetdev;
2604
2605         DBG_8723A("%s(padapter =%p,%s)\n", __func__, padapter, ndev->name);
2606
2607 #if defined(RTW_USE_CFG80211_STA_EVENT)
2608         cfg80211_del_sta(ndev, da, GFP_ATOMIC);
2609 #else /* defined(RTW_USE_CFG80211_STA_EVENT) */
2610         channel = pmlmeext->cur_channel;
2611         if (channel <= RTW_CH_MAX_2G_CHANNEL)
2612                 freq = ieee80211_channel_to_frequency(channel,
2613                                                       IEEE80211_BAND_2GHZ);
2614         else
2615                 freq = ieee80211_channel_to_frequency(channel,
2616                                                       IEEE80211_BAND_5GHZ);
2617
2618         pmgmt_frame = mgmt_buf;
2619         pwlanhdr = (struct ieee80211_hdr *)pmgmt_frame;
2620
2621         fctrl = &pwlanhdr->frame_control;
2622         *(fctrl) = 0;
2623
2624         memcpy(pwlanhdr->addr1, myid(&padapter->eeprompriv), ETH_ALEN);
2625         memcpy(pwlanhdr->addr2, da, ETH_ALEN);
2626         memcpy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN);
2627
2628         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2629         pmlmeext->mgnt_seq++;
2630         SetFrameSubType(pmgmt_frame, WIFI_DEAUTH);
2631
2632         pmgmt_frame += sizeof(struct ieee80211_hdr_3addr);
2633         frame_len = sizeof(struct ieee80211_hdr_3addr);
2634
2635         reason = cpu_to_le16(reason);
2636         pmgmt_frame = rtw_set_fixed_ie23a(pmgmt_frame,
2637                                        WLAN_REASON_PREV_AUTH_NOT_VALID,
2638                                        (unsigned char *)&reason, &frame_len);
2639
2640         rtw_cfg80211_rx_mgmt(padapter, freq, 0, mgmt_buf, frame_len,
2641                              GFP_ATOMIC);
2642 #endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
2643 }
2644
2645 static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
2646 {
2647         int ret = 0;
2648
2649         DBG_8723A("%s\n", __func__);
2650
2651         return ret;
2652 }
2653
2654 static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
2655 {
2656         int ret = 0;
2657
2658         DBG_8723A("%s\n", __func__);
2659
2660         return ret;
2661 }
2662
2663 static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb,
2664                                               struct net_device *ndev)
2665 {
2666         int ret = 0;
2667         int rtap_len;
2668         int qos_len = 0;
2669         int dot11_hdr_len = 24;
2670         int snap_len = 6;
2671         unsigned char *pdata;
2672         unsigned char src_mac_addr[6];
2673         unsigned char dst_mac_addr[6];
2674         struct ieee80211_hdr *dot11_hdr;
2675         struct ieee80211_radiotap_header *rtap_hdr;
2676         struct rtw_adapter *padapter = netdev_priv(ndev);
2677
2678         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
2679
2680         if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
2681                 goto fail;
2682
2683         rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
2684         if (unlikely(rtap_hdr->it_version))
2685                 goto fail;
2686
2687         rtap_len = ieee80211_get_radiotap_len(skb->data);
2688         if (unlikely(skb->len < rtap_len))
2689                 goto fail;
2690
2691         if (rtap_len != 14) {
2692                 DBG_8723A("radiotap len (should be 14): %d\n", rtap_len);
2693                 goto fail;
2694         }
2695
2696         /* Skip the ratio tap header */
2697         skb_pull(skb, rtap_len);
2698
2699         dot11_hdr = (struct ieee80211_hdr *)skb->data;
2700         /* Check if the QoS bit is set */
2701         if (ieee80211_is_data(dot11_hdr->frame_control)) {
2702                 /* Check if this ia a Wireless Distribution System (WDS) frame
2703                  * which has 4 MAC addresses
2704                  */
2705                 if (ieee80211_is_data_qos(dot11_hdr->frame_control))
2706                         qos_len = IEEE80211_QOS_CTL_LEN;
2707                 if (ieee80211_has_a4(dot11_hdr->frame_control))
2708                         dot11_hdr_len += 6;
2709
2710                 memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
2711                 memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
2712
2713                 /*
2714                  * Skip the 802.11 header, QoS (if any) and SNAP,
2715                  * but leave spaces for two MAC addresses
2716                  */
2717                 skb_pull(skb, dot11_hdr_len + qos_len + snap_len -
2718                          ETH_ALEN * 2);
2719                 pdata = (unsigned char *)skb->data;
2720                 memcpy(pdata, dst_mac_addr, ETH_ALEN);
2721                 memcpy(pdata + ETH_ALEN, src_mac_addr, ETH_ALEN);
2722
2723                 DBG_8723A("should be eapol packet\n");
2724
2725                 /* Use the real net device to transmit the packet */
2726                 ret = rtw_xmit23a_entry23a(skb, padapter->pnetdev);
2727
2728                 return ret;
2729
2730         } else if (ieee80211_is_action(dot11_hdr->frame_control)) {
2731                 /* only for action frames */
2732                 struct xmit_frame *pmgntframe;
2733                 struct pkt_attrib *pattrib;
2734                 unsigned char *pframe;
2735                 /* u8 category, action, OUI_Subtype, dialogToken = 0; */
2736                 /* unsigned char        *frame_body; */
2737                 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2738                 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2739                 u32 len = skb->len;
2740                 u8 category, action;
2741                 int type = -1;
2742
2743                 if (rtw_action_frame_parse23a(skb->data, len, &category,
2744                                            &action) == false) {
2745                         DBG_8723A(FUNC_NDEV_FMT " frame_control:0x%x\n",
2746                                   FUNC_NDEV_ARG(ndev),
2747                                   le16_to_cpu(dot11_hdr->frame_control));
2748                         goto fail;
2749                 }
2750
2751                 DBG_8723A("RTW_Tx:da =" MAC_FMT " via " FUNC_NDEV_FMT "\n",
2752                           MAC_ARG(dot11_hdr->addr1), FUNC_NDEV_ARG(ndev));
2753 #ifdef CONFIG_8723AU_P2P
2754                 type = rtw_p2p_check_frames(padapter, skb->data, len, true);
2755                 if (type >= 0)
2756                         goto dump;
2757 #endif
2758                 if (category == WLAN_CATEGORY_PUBLIC)
2759                         DBG_8723A("RTW_Tx:%s\n", action_public_str23a(action));
2760                 else
2761                         DBG_8723A("RTW_Tx:category(%u), action(%u)\n", category,
2762                                   action);
2763 dump:
2764                 /* starting alloc mgmt frame to dump it */
2765                 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2766                 if (pmgntframe == NULL)
2767                         goto fail;
2768
2769                 /* update attribute */
2770                 pattrib = &pmgntframe->attrib;
2771                 update_mgntframe_attrib23a(padapter, pattrib);
2772                 pattrib->retry_ctrl = false;
2773
2774                 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2775
2776                 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2777
2778                 memcpy(pframe, skb->data, len);
2779 #ifdef CONFIG_8723AU_P2P
2780                 if (type >= 0) {
2781                         struct wifi_display_info *pwfd_info;
2782
2783                         pwfd_info = padapter->wdinfo.wfd_info;
2784
2785                         if (pwfd_info->wfd_enable)
2786                                 rtw_append_wfd_ie(padapter, pframe, &len);
2787                 }
2788 #endif /*  CONFIG_8723AU_P2P */
2789                 pattrib->pktlen = len;
2790
2791                 /* update seq number */
2792                 pmlmeext->mgnt_seq = le16_to_cpu(dot11_hdr->seq_ctrl) >> 4;
2793                 pattrib->seqnum = pmlmeext->mgnt_seq;
2794                 pmlmeext->mgnt_seq++;
2795
2796                 pattrib->last_txcmdsz = pattrib->pktlen;
2797
2798                 dump_mgntframe23a(padapter, pmgntframe);
2799         }
2800
2801 fail:
2802
2803         dev_kfree_skb(skb);
2804
2805         return 0;
2806 }
2807
2808 static int
2809 rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
2810 {
2811         int ret = 0;
2812
2813         DBG_8723A("%s\n", __func__);
2814
2815         return ret;
2816 }
2817
2818 static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
2819         .ndo_open = rtw_cfg80211_monitor_if_open,
2820         .ndo_stop = rtw_cfg80211_monitor_if_close,
2821         .ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
2822         .ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
2823 };
2824
2825 static int rtw_cfg80211_add_monitor_if(struct rtw_adapter *padapter, char *name,
2826                                        struct net_device **ndev)
2827 {
2828         int ret = 0;
2829         struct net_device *mon_ndev = NULL;
2830         struct wireless_dev *mon_wdev = NULL;
2831         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
2832
2833         if (!name) {
2834                 DBG_8723A(FUNC_ADPT_FMT " without specific name\n",
2835                           FUNC_ADPT_ARG(padapter));
2836                 ret = -EINVAL;
2837                 goto out;
2838         }
2839
2840         if (pwdev_priv->pmon_ndev) {
2841                 DBG_8723A(FUNC_ADPT_FMT " monitor interface exist: " NDEV_FMT
2842                           "\n", FUNC_ADPT_ARG(padapter),
2843                           NDEV_ARG(pwdev_priv->pmon_ndev));
2844                 ret = -EBUSY;
2845                 goto out;
2846         }
2847
2848         mon_ndev = alloc_etherdev(sizeof(struct rtw_adapter));
2849         if (!mon_ndev) {
2850                 DBG_8723A(FUNC_ADPT_FMT " allocate ndev fail\n",
2851                           FUNC_ADPT_ARG(padapter));
2852                 ret = -ENOMEM;
2853                 goto out;
2854         }
2855
2856         mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
2857         strncpy(mon_ndev->name, name, IFNAMSIZ);
2858         mon_ndev->name[IFNAMSIZ - 1] = 0;
2859         mon_ndev->destructor = rtw_ndev_destructor;
2860
2861         mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
2862
2863         /*  wdev */
2864         mon_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2865         if (!mon_wdev) {
2866                 DBG_8723A(FUNC_ADPT_FMT " allocate mon_wdev fail\n",
2867                           FUNC_ADPT_ARG(padapter));
2868                 ret = -ENOMEM;
2869                 goto out;
2870         }
2871
2872         mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
2873         mon_wdev->netdev = mon_ndev;
2874         mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
2875         mon_ndev->ieee80211_ptr = mon_wdev;
2876
2877         ret = register_netdevice(mon_ndev);
2878         if (ret) {
2879                 goto out;
2880         }
2881
2882         *ndev = pwdev_priv->pmon_ndev = mon_ndev;
2883         memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ + 1);
2884
2885 out:
2886         if (ret) {
2887                 kfree(mon_wdev);
2888                 mon_wdev = NULL;
2889         }
2890
2891         if (ret && mon_ndev) {
2892                 free_netdev(mon_ndev);
2893                 *ndev = mon_ndev = NULL;
2894         }
2895
2896         return ret;
2897 }
2898
2899 static struct wireless_dev *
2900 cfg80211_rtw_add_virtual_intf(struct wiphy *wiphy, const char *name,
2901                               enum nl80211_iftype type, u32 *flags,
2902                               struct vif_params *params)
2903 {
2904         int ret = 0;
2905         struct net_device *ndev = NULL;
2906         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
2907
2908         DBG_8723A(FUNC_ADPT_FMT " wiphy:%s, name:%s, type:%d\n",
2909                   FUNC_ADPT_ARG(padapter), wiphy_name(wiphy), name, type);
2910
2911         switch (type) {
2912         case NL80211_IFTYPE_ADHOC:
2913         case NL80211_IFTYPE_AP_VLAN:
2914         case NL80211_IFTYPE_WDS:
2915         case NL80211_IFTYPE_MESH_POINT:
2916                 ret = -ENODEV;
2917                 break;
2918         case NL80211_IFTYPE_MONITOR:
2919                 ret =
2920                     rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
2921                 break;
2922
2923         case NL80211_IFTYPE_P2P_CLIENT:
2924         case NL80211_IFTYPE_STATION:
2925                 ret = -ENODEV;
2926                 break;
2927
2928         case NL80211_IFTYPE_P2P_GO:
2929         case NL80211_IFTYPE_AP:
2930                 ret = -ENODEV;
2931                 break;
2932         default:
2933                 ret = -ENODEV;
2934                 DBG_8723A("Unsupported interface type\n");
2935                 break;
2936         }
2937
2938         DBG_8723A(FUNC_ADPT_FMT " ndev:%p, ret:%d\n", FUNC_ADPT_ARG(padapter),
2939                   ndev, ret);
2940
2941         return ndev ? ndev->ieee80211_ptr : ERR_PTR(ret);
2942 }
2943
2944 static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
2945                                          struct wireless_dev *wdev)
2946 {
2947         struct rtw_wdev_priv *pwdev_priv =
2948             (struct rtw_wdev_priv *)wiphy_priv(wiphy);
2949         struct net_device *ndev;
2950         ndev = wdev ? wdev->netdev : NULL;
2951
2952         if (!ndev)
2953                 goto exit;
2954
2955         unregister_netdevice(ndev);
2956
2957         if (ndev == pwdev_priv->pmon_ndev) {
2958                 pwdev_priv->pmon_ndev = NULL;
2959                 pwdev_priv->ifname_mon[0] = '\0';
2960                 DBG_8723A(FUNC_NDEV_FMT " remove monitor interface\n",
2961                           FUNC_NDEV_ARG(ndev));
2962         }
2963
2964 exit:
2965         return 0;
2966 }
2967
2968 static int rtw_add_beacon(struct rtw_adapter *adapter, const u8 *head,
2969                           size_t head_len, const u8 *tail, size_t tail_len)
2970 {
2971         int ret = 0;
2972         u8 *pbuf = NULL;
2973         uint len, wps_ielen = 0;
2974         uint p2p_ielen = 0;
2975         u8 got_p2p_ie = false;
2976         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2977         /* struct sta_priv *pstapriv = &padapter->stapriv; */
2978
2979         DBG_8723A("%s beacon_head_len =%zu, beacon_tail_len =%zu\n",
2980                   __func__, head_len, tail_len);
2981
2982         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != true)
2983                 return -EINVAL;
2984
2985         if (head_len < 24)
2986                 return -EINVAL;
2987
2988         pbuf = kzalloc(head_len + tail_len, GFP_KERNEL);
2989         if (!pbuf)
2990                 return -ENOMEM;
2991         /*  24 = beacon header len. */
2992         memcpy(pbuf, (void *)head + 24, head_len - 24);
2993         memcpy(pbuf + head_len - 24, (void *)tail, tail_len);
2994
2995         len = head_len + tail_len - 24;
2996
2997         /* check wps ie if inclued */
2998         if (rtw_get_wps_ie23a
2999             (pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL,
3000              &wps_ielen))
3001                 DBG_8723A("add bcn, wps_ielen =%d\n", wps_ielen);
3002
3003 #ifdef CONFIG_8723AU_P2P
3004         /* check p2p ie if inclued */
3005         if (rtw_get_p2p_ie23a
3006             (pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL,
3007              &p2p_ielen)) {
3008                 DBG_8723A("got p2p_ie, len =%d\n", p2p_ielen);
3009                 got_p2p_ie = true;
3010         }
3011 #endif
3012
3013         /* pbss_network->IEs will not include p2p_ie, wfd ie */
3014         rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_,
3015                           P2P_OUI23A, 4);
3016         rtw_ies_remove_ie23a(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_,
3017                           WFD_OUI23A, 4);
3018
3019         if (rtw_check_beacon_data23a(adapter, pbuf, len) == _SUCCESS) {
3020 #ifdef CONFIG_8723AU_P2P
3021                 /* check p2p if enable */
3022                 if (got_p2p_ie == true) {
3023                         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
3024                         struct wifidirect_info *pwdinfo = &adapter->wdinfo;
3025
3026                         if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
3027                                 DBG_8723A("Enable P2P function for the first "
3028                                           "time\n");
3029                                 rtw_p2p_enable23a(adapter, P2P_ROLE_GO);
3030                                 wdev_to_priv(adapter->rtw_wdev)->p2p_enabled =
3031                                         true;
3032                         } else {
3033                                 del_timer_sync(&pwdinfo->find_phase_timer);
3034                                 del_timer_sync(&pwdinfo->
3035                                                restore_p2p_state_timer);
3036                                 del_timer_sync(&pwdinfo->pre_tx_scan_timer);
3037
3038                                 DBG_8723A("enter GO Mode, p2p_ielen =%d\n",
3039                                           p2p_ielen);
3040
3041                                 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
3042                                 rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
3043                                 pwdinfo->intent = 15;
3044                         }
3045
3046                         pwdinfo->operating_channel = pmlmeext->cur_channel;
3047                 }
3048 #endif /* CONFIG_8723AU_P2P */
3049
3050                 ret = 0;
3051
3052         } else {
3053                 ret = -EINVAL;
3054         }
3055
3056         kfree(pbuf);
3057
3058         return ret;
3059 }
3060
3061 static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3062                                  struct cfg80211_ap_settings *settings)
3063 {
3064         int ret = 0;
3065         struct rtw_adapter *adapter = wiphy_to_adapter(wiphy);
3066
3067         DBG_8723A(FUNC_NDEV_FMT " hidden_ssid:%d, auth_type:%d\n",
3068                   FUNC_NDEV_ARG(ndev), settings->hidden_ssid,
3069                   settings->auth_type);
3070
3071         ret = rtw_add_beacon(adapter, settings->beacon.head,
3072                              settings->beacon.head_len, settings->beacon.tail,
3073                              settings->beacon.tail_len);
3074
3075         adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode =
3076                 settings->hidden_ssid;
3077
3078         if (settings->ssid && settings->ssid_len) {
3079                 struct wlan_bssid_ex *pbss_network =
3080                         &adapter->mlmepriv.cur_network.network;
3081                 struct wlan_bssid_ex *pbss_network_ext =
3082                         &adapter->mlmeextpriv.mlmext_info.network;
3083
3084                 if (0)
3085                         DBG_8723A(FUNC_ADPT_FMT
3086                                   " ssid:(%s,%d), from ie:(%s,%d)\n",
3087                                   FUNC_ADPT_ARG(adapter), settings->ssid,
3088                                   (int)settings->ssid_len,
3089                                   pbss_network->Ssid.ssid,
3090                                   pbss_network->Ssid.ssid_len);
3091
3092                 memcpy(pbss_network->Ssid.ssid, (void *)settings->ssid,
3093                        settings->ssid_len);
3094                 pbss_network->Ssid.ssid_len = settings->ssid_len;
3095                 memcpy(pbss_network_ext->Ssid.ssid, (void *)settings->ssid,
3096                        settings->ssid_len);
3097                 pbss_network_ext->Ssid.ssid_len = settings->ssid_len;
3098
3099                 if (0)
3100                         DBG_8723A(FUNC_ADPT_FMT
3101                                   " after ssid:(%s,%d), (%s,%d)\n",
3102                                   FUNC_ADPT_ARG(adapter),
3103                                   pbss_network->Ssid.ssid,
3104                                   pbss_network->Ssid.ssid_len,
3105                                   pbss_network_ext->Ssid.ssid,
3106                                   pbss_network_ext->Ssid.ssid_len);
3107         }
3108
3109         return ret;
3110 }
3111
3112 static int cfg80211_rtw_change_beacon(struct wiphy *wiphy,
3113                                       struct net_device *ndev,
3114                                       struct cfg80211_beacon_data *info)
3115 {
3116         int ret = 0;
3117         struct rtw_adapter *adapter = wiphy_to_adapter(wiphy);
3118
3119         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3120
3121         ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail,
3122                              info->tail_len);
3123
3124         return ret;
3125 }
3126
3127 static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3128 {
3129         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3130         return 0;
3131 }
3132
3133 static int cfg80211_rtw_add_station(struct wiphy *wiphy,
3134                                     struct net_device *ndev, u8 *mac,
3135                                     struct station_parameters *params)
3136 {
3137         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3138
3139         return 0;
3140 }
3141
3142 static int cfg80211_rtw_del_station(struct wiphy *wiphy,
3143                                     struct net_device *ndev, u8 *mac)
3144 {
3145         int ret = 0;
3146         struct list_head *phead, *plist, *ptmp;
3147         u8 updated = 0;
3148         struct sta_info *psta;
3149         struct rtw_adapter *padapter = netdev_priv(ndev);
3150         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3151         struct sta_priv *pstapriv = &padapter->stapriv;
3152
3153         DBG_8723A("+" FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3154
3155         if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != true) {
3156                 DBG_8723A("%s, fw_state != FW_LINKED|WIFI_AP_STATE\n",
3157                           __func__);
3158                 return -EINVAL;
3159         }
3160
3161         if (!mac) {
3162                 DBG_8723A("flush all sta, and cam_entry\n");
3163
3164                 flush_all_cam_entry23a(padapter);       /* clear CAM */
3165
3166                 ret = rtw_sta_flush23a(padapter);
3167
3168                 return ret;
3169         }
3170
3171         DBG_8723A("free sta macaddr =" MAC_FMT "\n", MAC_ARG(mac));
3172
3173         if (is_broadcast_ether_addr(mac))
3174                 return -EINVAL;
3175
3176         spin_lock_bh(&pstapriv->asoc_list_lock);
3177
3178         phead = &pstapriv->asoc_list;
3179
3180         /* check asoc_queue */
3181         list_for_each_safe(plist, ptmp, phead) {
3182                 psta = container_of(plist, struct sta_info, asoc_list);
3183
3184                 if (!memcmp(mac, psta->hwaddr, ETH_ALEN)) {
3185                         if (psta->dot8021xalg == 1 &&
3186                             psta->bpairwise_key_installed == false) {
3187                                 DBG_8723A("%s, sta's dot8021xalg = 1 and "
3188                                           "key_installed = false\n", __func__);
3189                         } else {
3190                                 DBG_8723A("free psta =%p, aid =%d\n", psta,
3191                                           psta->aid);
3192
3193                                 list_del_init(&psta->asoc_list);
3194                                 pstapriv->asoc_list_cnt--;
3195
3196                                 /* spin_unlock_bh(&pstapriv->asoc_list_lock); */
3197                                 updated =
3198                                     ap_free_sta23a(padapter, psta, true,
3199                                                 WLAN_REASON_DEAUTH_LEAVING);
3200                                 /* spin_lock_bh(&pstapriv->asoc_list_lock); */
3201
3202                                 psta = NULL;
3203
3204                                 break;
3205                         }
3206                 }
3207         }
3208
3209         spin_unlock_bh(&pstapriv->asoc_list_lock);
3210
3211         associated_clients_update23a(padapter, updated);
3212
3213         DBG_8723A("-" FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3214
3215         return ret;
3216 }
3217
3218 static int cfg80211_rtw_change_station(struct wiphy *wiphy,
3219                                        struct net_device *ndev, u8 *mac,
3220                                        struct station_parameters *params)
3221 {
3222         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3223         return 0;
3224 }
3225
3226 static int cfg80211_rtw_dump_station(struct wiphy *wiphy,
3227                                      struct net_device *ndev, int idx, u8 *mac,
3228                                      struct station_info *sinfo)
3229 {
3230         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3231
3232         /* TODO: dump scanned queue */
3233
3234         return -ENOENT;
3235 }
3236
3237 static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
3238                                    struct bss_parameters *params)
3239 {
3240         DBG_8723A(FUNC_NDEV_FMT "\n", FUNC_NDEV_ARG(ndev));
3241         return 0;
3242 }
3243 #endif /* CONFIG_8723AU_AP_MODE */
3244
3245 void rtw_cfg80211_rx_action_p2p(struct rtw_adapter *padapter, u8 *pmgmt_frame,
3246                                 uint frame_len)
3247 {
3248         int type;
3249         s32 freq;
3250         int channel;
3251         u8 category, action;
3252
3253         channel = rtw_get_oper_ch23a(padapter);
3254
3255         DBG_8723A("RTW_Rx:cur_ch =%d\n", channel);
3256 #ifdef CONFIG_8723AU_P2P
3257         type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, false);
3258         if (type >= 0)
3259                 goto indicate;
3260 #endif
3261         rtw_action_frame_parse23a(pmgmt_frame, frame_len, &category, &action);
3262         DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action);
3263
3264 indicate:
3265         if (channel <= RTW_CH_MAX_2G_CHANNEL)
3266                 freq = ieee80211_channel_to_frequency(channel,
3267                                                       IEEE80211_BAND_2GHZ);
3268         else
3269                 freq = ieee80211_channel_to_frequency(channel,
3270                                                       IEEE80211_BAND_5GHZ);
3271
3272         rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len,
3273                              GFP_ATOMIC);
3274 }
3275
3276 void rtw_cfg80211_rx_p2p_action_public(struct rtw_adapter *padapter,
3277                                        u8 *pmgmt_frame, uint frame_len)
3278 {
3279         int type;
3280         s32 freq;
3281         int channel;
3282         u8 category, action;
3283
3284         channel = rtw_get_oper_ch23a(padapter);
3285
3286         DBG_8723A("RTW_Rx:cur_ch =%d\n", channel);
3287 #ifdef CONFIG_8723AU_P2P
3288         type = rtw_p2p_check_frames(padapter, pmgmt_frame, frame_len, false);
3289         if (type >= 0) {
3290                 switch (type) {
3291                 case P2P_GO_NEGO_CONF:
3292                 case P2P_PROVISION_DISC_RESP:
3293                         rtw_clear_scan_deny(padapter);
3294                 }
3295                 goto indicate;
3296         }
3297 #endif
3298         rtw_action_frame_parse23a(pmgmt_frame, frame_len, &category, &action);
3299         DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category, action);
3300
3301 indicate:
3302         if (channel <= RTW_CH_MAX_2G_CHANNEL)
3303                 freq = ieee80211_channel_to_frequency(channel,
3304                                                       IEEE80211_BAND_2GHZ);
3305         else
3306                 freq = ieee80211_channel_to_frequency(channel,
3307                                                       IEEE80211_BAND_5GHZ);
3308
3309         rtw_cfg80211_rx_mgmt(padapter, freq, 0, pmgmt_frame, frame_len,
3310                              GFP_ATOMIC);
3311 }
3312
3313 void rtw_cfg80211_rx_action(struct rtw_adapter *adapter, u8 *frame,
3314                             uint frame_len, const char *msg)
3315 {
3316         s32 freq;
3317         int channel;
3318         u8 category, action;
3319
3320         channel = rtw_get_oper_ch23a(adapter);
3321
3322         rtw_action_frame_parse23a(frame, frame_len, &category, &action);
3323
3324         DBG_8723A("RTW_Rx:cur_ch =%d\n", channel);
3325         if (msg)
3326                 DBG_8723A("RTW_Rx:%s\n", msg);
3327         else
3328                 DBG_8723A("RTW_Rx:category(%u), action(%u)\n", category,
3329                           action);
3330
3331         if (channel <= RTW_CH_MAX_2G_CHANNEL)
3332                 freq = ieee80211_channel_to_frequency(channel,
3333                                                       IEEE80211_BAND_2GHZ);
3334         else
3335                 freq = ieee80211_channel_to_frequency(channel,
3336                                                       IEEE80211_BAND_5GHZ);
3337
3338         rtw_cfg80211_rx_mgmt(adapter, freq, 0, frame, frame_len, GFP_ATOMIC);
3339 }
3340
3341 #ifdef CONFIG_8723AU_P2P
3342 void rtw_cfg80211_issue_p2p_provision_request23a(struct rtw_adapter *padapter,
3343                                               const u8 *buf, size_t len)
3344 {
3345         u16 wps_devicepassword_id = 0x0000;
3346         uint wps_devicepassword_id_len = 0;
3347         u8 wpsie[255] = { 0x00 }, p2p_ie[255] = { 0x00 };
3348         uint p2p_ielen = 0;
3349         uint wpsielen = 0;
3350         u32 devinfo_contentlen = 0;
3351         u8 devinfo_content[64] = { 0x00 };
3352         u16 capability = 0;
3353         uint capability_len = 0;
3354
3355         unsigned char category = WLAN_CATEGORY_PUBLIC;
3356         u8 action = P2P_PUB_ACTION_ACTION;
3357         u8 dialogToken = 1;
3358         u32 p2poui = cpu_to_be32(P2POUI);
3359         u8 oui_subtype = P2P_PROVISION_DISC_REQ;
3360         u32 p2pielen = 0;
3361 #ifdef CONFIG_8723AU_P2P
3362         u32 wfdielen = 0;
3363 #endif /* CONFIG_8723AU_P2P */
3364
3365         struct xmit_frame *pmgntframe;
3366         struct pkt_attrib *pattrib;
3367         unsigned char *pframe;
3368         struct ieee80211_hdr *pwlanhdr, *hdr;
3369         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3370         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3371
3372         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3373         u8 *frame_body =
3374             (unsigned char *)(buf + sizeof(struct ieee80211_hdr_3addr));
3375         size_t frame_body_len = len - sizeof(struct ieee80211_hdr_3addr);
3376
3377         DBG_8723A("[%s] In\n", __func__);
3378
3379         hdr = (struct ieee80211_hdr *)buf;
3380         /* prepare for building provision_request frame */
3381         memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, hdr->addr1, ETH_ALEN);
3382         memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, hdr->addr1, ETH_ALEN);
3383
3384         pwdinfo->tx_prov_disc_info.wps_config_method_request =
3385             WPS_CM_PUSH_BUTTON;
3386
3387         rtw_get_wps_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_,
3388                        frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie,
3389                        &wpsielen);
3390         rtw_get_wps_attr_content23a(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID,
3391                                     (u8 *)&wps_devicepassword_id,
3392                                     &wps_devicepassword_id_len);
3393         wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
3394
3395         switch (wps_devicepassword_id) {
3396         case WPS_DPID_PIN:
3397                 pwdinfo->tx_prov_disc_info.wps_config_method_request =
3398                         WPS_CM_LABEL;
3399                 break;
3400         case WPS_DPID_USER_SPEC:
3401                 pwdinfo->tx_prov_disc_info.wps_config_method_request =
3402                         WPS_CM_DISPLYA;
3403                 break;
3404         case WPS_DPID_MACHINE_SPEC:
3405                 break;
3406         case WPS_DPID_REKEY:
3407                 break;
3408         case WPS_DPID_PBC:
3409                 pwdinfo->tx_prov_disc_info.wps_config_method_request =
3410                         WPS_CM_PUSH_BUTTON;
3411                 break;
3412         case WPS_DPID_REGISTRAR_SPEC:
3413                 pwdinfo->tx_prov_disc_info.wps_config_method_request =
3414                         WPS_CM_KEYPAD;
3415                 break;
3416         default:
3417                 break;
3418         }
3419
3420         if (rtw_get_p2p_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_,
3421                            frame_body_len - _PUBLIC_ACTION_IE_OFFSET_,
3422                            p2p_ie, &p2p_ielen)) {
3423                 rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen,
3424                                          P2P_ATTR_DEVICE_INFO, devinfo_content,
3425                                          &devinfo_contentlen);
3426                 rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY,
3427                                          (u8 *)&capability, &capability_len);
3428         }
3429
3430         /* start to build provision_request frame */
3431         memset(wpsie, 0, sizeof(wpsie));
3432         memset(p2p_ie, 0, sizeof(p2p_ie));
3433         p2p_ielen = 0;
3434
3435         pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3436         if (pmgntframe == NULL)
3437                 return;
3438         /* update attribute */
3439         pattrib = &pmgntframe->attrib;
3440         update_mgntframe_attrib23a(padapter, pattrib);
3441
3442         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3443
3444         pframe = (u8 *) (pmgntframe->buf_addr) + TXDESC_OFFSET;
3445         pwlanhdr = (struct ieee80211_hdr *)pframe;
3446
3447         pwlanhdr->frame_control = 0;
3448
3449         memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr,
3450                ETH_ALEN);
3451         memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
3452         memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr,
3453                ETH_ALEN);
3454
3455         SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3456         pmlmeext->mgnt_seq++;
3457         SetFrameSubType(pframe, WIFI_ACTION);
3458
3459         pframe += sizeof(struct ieee80211_hdr_3addr);
3460         pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3461
3462         pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
3463         pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
3464         pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *)&p2poui,
3465                                   &pattrib->pktlen);
3466         pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
3467         pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
3468
3469         /* build_prov_disc_request_p2p_ie23a */
3470         /*      P2P OUI */
3471         p2pielen = 0;
3472         p2p_ie[p2pielen++] = 0x50;
3473         p2p_ie[p2pielen++] = 0x6F;
3474         p2p_ie[p2pielen++] = 0x9A;
3475         p2p_ie[p2pielen++] = 0x09;      /*      WFA P2P v1.0 */
3476
3477         /*      Commented by Albert 20110301 */
3478         /*      According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes */
3479         /*      1. P2P Capability */
3480         /*      2. Device Info */
3481         /*      3. Group ID ( When joining an operating P2P Group ) */
3482
3483         /*      P2P Capability ATTR */
3484         /*      Type: */
3485         p2p_ie[p2pielen++] = P2P_ATTR_CAPABILITY;
3486
3487         /*      Length: */
3488         RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
3489         p2pielen += 2;
3490
3491         /*      Value: */
3492         /*      Device Capability Bitmap, 1 byte */
3493         /*      Group Capability Bitmap, 1 byte */
3494         memcpy(p2p_ie + p2pielen, &capability, 2);
3495         p2pielen += 2;
3496
3497         /*      Device Info ATTR */
3498         /*      Type: */
3499         p2p_ie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
3500
3501         /*      Length: */
3502         RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
3503         p2pielen += 2;
3504
3505         /*      Value: */
3506         memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
3507         p2pielen += devinfo_contentlen;
3508
3509         pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
3510                             (unsigned char *)p2p_ie, &p2p_ielen);
3511         pattrib->pktlen += p2p_ielen;
3512
3513         wpsielen = 0;
3514         /*      WPS OUI */
3515         *(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
3516         wpsielen += 4;
3517
3518         /*      WPS version */
3519         /*      Type: */
3520         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
3521         wpsielen += 2;
3522
3523         /*      Length: */
3524         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
3525         wpsielen += 2;
3526
3527         /*      Value: */
3528         wpsie[wpsielen++] = WPS_VERSION_1;      /*      Version 1.0 */
3529
3530         /*      Config Method */
3531         /*      Type: */
3532         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
3533         wpsielen += 2;
3534
3535         /*      Length: */
3536         *(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
3537         wpsielen += 2;
3538
3539         /*      Value: */
3540         *(u16 *)(wpsie + wpsielen) =
3541             cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
3542         wpsielen += 2;
3543
3544         pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen,
3545                             (unsigned char *)wpsie, &pattrib->pktlen);
3546
3547 #ifdef CONFIG_8723AU_P2P
3548         wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
3549         pframe += wfdielen;
3550         pattrib->pktlen += wfdielen;
3551 #endif /* CONFIG_8723AU_P2P */
3552
3553         pattrib->last_txcmdsz = pattrib->pktlen;
3554
3555         /* dump_mgntframe23a(padapter, pmgntframe); */
3556         if (dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe) != _SUCCESS)
3557                 DBG_8723A("%s, ack to\n", __func__);
3558 }
3559
3560 static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
3561                                           struct wireless_dev *wdev,
3562                                           struct ieee80211_channel *channel,
3563                                           unsigned int duration, u64 *cookie)
3564 {
3565         s32 err = 0;
3566         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
3567         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3568         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3569         struct cfg80211_wifidirect_info *pcfg80211_wdinfo =
3570             &padapter->cfg80211_wdinfo;
3571         u8 remain_ch =
3572                 (u8) ieee80211_frequency_to_channel(channel->center_freq);
3573         u8 ready_on_channel = false;
3574
3575         DBG_8723A(FUNC_ADPT_FMT " ch:%u duration:%d\n", FUNC_ADPT_ARG(padapter),
3576                   remain_ch, duration);
3577
3578         if (pcfg80211_wdinfo->is_ro_ch == true) {
3579                 DBG_8723A("%s, cancel ro ch timer\n", __func__);
3580
3581                 del_timer_sync(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
3582
3583                 p2p_protocol_wk_hdl23a(padapter, P2P_RO_CH_WK);
3584         }
3585
3586         pcfg80211_wdinfo->is_ro_ch = true;
3587
3588         if (_FAIL == rtw_pwr_wakeup(padapter)) {
3589                 err = -EFAULT;
3590                 goto exit;
3591         }
3592
3593         memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel,
3594                sizeof(struct ieee80211_channel));
3595         pcfg80211_wdinfo->remain_on_ch_cookie = *cookie;
3596
3597         rtw_scan_abort23a(padapter);
3598         if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
3599                 rtw_p2p_enable23a(padapter, P2P_ROLE_DEVICE);
3600                 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled = true;
3601         } else {
3602                 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
3603 #ifdef CONFIG_DEBUG_CFG80211
3604                 DBG_8723A("%s, role =%d, p2p_state =%d\n", __func__,
3605                           rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
3606 #endif
3607         }
3608
3609         rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
3610
3611         if (duration < 400)
3612                 duration = duration * 3;        /* extend from exper. */
3613
3614         pcfg80211_wdinfo->restore_channel = pmlmeext->cur_channel;
3615
3616         if (rtw_ch_set_search_ch23a(pmlmeext->channel_set, remain_ch) >= 0) {
3617                 if (remain_ch != pmlmeext->cur_channel) {
3618                         ready_on_channel = true;
3619                 }
3620         } else {
3621                 DBG_8723A("%s remain_ch:%u not in channel plan!!!!\n",
3622                           __func__, remain_ch);
3623         }
3624
3625         /* call this after other things have been done */
3626         if (ready_on_channel == true) {
3627                 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
3628                         pmlmeext->cur_channel = remain_ch;
3629
3630                         set_channel_bwmode23a(padapter, remain_ch,
3631                                            HAL_PRIME_CHNL_OFFSET_DONT_CARE,
3632                                            HT_CHANNEL_WIDTH_20);
3633                 }
3634         }
3635         DBG_8723A("%s, set ro ch timer, duration =%d\n", __func__, duration);
3636         mod_timer(&pcfg80211_wdinfo->remain_on_ch_timer,
3637                   jiffies + msecs_to_jiffies(duration));
3638
3639         rtw_cfg80211_ready_on_channel(padapter, *cookie, channel, channel_type,
3640                                       duration, GFP_KERNEL);
3641
3642         pwdinfo->listen_channel = pmlmeext->cur_channel;
3643
3644 exit:
3645         if (err)
3646                 pcfg80211_wdinfo->is_ro_ch = false;
3647
3648         return err;
3649 }
3650
3651 static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
3652                                                  struct wireless_dev *wdev,
3653                                                  u64 cookie)
3654 {
3655         s32 err = 0;
3656         struct rtw_adapter *padapter = wiphy_to_adapter(wiphy);
3657         struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3658         struct cfg80211_wifidirect_info *pcfg80211_wdinfo =
3659             &padapter->cfg80211_wdinfo;
3660
3661         DBG_8723A(FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(padapter));
3662
3663         if (pcfg80211_wdinfo->is_ro_ch == true) {
3664                 DBG_8723A("%s, cancel ro ch timer\n", __func__);
3665                 del_timer_sync(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
3666                 p2p_protocol_wk_hdl23a(padapter, P2P_RO_CH_WK);
3667         }
3668
3669         rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
3670 #ifdef CONFIG_DEBUG_CFG80211
3671         DBG_8723A("%s, role =%d, p2p_state =%d\n", __func__,
3672                   rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
3673 #endif
3674         pcfg80211_wdinfo->is_ro_ch = false;
3675
3676         return err;
3677 }
3678
3679 #endif /* CONFIG_8723AU_P2P */
3680
3681 static int _cfg80211_rtw_mgmt_tx(struct rtw_adapter *padapter, u8 tx_ch,
3682                                  const u8 *buf, size_t len)
3683 {
3684         struct xmit_frame *pmgntframe;
3685         struct pkt_attrib *pattrib;
3686         unsigned char *pframe;
3687         int ret = _FAIL;
3688         bool ack = true;
3689         struct ieee80211_hdr *pwlanhdr;
3690         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3691         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3692         /* struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo; */
3693
3694         if (_FAIL == rtw_pwr_wakeup(padapter)) {
3695                 ret = -EFAULT;
3696                 goto exit;
3697         }
3698
3699         rtw_set_scan_deny(padapter, 1000);
3700
3701         rtw_scan_abort23a(padapter);
3702
3703         if (tx_ch != rtw_get_oper_ch23a(padapter)) {
3704                 if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED))
3705                         pmlmeext->cur_channel = tx_ch;
3706                 set_channel_bwmode23a(padapter, tx_ch,
3707                                    HAL_PRIME_CHNL_OFFSET_DONT_CARE,
3708                                    HT_CHANNEL_WIDTH_20);
3709         }
3710
3711         /* starting alloc mgmt frame to dump it */
3712         pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3713         if (pmgntframe == NULL) {
3714                 /* ret = -ENOMEM; */
3715                 ret = _FAIL;
3716                 goto exit;
3717         }
3718
3719         /* update attribute */
3720         pattrib = &pmgntframe->attrib;
3721         update_mgntframe_attrib23a(padapter, pattrib);
3722         pattrib->retry_ctrl = false;
3723
3724         memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3725
3726         pframe = (u8 *) (pmgntframe->buf_addr) + TXDESC_OFFSET;
3727
3728         memcpy(pframe, (void *)buf, len);
3729         pattrib->pktlen = len;
3730
3731         pwlanhdr = (struct ieee80211_hdr *)pframe;
3732         /* update seq number */
3733         pmlmeext->mgnt_seq = le16_to_cpu(pwlanhdr->seq_ctrl) >> 4;
3734         pattrib->seqnum = pmlmeext->mgnt_seq;
3735         pmlmeext->mgnt_seq++;
3736
3737 #ifdef CONFIG_8723AU_P2P
3738         {
3739                 struct wifi_display_info *pwfd_info;
3740
3741                 pwfd_info = padapter->wdinfo.wfd_info;
3742
3743                 if (true == pwfd_info->wfd_enable) {
3744                         rtw_append_wfd_ie(padapter, pframe, &pattrib->pktlen);
3745                 }
3746         }
3747 #endif /*  CONFIG_8723AU_P2P */
3748
3749         pattrib->last_txcmdsz = pattrib->pktlen;
3750
3751         if (dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe) != _SUCCESS) {
3752                 ack = false;
3753                 ret = _FAIL;
3754
3755 #ifdef CONFIG_DEBUG_CFG80211
3756                 DBG_8723A("%s, ack == _FAIL\n", __func__);
3757 #endif
3758         } else {
3759 #ifdef CONFIG_DEBUG_CFG80211
3760                 DBG_8723A("%s, ack =%d, ok!\n", __func__, ack);
3761 #endif
3762                 ret = _SUCCESS;
3763         }
3764
3765 exit:
3766
3767 #ifdef CONFIG_DEBUG_CFG80211
3768         DBG_8723A("%s, ret =%d\n", __func__, ret);
3769 #endif
3770
3771         return ret;
3772 }
3773
3774 static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3775 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
3776                                 struct ieee80211_channel *chan,
3777                                 bool offchan,
3778                                 unsigned int wait,
3779                                 const u8 *buf, size_t len,
3780                                 bool no_cck, bool dont_wait_for_ack,
3781 #else
3782                                 struct cfg80211_mgmt_tx_params *params,
3783 #endif
3784                                 u64 *cookie)
3785 {
3786         struct rtw_adapter *padapter =
3787                 (struct rtw_adapter *)wiphy_to_adapter(wiphy);
3788         struct rtw_wdev_priv *pwdev_priv = wdev_to_priv(padapter->rtw_wdev);
3789         int ret = 0;
3790         int tx_ret;
3791         u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
3792         u32 dump_cnt = 0;
3793         bool ack = true;
3794         u8 category, action;
3795         int type = (-1);
3796         unsigned long start = jiffies;
3797 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
3798         size_t len = params->len;
3799         struct ieee80211_channel *chan = params->chan;
3800         const u8 *buf = params->buf;
3801 #endif
3802         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)buf;
3803         u8 tx_ch = (u8) ieee80211_frequency_to_channel(chan->center_freq);
3804
3805         /* cookie generation */
3806         *cookie = (unsigned long)buf;
3807
3808 #ifdef CONFIG_DEBUG_CFG80211
3809         DBG_8723A(FUNC_ADPT_FMT " len =%zu, ch =%d"
3810                   "\n", FUNC_ADPT_ARG(padapter), len, tx_ch);
3811 #endif /* CONFIG_DEBUG_CFG80211 */
3812
3813         /* indicate ack before issue frame to avoid racing with rsp frame */
3814         rtw_cfg80211_mgmt_tx_status(padapter, *cookie, buf, len, ack,
3815                                     GFP_KERNEL);
3816
3817         if (rtw_action_frame_parse23a(buf, len, &category, &action) == false) {
3818                 DBG_8723A(FUNC_ADPT_FMT " frame_control:0x%x\n",
3819                           FUNC_ADPT_ARG(padapter),
3820                           le16_to_cpu(hdr->frame_control));
3821                 goto exit;
3822         }
3823
3824         DBG_8723A("RTW_Tx:tx_ch =%d, da =" MAC_FMT "\n", tx_ch,
3825                   MAC_ARG(hdr->addr1));
3826 #ifdef CONFIG_8723AU_P2P
3827         type = rtw_p2p_check_frames(padapter, buf, len, true);
3828         if (type >= 0)
3829                 goto dump;
3830 #endif
3831         if (category == WLAN_CATEGORY_PUBLIC)
3832                 DBG_8723A("RTW_Tx:%s\n", action_public_str23a(action));
3833         else
3834                 DBG_8723A("RTW_Tx:category(%u), action(%u)\n",
3835                           category, action);
3836
3837 dump:
3838         do {
3839                 dump_cnt++;
3840                 tx_ret = _cfg80211_rtw_mgmt_tx(padapter, tx_ch, buf, len);
3841         } while (dump_cnt < dump_limit && tx_ret != _SUCCESS);
3842
3843         if (tx_ret != _SUCCESS || dump_cnt > 1) {
3844                 DBG_8723A(FUNC_ADPT_FMT " %s (%d/%d) in %d ms\n",
3845                           FUNC_ADPT_ARG(padapter),
3846                           tx_ret == _SUCCESS ? "OK" : "FAIL", dump_cnt,
3847                           dump_limit, jiffies_to_msecs(jiffies - start));
3848         }
3849
3850         switch (type) {
3851         case P2P_GO_NEGO_CONF:
3852                 rtw_clear_scan_deny(padapter);
3853                 break;
3854         case P2P_INVIT_RESP:
3855                 if (pwdev_priv->invit_info.flags & BIT(0)
3856                     && pwdev_priv->invit_info.status == 0) {
3857                         DBG_8723A(FUNC_ADPT_FMT " agree with invitation of "
3858                                   "persistent group\n",
3859                                   FUNC_ADPT_ARG(padapter));
3860                         rtw_set_scan_deny(padapter, 5000);
3861                         rtw_pwr_wakeup_ex(padapter, 5000);
3862                         rtw_clear_scan_deny(padapter);
3863                 }
3864                 break;
3865         }
3866
3867 exit:
3868         return ret;
3869 }
3870
3871 static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
3872                                              struct wireless_dev *wdev,
3873                                              u16 frame_type, bool reg)
3874 {
3875
3876 #ifdef CONFIG_DEBUG_CFG80211
3877         DBG_8723A(FUNC_ADPT_FMT " frame_type:%x, reg:%d\n",
3878                   FUNC_ADPT_ARG(adapter), frame_type, reg);
3879 #endif
3880
3881         if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
3882                 return;
3883
3884         return;
3885 }
3886
3887 static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf,
3888                                             int len)
3889 {
3890         int ret = 0;
3891         uint wps_ielen = 0;
3892         u8 *wps_ie;
3893         u32 p2p_ielen = 0;
3894         u8 wps_oui[8] = { 0x0, 0x50, 0xf2, 0x04 };
3895         u8 *p2p_ie;
3896         u32 wfd_ielen = 0;
3897         struct rtw_adapter *padapter = netdev_priv(ndev);
3898         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3899         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3900
3901         DBG_8723A(FUNC_NDEV_FMT " ielen =%d\n", FUNC_NDEV_ARG(ndev), len);
3902
3903         if (len > 0) {
3904                 wps_ie = rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen);
3905                 if (wps_ie) {
3906 #ifdef CONFIG_DEBUG_CFG80211
3907                         DBG_8723A("bcn_wps_ielen =%d\n", wps_ielen);
3908 #endif
3909
3910                         if (pmlmepriv->wps_beacon_ie) {
3911                                 pmlmepriv->wps_beacon_ie_len = 0;
3912                                 kfree(pmlmepriv->wps_beacon_ie);
3913                                 pmlmepriv->wps_beacon_ie = NULL;
3914                         }
3915
3916                         pmlmepriv->wps_beacon_ie =
3917                                 kmalloc(wps_ielen, GFP_KERNEL);
3918                         if (pmlmepriv->wps_beacon_ie == NULL) {
3919                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
3920                                           __func__, __LINE__);
3921                                 return -EINVAL;
3922                         }
3923                         memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
3924                         pmlmepriv->wps_beacon_ie_len = wps_ielen;
3925
3926                         update_beacon23a(padapter, _VENDOR_SPECIFIC_IE_, wps_oui,
3927                                       true);
3928                 }
3929 #ifdef CONFIG_8723AU_P2P
3930                 p2p_ie = rtw_get_p2p_ie23a(buf, len, NULL, &p2p_ielen);
3931                 if (p2p_ie) {
3932 #ifdef CONFIG_DEBUG_CFG80211
3933                         DBG_8723A("bcn_p2p_ielen =%d\n", p2p_ielen);
3934 #endif
3935
3936                         if (pmlmepriv->p2p_beacon_ie) {
3937                                 pmlmepriv->p2p_beacon_ie_len = 0;
3938                                 kfree(pmlmepriv->p2p_beacon_ie);
3939                                 pmlmepriv->p2p_beacon_ie = NULL;
3940                         }
3941
3942                         pmlmepriv->p2p_beacon_ie =
3943                                 kmalloc(p2p_ielen, GFP_KERNEL);
3944                         if (pmlmepriv->p2p_beacon_ie == NULL) {
3945                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
3946                                           __func__, __LINE__);
3947                                 return -EINVAL;
3948                         }
3949
3950                         memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
3951                         pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
3952                 }
3953 #endif /* CONFIG_8723AU_P2P */
3954
3955                 /* buf += p2p_ielen; */
3956                 /* len -= p2p_ielen; */
3957
3958 #ifdef CONFIG_8723AU_P2P
3959                 if (rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) {
3960 #ifdef CONFIG_DEBUG_CFG80211
3961                         DBG_8723A("bcn_wfd_ielen =%d\n", wfd_ielen);
3962 #endif
3963
3964                         if (pmlmepriv->wfd_beacon_ie) {
3965                                 pmlmepriv->wfd_beacon_ie_len = 0;
3966                                 kfree(pmlmepriv->wfd_beacon_ie);
3967                                 pmlmepriv->wfd_beacon_ie = NULL;
3968                         }
3969
3970                         pmlmepriv->wfd_beacon_ie =
3971                                 kmalloc(wfd_ielen, GFP_KERNEL);
3972                         if (pmlmepriv->wfd_beacon_ie == NULL) {
3973                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
3974                                           __func__, __LINE__);
3975                                 return -EINVAL;
3976
3977                         }
3978                         rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_beacon_ie,
3979                                        &pmlmepriv->wfd_beacon_ie_len);
3980                 }
3981 #endif /* CONFIG_8723AU_P2P */
3982
3983                 pmlmeext->bstart_bss = true;
3984
3985         }
3986
3987         return ret;
3988 }
3989
3990 static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net,
3991                                                 char *buf, int len)
3992 {
3993         struct rtw_adapter *padapter = netdev_priv(net);
3994         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3995         int ret = 0;
3996         uint wps_ielen = 0;
3997         u8 *wps_ie;
3998         u32 p2p_ielen = 0;
3999         u8 *p2p_ie;
4000         u32 wfd_ielen = 0;
4001
4002         if (len > 0) {
4003                 wps_ie = rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen);
4004                 if (wps_ie) {
4005                         uint attr_contentlen = 0;
4006                         u16 uconfig_method, *puconfig_method = NULL;
4007
4008                         if (pmlmepriv->wps_probe_resp_ie) {
4009                                 pmlmepriv->wps_probe_resp_ie_len = 0;
4010                                 kfree(pmlmepriv->wps_probe_resp_ie);
4011                                 pmlmepriv->wps_probe_resp_ie = NULL;
4012                         }
4013
4014                         pmlmepriv->wps_probe_resp_ie =
4015                                 kmalloc(wps_ielen, GFP_KERNEL);
4016                         if (pmlmepriv->wps_probe_resp_ie == NULL) {
4017                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
4018                                           __func__, __LINE__);
4019                                 return -EINVAL;
4020
4021                         }
4022
4023                         /* add PUSH_BUTTON config_method by driver self in
4024                            wpsie of probe_resp at GO Mode */
4025                         puconfig_method = (u16 *)rtw_get_wps_attr_content23a(wps_ie, wps_ielen,
4026                                                               WPS_ATTR_CONF_METHOD,
4027                                                               NULL,
4028                                                               &attr_contentlen);
4029                         if (puconfig_method) {
4030                                 uconfig_method = WPS_CM_PUSH_BUTTON;
4031                                 uconfig_method = cpu_to_be16(uconfig_method);
4032
4033                                 *puconfig_method |= uconfig_method;
4034                         }
4035
4036                         memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
4037                         pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
4038
4039                 }
4040
4041                 /* buf += wps_ielen; */
4042                 /* len -= wps_ielen; */
4043
4044 #ifdef CONFIG_8723AU_P2P
4045                 p2p_ie = rtw_get_p2p_ie23a(buf, len, NULL, &p2p_ielen);
4046                 if (p2p_ie) {
4047                         u8 is_GO = false;
4048                         u32 attr_contentlen = 0;
4049                         u16 cap_attr = 0;
4050
4051 #ifdef CONFIG_DEBUG_CFG80211
4052                         DBG_8723A("probe_resp_p2p_ielen =%d\n", p2p_ielen);
4053 #endif
4054
4055                         /* Check P2P Capability ATTR */
4056                         if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen,
4057                                                      P2P_ATTR_CAPABILITY,
4058                                                      (u8 *) &cap_attr,
4059                                                      (uint *) &attr_contentlen)) {
4060                                 u8 grp_cap = 0;
4061                                 /* DBG_8723A( "[%s] Got P2P Capability Attr!!\n", __func__ ); */
4062                                 cap_attr = le16_to_cpu(cap_attr);
4063                                 grp_cap = (u8) ((cap_attr >> 8) & 0xff);
4064
4065                                 is_GO = (grp_cap & BIT(0)) ? true : false;
4066
4067                                 if (is_GO)
4068                                         DBG_8723A
4069                                             ("Got P2P Capability Attr, grp_cap"
4070                                              "= 0x%x, is_GO\n", grp_cap);
4071                         }
4072
4073                         if (is_GO == false) {
4074                                 if (pmlmepriv->p2p_probe_resp_ie) {
4075                                         pmlmepriv->p2p_probe_resp_ie_len = 0;
4076                                         kfree(pmlmepriv->p2p_probe_resp_ie);
4077                                         pmlmepriv->p2p_probe_resp_ie = NULL;
4078                                 }
4079
4080                                 pmlmepriv->p2p_probe_resp_ie =
4081                                     kmalloc(p2p_ielen, GFP_KERNEL);
4082                                 if (pmlmepriv->p2p_probe_resp_ie == NULL) {
4083                                         DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
4084                                                   __func__, __LINE__);
4085                                         return -EINVAL;
4086                                 }
4087                                 memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie,
4088                                        p2p_ielen);
4089                                 pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
4090                         } else {
4091                                 if (pmlmepriv->p2p_go_probe_resp_ie) {
4092                                         pmlmepriv->p2p_go_probe_resp_ie_len = 0;
4093                                         kfree(pmlmepriv->p2p_go_probe_resp_ie);
4094                                         pmlmepriv->p2p_go_probe_resp_ie = NULL;
4095                                 }
4096
4097                                 pmlmepriv->p2p_go_probe_resp_ie =
4098                                     kmalloc(p2p_ielen, GFP_KERNEL);
4099                                 if (pmlmepriv->p2p_go_probe_resp_ie == NULL) {
4100                                         DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
4101                                                   __func__, __LINE__);
4102                                         return -EINVAL;
4103
4104                                 }
4105                                 memcpy(pmlmepriv->p2p_go_probe_resp_ie,
4106                                        p2p_ie, p2p_ielen);
4107                                 pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
4108                         }
4109                 }
4110 #endif /* CONFIG_8723AU_P2P */
4111
4112                 /* buf += p2p_ielen; */
4113                 /* len -= p2p_ielen; */
4114
4115 #ifdef CONFIG_8723AU_P2P
4116                 if (rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen)) {
4117 #ifdef CONFIG_DEBUG_CFG80211
4118                         DBG_8723A("probe_resp_wfd_ielen =%d\n", wfd_ielen);
4119 #endif
4120
4121                         if (pmlmepriv->wfd_probe_resp_ie) {
4122                                 pmlmepriv->wfd_probe_resp_ie_len = 0;
4123                                 kfree(pmlmepriv->wfd_probe_resp_ie);
4124                                 pmlmepriv->wfd_probe_resp_ie = NULL;
4125                         }
4126
4127                         pmlmepriv->wfd_probe_resp_ie =
4128                             kmalloc(wfd_ielen, GFP_KERNEL);
4129                         if (pmlmepriv->wfd_probe_resp_ie == NULL) {
4130                                 DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
4131                                           __func__, __LINE__);
4132                                 return -EINVAL;
4133
4134                         }
4135                         rtw_get_wfd_ie(buf, len, pmlmepriv->wfd_probe_resp_ie,
4136                                        &pmlmepriv->wfd_probe_resp_ie_len);
4137                 }
4138 #endif /* CONFIG_8723AU_P2P */
4139         }
4140
4141         return ret;
4142 }
4143
4144 static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net,
4145                                                 char *buf, int len)
4146 {
4147         int ret = 0;
4148         struct rtw_adapter *padapter = netdev_priv(net);
4149         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4150
4151         DBG_8723A("%s, ielen =%d\n", __func__, len);
4152
4153         if (len > 0) {
4154                 if (pmlmepriv->wps_assoc_resp_ie) {
4155                         pmlmepriv->wps_assoc_resp_ie_len = 0;
4156                         kfree(pmlmepriv->wps_assoc_resp_ie);
4157                         pmlmepriv->wps_assoc_resp_ie = NULL;
4158                 }
4159
4160                 pmlmepriv->wps_assoc_resp_ie = kmalloc(len, GFP_KERNEL);
4161                 if (pmlmepriv->wps_assoc_resp_ie == NULL) {
4162                         DBG_8723A("%s()-%d: kmalloc() ERROR!\n",
4163                                   __func__, __LINE__);
4164                         return -EINVAL;
4165
4166                 }
4167                 memcpy(pmlmepriv->wps_assoc_resp_ie, buf, len);
4168                 pmlmepriv->wps_assoc_resp_ie_len = len;
4169         }
4170
4171         return ret;
4172 }
4173
4174 int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
4175                                    int type)
4176 {
4177         int ret = 0;
4178         uint wps_ielen = 0;
4179         u32 p2p_ielen = 0;
4180
4181 #ifdef CONFIG_DEBUG_CFG80211
4182         DBG_8723A("%s, ielen =%d\n", __func__, len);
4183 #endif
4184
4185         if ((rtw_get_wps_ie23a(buf, len, NULL, &wps_ielen) && (wps_ielen > 0))
4186 #ifdef CONFIG_8723AU_P2P
4187             || (rtw_get_p2p_ie23a(buf, len, NULL, &p2p_ielen) && (p2p_ielen > 0))
4188 #endif
4189             ) {
4190                 if (net) {
4191                         switch (type) {
4192                         case 0x1:       /* BEACON */
4193                                 ret =
4194                                     rtw_cfg80211_set_beacon_wpsp2pie(net, buf,
4195                                                                      len);
4196                                 break;
4197                         case 0x2:       /* PROBE_RESP */
4198                                 ret =
4199                                     rtw_cfg80211_set_probe_resp_wpsp2pie(net,
4200                                                                          buf,
4201                                                                          len);
4202                                 break;
4203                         case 0x4:       /* ASSOC_RESP */
4204                                 ret =
4205                                     rtw_cfg80211_set_assoc_resp_wpsp2pie(net,
4206                                                                          buf,
4207                                                                          len);
4208                                 break;
4209                         }
4210                 }
4211         }
4212
4213         return ret;
4214
4215 }
4216
4217 static struct cfg80211_ops rtw_cfg80211_ops = {
4218         .change_virtual_intf = cfg80211_rtw_change_iface,
4219         .add_key = cfg80211_rtw_add_key,
4220         .get_key = cfg80211_rtw_get_key,
4221         .del_key = cfg80211_rtw_del_key,
4222         .set_default_key = cfg80211_rtw_set_default_key,
4223         .get_station = cfg80211_rtw_get_station,
4224         .scan = cfg80211_rtw_scan,
4225         .set_wiphy_params = cfg80211_rtw_set_wiphy_params,
4226         .connect = cfg80211_rtw_connect,
4227         .disconnect = cfg80211_rtw_disconnect,
4228         .join_ibss = cfg80211_rtw_join_ibss,
4229         .leave_ibss = cfg80211_rtw_leave_ibss,
4230         .set_tx_power = cfg80211_rtw_set_txpower,
4231         .get_tx_power = cfg80211_rtw_get_txpower,
4232         .set_power_mgmt = cfg80211_rtw_set_power_mgmt,
4233         .set_pmksa = cfg80211_rtw_set_pmksa,
4234         .del_pmksa = cfg80211_rtw_del_pmksa,
4235         .flush_pmksa = cfg80211_rtw_flush_pmksa,
4236
4237 #ifdef CONFIG_8723AU_AP_MODE
4238         .add_virtual_intf = cfg80211_rtw_add_virtual_intf,
4239         .del_virtual_intf = cfg80211_rtw_del_virtual_intf,
4240
4241         .start_ap = cfg80211_rtw_start_ap,
4242         .change_beacon = cfg80211_rtw_change_beacon,
4243         .stop_ap = cfg80211_rtw_stop_ap,
4244
4245         .add_station = cfg80211_rtw_add_station,
4246         .del_station = cfg80211_rtw_del_station,
4247         .change_station = cfg80211_rtw_change_station,
4248         .dump_station = cfg80211_rtw_dump_station,
4249         .change_bss = cfg80211_rtw_change_bss,
4250 #endif /* CONFIG_8723AU_AP_MODE */
4251
4252 #ifdef CONFIG_8723AU_P2P
4253         .remain_on_channel = cfg80211_rtw_remain_on_channel,
4254         .cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
4255 #endif
4256
4257         .mgmt_tx = cfg80211_rtw_mgmt_tx,
4258         .mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
4259 };
4260
4261 static void rtw_cfg80211_init_ht_capab(struct ieee80211_sta_ht_cap *ht_cap,
4262                                        enum ieee80211_band band, u8 rf_type)
4263 {
4264
4265 #define MAX_BIT_RATE_40MHZ_MCS15        300     /* Mbps */
4266 #define MAX_BIT_RATE_40MHZ_MCS7         150     /* Mbps */
4267
4268         ht_cap->ht_supported = true;
4269
4270         ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
4271             IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
4272             IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
4273
4274         /*
4275          *Maximum length of AMPDU that the STA can receive.
4276          *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
4277          */
4278         ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
4279
4280         /*Minimum MPDU start spacing , */
4281         ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
4282
4283         ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
4284
4285         /*
4286          *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
4287          *base on ant_num
4288          *rx_mask: RX mask
4289          *if rx_ant = 1 rx_mask[0]= 0xff;==>MCS0-MCS7
4290          *if rx_ant = 2 rx_mask[1]= 0xff;==>MCS8-MCS15
4291          *if rx_ant >= 3 rx_mask[2]= 0xff;
4292          *if BW_40 rx_mask[4]= 0x01;
4293          *highest supported RX rate
4294          */
4295         if (rf_type == RF_1T1R) {
4296                 ht_cap->mcs.rx_mask[0] = 0xFF;
4297                 ht_cap->mcs.rx_mask[1] = 0x00;
4298                 ht_cap->mcs.rx_mask[4] = 0x01;
4299
4300                 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
4301         } else if ((rf_type == RF_1T2R) || (rf_type == RF_2T2R)) {
4302                 ht_cap->mcs.rx_mask[0] = 0xFF;
4303                 ht_cap->mcs.rx_mask[1] = 0xFF;
4304                 ht_cap->mcs.rx_mask[4] = 0x01;
4305
4306                 ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
4307         } else {
4308                 DBG_8723A("%s, error rf_type =%d\n", __func__, rf_type);
4309         }
4310
4311 }
4312
4313 void rtw_cfg80211_init_wiphy(struct rtw_adapter *padapter)
4314 {
4315         u8 rf_type;
4316         struct ieee80211_supported_band *bands;
4317         struct wireless_dev *pwdev = padapter->rtw_wdev;
4318         struct wiphy *wiphy = pwdev->wiphy;
4319
4320         rtw23a_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
4321
4322         DBG_8723A("%s:rf_type =%d\n", __func__, rf_type);
4323
4324         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
4325         {
4326                 bands = wiphy->bands[IEEE80211_BAND_2GHZ];
4327                 if (bands)
4328                         rtw_cfg80211_init_ht_capab(&bands->ht_cap,
4329                                                    IEEE80211_BAND_2GHZ,
4330                                                    rf_type);
4331         }
4332
4333         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
4334         {
4335                 bands = wiphy->bands[IEEE80211_BAND_5GHZ];
4336                 if (bands)
4337                         rtw_cfg80211_init_ht_capab(&bands->ht_cap,
4338                                                    IEEE80211_BAND_5GHZ,
4339                                                    rf_type);
4340         }
4341 }
4342
4343 static void rtw_cfg80211_preinit_wiphy(struct rtw_adapter *padapter,
4344                                        struct wiphy *wiphy)
4345 {
4346         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4347
4348         wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
4349         wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
4350         wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
4351
4352         wiphy->max_remain_on_channel_duration =
4353             RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
4354
4355         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4356             BIT(NL80211_IFTYPE_ADHOC) |
4357 #ifdef CONFIG_8723AU_AP_MODE
4358             BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) |
4359 #endif
4360 #if defined(CONFIG_8723AU_P2P)
4361             BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO) |
4362 #endif
4363             0;
4364
4365 #ifdef CONFIG_8723AU_AP_MODE
4366         wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
4367 #endif /* CONFIG_8723AU_AP_MODE */
4368
4369         wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
4370
4371         /*
4372            wiphy->iface_combinations = &rtw_combinations;
4373            wiphy->n_iface_combinations = 1;
4374          */
4375
4376         wiphy->cipher_suites = rtw_cipher_suites;
4377         wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
4378
4379         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11G) */
4380         wiphy->bands[IEEE80211_BAND_2GHZ] =
4381             rtw_spt_band_alloc(IEEE80211_BAND_2GHZ);
4382         /* if (padapter->registrypriv.wireless_mode & WIRELESS_11A) */
4383         wiphy->bands[IEEE80211_BAND_5GHZ] =
4384             rtw_spt_band_alloc(IEEE80211_BAND_5GHZ);
4385
4386         wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
4387         wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME;
4388
4389         if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
4390                 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
4391         else
4392                 wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
4393 }
4394
4395 int rtw_wdev_alloc(struct rtw_adapter *padapter, struct device *dev)
4396 {
4397         int ret = 0;
4398         struct wiphy *wiphy;
4399         struct wireless_dev *wdev;
4400         struct rtw_wdev_priv *pwdev_priv;
4401         struct net_device *pnetdev = padapter->pnetdev;
4402
4403         DBG_8723A("%s(padapter =%p)\n", __func__, padapter);
4404
4405         /* wiphy */
4406         wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wdev_priv));
4407         if (!wiphy) {
4408                 DBG_8723A("Couldn't allocate wiphy device\n");
4409                 ret = -ENOMEM;
4410                 goto exit;
4411         }
4412         set_wiphy_dev(wiphy, dev);
4413         rtw_cfg80211_preinit_wiphy(padapter, wiphy);
4414
4415         ret = wiphy_register(wiphy);
4416         if (ret < 0) {
4417                 DBG_8723A("Couldn't register wiphy device\n");
4418                 goto free_wiphy;
4419         }
4420
4421         /*  wdev */
4422         wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
4423         if (!wdev) {
4424                 DBG_8723A("Couldn't allocate wireless device\n");
4425                 ret = -ENOMEM;
4426                 goto unregister_wiphy;
4427         }
4428         wdev->wiphy = wiphy;
4429         wdev->netdev = pnetdev;
4430         /* wdev->iftype = NL80211_IFTYPE_STATION; */
4431         /*  for rtw_setopmode_cmd23a() in cfg80211_rtw_change_iface() */
4432         wdev->iftype = NL80211_IFTYPE_MONITOR;
4433         padapter->rtw_wdev = wdev;
4434         pnetdev->ieee80211_ptr = wdev;
4435
4436         /* init pwdev_priv */
4437         pwdev_priv = wdev_to_priv(wdev);
4438         pwdev_priv->rtw_wdev = wdev;
4439         pwdev_priv->pmon_ndev = NULL;
4440         pwdev_priv->ifname_mon[0] = '\0';
4441         pwdev_priv->padapter = padapter;
4442         pwdev_priv->scan_request = NULL;
4443         spin_lock_init(&pwdev_priv->scan_req_lock);
4444
4445         pwdev_priv->p2p_enabled = false;
4446         pwdev_priv->provdisc_req_issued = false;
4447         rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
4448
4449         if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
4450                 pwdev_priv->power_mgmt = true;
4451         else
4452                 pwdev_priv->power_mgmt = false;
4453
4454         return ret;
4455 unregister_wiphy:
4456         wiphy_unregister(wiphy);
4457 free_wiphy:
4458         wiphy_free(wiphy);
4459 exit:
4460         return ret;
4461 }
4462
4463 void rtw_wdev_free(struct wireless_dev *wdev)
4464 {
4465         struct rtw_wdev_priv *pwdev_priv;
4466
4467         DBG_8723A("%s(wdev =%p)\n", __func__, wdev);
4468
4469         if (!wdev)
4470                 return;
4471
4472         pwdev_priv = wdev_to_priv(wdev);
4473
4474         kfree(wdev->wiphy->bands[IEEE80211_BAND_2GHZ]);
4475         kfree(wdev->wiphy->bands[IEEE80211_BAND_5GHZ]);
4476
4477         wiphy_free(wdev->wiphy);
4478
4479         kfree(wdev);
4480 }
4481
4482 void rtw_wdev_unregister(struct wireless_dev *wdev)
4483 {
4484         struct rtw_wdev_priv *pwdev_priv;
4485
4486         DBG_8723A("%s(wdev =%p)\n", __func__, wdev);
4487
4488         if (!wdev)
4489                 return;
4490
4491         pwdev_priv = wdev_to_priv(wdev);
4492
4493         rtw_cfg80211_indicate_scan_done(pwdev_priv, true);
4494
4495         if (pwdev_priv->pmon_ndev) {
4496                 DBG_8723A("%s, unregister monitor interface\n", __func__);
4497                 unregister_netdev(pwdev_priv->pmon_ndev);
4498         }
4499
4500         wiphy_unregister(wdev->wiphy);
4501 }