Commit 869f0646 authored by MeiChia Chiu's avatar MeiChia Chiu Committed by Felix Fietkau

mt76: mt7915: add support for 6G in-band discovery

Add offloading FILS discovery and unsolicited broadcast probe response support.
Reviewed-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarMeiChia Chiu <MeiChia.Chiu@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent f68d6762
...@@ -351,6 +351,8 @@ mt7915_init_wiphy(struct ieee80211_hw *hw) ...@@ -351,6 +351,8 @@ mt7915_init_wiphy(struct ieee80211_hw *hw)
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE); wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HE);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP);
wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_DISCOVERY);
if (!mdev->dev->of_node || if (!mdev->dev->of_node ||
!of_property_read_bool(mdev->dev->of_node, !of_property_read_bool(mdev->dev->of_node,
......
...@@ -1177,7 +1177,7 @@ mt7915_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif, ...@@ -1177,7 +1177,7 @@ mt7915_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif,
void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid, int pid, struct sk_buff *skb, struct mt76_wcid *wcid, int pid,
struct ieee80211_key_conf *key, bool beacon) struct ieee80211_key_conf *key, u32 changed)
{ {
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_vif *vif = info->control.vif; struct ieee80211_vif *vif = info->control.vif;
...@@ -1188,6 +1188,10 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, ...@@ -1188,6 +1188,10 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
bool mcast = false; bool mcast = false;
u16 tx_count = 15; u16 tx_count = 15;
u32 val; u32 val;
bool beacon = !!(changed & (BSS_CHANGED_BEACON |
BSS_CHANGED_BEACON_ENABLED));
bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
BSS_CHANGED_FILS_DISCOVERY));
if (vif) { if (vif) {
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
...@@ -1200,7 +1204,10 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, ...@@ -1200,7 +1204,10 @@ void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
if (ext_phy && dev->mt76.phy2) if (ext_phy && dev->mt76.phy2)
mphy = dev->mt76.phy2; mphy = dev->mt76.phy2;
if (beacon) { if (inband_disc) {
p_fmt = MT_TX_TYPE_FW;
q_idx = MT_LMAC_ALTX0;
} else if (beacon) {
p_fmt = MT_TX_TYPE_FW; p_fmt = MT_TX_TYPE_FW;
q_idx = MT_LMAC_BCN0; q_idx = MT_LMAC_BCN0;
} else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) { } else if (skb_get_queue_mapping(skb) >= MT_TXQ_PSD) {
...@@ -1308,8 +1315,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, ...@@ -1308,8 +1315,7 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
return id; return id;
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb); pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key, mt7915_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, pid, key, 0);
false);
txp = (struct mt7915_txp *)(txwi + MT_TXD_SIZE); txp = (struct mt7915_txp *)(txwi + MT_TXD_SIZE);
for (i = 0; i < nbuf; i++) { for (i = 0; i < nbuf; i++) {
...@@ -2008,7 +2014,8 @@ mt7915_update_vif_beacon(void *priv, u8 *mac, struct ieee80211_vif *vif) ...@@ -2008,7 +2014,8 @@ mt7915_update_vif_beacon(void *priv, u8 *mac, struct ieee80211_vif *vif)
case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_MESH_POINT:
case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
mt7915_mcu_add_beacon(hw, vif, vif->bss_conf.enable_beacon); mt7915_mcu_add_beacon(hw, vif, vif->bss_conf.enable_beacon,
BSS_CHANGED_BEACON_ENABLED);
break; break;
default: default:
break; break;
......
...@@ -622,8 +622,10 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw, ...@@ -622,8 +622,10 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
mt7915_update_bss_color(hw, vif, &info->he_bss_color); mt7915_update_bss_color(hw, vif, &info->he_bss_color);
if (changed & (BSS_CHANGED_BEACON | if (changed & (BSS_CHANGED_BEACON |
BSS_CHANGED_BEACON_ENABLED)) BSS_CHANGED_BEACON_ENABLED |
mt7915_mcu_add_beacon(hw, vif, info->enable_beacon); BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
BSS_CHANGED_FILS_DISCOVERY))
mt7915_mcu_add_beacon(hw, vif, info->enable_beacon, changed);
mutex_unlock(&dev->mt76.mutex); mutex_unlock(&dev->mt76.mutex);
} }
...@@ -636,7 +638,7 @@ mt7915_channel_switch_beacon(struct ieee80211_hw *hw, ...@@ -636,7 +638,7 @@ mt7915_channel_switch_beacon(struct ieee80211_hw *hw,
struct mt7915_dev *dev = mt7915_hw_dev(hw); struct mt7915_dev *dev = mt7915_hw_dev(hw);
mutex_lock(&dev->mt76.mutex); mutex_lock(&dev->mt76.mutex);
mt7915_mcu_add_beacon(hw, vif, true); mt7915_mcu_add_beacon(hw, vif, true, BSS_CHANGED_BEACON);
mutex_unlock(&dev->mt76.mutex); mutex_unlock(&dev->mt76.mutex);
} }
......
...@@ -1892,6 +1892,7 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif, ...@@ -1892,6 +1892,7 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
u8 *buf; u8 *buf;
int len = sizeof(*cont) + MT_TXD_SIZE + skb->len; int len = sizeof(*cont) + MT_TXD_SIZE + skb->len;
len = (len & 0x3) ? ((len | 0x3) + 1) : len;
tlv = mt7915_mcu_add_nested_subtlv(rskb, BSS_INFO_BCN_CONTENT, tlv = mt7915_mcu_add_nested_subtlv(rskb, BSS_INFO_BCN_CONTENT,
len, &bcn->sub_ntlv, &bcn->len); len, &bcn->sub_ntlv, &bcn->len);
...@@ -1910,7 +1911,7 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif, ...@@ -1910,7 +1911,7 @@ mt7915_mcu_beacon_cont(struct mt7915_dev *dev, struct ieee80211_vif *vif,
buf = (u8 *)tlv + sizeof(*cont); buf = (u8 *)tlv + sizeof(*cont);
mt7915_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL, mt7915_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL,
true); BSS_CHANGED_BEACON);
memcpy(buf + MT_TXD_SIZE, skb->data, skb->len); memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
} }
...@@ -1992,8 +1993,71 @@ mt7915_mcu_beacon_check_caps(struct mt7915_phy *phy, struct ieee80211_vif *vif, ...@@ -1992,8 +1993,71 @@ mt7915_mcu_beacon_check_caps(struct mt7915_phy *phy, struct ieee80211_vif *vif,
} }
} }
int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, static void
struct ieee80211_vif *vif, int en) mt7915_mcu_beacon_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct sk_buff *rskb, struct bss_info_bcn *bcn,
u32 changed)
{
#define OFFLOAD_TX_MODE_SU BIT(0)
#define OFFLOAD_TX_MODE_MU BIT(1)
struct ieee80211_hw *hw = mt76_hw(dev);
struct mt7915_phy *phy = mt7915_hw_phy(hw);
struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef;
enum nl80211_band band = chandef->chan->band;
struct mt76_wcid *wcid = &dev->mt76.global_wcid;
struct bss_info_inband_discovery *discov;
struct ieee80211_tx_info *info;
struct sk_buff *skb = NULL;
struct tlv *tlv;
bool ext_phy = phy != &dev->phy;
u8 *buf, interval;
int len;
if (changed & BSS_CHANGED_FILS_DISCOVERY &&
vif->bss_conf.fils_discovery.max_interval) {
interval = vif->bss_conf.fils_discovery.max_interval;
skb = ieee80211_get_fils_discovery_tmpl(hw, vif);
} else if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP &&
vif->bss_conf.unsol_bcast_probe_resp_interval) {
interval = vif->bss_conf.unsol_bcast_probe_resp_interval;
skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif);
}
if (!skb)
return;
info = IEEE80211_SKB_CB(skb);
info->control.vif = vif;
info->band = band;
if (ext_phy)
info->hw_queue |= MT_TX_HW_QUEUE_EXT_PHY;
len = sizeof(*discov) + MT_TXD_SIZE + skb->len;
len = (len & 0x3) ? ((len | 0x3) + 1) : len;
tlv = mt7915_mcu_add_nested_subtlv(rskb, BSS_INFO_BCN_DISCOV,
len, &bcn->sub_ntlv, &bcn->len);
discov = (struct bss_info_inband_discovery *)tlv;
discov->tx_mode = OFFLOAD_TX_MODE_SU;
/* 0: UNSOL PROBE RESP, 1: FILS DISCOV */
discov->tx_type = !!(changed & BSS_CHANGED_FILS_DISCOVERY);
discov->tx_interval = interval;
discov->prob_rsp_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
discov->enable = true;
buf = (u8 *)tlv + sizeof(*discov);
mt7915_mac_write_txwi(dev, (__le32 *)buf, skb, wcid, 0, NULL,
changed);
memcpy(buf + MT_TXD_SIZE, skb->data, skb->len);
dev_kfree_skb(skb);
}
int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
int en, u32 changed)
{ {
#define MAX_BEACON_SIZE 512 #define MAX_BEACON_SIZE 512
struct mt7915_dev *dev = mt7915_hw_dev(hw); struct mt7915_dev *dev = mt7915_hw_dev(hw);
...@@ -2044,6 +2108,11 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, ...@@ -2044,6 +2108,11 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw,
mt7915_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs); mt7915_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs);
dev_kfree_skb(skb); dev_kfree_skb(skb);
if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP ||
changed & BSS_CHANGED_FILS_DISCOVERY)
mt7915_mcu_beacon_inband_discov(dev, vif, rskb,
bcn, changed);
out: out:
return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb, return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb,
MCU_EXT_CMD(BSS_INFO_UPDATE), true); MCU_EXT_CMD(BSS_INFO_UPDATE), true);
......
...@@ -404,11 +404,23 @@ struct bss_info_bcn_cont { ...@@ -404,11 +404,23 @@ struct bss_info_bcn_cont {
__le16 pkt_len; __le16 pkt_len;
} __packed __aligned(4); } __packed __aligned(4);
struct bss_info_inband_discovery {
__le16 tag;
__le16 len;
u8 tx_type;
u8 tx_mode;
u8 tx_interval;
u8 enable;
__le16 rsv;
__le16 prob_rsp_len;
} __packed __aligned(4);
enum { enum {
BSS_INFO_BCN_CSA, BSS_INFO_BCN_CSA,
BSS_INFO_BCN_BCC, BSS_INFO_BCN_BCC,
BSS_INFO_BCN_MBSSID, BSS_INFO_BCN_MBSSID,
BSS_INFO_BCN_CONTENT, BSS_INFO_BCN_CONTENT,
BSS_INFO_BCN_DISCOV,
BSS_INFO_BCN_MAX BSS_INFO_BCN_MAX
}; };
...@@ -490,6 +502,7 @@ enum { ...@@ -490,6 +502,7 @@ enum {
#define MT7915_BEACON_UPDATE_SIZE (sizeof(struct sta_req_hdr) + \ #define MT7915_BEACON_UPDATE_SIZE (sizeof(struct sta_req_hdr) + \
sizeof(struct bss_info_bcn_cntdwn) + \ sizeof(struct bss_info_bcn_cntdwn) + \
sizeof(struct bss_info_bcn_mbss) + \ sizeof(struct bss_info_bcn_mbss) + \
sizeof(struct bss_info_bcn_cont)) sizeof(struct bss_info_bcn_cont) + \
sizeof(struct bss_info_inband_discovery))
#endif #endif
...@@ -469,7 +469,7 @@ int mt7915_mcu_add_rx_ba(struct mt7915_dev *dev, ...@@ -469,7 +469,7 @@ int mt7915_mcu_add_rx_ba(struct mt7915_dev *dev,
int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif, int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
struct cfg80211_he_bss_color *he_bss_color); struct cfg80211_he_bss_color *he_bss_color);
int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
int enable); int enable, u32 changed);
int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif, int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif,
bool enable); bool enable);
int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif, int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
...@@ -556,7 +556,7 @@ void mt7915_mac_cca_stats_reset(struct mt7915_phy *phy); ...@@ -556,7 +556,7 @@ void mt7915_mac_cca_stats_reset(struct mt7915_phy *phy);
void mt7915_mac_enable_nf(struct mt7915_dev *dev, bool ext_phy); void mt7915_mac_enable_nf(struct mt7915_dev *dev, bool ext_phy);
void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi, void mt7915_mac_write_txwi(struct mt7915_dev *dev, __le32 *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid, int pid, struct sk_buff *skb, struct mt76_wcid *wcid, int pid,
struct ieee80211_key_conf *key, bool beacon); struct ieee80211_key_conf *key, u32 changed);
void mt7915_mac_set_timing(struct mt7915_phy *phy); void mt7915_mac_set_timing(struct mt7915_phy *phy);
int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta); struct ieee80211_sta *sta);
......
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