Commit 6094f86f authored by Ryder Lee's avatar Ryder Lee Committed by Felix Fietkau

mt76: mt7915: add HE bss_conf support for interfaces

Add basic HE BSS's info for interfaces. As for the advanced features
will be added gradually in the future patches.
(i.e. BSS color, TWT, spatial reuse and OFDMA)
Signed-off-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Tested-by: default avatarShayne Chen <shayne.chen@mediatek.com>
Tested-by: default avatarChih-Min Chen <chih-min.chen@mediatek.com>
Tested-by: default avatarEvelyn Tsai <evelyn.tsai@mediatek.com>
Acked-by: default avatarYiwei Chung <yiwei.chung@mediatek.com>
Acked-by: default avatarYF Luo <yf.luo@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 37f4ca90
......@@ -744,6 +744,47 @@ mt7915_mcu_bss_omac_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)
omac->hw_bss_idx = idx;
}
struct mt7915_he_obss_narrow_bw_ru_data {
bool tolerated;
};
static void mt7915_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
struct cfg80211_bss *bss,
void *_data)
{
struct mt7915_he_obss_narrow_bw_ru_data *data = _data;
const struct element *elem;
elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, bss->ies->data,
bss->ies->len);
if (!elem || elem->datalen < 10 ||
!(elem->data[10] &
WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT))
data->tolerated = false;
}
static bool mt7915_check_he_obss_narrow_bw_ru(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct mt7915_he_obss_narrow_bw_ru_data iter_data = {
.tolerated = true,
};
if (!(vif->bss_conf.chandef.chan->flags & IEEE80211_CHAN_RADAR))
return false;
cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chandef,
mt7915_check_he_obss_narrow_bw_ru_iter,
&iter_data);
/*
* If there is at least one AP on radar channel that cannot
* tolerate 26-tone RU UL OFDMA transmissions using HE TB PPDU.
*/
return !iter_data.tolerated;
}
static void
mt7915_mcu_bss_rfch_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
struct mt7915_phy *phy)
......@@ -766,7 +807,20 @@ mt7915_mcu_bss_rfch_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
ch->center_ch1 = ieee80211_frequency_to_channel(freq2);
}
if (vif->bss_conf.he_support && vif->type == NL80211_IFTYPE_STATION) {
struct mt7915_dev *dev = phy->dev;
struct mt76_phy *mphy = &dev->mt76.phy;
bool ext_phy = phy != &dev->phy;
if (ext_phy && dev->mt76.phy2)
mphy = dev->mt76.phy2;
ch->he_ru26_block =
mt7915_check_he_obss_narrow_bw_ru(mphy->hw, vif);
ch->he_all_disable = false;
} else {
ch->he_all_disable = true;
}
}
static void
......@@ -795,6 +849,42 @@ mt7915_mcu_bss_ra_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
ra->fast_interval = cpu_to_le32(100);
}
static void
mt7915_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
struct mt7915_phy *phy)
{
#define DEFAULT_HE_PE_DURATION 4
#define DEFAULT_HE_DURATION_RTS_THRES 1023
struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
enum nl80211_band band = chandef->chan->band;
struct ieee80211_supported_band *sband;
const struct ieee80211_sta_he_cap *cap;
struct bss_info_he *he;
struct tlv *tlv;
if (band == NL80211_BAND_2GHZ)
sband = &phy->mt76->sband_2g.sband;
else
sband = &phy->mt76->sband_5g.sband;
cap = ieee80211_get_he_iftype_cap(sband, vif->type);
tlv = mt7915_mcu_add_tlv(skb, BSS_INFO_HE_BASIC, sizeof(*he));
he = (struct bss_info_he *)tlv;
he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext * 4;
if (!he->he_pe_duration)
he->he_pe_duration = DEFAULT_HE_PE_DURATION;
he->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th * 32);
if (!he->he_rts_thres)
he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES);
he->max_nss_mcs[CMD_HE_MCS_BW80] = cap->he_mcs_nss_supp.tx_mcs_80;
he->max_nss_mcs[CMD_HE_MCS_BW160] = cap->he_mcs_nss_supp.tx_mcs_160;
he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
}
static void
mt7915_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt7915_vif *mvif)
{
......@@ -870,6 +960,9 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
mt7915_mcu_bss_bmc_tlv(skb, phy);
mt7915_mcu_bss_ra_tlv(skb, vif, phy);
if (vif->bss_conf.he_support)
mt7915_mcu_bss_he_tlv(skb, vif, phy);
if (mvif->omac_idx > HW_BSSID_MAX)
mt7915_mcu_bss_ext_tlv(skb, mvif);
else
......
......@@ -396,6 +396,16 @@ struct bss_info_ra {
__le32 fast_interval;
} __packed;
struct bss_info_he {
__le16 tag;
__le16 len;
u8 he_pe_duration;
u8 vht_op_info_present;
__le16 he_rts_thres;
__le16 max_nss_mcs[CMD_HE_MCS_BW_NUM];
u8 rsv[6];
} __packed;
struct bss_info_bcn {
__le16 tag;
__le16 len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment