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