From 9daa7978e941b7304e42a08d5884031c9b998673 Mon Sep 17 00:00:00 2001 From: kimocoder Date: Fri, 16 Aug 2019 06:28:27 +0200 Subject: [PATCH] Merge a collection of fixes --- core/rtw_mlme_ext.c | 9 +- core/rtw_pwrctrl.c | 2 + core/rtw_recv.c | 11 +- core/rtw_wlan_util.c | 2 +- core/rtw_xmit.c | 3 +- docs/pine64 | 1 + hal/rtl8814a/rtl8814a_phycfg.c | 10 +- hal/rtl8814a/usb/rtl8814au_xmit.c | 7 +- include/rtw_xmit.h | 3 +- os_dep/linux/ioctl_cfg80211.c | 289 ++++++++++++++++++++++++------ 10 files changed, 265 insertions(+), 72 deletions(-) create mode 100644 docs/pine64 diff --git a/core/rtw_mlme_ext.c b/core/rtw_mlme_ext.c index c4af4b9..3715889 100755 --- a/core/rtw_mlme_ext.c +++ b/core/rtw_mlme_ext.c @@ -1338,11 +1338,11 @@ void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame) #ifdef CONFIG_AP_MODE switch (get_frame_sub_type(pframe)) { case WIFI_AUTH: - if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) + if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) { ptable->func = &OnAuth; - else + } else ptable->func = &OnAuthClient; - /* pass through */ + /* Intentional fallthrough */ case WIFI_ASSOCREQ: case WIFI_REASSOCREQ: _mgt_dispatcher(padapter, ptable, precv_frame); @@ -2150,9 +2150,10 @@ unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame) } _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); - if (seq == 1) + if (seq == 1) { ; /* TODO: STA re_auth and auth timeout */ + } } } diff --git a/core/rtw_pwrctrl.c b/core/rtw_pwrctrl.c index fa66c2a..0e8fee3 100644 --- a/core/rtw_pwrctrl.c +++ b/core/rtw_pwrctrl.c @@ -229,6 +229,7 @@ bool rtw_pwr_unassociated_idle(_adapter *adapter) || MLME_IS_AP(iface) || MLME_IS_MESH(iface) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) + || check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) || rtw_cfg80211_get_is_roch(iface) == _TRUE || (rtw_cfg80211_is_ro_ch_once(adapter) @@ -716,6 +717,7 @@ u8 PS_RDY_CHECK(_adapter *padapter) || MLME_IS_AP(padapter) || MLME_IS_MESH(padapter) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_ADHOC_STATE) + || check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211) || rtw_cfg80211_get_is_roch(padapter) == _TRUE #endif diff --git a/core/rtw_recv.c b/core/rtw_recv.c index 4b6f152..9b5707c 100755 --- a/core/rtw_recv.c +++ b/core/rtw_recv.c @@ -4042,8 +4042,15 @@ static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe, if (pattrib->mfrag) hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FRAG; - /* always append FCS */ - hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FCS; +#ifdef CONFIG_RX_PACKET_APPEND_FCS + // Start by always indicating FCS is there: + hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FCS; + + // Next, test for prior conditions that will remove FCS, and update flag accordingly: + if(check_fwstate(&padapter->mlmepriv,WIFI_MONITOR_STATE) == _FALSE) + if((pattrib->pkt_rpt_type == NORMAL_RX) && (pHalData->ReceiveConfig & RCR_APPFCS)) + hdr_buf[rt_len] &= ~IEEE80211_RADIOTAP_F_FCS; +#endif if (0) diff --git a/core/rtw_wlan_util.c b/core/rtw_wlan_util.c index fd9b7ca..c2d8bad 100644 --- a/core/rtw_wlan_util.c +++ b/core/rtw_wlan_util.c @@ -2524,7 +2524,7 @@ int rtw_get_bcn_keys(ADAPTER *Adapter, u8 *pframe, u32 packet_len, _rtw_memcpy(recv_beacon->ssid, elems.ssid, elems.ssid_len); recv_beacon->ssid_len = elems.ssid_len; - } + } else { ; } /* means hidden ssid */ /* checking RSN first */ if (elems.rsn_ie && elems.rsn_ie_len) { diff --git a/core/rtw_xmit.c b/core/rtw_xmit.c index 80de669..adafd55 100644 --- a/core/rtw_xmit.c +++ b/core/rtw_xmit.c @@ -1378,11 +1378,12 @@ static s32 update_attrib(_adapter *padapter, _pkt *pkt, struct pkt_attrib *pattr _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); _rtw_memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN); DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_ap); - } else + } else { DBG_COUNTER(padapter->tx_logs.core_tx_upd_attrib_unknown); get_sta_info: bmcast = IS_MCAST(pattrib->ra); + } if (bmcast) { psta = rtw_get_bcmc_stainfo(padapter); if (psta == NULL) { /* if we cannot get psta => drop the pkt */ diff --git a/docs/pine64 b/docs/pine64 new file mode 100644 index 0000000..671c77f --- /dev/null +++ b/docs/pine64 @@ -0,0 +1 @@ +https://github.com/armbian/build/blob/master/patch/kernel/pine64-default/wifi-0005-realtek-881xAU-update-to-5a5d0f.patch diff --git a/hal/rtl8814a/rtl8814a_phycfg.c b/hal/rtl8814a/rtl8814a_phycfg.c index 3bed477..e997f30 100644 --- a/hal/rtl8814a/rtl8814a_phycfg.c +++ b/hal/rtl8814a/rtl8814a_phycfg.c @@ -1222,10 +1222,10 @@ PHY_GetTxPowerIndex8814A( tpt_offset = PHY_GetTxPowerTrackingOffset(pAdapter, RFPath, Rate); powerDiffByRate = powerDiffByRate > limit ? limit : powerDiffByRate; - /*RTW_INFO("Rate-0x%x: (TxPower, PowerDiffByRate Path-%c) = (0x%X, %d)\n", Rate, ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), txPower, powerDiffByRate);*/ + RTW_INFO("Rate-0x%x: (TxPower, PowerDiffByRate Path-%c) = (0x%X, %d)\n", Rate, ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), txPower, powerDiffByRate); txPower += powerDiffByRate; - + //txPower += PHY_GetTxPowerTrackingOffset( pAdapter, RFPath, Rate ); #if 0 //todo ? #if CCX_SUPPORT @@ -1246,12 +1246,12 @@ PHY_GetTxPowerIndex8814A( if(txPower > hal_spec->txgi_max) txPower = hal_spec->txgi_max; - //if (Adapter->registrypriv.mp_mode==0 && + //if (Adapter->registrypriv.mp_mode==0 && //(pHalData->bautoload_fail_flag || pHalData->EfuseMap[EFUSE_INIT_MAP][EEPROM_TX_PWR_INX_JAGUAR] == 0xFF)) //txPower = 0x12; - /*RTW_INFO("Final Tx Power(RF-%c, Channel: %d) = %d(0x%X)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), Channel, - txPower, txPower);*/ + RTW_INFO("Final Tx Power(RF-%c, Channel: %d) = %d(0x%X)\n", ((RFPath==0)?'A':(RFPath==1)?'B':(RFPath==2)?'C':'D'), Channel, + txPower, txPower); return (u8) txPower; } diff --git a/hal/rtl8814a/usb/rtl8814au_xmit.c b/hal/rtl8814a/usb/rtl8814au_xmit.c index 73b1acc..2199968 100644 --- a/hal/rtl8814a/usb/rtl8814au_xmit.c +++ b/hal/rtl8814a/usb/rtl8814au_xmit.c @@ -55,7 +55,7 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz ,u8 bag u16 SWDefineContent = 0x0; u8 DriverFixedRate = 0x0; -#ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX +#ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX if (padapter->registrypriv.mp_mode == 0) { if((PACKET_OFFSET_SZ != 0) && (!bagg_pkt) &&(rtw_usb_bulk_size_boundary(padapter,TXDESC_SIZE+sz)==_FALSE)) @@ -92,10 +92,9 @@ static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz ,u8 bag } #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX - if (padapter->registrypriv.mp_mode == 0) - { + if (padapter->registrypriv.mp_mode == 0) { if ((PACKET_OFFSET_SZ != 0) && (!bagg_pkt)) { - if ((pull) && (pxmitframe->pkt_offset>0)) { + if ((pull) && (pxmitframe->pkt_offset>0)) { pxmitframe->pkt_offset = pxmitframe->pkt_offset -1; } } diff --git a/include/rtw_xmit.h b/include/rtw_xmit.h index 6c718d5..e9a4ddf 100644 --- a/include/rtw_xmit.h +++ b/include/rtw_xmit.h @@ -461,13 +461,14 @@ struct pkt_attrib { u8 rate; u8 intel_proxim; u8 retry_ctrl; + //u8 sw_seq; // Add support for pre-configured SeqNum via RadioTap u8 mbssid; u8 ldpc; u8 stbc; #ifdef CONFIG_WMMPS_STA u8 trigger_frame; #endif /* CONFIG_WMMPS_STA */ - + struct sta_info *psta; u8 rtsen; diff --git a/os_dep/linux/ioctl_cfg80211.c b/os_dep/linux/ioctl_cfg80211.c index 6fcfcf2..83e0fe9 100755 --- a/os_dep/linux/ioctl_cfg80211.c +++ b/os_dep/linux/ioctl_cfg80211.c @@ -730,7 +730,11 @@ static u64 rtw_get_systime_us(void) return ktime_to_us(ktime_get_boottime()); #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)) struct timespec ts; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0)) + getboottime(&ts); +#else get_monotonic_boottime(&ts); +#endif return ((u64)ts.tv_sec * 1000000) + ts.tv_nsec / 1000; #else struct timeval tv; @@ -742,6 +746,7 @@ static u64 rtw_get_systime_us(void) /* Try to remove non target BSS's SR to reduce PBC overlap rate */ static int rtw_cfg80211_clear_wps_sr_of_non_target_bss(_adapter *padapter, struct wlan_network *pnetwork, struct cfg80211_ssid *req_ssid) { + struct rtw_wdev_priv *wdev_data = adapter_wdev_data(padapter); int ret = 0; u8 *psr = NULL, sr = 0; NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid; @@ -982,6 +987,7 @@ void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_network *cur_network = &(pmlmepriv->cur_network); struct wireless_dev *pwdev = padapter->rtw_wdev; + struct cfg80211_bss *bss = NULL; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) struct wiphy *wiphy = pwdev->wiphy; int freq = 2412; @@ -990,6 +996,13 @@ void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter) RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter)); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) + freq = rtw_ch2freq(cur_network->network.Configuration.DSConfig); + + if (0) + RTW_INFO("chan: %d, freq: %d\n", cur_network->network.Configuration.DSConfig, freq); +#endif + if (pwdev->iftype != NL80211_IFTYPE_ADHOC) return; @@ -1052,6 +1065,8 @@ void rtw_cfg80211_indicate_connect(_adapter *padapter) #ifdef CONFIG_P2P struct wifidirect_info *pwdinfo = &(padapter->wdinfo); #endif + struct cfg80211_bss *bss = NULL; + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0) struct cfg80211_roam_info roam_info ={}; #endif @@ -1176,6 +1191,7 @@ check_bss: void rtw_cfg80211_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generated) { + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wireless_dev *pwdev = padapter->rtw_wdev; struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); _irqL irqL; @@ -1238,12 +1254,15 @@ void rtw_cfg80211_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally rtw_cfg80211_connect_result(pwdev, NULL, NULL, 0, NULL, 0, reason, GFP_ATOMIC); } else { - RTW_INFO(FUNC_ADPT_FMT" call cfg80211_disconnected\n", FUNC_ADPT_ARG(padapter)); - rtw_cfg80211_disconnected(pwdev, reason, NULL, 0, locally_generated, GFP_ATOMIC); + RTW_INFO(FUNC_ADPT_FMT" call cfg80211_disconnected\n", FUNC_ADPT_ARG(padapter)); + rtw_cfg80211_disconnected(pwdev, reason, NULL, 0, locally_generated, GFP_ATOMIC); + + cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC); } #endif - } + } rtw_wdev_free_connect_req(pwdev_priv); _exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL); @@ -1254,10 +1273,10 @@ void rtw_cfg80211_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param) { int ret = 0; - u32 wep_key_idx, wep_key_len; + u32 wep_key_idx, wep_key_len, wep_total_len; struct sta_info *psta = NULL, *pbcmc_sta = NULL; _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); - struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &(padapter->securitypriv); struct sta_priv *pstapriv = &padapter->stapriv; @@ -1507,7 +1526,7 @@ exit: static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param) { int ret = 0; - u32 wep_key_idx, wep_key_len; + u32 wep_key_idx, wep_key_len, wep_total_len; _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; @@ -2339,46 +2358,10 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy, /* is this actually the dtim_period? */ sinfo->bss_param.flags |= STATION_INFO_BSS_PARAM_DTIM_PERIOD; - //sinfo->bss_param.dtim_period = pwrctl->vif.bss_conf.dtim_period; + //sinfo->bss_param.dtim_period = pwrctl->dtim; // kimocoder: this one below needs attention - //sinfo->bss_param.beacon_interval = get_beacon_interval(&cur_network->network); - - /* - sinfo->sta_flags.mask = BIT(NL80211_STA_FLAG_AUTHORIZED) | - BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | - BIT(NL80211_STA_FLAG_WME) | - BIT(NL80211_STA_FLAG_MFP) | - BIT(NL80211_STA_FLAG_AUTHENTICATED) | - BIT(NL80211_STA_FLAG_ASSOCIATED) | - BIT(NL80211_STA_FLAG_TDLS_PEER); - - if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) - sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); - if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) - sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); - if (sta->sta.wme) - sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME); - if (test_sta_flag(sta, WLAN_STA_MFP)) - sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); - if (test_sta_flag(sta, WLAN_STA_AUTH)) - sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); - if (test_sta_flag(sta, WLAN_STA_ASSOC)) - sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_ASSOCIATED); - if (test_sta_flag(sta, WLAN_STA_TDLS_PEER)) - sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); - */ - - /* check if the driver has a SW RC implementation */ - //if (ref && ref->ops->get_expected_throughput) - // thr = ref->ops->get_expected_throughput(sta->rate_ctrl_priv); - //else - // thr = drv_get_expected_throughput(local, &sta->sta); - - //if (thr != 0) { - // sinfo->filled |= BIT(NL80211_STA_INFO_EXPECTED_THROUGHPUT); - // sinfo->expected_throughput = thr; - + //sinfo->bss_param.beacon_interval = get_beacon_interval(wlan_network->network); #endif @@ -2412,6 +2395,11 @@ enum nl80211_iftype { NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 }; #endif + +#ifdef CONFIG_CONCURRENT_MODE +extern int netdev_if2_open(struct net_device *pnetdev); +#endif + static int cfg80211_rtw_change_iface(struct wiphy *wiphy, struct net_device *ndev, enum nl80211_iftype type, @@ -2491,6 +2479,7 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy, case NL80211_IFTYPE_P2P_CLIENT: is_p2p = _TRUE; #endif + /* intentional fallthrough */ case NL80211_IFTYPE_STATION: networkType = Ndis802_11Infrastructure; @@ -2515,6 +2504,7 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy, case NL80211_IFTYPE_P2P_GO: is_p2p = _TRUE; #endif + /* intentional fallthrough */ case NL80211_IFTYPE_AP: networkType = Ndis802_11APMode; @@ -2645,7 +2635,8 @@ void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork) struct cfg80211_bss *bss = NULL; WLAN_BSSID_EX select_network = pnetwork->network; - bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/, + + bss = cfg80211_get_bss(wiphy, NULL /*notify_channel*/, select_network.MacAddress, select_network.Ssid.Ssid, select_network.Ssid.SsidLength, #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) @@ -2656,10 +2647,16 @@ void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork) select_network.InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS); #endif + if (!wiphy) { + pr_info("88XXau: rtw_cfg80211_unlink_bss: wiphy is NULL\n"); + return; + } if (bss) { cfg80211_unlink_bss(wiphy, bss); RTW_INFO("%s(): cfg80211_unlink %s!!\n", __func__, select_network.Ssid.Ssid); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0) + if (!padapter->rtw_wdev->wiphy) + return; cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss); #else cfg80211_put_bss(bss); @@ -2696,6 +2693,9 @@ static void _rtw_cfg80211_surveydone_event_callback(_adapter *padapter, struct c struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); _queue *queue = &(pmlmepriv->scanned_queue); struct wlan_network *pnetwork = NULL; + u32 cnt = 0; + u32 wait_for_surveydone; + sint wait_status; struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); struct cfg80211_ssid target_ssid; u8 target_wps_scan = 0; @@ -2957,11 +2957,15 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy #endif , struct cfg80211_scan_request *request) { - int i; + int i, chan_num = 0; u8 _status = _FALSE; int ret = 0; struct sitesurvey_parm parm; _irqL irqL; + u8 *wps_ie = NULL; + uint wps_ielen = 0; + u8 *p2p_ie = NULL; + uint p2p_ielen = 0; u8 survey_times = 3; u8 survey_times_for_one_ch = 6; struct cfg80211_ssid *ssids = request->ssids; @@ -3529,6 +3533,7 @@ static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen) { u8 *buf = NULL, *pos = NULL; + u32 left; int group_cipher = 0, pairwise_cipher = 0; u8 mfp_opt = MFP_NO; int ret = 0; @@ -3731,7 +3736,10 @@ static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev, _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); NDIS_802_11_SSID ndis_ssid; struct security_priv *psecuritypriv = &padapter->securitypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network)); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) struct cfg80211_chan_def *pch_def; #endif @@ -3804,6 +3812,7 @@ static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) { _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); struct wireless_dev *rtw_wdev = padapter->rtw_wdev; + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); enum nl80211_iftype old_type; int ret = 0; @@ -3923,14 +3932,20 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, struct cfg80211_connect_params *sme) { int ret = 0; + struct wlan_network *pnetwork = NULL; NDIS_802_11_AUTHENTICATION_MODE authmode; NDIS_802_11_SSID ndis_ssid; + u8 *dst_ssid, *src_ssid; + u8 *dst_bssid, *src_bssid; /* u8 matched_by_bssid=_FALSE; */ /* u8 matched_by_ssid=_FALSE; */ + u8 matched = _FALSE; _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; + _queue *queue = &pmlmepriv->scanned_queue; + struct wireless_dev *pwdev = padapter->rtw_wdev; struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); - struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); _irqL irqL; #if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_CONNECT) @@ -3957,6 +3972,7 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, _rtw_disconnect(wiphy, ndev); RTW_INFO("%s disconnect before connecting! fw_state=0x%x\n", __FUNCTION__, pmlmepriv->fw_state); + goto exit; } #ifdef CONFIG_PLATFORM_MSTAR_SCAN_BEFORE_CONNECT @@ -4180,6 +4196,7 @@ static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code) { _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); RTW_INFO(FUNC_NDEV_FMT" - Start to Disconnect\n", FUNC_NDEV_ARG(ndev)); @@ -4215,6 +4232,26 @@ static int cfg80211_rtw_set_txpower(struct wiphy *wiphy, enum tx_power_setting type, int dbm) #endif { +_adapter *padapter = wiphy_to_adapter(wiphy); +HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); +int value; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE) + value = mbm/100; +#else + value = dbm; +#endif + +if(value < 0) + value = 0; +if(value > 40) + value = 40; + +if(type == NL80211_TX_POWER_FIXED) { + pHalData->CurrentTxPwrIdx = value; + rtw_hal_set_tx_power_level(padapter, pHalData->current_channel); +} else + return -EOPNOTSUPP; + #if 0 struct iwm_priv *iwm = wiphy_to_iwm(wiphy); int ret; @@ -4251,9 +4288,13 @@ static int cfg80211_rtw_get_txpower(struct wiphy *wiphy, #endif int *dbm) { + _adapter *padapter = wiphy_to_adapter(wiphy); + HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); + RTW_INFO("%s\n", __func__); - *dbm = (12); + // *dbm = (12); + *dbm = pHalData->CurrentTxPwrIdx; return 0; } @@ -4416,6 +4457,8 @@ void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint f { struct station_info sinfo; u8 ie_offset; + _rtw_memset(&sinfo, 0, sizeof(struct station_info)); + if (get_frame_sub_type(pmgmt_frame) == WIFI_ASSOCREQ) ie_offset = _ASOCREQ_IE_OFFSET_; else /* WIFI_REASSOCREQ */ @@ -4685,11 +4728,12 @@ fail: } +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev) { RTW_INFO("%s\n", __func__); } - +#endif static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr) { int ret = 0; @@ -4918,7 +4962,11 @@ static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy, pwdev_priv = adapter_wdev_data(adapter); if (ndev == pwdev_priv->pmon_ndev) { - unregister_netdevice(ndev); + /* unregister only monitor device + * because only monitor can be added + */ + if(wdev->iftype == NL80211_IFTYPE_MONITOR) + unregister_netdevice(ndev); pwdev_priv->pmon_ndev = NULL; pwdev_priv->ifname_mon[0] = '\0'; RTW_INFO(FUNC_NDEV_FMT" remove monitor ndev\n", FUNC_NDEV_ARG(ndev)); @@ -4953,6 +5001,7 @@ static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, co u8 *pbuf = NULL; uint len, wps_ielen = 0; uint p2p_ielen = 0; + u8 *p2p_ie; u8 got_p2p_ie = _FALSE; struct mlme_priv *pmlmepriv = &(adapter->mlmepriv); /* struct sta_priv *pstapriv = &padapter->stapriv; */ @@ -4998,6 +5047,7 @@ static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, co if (adapter->wdinfo.driver_interface == DRIVER_CFG80211) { /* check p2p if enable */ if (rtw_get_p2p_ie(pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL, &p2p_ielen)) { + struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; struct wifidirect_info *pwdinfo = &(adapter->wdinfo); RTW_INFO("got p2p_ie, len=%d\n", p2p_ielen); @@ -5115,6 +5165,18 @@ static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev, ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len, settings->beacon.tail, settings->beacon.tail_len); + // In cases like WPS, the proberesp and assocresp IEs vary from the beacon, and need to be explicitly set + if(ret == 0) { + if(settings->beacon.proberesp_ies && settings->beacon.proberesp_ies_len > 0) { + rtw_cfg80211_set_mgnt_wpsp2pie(ndev, (char *)settings->beacon.proberesp_ies, + settings->beacon.proberesp_ies_len, 0x2/*PROBE_RESP*/); + } + if(settings->beacon.assocresp_ies && settings->beacon.assocresp_ies_len < 0) { + rtw_cfg80211_set_mgnt_wpsp2pie(ndev, (char *)settings->beacon.assocresp_ies, + settings->beacon.assocresp_ies_len, 0x4/*ASSOC_RESP*/); + } + } + adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid; if (settings->ssid && settings->ssid_len) { @@ -5151,6 +5213,18 @@ static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *nd ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len); + // In cases like WPS, the proberesp and assocresp IEs vary from the beacon, and need to be explicitly set + if(ret == 0) { + if(info->proberesp_ies && info->proberesp_ies_len > 0) { + rtw_cfg80211_set_mgnt_wpsp2pie(ndev, (char *)info->proberesp_ies, + info->proberesp_ies_len, 0x2/*PROBE_RESP*/); + } + if(info->assocresp_ies && info->assocresp_ies_len > 0) { + rtw_cfg80211_set_mgnt_wpsp2pie(ndev, (char *)info->assocresp_ies, + info->assocresp_ies_len, 0x4/*ASSOC_RESP*/); + } + } + return ret; } @@ -5445,6 +5519,14 @@ static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev } #endif + /* wpa_supplicant's auto peer will initiate peering when candidate peer is reported without max_peer_links consideration */ + if (plink_ctl->num >= mcfg->max_peer_links) { + RTW_INFO(FUNC_NDEV_FMT" exceed max_peer_links:%u\n" + , FUNC_NDEV_ARG(ndev), mcfg->max_peer_links); + ret = -EINVAL; + goto release_plink_ctl; + } + scanned = rtw_find_network(&padapter->mlmepriv.scanned_queue, mac); if (!scanned || rtw_get_passing_time_ms(scanned->last_scanned) >= mcfg->peer_sel_policy.scanr_exp_ms @@ -5877,6 +5959,8 @@ exit: static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev, struct bss_parameters *params) { + u8 i; + RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev)); /* RTW_INFO("use_cts_prot=%d\n", params->use_cts_prot); @@ -5983,6 +6067,7 @@ static int cfg80211_rtw_set_txq_params(struct wiphy *wiphy } #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) static int cfg80211_rtw_set_channel(struct wiphy *wiphy #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)) , struct net_device *ndev @@ -6029,6 +6114,7 @@ static int cfg80211_rtw_set_channel(struct wiphy *wiphy return 0; } +#endif /*#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))*/ static int cfg80211_rtw_set_monitor_channel(struct wiphy *wiphy #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) @@ -6149,6 +6235,7 @@ static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev, void rtw_cfg80211_rx_probe_request(_adapter *adapter, union recv_frame *rframe) { struct wireless_dev *wdev = adapter->rtw_wdev; + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); u8 *frame = get_recvframe_data(rframe); uint frame_len = rframe->u.hdr.len; s32 freq; @@ -6274,6 +6361,7 @@ indicate: void rtw_cfg80211_rx_action(_adapter *adapter, union recv_frame *rframe, const char *msg) { struct wireless_dev *wdev = adapter->rtw_wdev; + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); u8 *frame = get_recvframe_data(rframe); uint frame_len = rframe->u.hdr.len; s32 freq; @@ -6301,8 +6389,10 @@ void rtw_cfg80211_rx_action(_adapter *adapter, union recv_frame *rframe, const c rtw_mi_scan_abort(adapter, _FALSE); /*rtw_scan_abort_no_wait*/ } } - +#ifdef CONFIG_RTW_MESH indicate: +#endif + #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE) rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC); #else @@ -6342,6 +6432,7 @@ void rtw_cfg80211_rx_rrm_action(_adapter *adapter, union recv_frame *rframe) void rtw_cfg80211_rx_mframe(_adapter *adapter, union recv_frame *rframe, const char *msg) { struct wireless_dev *wdev = adapter->rtw_wdev; + struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter); u8 *frame = get_recvframe_data(rframe); uint frame_len = rframe->u.hdr.len; s32 freq; @@ -6395,6 +6486,7 @@ void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, unsigned short *fctrl; struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); struct wifidirect_info *pwdinfo = &(padapter->wdinfo); u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr)); @@ -6720,6 +6812,8 @@ static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy, { s32 err = 0; u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq); + u8 union_ch = 0, union_bw = 0, union_offset = 0; + u8 i; _adapter *padapter = NULL; struct rtw_wdev_priv *pwdev_priv; struct wifidirect_info *pwdinfo; @@ -6907,6 +7001,9 @@ exit: inline int rtw_cfg80211_iface_has_p2p_group_cap(_adapter *adapter) { + struct wiphy *wiphy = adapter_to_wiphy(adapter); + struct rtw_wdev_priv *wdev_data = adapter_wdev_data(adapter); + #if RTW_P2P_GROUP_INTERFACE if (is_primary_adapter(adapter)) return 0; @@ -7107,6 +7204,7 @@ static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, u8 no_cck, const struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter); #endif struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); + struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); u8 u_ch = rtw_mi_get_union_chan(padapter); u8 leave_op = 0; @@ -7167,8 +7265,9 @@ static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, u8 no_cck, const if (tx_ch != rtw_get_oper_ch(padapter)) set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); - +#ifdef CONFIG_MCC_MODE issue_mgmt_frame: +#endif /* starting alloc mgmt frame to dump it */ pmgntframe = alloc_mgtxmitframe(pxmitpriv); if (pmgntframe == NULL) { @@ -7314,9 +7413,12 @@ static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(COMPAT_KERNEL_RELEASE) struct ieee80211_channel *chan = params->chan; + bool offchan = params->offchan; + unsigned int wait = params->wait; const u8 *buf = params->buf; size_t len = params->len; bool no_cck = params->no_cck; + bool dont_wait_for_ack = params->dont_wait_for_ack; #endif #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0)) bool no_cck = 0; @@ -7423,6 +7525,7 @@ static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, wait_ack = 0; goto dump; } +#ifdef CONFIG_RTW_MESH else if (frame_styp == RTW_IEEE80211_STYPE_AUTH) { int retval = 0; @@ -7436,6 +7539,7 @@ static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy, dump_limit = 1; goto dump; } +#endif if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) { RTW_INFO(FUNC_ADPT_FMT" frame_control:0x%02x\n", FUNC_ADPT_ARG(padapter), @@ -7581,6 +7685,9 @@ static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy, frame_type, reg); #endif + /* Wait QC Verify */ + return; + switch (frame_type) { case IEEE80211_STYPE_AUTH: /* 0x00B0 */ if (reg > 0) @@ -9387,10 +9494,13 @@ static void rtw_cfg80211_init_ht_capab(_adapter *padapter static void rtw_cfg80211_init_vht_capab(_adapter *padapter , struct ieee80211_sta_vht_cap *sta_vht_cap, BAND_TYPE band, u8 rf_type) { + struct hal_spec_t *hal_spec = GET_HAL_SPEC(padapter); struct registry_priv *regsty = &padapter->registrypriv; + struct vht_priv *vhtpriv = &padapter->mlmepriv.vhtpriv; u8 vht_cap_ie[2 + 12] = {0}; + u8 bw; - if (!REGSTY_IS_11AC_ENABLE(regsty) || !is_supported_vht(regsty->wireless_mode)) + if (!REGSTY_IS_11AC_ENABLE(regsty) || !is_supported_vht(regsty->wireless_mode) || !hal_chk_proto_cap(padapter, PROTO_CAP_11AC)) return; rtw_vht_use_default_setting(padapter); @@ -9412,6 +9522,75 @@ void rtw_cfg80211_init_wdev_data(_adapter *padapter) #endif } +static void rtw_cfg80211_init_vht_capab_ex(_adapter *padapter, struct ieee80211_sta_vht_cap *vht_cap, u8 rf_type) +{ +//todo: Support for other bandwidths +/* NSS = Number of Spatial Streams */ +#define MAX_BIT_RATE_80MHZ_NSS3 1300 /* Mbps */ +#define MAX_BIT_RATE_80MHZ_NSS2 867 /* Mbps */ +#define MAX_BIT_RATE_80MHZ_NSS1 434 /* Mbps */ + struct registry_priv *pregistrypriv = &padapter->registrypriv; + struct mlme_priv *pmlmepriv = &padapter->mlmepriv; + struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + rtw_vht_use_default_setting(padapter); + /* RX LDPC */ + if (TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_RX)) + vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; + /* TX STBC */ + if (TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX)) + vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; + /* RX STBC */ + if (TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_RX)) { + switch (rf_type) { + case RF_1T1R: + vht_cap->cap |= IEEE80211_VHT_CAP_RXSTBC_1;/*RX STBC One spatial stream*/ + break; + case RF_2T2R: + case RF_1T2R: + vht_cap->cap |= IEEE80211_VHT_CAP_RXSTBC_2;/*RX STBC Two spatial streams*/ + break; + case RF_3T3R: + case RF_3T4R: + case RF_4T4R: + vht_cap->cap |= IEEE80211_VHT_CAP_RXSTBC_3;/*RX STBC Three spatial streams*/ + break; + default: + /* DBG_871X("[warning] rf_type %d is not expected\n", rf_type); */ + break; + } + } + /* switch (rf_type) { + case RF_1T1R: + vht_cap->vht_mcs.tx_highest = MAX_BIT_RATE_80MHZ_NSS1; + vht_cap->vht_mcs.rx_highest = MAX_BIT_RATE_80MHZ_NSS1; + break; + case RF_2T2R: + case RF_1T2R: + vht_cap->vht_mcs.tx_highest = MAX_BIT_RATE_80MHZ_NSS2; + vht_cap->vht_mcs.rx_highest = MAX_BIT_RATE_80MHZ_NSS2; + break; + case RF_3T3R: + case RF_3T4R: + case RF_4T4R: + vht_cap->vht_mcs.tx_highest = MAX_BIT_RATE_80MHZ_NSS3; + vht_cap->vht_mcs.rx_highest = MAX_BIT_RATE_80MHZ_NSS3; + break; + default: + DBG_871X("[warning] rf_type %d is not expected\n", rf_type); + break; + } */ + /* MCS map */ + vht_cap->vht_mcs.tx_mcs_map = pvhtpriv->vht_mcs_map[0] | (pvhtpriv->vht_mcs_map[1] << 8); + vht_cap->vht_mcs.rx_mcs_map = vht_cap->vht_mcs.tx_mcs_map; + if (rf_type == RF_1T1R) { + vht_cap->vht_mcs.tx_highest = MAX_BIT_RATE_80MHZ_NSS1; + vht_cap->vht_mcs.rx_highest = MAX_BIT_RATE_80MHZ_NSS1; + } + if (pvhtpriv->sgi_80m) + vht_cap->cap |= IEEE80211_VHT_CAP_SHORT_GI_80; + vht_cap->cap |= (pvhtpriv->ampdu_len << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT); +} + void rtw_cfg80211_init_wiphy(_adapter *padapter) { u8 rf_type; @@ -10037,6 +10216,7 @@ static struct cfg80211_ops rtw_cfg80211_ops = { .suspend = cfg80211_rtw_suspend, .resume = cfg80211_rtw_resume, #endif /* CONFIG_PNO_SUPPORT */ + #ifdef CONFIG_RFKILL_POLL .rfkill_poll = cfg80211_rtw_rfkill_poll, #endif @@ -10141,7 +10321,8 @@ int rtw_wdev_alloc(_adapter *padapter, struct wiphy *wiphy) } wdev->wiphy = wiphy; wdev->netdev = pnetdev; - wdev->iftype = NL80211_IFTYPE_STATION; + wdev->iftype = NL80211_IFTYPE_STATION; /* will be init in rtw_hal_init() */ + /* wdev->iftype = NL80211_IFTYPE_MONITOR; */ /* for rtw_setopmode_cmd() in cfg80211_rtw_change_iface() */ padapter->rtw_wdev = wdev; pnetdev->ieee80211_ptr = wdev;