Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: r8723au: Add source files for new driver - part 3

The Realtek USB device RTL8723AU is found in Lenovo Yoga 13 tablets.
A driver for it has been available in a GitHub repo for several months.
This commit contains the third part of source files. The source
is arbitrarily split to avoid E-mail files that are too large.

Jes Sorensen at RedHat has made many improvements to the vendor code,
and he has been doing the testing. I do not have access to this device.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Jes Sorensen <Jes.Sorensen@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Larry Finger and committed by
Greg Kroah-Hartman
b1925ad8 f7c92d2c

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