diff --git a/core/rtw_recv.c b/core/rtw_recv.c index 3dd146b..38e91fd 100644 --- a/core/rtw_recv.c +++ b/core/rtw_recv.c @@ -3943,7 +3943,7 @@ exit: } #endif -static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe, u8 *buf) +static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe) { #define CHAN2FREQ(a) ((a < 14) ? (2407+5*a) : (5000+5*a)) @@ -3999,7 +3999,7 @@ static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe, u16 tmp_16bit = 0; - u8 data_rate[] = { + static u8 data_rate[] = { 2, 4, 11, 22, /* CCK */ 12, 18, 24, 36, 48, 72, 93, 108, /* OFDM */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* HT MCS index */ @@ -4015,12 +4015,61 @@ static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe, struct ieee80211_radiotap_header *rtap_hdr = NULL; u8 *ptr = NULL; +#ifdef CONFIG_RADIOTAP_WITH_RXDESC + u8 hdr_buf[128] = {0}; +#else u8 hdr_buf[64] = {0}; +#endif u16 rt_len = 8; + uint vendor_oui = 0; + + __le32 *it_present, *it_start; + u32 it_present_val; + int i; /* create header */ rtap_hdr = (struct ieee80211_radiotap_header *)&hdr_buf[0]; rtap_hdr->it_version = PKTHDR_RADIOTAP_VERSION; + it_start = it_present = &rtap_hdr->it_present; + + it_present_val = BIT(IEEE80211_RADIOTAP_FLAGS) | + BIT(IEEE80211_RADIOTAP_CHANNEL) | + BIT(IEEE80211_RADIOTAP_RX_FLAGS); + + if (pHalData->NumTotalRFPath <= 1) + it_present_val |= BIT(IEEE80211_RADIOTAP_ANTENNA); + + if(pHalData->NumTotalRFPath>0 && pattrib->physt) { + if(pHalData->NumTotalRFPath>1) { + for(i=0; iNumTotalRFPath - 1; i++) { + it_present_val |= BIT(IEEE80211_RADIOTAP_EXT) | + BIT(IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE); + //memcpy(it_present, &it_present_val, 4); + put_unaligned_le32(it_present_val, it_present); + it_present++; + it_present_val = BIT(IEEE80211_RADIOTAP_ANTENNA) | + BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL); + } + } + +#ifdef CONFIG_RADIOTAP_WITH_RXDESC + it_present_val |= BIT(IEEE80211_RADIOTAP_EXT) | + BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE); + put_unaligned_le32(it_present_val, it_present); + it_present++; + parse_beacon_vendor_oui(padapter, precvframe, &vendor_oui); + it_present_val = vendor_oui; +#endif + put_unaligned_le32(it_present_val, it_present); + it_present++; + + rt_len += (4*(it_present - it_start) - 4); + + } else { +#ifdef CONFIG_RADIOTAP_WITH_RXDESC + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE); +#endif + } /* tsft */ if (pattrib->tsfl) { @@ -4110,27 +4159,35 @@ static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe, memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); rt_len += 2; - /* dBm Antenna Signal */ - rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); - hdr_buf[rt_len] = pattrib->phy_info.recv_signal_power; - rt_len += 1; + if(pattrib->physt) { + /* dBm Antenna Signal */ + rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); + hdr_buf[rt_len] = pattrib->phy_info.RecvSignalPower; + rt_len += 1; #if 0 /* dBm Antenna Noise */ rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE); hdr_buf[rt_len] = 0; rt_len += 1; +#else + rt_len++; // alignment +#endif + } /* Signal Quality */ rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_LOCK_QUALITY); - hdr_buf[rt_len] = pattrib->phy_info.signal_quality; - rt_len += 1; -#endif + tmp_16bit = cpu_to_le16(pattrib->phy_info.SignalQuality); + memcpy(&hdr_buf[rt_len], &tmp_16bit, 2); + rt_len += 2; +#if 0 /* Antenna */ rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_ANTENNA); - hdr_buf[rt_len] = 0; /* pHalData->rf_type; */ + hdr_buf[rt_len] = pHalData->rf_type; rt_len += 1; + rt_len++; // alignment +#endif /* RX flags */ rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_RX_FLAGS); @@ -4237,24 +4294,64 @@ static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe, rt_len += 2; } + if (pattrib->physt) { + for(i=0; iNumTotalRFPath; i++) { + hdr_buf[rt_len] = pattrib->phy_info.RxPwr[i]; + rt_len ++; + hdr_buf[rt_len] = i; + rt_len ++; + } + } + +#ifdef CONFIG_RADIOTAP_WITH_RXDESC + rt_len += rt_len&1; + hdr_buf[rt_len++] = 0xde; + hdr_buf[rt_len++] = 0xab; + hdr_buf[rt_len++] = 0xbe; + hdr_buf[rt_len++] = 0xaf; + hdr_buf[rt_len++] = 24; + hdr_buf[rt_len++] = 0; + _rtw_memcpy(hdr_buf + rt_len, pattrib->rxdesc, RXDESC_SIZE); + rt_len += RXDESC_SIZE; +#endif + /* push to skb */ - pskb = (_pkt *)buf; + /* read skb information from recv frame */ + pskb = precvframe->u.hdr.pkt; + pskb->len = precvframe->u.hdr.len; + pskb->data = precvframe->u.hdr.rx_data; + skb_set_tail_pointer(pskb, precvframe->u.hdr.len); + if (skb_headroom(pskb) < rt_len) { - RTW_INFO("%s:%d %s headroom is too small.\n", __FILE__, __LINE__, __func__); - ret = _FAIL; - return ret; + pskb = skb_realloc_headroom(pskb, rt_len); + if(pskb == NULL) { + RTW_INFO("%s:%d %s headroom is too small.\n", __FILE__, __LINE__, __func__); + ret = _FAIL; + return ret; + } + precvframe->u.hdr.pkt = pskb; } ptr = skb_push(pskb, rt_len); if (ptr) { rtap_hdr->it_len = cpu_to_le16(rt_len); rtap_hdr->it_present = cpu_to_le32(rtap_hdr->it_present); - memcpy(ptr, rtap_hdr, rt_len); - } else + _rtw_memcpy(ptr, rtap_hdr, rt_len); + } else { + ret = _FAIL; + return ret; + } +out: + /* write skb information to recv frame */ + skb_reset_mac_header(pskb); + precvframe->u.hdr.len = pskb->len; + precvframe->u.hdr.rx_data = pskb->data; + precvframe->u.hdr.rx_head = pskb->head; + precvframe->u.hdr.rx_tail = skb_tail_pointer(pskb); + precvframe->u.hdr.rx_end = skb_end_pointer(pskb); ret = _FAIL; return ret; - } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)) int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe) @@ -4263,27 +4360,14 @@ int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe) _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; _pkt *pskb = NULL; - /* read skb information from recv frame */ - pskb = rframe->u.hdr.pkt; - pskb->len = rframe->u.hdr.len; - pskb->data = rframe->u.hdr.rx_data; - skb_set_tail_pointer(pskb, rframe->u.hdr.len); - #ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL /* fill radiotap header */ - if (fill_radiotap_hdr(padapter, rframe, (u8 *)pskb) == _FAIL) { + if (fill_radiotap_hdr(padapter, rframe) == _FAIL) { ret = _FAIL; rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */ goto exit; } #endif - /* write skb information to recv frame */ - skb_reset_mac_header(pskb); - rframe->u.hdr.len = pskb->len; - rframe->u.hdr.rx_data = pskb->data; - rframe->u.hdr.rx_head = pskb->head; - rframe->u.hdr.rx_tail = skb_tail_pointer(pskb); - rframe->u.hdr.rx_end = skb_end_pointer(pskb); if (!RTW_CANNOT_RUN(padapter)) { /* indicate this recv_frame */ diff --git a/core/rtw_vht.c b/core/rtw_vht.c index 9a7608c..1b8d185 100644 --- a/core/rtw_vht.c +++ b/core/rtw_vht.c @@ -106,38 +106,44 @@ void dump_vht_op_ie(void *sel, const u8 *ie, u32 ie_len) } /* 20/40/80, ShortGI, MCS Rate */ -const u16 VHT_MCS_DATA_RATE[3][2][30] = { +const u16 VHT_MCS_DATA_RATE[3][2][40] = { { { - 13, 26, 39, 52, 78, 104, 117, 130, 156, 156, - 26, 52, 78, 104, 156, 208, 234, 260, 312, 312, - 39, 78, 117, 156, 234, 312, 351, 390, 468, 520 + 7, 13, 20, 26, 39, 52, 59, 65, 78, 78, /*1T1R*/ + 13, 26, 39, 52, 78, 104, 117, 130, 156, 156, /*2T2R*/ + 20, 39, 59, 78, 117, 156, 176, 195, 234, 260, /*3T3R*/ + 26, 52, 78, 104, 156, 208, 234, 260, 312, 312 /*4T4R*/ }, /* Long GI, 20MHz */ { - 14, 29, 43, 58, 87, 116, 130, 144, 173, 173, - 29, 58, 87, 116, 173, 231, 260, 289, 347, 347, - 43, 87, 130, 173, 260, 347, 390, 433, 520, 578 + 7, 14, 22, 29, 43, 58, 65, 72, 87, 87, /*1T1R*/ + 14, 29, 43, 58, 87, 116, 130, 144, 173, 173, /*2T2R*/ + 22, 43, 65, 87, 130, 173, 195, 217, 260, 289, /*3T3R*/ + 29, 58, 87, 116, 173, 231, 260, 289, 347, 347 /*4T4R*/ } }, /* Short GI, 20MHz */ { { - 27, 54, 81, 108, 162, 216, 243, 270, 324, 360, - 54, 108, 162, 216, 324, 432, 486, 540, 648, 720, - 81, 162, 243, 324, 486, 648, 729, 810, 972, 1080 - }, /* Long GI, 40MHz */ + 14, 27, 41, 54, 81, 108, 122, 135, 162, 180, /*1T1R*/ + 27, 54, 81, 108, 162, 216, 243, 270, 324, 360,/*2T2R*/ + 41, 81, 122, 162, 243, 324, 365, 405, 486, 540, /*3T3R*/ + 54, 108, 162, 216, 324, 432, 486, 540, 648, 720 /*4T4R*/ + }, /* Long GI, 40MHz */ { - 30, 60, 90, 120, 180, 240, 270, 300, 360, 400, - 60, 120, 180, 240, 360, 480, 540, 600, 720, 800, - 90, 180, 270, 360, 540, 720, 810, 900, 1080, 1200 + 15, 30, 45, 60, 90, 120, 135, 150, 180, 200, /*1T1R*/ + 30, 60, 90, 120, 180, 240, 270, 300, 360, 400, /*2T2R*/ + 40, 95, 135, 180, 270, 360, 405, 450, 540, 600, /*3T3R*/ + 60, 120, 180, 240, 360, 480, 540, 600, 720, 800 /*4T4R*/ } }, /* Short GI, 40MHz */ { { - 59, 117, 176, 234, 351, 468, 527, 585, 702, 780, - 117, 234, 351, 468, 702, 936, 1053, 1170, 1404, 1560, - 176, 351, 527, 702, 1053, 1404, 1580, 1755, 2106, 2340 + 29, 59, 89, 117, 176, 234, 263, 293, 351, 390, /*1T1R*/ + 59, 117, 176, 234, 351, 468, 527, 585, 702, 780,/*2T2R*/ + 88, 176, 263, 351, 527, 702, 790, 878, 1053, 1170,/*3T3R*/ + 117, 234, 351, 468, 702, 936, 1053, 1170, 1404, 1560 /*4T4R*/ }, /* Long GI, 80MHz */ { - 65, 130, 195, 260, 390, 520, 585, 650, 780, 867, - 130, 260, 390, 520, 780, 1040, 1170, 1300, 1560, 1734, - 195, 390, 585, 780, 1170, 1560, 1755, 1950, 2340, 2600 + 33, 65, 98, 130, 195, 260, 293, 325, 390, 433,/*1T1R*/ + 65, 130, 195, 260, 390, 520, 585, 650, 780, 867, /*2T2R*/ + 98, 195, 293, 390, 585, 780, 878, 975, 1170, 1300, /*3T3R*/ + 130, 260, 390, 520, 780, 1040, 1170, 1300, 1560, 1733/*4T4R*/ } } /* Short GI, 80MHz */ }; diff --git a/include/ieee80211.h b/include/ieee80211.h index 5f7f3ec..ad3502d 100644 --- a/include/ieee80211.h +++ b/include/ieee80211.h @@ -1852,8 +1852,9 @@ enum rtw_ieee80211_wnm_actioncode { #define WME_TSPEC_DIRECTION_DOWNLINK 1 #define WME_TSPEC_DIRECTION_BI_DIRECTIONAL 3 - #define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */ +#define OUI_ATHEROS 0x00037f /*Atheros*/ +#define OUI_WFA 0x506f9a #define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */ @@ -2028,6 +2029,7 @@ struct rtw_ieee802_11_elems { u8 vht_operation_len; u8 *vht_op_mode_notify; u8 vht_op_mode_notify_len; + uint oui; u8 *rm_en_cap; u8 rm_en_cap_len; #ifdef CONFIG_RTW_MESH diff --git a/include/rtl_autoconf.h b/include/rtl_autoconf.h index 668cd6e..34b09d2 100644 --- a/include/rtl_autoconf.h +++ b/include/rtl_autoconf.h @@ -30,6 +30,11 @@ #define PLATFORM_LINUX +/* + * Monitor function Config + */ +//#define CONFIG_RADIOTAP_WITH_RXDESC + /* #define CONFIG_IOCTL_CFG80211 1 */ #ifdef CONFIG_IOCTL_CFG80211 diff --git a/include/rtw_recv.h b/include/rtw_recv.h index a541d87..2e39135 100644 --- a/include/rtw_recv.h +++ b/include/rtw_recv.h @@ -188,6 +188,9 @@ struct rx_pkt_attrib { u32 tsfl; u32 MacIDValidEntry[2]; /* 64 bits present 64 entry. */ u8 ppdu_cnt; +#ifdef CONFIG_RADIOTAP_WITH_RXDESC + u8 rxdesc[RXDESC_SIZE]; +#endif u32 free_cnt; /* free run counter */ struct phydm_phyinfo_struct phy_info; diff --git a/os_dep/linux/ioctl_cfg80211.c b/os_dep/linux/ioctl_cfg80211.c index 24cd0f9..ec37415 100644 --- a/os_dep/linux/ioctl_cfg80211.c +++ b/os_dep/linux/ioctl_cfg80211.c @@ -2328,7 +2328,6 @@ static int cfg80211_rtw_get_station(struct wiphy *wiphy, //sinfo->txrate.flags |= NL80211_RATE_INFO_VHT_NSS; //sinfo->txrate.nss = rtw_vht_mcsmap_to_nss(psta->vhtpriv.vht_mcs_map); - /* bw_mode is more delicate sinfo->txrate.bw is flagged psta->bw_mode */ @@ -2371,10 +2370,9 @@ 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->dtim; + sinfo->bss_param.dtim_period = pwrctl->dtim; - // kimocoder: this one below needs attention - //sinfo->bss_param.beacon_interval = get_beacon_interval(wlan_network->network); + sinfo->bss_param.beacon_interval = get_beacon_interval(wlan_network->network); #endif @@ -2425,7 +2423,7 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy, NDIS_802_11_NETWORK_INFRASTRUCTURE networkType; _adapter *padapter = (_adapter *)rtw_netdev_priv(ndev); struct wireless_dev *rtw_wdev = padapter->rtw_wdev; - struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); + struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); #ifdef CONFIG_P2P struct wifidirect_info *pwdinfo = &(padapter->wdinfo); u8 is_p2p = _FALSE; @@ -2443,7 +2441,6 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy, goto exit; } - RTW_INFO(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev)); if (netdev_open(ndev) != 0) { RTW_INFO(FUNC_NDEV_FMT" call netdev_open fail\n", FUNC_NDEV_ARG(ndev)); @@ -2451,7 +2448,6 @@ static int cfg80211_rtw_change_iface(struct wiphy *wiphy, goto exit; } - if (_FAIL == rtw_pwr_wakeup(padapter)) { RTW_INFO(FUNC_NDEV_FMT" call rtw_pwr_wakeup fail\n", FUNC_NDEV_ARG(ndev)); ret = -EPERM; @@ -9532,12 +9528,15 @@ static void rtw_cfg80211_init_vht_capab_ex(_adapter *padapter, struct ieee80211_ { //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 */ +//#define MAX_BIT_RATE_80MHZ_NSS3 1300 /* Mbps */ +//#define MAX_BIT_RATE_80MHZ_NSS2 867 /* Mbps */ +//#define MAX_BIT_RATE_80MHZ_NSS1 433 /* Mbps */ struct registry_priv *pregistrypriv = &padapter->registrypriv; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct vht_priv *pvhtpriv = &pmlmepriv->vhtpriv; + u32 rx_packet_offset, max_recvbuf_sz; + u16 HighestRate; + u8 bw, rf_num; rtw_vht_use_default_setting(padapter); /* RX LDPC */ if (TEST_FLAG(pvhtpriv->ldpc_cap, LDPC_VHT_ENABLE_RX)) @@ -9545,6 +9544,10 @@ static void rtw_cfg80211_init_vht_capab_ex(_adapter *padapter, struct ieee80211_ /* TX STBC */ if (TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_TX)) vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; + + if (pvhtpriv->sgi_80m) + vht_cap->cap |= IEEE80211_VHT_CAP_SHORT_GI_80; + /* RX STBC */ if (TEST_FLAG(pvhtpriv->stbc_cap, STBC_VHT_ENABLE_RX)) { switch (rf_type) { @@ -9588,13 +9591,67 @@ static void rtw_cfg80211_init_vht_capab_ex(_adapter *padapter, struct ieee80211_ /* 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; + /* B0 B1 Maximum MPDU Length */ + rtw_hal_get_def_var(padapter, HAL_DEF_RX_PACKET_OFFSET, &rx_packet_offset); + rtw_hal_get_def_var(padapter, HAL_DEF_MAX_RECVBUF_SZ, &max_recvbuf_sz); + + if ((max_recvbuf_sz - rx_packet_offset) >= 11454) { + vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454; + } else if ((max_recvbuf_sz - rx_packet_offset) >= 7991) { + vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991; + } else if ((max_recvbuf_sz - rx_packet_offset) >= 3895) { + vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895; } - 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); + /* B2 B3 Supported Channel Width Set */ + if (hal_chk_bw_cap(padapter, BW_CAP_160M) && REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_160)) { + if (hal_chk_bw_cap(padapter, BW_CAP_80_80M) && REGSTY_IS_BW_5G_SUPPORT(pregistrypriv, CHANNEL_WIDTH_80_80)) + vht_cap->cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; + else + vht_cap->cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; + } + +#ifdef CONFIG_BEAMFORMING + /* B11 SU Beamformer Capable */ + if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMER_ENABLE)) { + vht_cap->cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE; + /* B16 17 18 Number of Sounding Dimensions */ + rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMER_CAP, (u8 *)&rf_num); + vht_cap->cap |= rf_num << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT; + /* B19 MU Beamformer Capable */ + if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_MU_MIMO_AP_ENABLE)) + vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE; + } + /* B12 SU Beamformee Capable */ + if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_BEAMFORMEE_ENABLE)) { + vht_cap->cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE; + // B13 14 15 Compressed Steering Number of Beamformer Antennas Supported + rtw_hal_get_def_var(padapter, HAL_DEF_BEAMFORMEE_CAP, (u8 *)&rf_num); + vht_cap->cap |= rf_num << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT; + /* B20 MU Beamformee Capable */ + if (TEST_FLAG(pvhtpriv->beamform_cap, BEAMFORMING_VHT_MU_MIMO_STA_ENABLE)) + vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE; + } +#endif + + /* B22 +HTC-VHT Capable */ + vht_cap->cap |= IEEE80211_VHT_CAP_HTC_VHT; + + /* B23 24 25 Maximum A-MPDU Length Exponent */ + if (pregistrypriv->ampdu_factor != 0xFE) + vht_cap->cap |= pregistrypriv->ampdu_factor << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; + else + vht_cap->cap |= 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; + + /* B26 27 VHT Link Adaptation Capable */ + /* find the largest bw supported by both registry and hal */ + /* this is taken from core/rtw_vht.c */ + bw = hal_largest_bw(padapter, REGSTY_BW_5G(pregistrypriv)); + HighestRate = rtw_vht_mcs_to_data_rate(bw, pvhtpriv->sgi_80m, pvhtpriv->vht_highest_rate); + + vht_cap->vht_mcs.tx_highest = HighestRate; + vht_cap->vht_mcs.rx_highest = HighestRate; + + return; } void rtw_cfg80211_init_wiphy(_adapter *padapter) diff --git a/os_dep/linux/recv_linux.c b/os_dep/linux/recv_linux.c index 2f7b3e3..4a9514a 100644 --- a/os_dep/linux/recv_linux.c +++ b/os_dep/linux/recv_linux.c @@ -619,7 +619,8 @@ void rtw_hostapd_mlme_rx(_adapter *padapter, union recv_frame *precv_frame) skb->ip_summed = CHECKSUM_NONE; skb->pkt_type = PACKET_OTHERHOST; /* skb->protocol = __constant_htons(0x0019); ETH_P_80211_RAW */ - skb->protocol = __constant_htons(0x0003); /*ETH_P_80211_RAW*/ + // skb->protocol = __constant_htons(0x0003); /*ETH_P_80211_RAW*/ + skb->protocol = htons(ETH_P_802_2); /* ETH_P_80211_RAW */ /* RTW_INFO("(1)data=0x%x, head=0x%x, tail=0x%x, mac_header=0x%x, len=%d\n", skb->data, skb->head, skb->tail, skb->mac_header, skb->len); */