diff --git a/sys/net80211/ieee80211_ht.h b/sys/net80211/ieee80211_ht.h --- a/sys/net80211/ieee80211_ht.h +++ b/sys/net80211/ieee80211_ht.h @@ -240,5 +240,9 @@ int ieee80211_ampdu_tx_request_active_ext(struct ieee80211_node *ni, int tid, int status); void ieee80211_htinfo_notify(struct ieee80211vap *vap); +int ieee80211_ht_get_node_ampdu_density(struct ieee80211_node *ni); +int ieee80211_ht_get_node_ampdu_limit(struct ieee80211_node *ni); +bool ieee80211_ht_check_tx_shortgi_20(struct ieee80211_node *ni); +bool ieee80211_ht_check_tx_shortgi_40(struct ieee80211_node *ni); #endif /* _NET80211_IEEE80211_HT_H_ */ diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c --- a/sys/net80211/ieee80211_ht.c +++ b/sys/net80211/ieee80211_ht.c @@ -3604,3 +3604,80 @@ frm[5] = BCM_OUI_HTINFO; return ieee80211_add_htinfo_body(frm + 6, ni); } + +/* + * Get the HT density for the given 802.11n node. + * + * Take into account the density advertised from the peer. + * Larger values are longer A-MPDU density spacing values, and + * we want to obey them per station if we get them. + */ +int +ieee80211_ht_get_node_ampdu_density(struct ieee80211_node *ni) +{ + struct ieee80211vap *vap = ni->ni_vap; + int peer_mpdudensity; + + peer_mpdudensity = + _IEEE80211_MASKSHIFT(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY); + if (vap->iv_ampdu_density > peer_mpdudensity) + peer_mpdudensity = vap->iv_ampdu_density; + return peer_mpdudensity; +} + +/* + * Get the transmit A-MPDU limit for the given 802.11n node. + * + * Take into account the limit advertised from the peer. + * Smaller values indicate smaller maximum A-MPDU sizes, and + * should be used when forming an A-MPDU to the given peer. + */ +int +ieee80211_ht_get_node_ampdu_limit(struct ieee80211_node *ni) +{ + struct ieee80211vap *vap = ni->ni_vap; + int peer_mpdulimit; + + peer_mpdulimit = + _IEEE80211_MASKSHIFT(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU); + + return MIN(vap->iv_ampdu_limit, peer_mpdulimit); +} + +/* + * Return true if short-GI is available when transmitting to + * the given node at 20MHz. + * + * Ensure it's configured and available in the VAP / driver as + * well as the node. + */ +bool +ieee80211_ht_check_tx_shortgi_20(struct ieee80211_node *ni) +{ + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; + + /* Note: always assume the node can do HT20 here */ + return (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI20) + && (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI20) + && (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI20); +} + +/* + * Return true if short-GI is available when transmitting to + * the given node at 40MHz. + * + * Ensure it's configured and available in the VAP / driver as + * well as the node. + */ +bool +ieee80211_ht_check_tx_shortgi_40(struct ieee80211_node *ni) +{ + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; + + return (ni->ni_chw == 40) + && (ic->ic_htcaps & IEEE80211_HTCAP_SHORTGI40) + && (ni->ni_htcap & IEEE80211_HTCAP_SHORTGI40) + && (vap->iv_flags_ht & IEEE80211_FHT_SHORTGI40); +}