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