diff --git a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c --- a/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c +++ b/sys/dev/rtwn/rtl8812a/usb/r12au_attach.c @@ -167,6 +167,8 @@ { struct r12a_softc *rs = sc->sc_priv; struct ieee80211com *ic = &sc->sc_ic; + uint32_t rx_mcs, tx_mcs; + if (rs->chip & R12A_CHIP_C_CUT) { ic->ic_htcaps |= IEEE80211_HTCAP_LDPC | @@ -178,7 +180,34 @@ | IEEE80211_HTCAP_SHORTGI40 /* short GI in 40MHz */ ; - /* TODO: STBC, VHT etc */ + /* TODO: STBC */ + + /* VHT config */ + ic->ic_flags_ext |= IEEE80211_FEXT_VHT; + ic->ic_vht_cap.vht_cap_info = + IEEE80211_VHTCAP_MAX_MPDU_LENGTH_11454 + | IEEE80211_VHTCAP_SHORT_GI_80 + | IEEE80211_VHTCAP_TXSTBC + | IEEE80211_VHTCAP_RXSTBC_1 + | IEEE80211_VHTCAP_HTC_VHT + | _IEEE80211_SHIFTMASK(7, + IEEE80211_VHTCAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK); + rx_mcs = tx_mcs = 0; + for (int i = 0 ; i < 8; i++) { + if (i < sc->ntxchains) + tx_mcs |= (IEEE80211_VHT_MCS_SUPPORT_0_9 << (i*2)); + else + tx_mcs |= (IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); + if (i < sc->nrxchains) + rx_mcs |= (IEEE80211_VHT_MCS_SUPPORT_0_9 << (i*2)); + else + rx_mcs |= (IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); + } + + ic->ic_vht_cap.supp_mcs.rx_mcs_map = rx_mcs; + ic->ic_vht_cap.supp_mcs.rx_highest = 0; + ic->ic_vht_cap.supp_mcs.tx_mcs_map = tx_mcs; + ic->ic_vht_cap.supp_mcs.tx_highest = 0; } void diff --git a/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c b/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c --- a/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c +++ b/sys/dev/rtwn/rtl8821a/usb/r21au_attach.c @@ -153,6 +153,8 @@ { struct ieee80211com *ic = &sc->sc_ic; struct r12a_softc *rs = sc->sc_priv; + uint32_t rx_mcs, tx_mcs; + ic->ic_htcaps |= IEEE80211_HTC_TXLDPC; if (rs->rs_radar != 0) @@ -163,7 +165,31 @@ | IEEE80211_HTCAP_SHORTGI40 /* short GI in 40MHz */ ; - /* TODO: VHT */ + /* VHT config */ + ic->ic_flags_ext |= IEEE80211_FEXT_VHT; + ic->ic_vht_cap.vht_cap_info = + IEEE80211_VHTCAP_MAX_MPDU_LENGTH_11454 + | IEEE80211_VHTCAP_SHORT_GI_80 + | IEEE80211_VHTCAP_TXSTBC + | IEEE80211_VHTCAP_RXSTBC_1 + | IEEE80211_VHTCAP_HTC_VHT + | _IEEE80211_SHIFTMASK(7, + IEEE80211_VHTCAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK); + rx_mcs = tx_mcs = 0; + for (int i = 0 ; i < 8; i++) { + if (i < sc->ntxchains) + tx_mcs |= (IEEE80211_VHT_MCS_SUPPORT_0_9 << (i*2)); + else + tx_mcs |= (IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); + if (i < sc->nrxchains) + rx_mcs |= (IEEE80211_VHT_MCS_SUPPORT_0_9 << (i*2)); + else + rx_mcs |= (IEEE80211_VHT_MCS_NOT_SUPPORTED << (i*2)); + } + ic->ic_vht_cap.supp_mcs.rx_mcs_map = rx_mcs; + ic->ic_vht_cap.supp_mcs.rx_highest = 0; + ic->ic_vht_cap.supp_mcs.tx_mcs_map = tx_mcs; + ic->ic_vht_cap.supp_mcs.tx_highest = 0; } void