From bf18f7172aa429ec6a68852984a2e9468560c066 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:47 +0100 Subject: [PATCH 01/16] wifi: mt76: rename struct mt76_vif to mt76_vif_link Preparation to use it for private bss link data instead of the full vif on MLO capable devices. Link: https://patch.msgid.link/20250102163508.52945-3-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76.h | 2 +- .../net/wireless/mediatek/mt76/mt7615/mac.c | 2 +- .../net/wireless/mediatek/mt76/mt7615/main.c | 2 +- .../wireless/mediatek/mt76/mt7615/mt7615.h | 2 +- .../wireless/mediatek/mt76/mt7615/pci_mac.c | 2 +- .../wireless/mediatek/mt76/mt76_connac_mac.c | 4 +- .../wireless/mediatek/mt76/mt76_connac_mcu.c | 54 +++++++++---------- .../wireless/mediatek/mt76/mt76_connac_mcu.h | 14 ++--- .../wireless/mediatek/mt76/mt7915/mt7915.h | 2 +- .../net/wireless/mediatek/mt76/mt7921/mcu.c | 4 +- .../net/wireless/mediatek/mt76/mt7925/mac.c | 4 +- .../net/wireless/mediatek/mt76/mt7925/main.c | 2 +- .../net/wireless/mediatek/mt76/mt7925/mcu.c | 26 ++++----- .../net/wireless/mediatek/mt76/mt7925/mcu.h | 2 +- drivers/net/wireless/mediatek/mt76/mt792x.h | 2 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/main.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 12 ++--- .../wireless/mediatek/mt76/mt7996/mt7996.h | 2 +- drivers/net/wireless/mediatek/mt76/scan.c | 2 +- 20 files changed, 74 insertions(+), 74 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index aac8ca7265c2..1782ebc7085e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -754,7 +754,7 @@ struct mt76_testmode_data { } rx_stats; }; -struct mt76_vif { +struct mt76_vif_link { u8 idx; u8 omac_idx; u8 band_idx; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c index 27c3857bcd7b..3ca4fae7c4b0 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -730,7 +730,7 @@ int mt7615_mac_write_txwi(struct mt7615_dev *dev, __le32 *txwi, u16 seqno = 0; if (vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; omac_idx = mvif->omac_idx; wmm_idx = mvif->wmm_idx; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index 646474aa828d..e883cf4e1095 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -464,7 +464,7 @@ mt7615_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id, u16 queue, const struct ieee80211_tx_queue_params *params) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt7615_dev *dev = mt7615_hw_dev(hw); int err; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h index 530da48ce3ea..9bdd29e8d25e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h @@ -139,7 +139,7 @@ struct mt7615_sta { }; struct mt7615_vif { - struct mt76_vif mt76; /* must be first */ + struct mt76_vif_link mt76; /* must be first */ struct mt7615_sta sta; bool sta_added; }; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c index fbb1181c58ff..a0ca3bbdfcaf 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c @@ -48,7 +48,7 @@ mt7615_write_fw_txp(struct mt7615_dev *dev, struct mt76_tx_info *tx_info, txp->flags |= cpu_to_le16(MT_CT_INFO_MGMT_FRAME); if (vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; txp->bss_idx = mvif->idx; } diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c index f719457e39b2..5170af3e3428 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c @@ -294,7 +294,7 @@ u16 mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif, bool beacon, bool mcast) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct cfg80211_chan_def *chandef = mvif->ctx ? &mvif->ctx->def : &mphy->chandef; u8 nss = 0, mode = 0, band = chandef->chan->band; @@ -505,7 +505,7 @@ void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, bool amsdu_en = wcid->amsdu; if (vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; omac_idx = mvif->omac_idx; wmm_idx = mvif->wmm_idx; diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c index 4171710d645c..5c76a0885278 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c @@ -189,7 +189,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_mac_enable); int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct { u8 bss_idx; u8 ps_state; /* 0: device awake @@ -232,7 +232,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rts_thresh); void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt76_connac_beacon_loss_event *event = priv; if (mvif->idx != event->bss_idx) @@ -273,7 +273,7 @@ mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag, int len, EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_nested_tlv); struct sk_buff * -__mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif, +__mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif_link *mvif, struct mt76_wcid *wcid, int len) { struct sta_req_hdr hdr = { @@ -329,7 +329,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_wtbl_req); void mt76_connac_mcu_bss_omac_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; u8 omac_idx = mvif->omac_idx; struct bss_info_omac *omac; struct tlv *tlv; @@ -497,7 +497,7 @@ int mt76_connac_mcu_sta_update_hdr_trans(struct mt76_dev *dev, struct ieee80211_vif *vif, struct mt76_wcid *wcid, int cmd) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct wtbl_req_hdr *wtbl_hdr; struct tlv *sta_wtbl; struct sk_buff *skb; @@ -545,7 +545,7 @@ void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev, struct ieee80211_sta *sta, void *sta_wtbl, void *wtbl_tlv) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct wtbl_generic *generic; struct wtbl_rx *rx; struct wtbl_spe *spe; @@ -849,7 +849,7 @@ void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb, struct ieee80211_vif *vif, u8 rcpi, u8 sta_state) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct cfg80211_chan_def *chandef = mvif->ctx ? &mvif->ctx->def : &mphy->chandef; enum nl80211_band band = chandef->chan->band; @@ -1041,7 +1041,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ht_tlv); int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy, struct mt76_sta_cmd_info *info) { - struct mt76_vif *mvif = (struct mt76_vif *)info->vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)info->vif->drv_priv; struct ieee80211_link_sta *link_sta; struct mt76_dev *dev = phy->dev; struct wtbl_req_hdr *wtbl_hdr; @@ -1137,7 +1137,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ba_tlv); int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy, struct ieee80211_bss_conf *bss_conf, - struct mt76_vif *mvif, + struct mt76_vif_link *mvif, struct mt76_wcid *wcid, bool enable) { @@ -1266,7 +1266,7 @@ int mt76_connac_mcu_sta_wed_update(struct mt76_dev *dev, struct sk_buff *skb) } EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_wed_update); -int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif, +int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif_link *mvif, struct ieee80211_ampdu_params *params, int cmd, bool enable, bool tx) { @@ -1404,7 +1404,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode_ext); const struct ieee80211_sta_he_cap * mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct cfg80211_chan_def *chandef = mvif->ctx ? &mvif->ctx->def : &phy->chandef; enum nl80211_band band = chandef->chan->band; @@ -1453,7 +1453,7 @@ mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif, he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80; } -int mt76_connac_mcu_uni_set_chctx(struct mt76_phy *phy, struct mt76_vif *mvif, +int mt76_connac_mcu_uni_set_chctx(struct mt76_phy *phy, struct mt76_vif_link *mvif, struct ieee80211_chanctx_conf *ctx) { struct cfg80211_chan_def *chandef = ctx ? &ctx->def : &phy->chandef; @@ -1541,7 +1541,7 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy, bool enable, struct ieee80211_chanctx_conf *ctx) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct cfg80211_chan_def *chandef = ctx ? &ctx->def : &phy->chandef; enum nl80211_band band = chandef->chan->band; struct mt76_dev *mdev = phy->dev; @@ -1667,7 +1667,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss); int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif, struct ieee80211_scan_request *scan_req) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct cfg80211_scan_request *sreq = &scan_req->req; int n_ssids = 0, err, i, duration; int ext_channels_num = max_t(int, sreq->n_channels - 32, 0); @@ -1773,7 +1773,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_hw_scan); int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct { u8 seq_num; u8 is_ext_channel; @@ -1799,7 +1799,7 @@ int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy, struct ieee80211_vif *vif, struct cfg80211_sched_scan_request *sreq) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct ieee80211_channel **scan_list = sreq->channels; struct mt76_connac_mcu_scan_channel *chan; struct mt76_connac_sched_scan_req *req; @@ -2211,7 +2211,7 @@ int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy) EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rate_txpower); int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev, - struct mt76_vif *vif, + struct mt76_vif_link *vif, struct ieee80211_bss_conf *info) { struct ieee80211_vif *mvif = container_of(info, struct ieee80211_vif, @@ -2254,7 +2254,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_arp_filter); int mt76_connac_mcu_set_p2p_oppps(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; int ct_window = vif->bss_conf.p2p_noa_attr.oppps_ctwindow; struct mt76_phy *phy = hw->priv; struct { @@ -2321,7 +2321,7 @@ int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct cfg80211_gtk_rekey_data *key) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt76_connac_gtk_rekey_tlv *gtk_tlv; struct mt76_phy *phy = hw->priv; struct sk_buff *skb; @@ -2362,7 +2362,7 @@ static int mt76_connac_mcu_set_arp_filter(struct mt76_dev *dev, struct ieee80211_vif *vif, bool suspend) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct { struct { u8 bss_idx; @@ -2388,7 +2388,7 @@ int mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif, bool suspend) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct { struct { u8 bss_idx; @@ -2417,7 +2417,7 @@ mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev, bool enable, u8 mdtim, bool wow_suspend) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct { struct { u8 bss_idx; @@ -2448,7 +2448,7 @@ mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev, u8 index, bool enable, struct cfg80211_pkt_pattern *pattern) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt76_connac_wow_pattern_tlv *ptlv; struct sk_buff *skb; struct req_hdr { @@ -2480,7 +2480,7 @@ int mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif, bool suspend, struct cfg80211_wowlan *wowlan) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt76_dev *dev = phy->dev; struct { struct { @@ -2689,7 +2689,7 @@ int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, struct ieee80211_key_conf *key, int mcu_cmd, struct mt76_wcid *wcid, enum set_key_cmd cmd) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct sk_buff *skb; int ret; @@ -2711,7 +2711,7 @@ EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_key); /* SIFS 20us + 512 byte beacon transmitted by 1Mbps (3906us) */ #define BCN_TX_ESTIMATE_TIME (4096 + 20) -void mt76_connac_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt76_vif *mvif) +void mt76_connac_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt76_vif_link *mvif) { struct bss_info_ext_bss *ext; int ext_bss_idx, tsf_offset; @@ -2735,7 +2735,7 @@ int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb, struct mt76_phy *phy, u16 wlan_idx, bool enable) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; u32 type = vif->p2p ? NETWORK_P2P : NETWORK_INFRA; struct bss_info_basic *bss; struct tlv *tlv; diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h index 919194ab6265..8f23b9e58d2a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h @@ -1878,10 +1878,10 @@ mt76_connac_mcu_get_wlan_idx(struct mt76_dev *dev, struct mt76_wcid *wcid, } struct sk_buff * -__mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif, +__mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif_link *mvif, struct mt76_wcid *wcid, int len); static inline struct sk_buff * -mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif, +mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif_link *mvif, struct mt76_wcid *wcid) { return __mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid, @@ -1940,14 +1940,14 @@ void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb, bool enable, bool tx); int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy, struct ieee80211_bss_conf *bss_conf, - struct mt76_vif *mvif, + struct mt76_vif_link *mvif, struct mt76_wcid *wcid, bool enable); -int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif, +int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif_link *mvif, struct ieee80211_ampdu_params *params, int cmd, bool enable, bool tx); int mt76_connac_mcu_uni_set_chctx(struct mt76_phy *phy, - struct mt76_vif *vif, + struct mt76_vif_link *vif, struct ieee80211_chanctx_conf *ctx); int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy, struct ieee80211_vif *vif, @@ -1978,7 +1978,7 @@ int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy, struct ieee80211_vif *vif, bool enable); int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev, - struct mt76_vif *vif, + struct mt76_vif_link *vif, struct ieee80211_bss_conf *info); int mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif, bool suspend); @@ -2025,7 +2025,7 @@ int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, struct ieee80211_key_conf *key, int mcu_cmd, struct mt76_wcid *wcid, enum set_key_cmd cmd); -void mt76_connac_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt76_vif *mvif); +void mt76_connac_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt76_vif_link *mvif); void mt76_connac_mcu_bss_omac_tlv(struct sk_buff *skb, struct ieee80211_vif *vif); int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb, diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 5fe872ef2e93..533939f2b7ed 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -166,7 +166,7 @@ struct mt7915_vif_cap { }; struct mt7915_vif { - struct mt76_vif mt76; /* must be first */ + struct mt76_vif_link mt76; /* must be first */ struct mt7915_vif_cap cap; struct mt7915_sta sta; diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c index 3f45221d00e8..86bd33b916a9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -180,7 +180,7 @@ static void mt7921_mcu_connection_loss_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt76_connac_beacon_loss_event *event = priv; if (mvif->idx != event->bss_idx) @@ -1131,7 +1131,7 @@ int mt7921_get_txpwr_info(struct mt792x_dev *dev, struct mt7921_txpwr *txpwr) int mt7921_mcu_set_sniffer(struct mt792x_dev *dev, struct ieee80211_vif *vif, bool enable) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct { struct { u8 band_idx; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c index 187770537a1a..91e854e3d0e8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c @@ -730,7 +730,7 @@ mt7925_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0, band_idx = 0; u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE; bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; - struct mt76_vif *mvif; + struct mt76_vif_link *mvif; bool beacon = !!(changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)); bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | @@ -739,7 +739,7 @@ mt7925_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi, mconf = vif ? mt792x_vif_to_link((struct mt792x_vif *)vif->drv_priv, wcid->link_id) : NULL; - mvif = mconf ? (struct mt76_vif *)&mconf->mt76 : NULL; + mvif = mconf ? (struct mt76_vif_link *)&mconf->mt76 : NULL; if (mvif) { omac_idx = mvif->omac_idx; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index ddc67423efe2..230e4d20c885 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -803,7 +803,7 @@ static u8 mt7925_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, bool beacon, bool mcast) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt76_phy *mphy = hw->priv; u16 rate; u8 i, idx, ht; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c index d4d3ecf863c4..6bd5322bcf14 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c @@ -164,7 +164,7 @@ static int mt7925_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif, bool suspend, struct cfg80211_wowlan *wowlan) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt76_dev *dev = phy->dev; struct { struct { @@ -219,7 +219,7 @@ mt7925_mcu_set_wow_pattern(struct mt76_dev *dev, u8 index, bool enable, struct cfg80211_pkt_pattern *pattern) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt7925_wow_pattern_tlv *tlv; struct sk_buff *skb; struct { @@ -274,7 +274,7 @@ static void mt7925_mcu_connection_loss_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt7925_uni_beacon_loss_event *event = priv; if (mvif->idx != event->hdr.bss_idx) @@ -304,7 +304,7 @@ mt7925_mcu_connection_loss_event(struct mt792x_dev *dev, struct sk_buff *skb) static void mt7925_mcu_roc_iter(void *priv, u8 *mac, struct ieee80211_vif *vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt7925_roc_grant_tlv *grant = priv; if (ieee80211_vif_is_mld(vif) && vif->type == NL80211_IFTYPE_STATION) @@ -528,7 +528,7 @@ void mt7925_mcu_rx_event(struct mt792x_dev *dev, struct sk_buff *skb) } static int -mt7925_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif, +mt7925_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif_link *mvif, struct mt76_wcid *wcid, struct ieee80211_ampdu_params *params, bool enable, bool tx) @@ -1807,7 +1807,7 @@ static int mt7925_mcu_sta_cmd(struct mt76_phy *phy, struct mt76_sta_cmd_info *info) { - struct mt76_vif *mvif = (struct mt76_vif *)info->vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)info->vif->drv_priv; struct mt76_dev *dev = phy->dev; struct sk_buff *skb; int conn_state; @@ -2264,7 +2264,7 @@ void mt7925_mcu_bss_rlm_tlv(struct sk_buff *skb, struct mt76_phy *phy, } static struct sk_buff * -__mt7925_mcu_alloc_bss_req(struct mt76_dev *dev, struct mt76_vif *mvif, int len) +__mt7925_mcu_alloc_bss_req(struct mt76_dev *dev, struct mt76_vif_link *mvif, int len) { struct bss_req_hdr hdr = { .bss_idx = mvif->idx, @@ -2280,7 +2280,7 @@ __mt7925_mcu_alloc_bss_req(struct mt76_dev *dev, struct mt76_vif *mvif, int len) return skb; } -int mt7925_mcu_set_chctx(struct mt76_phy *phy, struct mt76_vif *mvif, +int mt7925_mcu_set_chctx(struct mt76_phy *phy, struct mt76_vif_link *mvif, struct ieee80211_bss_conf *link_conf, struct ieee80211_chanctx_conf *ctx) { @@ -2433,7 +2433,7 @@ mt7925_mcu_bss_sec_tlv(struct sk_buff *skb, struct ieee80211_bss_conf *link_conf) { struct mt792x_bss_conf *mconf = mt792x_link_conf_to_mconf(link_conf); - struct mt76_vif *mvif = &mconf->mt76; + struct mt76_vif_link *mvif = &mconf->mt76; struct bss_sec_tlv { __le16 tag; __le16 len; @@ -2484,7 +2484,7 @@ mt7925_mcu_bss_bmc_tlv(struct sk_buff *skb, struct mt792x_phy *phy, &link_conf->chanreq.oper; struct mt792x_bss_conf *mconf = mt792x_link_conf_to_mconf(link_conf); enum nl80211_band band = chandef->chan->band; - struct mt76_vif *mvif = &mconf->mt76; + struct mt76_vif_link *mvif = &mconf->mt76; struct bss_rate_tlv *bmc; struct tlv *tlv; u8 idx = mvif->mcast_rates_idx ? @@ -2692,7 +2692,7 @@ int mt7925_mcu_set_dbdc(struct mt76_phy *phy, bool enable) int mt7925_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif, struct ieee80211_scan_request *scan_req) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct cfg80211_scan_request *sreq = &scan_req->req; int n_ssids = 0, err, i; struct ieee80211_channel **scan_list = sreq->channels; @@ -2801,7 +2801,7 @@ int mt7925_mcu_sched_scan_req(struct mt76_phy *phy, struct ieee80211_vif *vif, struct cfg80211_sched_scan_request *sreq) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct ieee80211_channel **scan_list = sreq->channels; struct mt76_connac_mcu_scan_channel *chan; struct mt76_dev *mdev = phy->dev; @@ -2937,7 +2937,7 @@ mt7925_mcu_sched_scan_enable(struct mt76_phy *phy, int mt7925_mcu_cancel_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct { struct scan_hdr { u8 seq_num; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h index fe6a613ba008..1e47d2c61b54 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.h @@ -637,7 +637,7 @@ int mt7925_mcu_set_timing(struct mt792x_phy *phy, int mt7925_mcu_set_deep_sleep(struct mt792x_dev *dev, bool enable); int mt7925_mcu_set_channel_domain(struct mt76_phy *phy); int mt7925_mcu_set_radio_en(struct mt792x_phy *phy, bool enable); -int mt7925_mcu_set_chctx(struct mt76_phy *phy, struct mt76_vif *mvif, +int mt7925_mcu_set_chctx(struct mt76_phy *phy, struct mt76_vif_link *mvif, struct ieee80211_bss_conf *link_conf, struct ieee80211_chanctx_conf *ctx); int mt7925_mcu_set_rate_txpower(struct mt76_phy *phy); diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h index 3f989e83f252..e331a056950f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x.h +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h @@ -117,7 +117,7 @@ struct mt792x_chanctx { }; struct mt792x_bss_conf { - struct mt76_vif mt76; /* must be first */ + struct mt76_vif_link mt76; /* must be first */ struct mt792x_vif *vif; struct ewma_rssi rssi; struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c index 8e3620d8a7c8..fb6ab96cdeab 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -831,7 +831,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi, u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2; u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0; bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP; - struct mt76_vif *mvif; + struct mt76_vif_link *mvif; u16 tx_count = 15; u32 val; bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | @@ -839,7 +839,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi, bool beacon = !!(changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) && (!inband_disc); - mvif = vif ? (struct mt76_vif *)vif->drv_priv : NULL; + mvif = vif ? (struct mt76_vif_link *)vif->drv_priv : NULL; if (mvif) { omac_idx = mvif->omac_idx; wmm_idx = mvif->wmm_idx; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index f3ca01899503..e0589b029167 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -532,7 +532,7 @@ static u8 mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, bool beacon, bool mcast) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt76_phy *mphy = hw->priv; u16 rate; u8 i, idx; @@ -583,7 +583,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_bss_conf *info, u64 changed) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct mt7996_phy *phy = mt7996_hw_phy(hw); struct mt7996_dev *dev = mt7996_hw_dev(hw); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index b3c7f4196ab4..d25afd1f67fc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -852,7 +852,7 @@ static void mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, struct mt7996_phy *phy) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct bss_rate_tlv *bmc; struct cfg80211_chan_def *chandef = &phy->mt76->chandef; enum nl80211_band band = chandef->chan->band; @@ -899,7 +899,7 @@ mt7996_mcu_bss_mld_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) static void mt7996_mcu_bss_sec_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct bss_sec_tlv *sec; struct tlv *tlv; @@ -988,7 +988,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, struct mt76_phy *phy, u16 wlan_idx, bool enable) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct cfg80211_chan_def *chandef = &phy->chandef; struct mt76_connac_bss_basic_tlv *bss; u32 type = CONNECTION_INFRA_AP; @@ -1060,7 +1060,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, } static struct sk_buff * -__mt7996_mcu_alloc_bss_req(struct mt76_dev *dev, struct mt76_vif *mvif, int len) +__mt7996_mcu_alloc_bss_req(struct mt76_dev *dev, struct mt76_vif_link *mvif, int len) { struct bss_req_hdr hdr = { .bss_idx = mvif->idx, @@ -1140,7 +1140,7 @@ int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif) } static int -mt7996_mcu_sta_ba(struct mt7996_dev *dev, struct mt76_vif *mvif, +mt7996_mcu_sta_ba(struct mt7996_dev *dev, struct mt76_vif_link *mvif, struct ieee80211_ampdu_params *params, bool enable, bool tx) { @@ -2283,7 +2283,7 @@ int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, struct ieee80211_key_conf *key, int mcu_cmd, struct mt76_wcid *wcid, enum set_key_cmd cmd) { - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct sk_buff *skb; int ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index d2bc96877797..465e3d9fd26d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -200,7 +200,7 @@ struct mt7996_sta { }; struct mt7996_vif { - struct mt76_vif mt76; /* must be first */ + struct mt76_vif_link mt76; /* must be first */ struct mt7996_sta sta; struct mt7996_phy *phy; diff --git a/drivers/net/wireless/mediatek/mt76/scan.c b/drivers/net/wireless/mediatek/mt76/scan.c index 79172ad3fa6e..70884faab905 100644 --- a/drivers/net/wireless/mediatek/mt76/scan.c +++ b/drivers/net/wireless/mediatek/mt76/scan.c @@ -33,7 +33,7 @@ mt76_scan_send_probe(struct mt76_dev *dev, struct cfg80211_ssid *ssid) { struct cfg80211_scan_request *req = dev->scan.req; struct ieee80211_vif *vif = dev->scan.vif; - struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv; + struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; enum nl80211_band band = dev->scan.chan->band; struct mt76_phy *phy = dev->scan.phy; struct ieee80211_tx_info *info; -- 2.51.0 From e24646ef7eded74c68cdef20e3f0d48d14522a0b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:48 +0100 Subject: [PATCH 02/16] wifi: mt76: add vif link specific data structure Preparation for splitting link data from vif data for MLO support. Link: https://patch.msgid.link/20250102163508.52945-4-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt76.h | 53 +++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 1782ebc7085e..669cbd63f403 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -766,6 +766,15 @@ struct mt76_vif_link { u8 beacon_rates_idx; struct ieee80211_chanctx_conf *ctx; struct mt76_wcid *wcid; + struct mt76_vif_data *mvif; + struct rcu_head rcu_head; +}; + +struct mt76_vif_data { + struct mt76_vif_link __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS]; + + u16 valid_links; + u8 deflink_id; }; struct mt76_phy { @@ -1168,6 +1177,10 @@ static inline int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q, for (i = 0; i < ARRAY_SIZE((dev)->q_rx); i++) \ if ((dev)->q_rx[i].ndesc) + +#define mt76_dereference(p, dev) \ + rcu_dereference_protected(p, lockdep_is_held(&(dev)->mutex)) + struct mt76_dev *mt76_alloc_device(struct device *pdev, unsigned int size, const struct ieee80211_ops *ops, const struct mt76_driver_ops *drv_ops); @@ -1755,4 +1768,44 @@ void mt76_wcid_init(struct mt76_wcid *wcid); void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid); void mt76_wcid_add_poll(struct mt76_dev *dev, struct mt76_wcid *wcid); +static inline void +mt76_vif_init(struct ieee80211_vif *vif, struct mt76_vif_data *mvif) +{ + struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv; + + mlink->mvif = mvif; + rcu_assign_pointer(mvif->link[0], mlink); +} + +static inline void +mt76_vif_cleanup(struct mt76_dev *dev, struct ieee80211_vif *vif) +{ + struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv; + struct mt76_vif_data *mvif = mlink->mvif; + + rcu_assign_pointer(mvif->link[0], NULL); +} + +static inline struct mt76_vif_link * +mt76_vif_link(struct mt76_dev *dev, struct ieee80211_vif *vif, int link_id) +{ + struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv; + struct mt76_vif_data *mvif = mlink->mvif; + + return mt76_dereference(mvif->link[link_id], dev); +} + +static inline struct mt76_vif_link * +mt76_vif_conf_link(struct mt76_dev *dev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +{ + struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv; + struct mt76_vif_data *mvif = mlink->mvif; + + if (link_conf == &vif->bss_conf) + return mlink; + + return mt76_dereference(mvif->link[link_conf->link_id], dev); +} + #endif -- 2.51.0 From 36e02101f84735672aefaf405af2f585f4804a34 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:49 +0100 Subject: [PATCH 03/16] wifi: mt76: mt7996: split link specific data from struct mt7996_vif Preparation for MLO support. Link: https://patch.msgid.link/20250102163508.52945-5-nbd@nbd.name Signed-off-by: Felix Fietkau --- .../wireless/mediatek/mt76/mt7996/debugfs.c | 6 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 8 +- .../net/wireless/mediatek/mt76/mt7996/main.c | 202 ++++++++++-------- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 80 +++---- .../wireless/mediatek/mt76/mt7996/mt7996.h | 21 +- 5 files changed, 185 insertions(+), 132 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c index 62c03d088925..335699405ac7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/debugfs.c @@ -601,7 +601,7 @@ static void mt7996_sta_hw_queue_read(void *data, struct ieee80211_sta *sta) { struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; - struct mt7996_dev *dev = msta->vif->phy->dev; + struct mt7996_dev *dev = msta->vif->deflink.phy->dev; struct seq_file *s = data; u8 ac; @@ -621,7 +621,7 @@ mt7996_sta_hw_queue_read(void *data, struct ieee80211_sta *sta) GENMASK(11, 0)); seq_printf(s, "\tSTA %pM wcid %d: AC%d%d queued:%d\n", sta->addr, msta->wcid.idx, - msta->vif->mt76.wmm_idx, ac, qlen); + msta->vif->deflink.mt76.wmm_idx, ac, qlen); } } @@ -899,7 +899,7 @@ static ssize_t mt7996_sta_fixed_rate_set(struct file *file, #define LONG_PREAMBLE 1 struct ieee80211_sta *sta = file->private_data; struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; - struct mt7996_dev *dev = msta->vif->phy->dev; + struct mt7996_dev *dev = msta->vif->deflink.phy->dev; struct ra_rate phy = {}; char buf[100]; int ret; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c index fb6ab96cdeab..2656e3f85bdc 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -72,7 +72,7 @@ static struct mt76_wcid *mt7996_rx_get_wcid(struct mt7996_dev *dev, if (!sta->vif) return NULL; - return &sta->vif->sta.wcid; + return &sta->vif->deflink.sta.wcid; } bool mt7996_mac_wtbl_update(struct mt7996_dev *dev, int idx, u32 mask) @@ -182,7 +182,7 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev) rssi[3] = to_rssi(GENMASK(31, 14), val); msta->ack_signal = - mt76_rx_signal(msta->vif->phy->mt76->antenna_mask, rssi); + mt76_rx_signal(msta->vif->deflink.phy->mt76->antenna_mask, rssi); ewma_avg_signal_add(&msta->avg_ack_signal, -msta->ack_signal); } @@ -196,7 +196,7 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev, struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; u32 addr; - addr = mt7996_mac_wtbl_lmac_addr(dev, mvif->sta.wcid.idx, 5); + addr = mt7996_mac_wtbl_lmac_addr(dev, mvif->deflink.sta.wcid.idx, 5); if (enable) mt76_set(dev, addr, BIT(5)); else @@ -984,7 +984,7 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, if (vif) { struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - txp->fw.bss_idx = mvif->mt76.idx; + txp->fw.bss_idx = mvif->deflink.mt76.idx; } txp->fw.token = cpu_to_le16(id); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index e0589b029167..8679f8a6d49f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -157,70 +157,69 @@ static int get_omac_idx(enum nl80211_iftype type, u64 mask) return -1; } -static void mt7996_init_bitrate_mask(struct ieee80211_vif *vif) +static void +mt7996_init_bitrate_mask(struct ieee80211_vif *vif, struct mt7996_vif_link *mlink) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; int i; - for (i = 0; i < ARRAY_SIZE(mvif->bitrate_mask.control); i++) { - mvif->bitrate_mask.control[i].gi = NL80211_TXRATE_DEFAULT_GI; - mvif->bitrate_mask.control[i].he_gi = 0xff; - mvif->bitrate_mask.control[i].he_ltf = 0xff; - mvif->bitrate_mask.control[i].legacy = GENMASK(31, 0); - memset(mvif->bitrate_mask.control[i].ht_mcs, 0xff, - sizeof(mvif->bitrate_mask.control[i].ht_mcs)); - memset(mvif->bitrate_mask.control[i].vht_mcs, 0xff, - sizeof(mvif->bitrate_mask.control[i].vht_mcs)); - memset(mvif->bitrate_mask.control[i].he_mcs, 0xff, - sizeof(mvif->bitrate_mask.control[i].he_mcs)); + for (i = 0; i < ARRAY_SIZE(mlink->bitrate_mask.control); i++) { + mlink->bitrate_mask.control[i].gi = NL80211_TXRATE_DEFAULT_GI; + mlink->bitrate_mask.control[i].he_gi = 0xff; + mlink->bitrate_mask.control[i].he_ltf = 0xff; + mlink->bitrate_mask.control[i].legacy = GENMASK(31, 0); + memset(mlink->bitrate_mask.control[i].ht_mcs, 0xff, + sizeof(mlink->bitrate_mask.control[i].ht_mcs)); + memset(mlink->bitrate_mask.control[i].vht_mcs, 0xff, + sizeof(mlink->bitrate_mask.control[i].vht_mcs)); + memset(mlink->bitrate_mask.control[i].he_mcs, 0xff, + sizeof(mlink->bitrate_mask.control[i].he_mcs)); } } -static int mt7996_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +static int +mt7996_vif_link_add(struct mt7996_phy *phy, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt7996_dev *dev = mt7996_hw_dev(hw); - struct mt7996_phy *phy = mt7996_hw_phy(hw); - struct mt76_txq *mtxq; + struct mt7996_dev *dev = phy->dev; u8 band_idx = phy->mt76->band_idx; - int idx, ret = 0; + struct mt7996_vif_link *mlink; + struct mt76_txq *mtxq; + int idx, ret; - mutex_lock(&dev->mt76.mutex); + mlink = mt7996_vif_conf_link(dev, vif, link_conf); + if (!mlink) + return -EINVAL; - mvif->mt76.idx = __ffs64(~dev->mt76.vif_mask); - if (mvif->mt76.idx >= mt7996_max_interface_num(dev)) { - ret = -ENOSPC; - goto out; - } + mlink->mt76.idx = __ffs64(~dev->mt76.vif_mask); + if (mlink->mt76.idx >= mt7996_max_interface_num(dev)) + return -ENOSPC; idx = get_omac_idx(vif->type, phy->omac_mask); - if (idx < 0) { - ret = -ENOSPC; - goto out; - } - mvif->mt76.omac_idx = idx; - mvif->phy = phy; - mvif->mt76.band_idx = band_idx; - mvif->mt76.wmm_idx = vif->type == NL80211_IFTYPE_AP ? 0 : 3; - mvif->mt76.wcid = &mvif->sta.wcid; + if (idx < 0) + return -ENOSPC; + + mlink->mt76.omac_idx = idx; + mlink->phy = phy; + mlink->mt76.band_idx = band_idx; + mlink->mt76.wmm_idx = vif->type == NL80211_IFTYPE_AP ? 0 : 3; + mlink->mt76.wcid = &mlink->sta.wcid; ret = mt7996_mcu_add_dev_info(phy, vif, true); if (ret) - goto out; + return ret; - dev->mt76.vif_mask |= BIT_ULL(mvif->mt76.idx); - phy->omac_mask |= BIT_ULL(mvif->mt76.omac_idx); + dev->mt76.vif_mask |= BIT_ULL(mlink->mt76.idx); + phy->omac_mask |= BIT_ULL(mlink->mt76.omac_idx); - idx = MT7996_WTBL_RESERVED - mvif->mt76.idx; + idx = MT7996_WTBL_RESERVED - mlink->mt76.idx; - INIT_LIST_HEAD(&mvif->sta.rc_list); - INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); - mvif->sta.wcid.idx = idx; - mvif->sta.wcid.phy_idx = band_idx; - mvif->sta.wcid.hw_key_idx = -1; - mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET; - mt76_wcid_init(&mvif->sta.wcid); + INIT_LIST_HEAD(&mlink->sta.rc_list); + INIT_LIST_HEAD(&mlink->sta.wcid.poll_list); + mlink->sta.wcid.idx = idx; + mlink->sta.wcid.phy_idx = band_idx; + mlink->sta.wcid.hw_key_idx = -1; + mlink->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET; + mt76_wcid_init(&mlink->sta.wcid); mt7996_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); @@ -231,16 +230,15 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, } if (vif->type != NL80211_IFTYPE_AP && - (!mvif->mt76.omac_idx || mvif->mt76.omac_idx > 3)) + (!mlink->mt76.omac_idx || mlink->mt76.omac_idx > 3)) vif->offload_flags = 0; - vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR; if (phy->mt76->chandef.chan->band != NL80211_BAND_2GHZ) - mvif->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL + 4; + mlink->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL + 4; else - mvif->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL; + mlink->mt76.basic_rates_idx = MT7996_BASIC_RATES_TBL; - mt7996_init_bitrate_mask(vif); + mt7996_init_bitrate_mask(vif, mlink); mt7996_mcu_add_bss_info(phy, vif, true); /* defer the first STA_REC of BMC entry to BSS_CHANGED_BSSID for STA @@ -248,32 +246,37 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, */ if (vif->type != NL80211_IFTYPE_STATION) mt7996_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, true); - rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid); - -out: - mutex_unlock(&dev->mt76.mutex); + rcu_assign_pointer(dev->mt76.wcid[idx], &mlink->sta.wcid); - return ret; + return 0; } -static void mt7996_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +static void +mt7996_vif_link_remove(struct mt7996_phy *phy, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt7996_sta *msta = &mvif->sta; - struct mt7996_dev *dev = mt7996_hw_dev(hw); - struct mt7996_phy *phy = mt7996_hw_phy(hw); - int idx = msta->wcid.idx; + struct mt7996_dev *dev = phy->dev; + struct mt7996_vif_link *mlink; + struct mt7996_sta *msta; + int idx; + + mlink = mt7996_vif_conf_link(dev, vif, link_conf); + if (!mlink) + return; + mlink->phy = NULL; + msta = &mlink->sta; + idx = msta->wcid.idx; mt7996_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false); mt7996_mcu_add_bss_info(phy, vif, false); + mt7996_mcu_add_dev_info(phy, vif, false); rcu_assign_pointer(dev->mt76.wcid[idx], NULL); mutex_lock(&dev->mt76.mutex); - dev->mt76.vif_mask &= ~BIT_ULL(mvif->mt76.idx); - phy->omac_mask &= ~BIT_ULL(mvif->mt76.omac_idx); + dev->mt76.vif_mask &= ~BIT_ULL(mlink->mt76.idx); + phy->omac_mask &= ~BIT_ULL(mlink->mt76.omac_idx); mutex_unlock(&dev->mt76.mutex); spin_lock_bh(&dev->mt76.sta_poll_lock); @@ -284,6 +287,36 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw, mt76_wcid_cleanup(&dev->mt76, &msta->wcid); } +static int mt7996_add_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt7996_dev *dev = mt7996_hw_dev(hw); + struct mt7996_phy *phy = mt7996_hw_phy(hw); + int ret = 0; + + mutex_lock(&dev->mt76.mutex); + + mt76_vif_init(vif, &mvif->mt76); + + vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR; + ret = mt7996_vif_link_add(phy, vif, &vif->bss_conf); + + mutex_unlock(&dev->mt76.mutex); + + return ret; +} + +static void mt7996_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct mt7996_phy *phy = mt7996_hw_phy(hw); + struct mt7996_dev *dev = mt7996_hw_dev(hw); + + mt7996_vif_link_remove(phy, vif, &vif->bss_conf); + mt76_vif_cleanup(&dev->mt76, vif); +} + int mt7996_set_channel(struct mt76_phy *mphy) { struct mt7996_phy *phy = mphy->priv; @@ -317,8 +350,9 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, struct mt7996_dev *dev = mt7996_hw_dev(hw); struct mt7996_phy *phy = mt7996_hw_phy(hw); struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt7996_vif_link *mlink = &mvif->deflink; struct mt7996_sta *msta = sta ? (struct mt7996_sta *)sta->drv_priv : - &mvif->sta; + &mlink->sta; struct mt76_wcid *wcid = &msta->wcid; u8 *wcid_keyidx = &wcid->hw_key_idx; int idx = key->keyidx; @@ -364,8 +398,8 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, mutex_lock(&dev->mt76.mutex); - if (cmd == SET_KEY && !sta && !mvif->mt76.cipher) { - mvif->mt76.cipher = mt76_connac_mcu_get_cipher(key->cipher); + if (cmd == SET_KEY && !sta && !mlink->mt76.cipher) { + mlink->mt76.cipher = mt76_connac_mcu_get_cipher(key->cipher); mt7996_mcu_add_bss_info(phy, vif, true); } @@ -444,7 +478,7 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, }; /* firmware uses access class index */ - mvif->queue_params[mq_to_aci[queue]] = *params; + mvif->deflink.queue_params[mq_to_aci[queue]] = *params; /* no need to update right away, we'll get BSS_CHANGED_QOS */ return 0; @@ -516,7 +550,7 @@ mt7996_update_bss_color(struct ieee80211_hw *hw, case NL80211_IFTYPE_AP: { struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - if (mvif->mt76.omac_idx > HW_BSSID_MAX) + if (mvif->deflink.mt76.omac_idx > HW_BSSID_MAX) return; fallthrough; } @@ -564,7 +598,7 @@ mt7996_update_mu_group(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; struct mt7996_dev *dev = mt7996_hw_dev(hw); - u8 band = mvif->mt76.band_idx; + u8 band = mvif->deflink.mt76.band_idx; u32 *mu; mu = (u32 *)info->mu_group.membership; @@ -666,7 +700,7 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76); struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - u8 band_idx = mvif->phy->mt76->band_idx; + u8 band_idx = mvif->deflink.phy->mt76->band_idx; int idx; idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7996_WTBL_STA); @@ -766,7 +800,7 @@ static void mt7996_tx(struct ieee80211_hw *hw, struct mt7996_vif *mvif; mvif = (struct mt7996_vif *)vif->drv_priv; - wcid = &mvif->sta.wcid; + wcid = &mvif->deflink.sta.wcid; } mt76_tx(mphy, control->sta, wcid, skb); @@ -873,8 +907,8 @@ u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif) lockdep_assert_held(&dev->mt76.mutex); - n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0 - : mvif->mt76.omac_idx; + n = mvif->deflink.mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0 + : mvif->deflink.mt76.omac_idx; /* TSF software read */ mt76_rmw(dev, MT_LPON_TCR(phy->mt76->band_idx, n), MT_LPON_TCR_SW_MODE, MT_LPON_TCR_SW_READ); @@ -913,8 +947,8 @@ mt7996_set_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&dev->mt76.mutex); - n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0 - : mvif->mt76.omac_idx; + n = mvif->deflink.mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0 + : mvif->deflink.mt76.omac_idx; mt76_wr(dev, MT_LPON_UTTR0(phy->mt76->band_idx), tsf.t32[0]); mt76_wr(dev, MT_LPON_UTTR1(phy->mt76->band_idx), tsf.t32[1]); /* TSF software overwrite */ @@ -939,8 +973,8 @@ mt7996_offset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&dev->mt76.mutex); - n = mvif->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0 - : mvif->mt76.omac_idx; + n = mvif->deflink.mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0 + : mvif->deflink.mt76.omac_idx; mt76_wr(dev, MT_LPON_UTTR0(phy->mt76->band_idx), tsf.t32[0]); mt76_wr(dev, MT_LPON_UTTR1(phy->mt76->band_idx), tsf.t32[1]); /* TSF software adjust*/ @@ -1056,7 +1090,7 @@ static void mt7996_sta_statistics(struct ieee80211_hw *hw, static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta) { struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; - struct mt7996_dev *dev = msta->vif->phy->dev; + struct mt7996_dev *dev = msta->vif->deflink.phy->dev; u32 *changed = data; spin_lock_bh(&dev->mt76.sta_poll_lock); @@ -1088,7 +1122,7 @@ mt7996_set_bitrate_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mt7996_dev *dev = phy->dev; u32 changed = IEEE80211_RC_SUPP_RATES_CHANGED; - mvif->bitrate_mask = *mask; + mvif->deflink.bitrate_mask = *mask; /* if multiple rates across different preambles are given we can * reconfigure this info with all peers using sta_rec command with @@ -1272,7 +1306,7 @@ static void mt7996_ethtool_worker(void *wi_data, struct ieee80211_sta *sta) struct mt76_ethtool_worker_info *wi = wi_data; struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; - if (msta->vif->mt76.idx != wi->idx) + if (msta->vif->deflink.mt76.idx != wi->idx) return; mt76_ethtool_worker(wi, &msta->wcid.stats, true); @@ -1289,7 +1323,7 @@ void mt7996_get_et_stats(struct ieee80211_hw *hw, struct mt76_mib_stats *mib = &phy->mib; struct mt76_ethtool_worker_info wi = { .data = data, - .idx = mvif->mt76.idx, + .idx = mvif->deflink.mt76.idx, }; /* See mt7996_ampdu_stat_read_phy, etc */ int i, ei = 0; @@ -1458,7 +1492,7 @@ mt7996_net_fill_forward_path(struct ieee80211_hw *hw, path->type = DEV_PATH_MTK_WDMA; path->dev = ctx->dev; path->mtk_wdma.wdma_idx = wed->wdma_idx; - path->mtk_wdma.bss = mvif->mt76.idx; + path->mtk_wdma.bss = mvif->deflink.mt76.idx; path->mtk_wdma.queue = 0; path->mtk_wdma.wcid = msta->wcid.idx; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index d25afd1f67fc..1f0090c97e9c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -122,8 +122,8 @@ mt7996_mcu_set_sta_he_mcs(struct ieee80211_sta *sta, __le16 *he_mcs, u16 mcs_map) { struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; - enum nl80211_band band = msta->vif->phy->mt76->chandef.chan->band; - const u16 *mask = msta->vif->bitrate_mask.control[band].he_mcs; + enum nl80211_band band = msta->vif->deflink.phy->mt76->chandef.chan->band; + const u16 *mask = msta->vif->deflink.bitrate_mask.control[band].he_mcs; int nss, max_nss = sta->deflink.rx_nss > 3 ? 4 : sta->deflink.rx_nss; for (nss = 0; nss < max_nss; nss++) { @@ -892,7 +892,7 @@ mt7996_mcu_bss_mld_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) mld = (struct bss_mld_tlv *)tlv; mld->group_mld_id = 0xff; - mld->own_mld_id = mvif->mt76.idx; + mld->own_mld_id = mvif->deflink.mt76.idx; mld->remap_idx = 0xff; } @@ -916,7 +916,7 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif, #define UNI_MUAR_ENTRY 2 struct mt7996_dev *dev = phy->dev; struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - u32 idx = mvif->mt76.omac_idx - REPEATER_BSSID_START; + u32 idx = mvif->deflink.mt76.omac_idx - REPEATER_BSSID_START; const u8 *addr = vif->addr; struct { @@ -957,7 +957,7 @@ static void mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) { struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt7996_phy *phy = mvif->phy; + struct mt7996_phy *phy = mvif->deflink.phy; struct bss_ifs_time_tlv *ifs_time; struct tlv *tlv; bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ; @@ -1083,19 +1083,19 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy, struct mt7996_dev *dev = phy->dev; struct sk_buff *skb; - if (mvif->mt76.omac_idx >= REPEATER_BSSID_START) { + if (mvif->deflink.mt76.omac_idx >= REPEATER_BSSID_START) { mt7996_mcu_muar_config(phy, vif, false, enable); mt7996_mcu_muar_config(phy, vif, true, enable); } - skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->deflink.mt76, MT7996_BSS_UPDATE_MAX_SIZE); if (IS_ERR(skb)) return PTR_ERR(skb); /* bss_basic must be first */ mt7996_mcu_bss_basic_tlv(skb, vif, NULL, phy->mt76, - mvif->sta.wcid.idx, enable); + mvif->deflink.sta.wcid.idx, enable); mt7996_mcu_bss_sec_tlv(skb, vif); if (vif->type == NL80211_IFTYPE_MONITOR) @@ -1128,7 +1128,7 @@ int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif) struct mt7996_dev *dev = phy->dev; struct sk_buff *skb; - skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->deflink.mt76, MT7996_BSS_UPDATE_MAX_SIZE); if (IS_ERR(skb)) return PTR_ERR(skb); @@ -1180,7 +1180,7 @@ int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev, if (enable && !params->amsdu) msta->wcid.amsdu = false; - return mt7996_mcu_sta_ba(dev, &mvif->mt76, params, enable, true); + return mt7996_mcu_sta_ba(dev, &mvif->deflink.mt76, params, enable, true); } int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev, @@ -1190,7 +1190,7 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev, struct mt7996_sta *msta = (struct mt7996_sta *)params->sta->drv_priv; struct mt7996_vif *mvif = msta->vif; - return mt7996_mcu_sta_ba(dev, &mvif->mt76, params, enable, false); + return mt7996_mcu_sta_ba(dev, &mvif->deflink.mt76, params, enable, false); } static void @@ -1667,7 +1667,7 @@ mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt7996_phy *phy = mvif->phy; + struct mt7996_phy *phy = mvif->deflink.phy; int tx_ant = hweight16(phy->mt76->chainmask) - 1; struct sta_rec_bf *bf; struct tlv *tlv; @@ -1738,7 +1738,7 @@ mt7996_mcu_sta_bfee_tlv(struct mt7996_dev *dev, struct sk_buff *skb, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt7996_phy *phy = mvif->phy; + struct mt7996_phy *phy = mvif->deflink.phy; int tx_ant = hweight8(phy->mt76->antenna_mask) - 1; struct sta_rec_bfee *bfee; struct tlv *tlv; @@ -1879,7 +1879,7 @@ int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif struct sk_buff *skb; struct tlv *tlv; - skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, + skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->deflink.mt76, &msta->wcid, MT7996_STA_UPDATE_MAX_SIZE); if (IS_ERR(skb)) @@ -1915,8 +1915,8 @@ mt7996_mcu_add_rate_ctrl_fixed(struct mt7996_dev *dev, struct ieee80211_vif *vif struct ieee80211_sta *sta) { struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef; - struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask; + struct cfg80211_chan_def *chandef = &mvif->deflink.phy->mt76->chandef; + struct cfg80211_bitrate_mask *mask = &mvif->deflink.bitrate_mask; enum nl80211_band band = chandef->chan->band; struct sta_phy_uni phy = {}; int ret, nrates = 0; @@ -2003,9 +2003,9 @@ mt7996_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, struct mt7996_dev *dev, { #define INIT_RCPI 180 struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt76_phy *mphy = mvif->phy->mt76; + struct mt76_phy *mphy = mvif->deflink.phy->mt76; struct cfg80211_chan_def *chandef = &mphy->chandef; - struct cfg80211_bitrate_mask *mask = &mvif->bitrate_mask; + struct cfg80211_bitrate_mask *mask = &mvif->deflink.bitrate_mask; enum nl80211_band band = chandef->chan->band; struct sta_rec_ra_uni *ra; struct tlv *tlv; @@ -2111,7 +2111,7 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif, struct sk_buff *skb; int ret; - skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, + skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->deflink.mt76, &msta->wcid, MT7996_STA_UPDATE_MAX_SIZE); if (IS_ERR(skb)) @@ -2158,10 +2158,10 @@ mt7996_mcu_add_group(struct mt7996_dev *dev, struct ieee80211_vif *vif, .tag = cpu_to_le16(UNI_VOW_DRR_CTRL), .len = cpu_to_le16(sizeof(req) - 4), .action = cpu_to_le32(MT_STA_BSS_GROUP), - .val = cpu_to_le32(mvif->mt76.idx % 16), + .val = cpu_to_le32(mvif->deflink.mt76.idx % 16), }; - msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->sta; + msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->deflink.sta; req.wlan_idx = cpu_to_le16(msta->wcid.idx); return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(VOW), &req, @@ -2177,10 +2177,10 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif, struct sk_buff *skb; int ret; - msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->sta; + msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->deflink.sta; link_sta = sta ? &sta->deflink : NULL; - skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, + skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->deflink.mt76, &msta->wcid, MT7996_STA_UPDATE_MAX_SIZE); if (IS_ERR(skb)) @@ -2309,7 +2309,7 @@ static int mt7996_mcu_get_pn(struct mt7996_dev *dev, struct ieee80211_vif *vif, struct tlv *tlv; int ret; - skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, &mvif->sta.wcid); + skb = mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->deflink.mt76, &mvif->deflink.sta.wcid); if (IS_ERR(skb)) return PTR_ERR(skb); @@ -2345,7 +2345,7 @@ int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif sizeof(struct mt7996_mcu_bcn_prot_tlv); int ret; - skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, len); + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->deflink.mt76, len); if (IS_ERR(skb)) return PTR_ERR(skb); @@ -2405,8 +2405,8 @@ int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, } __packed tlv; } data = { .hdr = { - .omac_idx = mvif->mt76.omac_idx, - .band_idx = mvif->mt76.band_idx, + .omac_idx = mvif->deflink.mt76.omac_idx, + .band_idx = mvif->deflink.mt76.band_idx, }, .tlv = { .tag = cpu_to_le16(DEV_INFO_ACTIVE), @@ -2415,7 +2415,7 @@ int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, }, }; - if (mvif->mt76.omac_idx >= REPEATER_BSSID_START) + if (mvif->deflink.mt76.omac_idx >= REPEATER_BSSID_START) return mt7996_mcu_muar_config(phy, vif, false, enable); memcpy(data.tlv.omac_addr, vif->addr, ETH_ALEN); @@ -2540,7 +2540,7 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, if (vif->bss_conf.nontransmitted) return 0; - rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, + rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->deflink.mt76, MT7996_MAX_BSS_OFFLOAD_SIZE); if (IS_ERR(rskb)) return PTR_ERR(rskb); @@ -2585,7 +2585,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev, struct ieee80211_hw *hw = mt76_hw(dev); struct mt7996_phy *phy = mt7996_hw_phy(hw); struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct cfg80211_chan_def *chandef = &mvif->phy->mt76->chandef; + struct cfg80211_chan_def *chandef = &mvif->deflink.phy->mt76->chandef; enum nl80211_band band = chandef->chan->band; struct mt76_wcid *wcid = &dev->mt76.global_wcid; struct bss_inband_discovery_tlv *discov; @@ -2598,7 +2598,7 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev, if (vif->bss_conf.nontransmitted) return 0; - rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, + rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->deflink.mt76, MT7996_MAX_BSS_OFFLOAD_SIZE); if (IS_ERR(rskb)) return PTR_ERR(rskb); @@ -3171,7 +3171,7 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif) u8 bss_idx; u8 __rsv[3]; } __packed hdr = { - .bss_idx = mvif->mt76.idx, + .bss_idx = mvif->deflink.mt76.idx, }; struct sk_buff *skb; int len = sizeof(hdr) + IEEE80211_NUM_ACS * sizeof(struct edca); @@ -3184,7 +3184,7 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif) skb_put_data(skb, &hdr, sizeof(hdr)); for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { - struct ieee80211_tx_queue_params *q = &mvif->queue_params[ac]; + struct ieee80211_tx_queue_params *q = &mvif->deflink.queue_params[ac]; struct edca *e; struct tlv *tlv; @@ -4039,7 +4039,7 @@ mt7996_mcu_set_obss_spr_siga(struct mt7996_phy *phy, struct ieee80211_vif *vif, { struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; struct mt7996_dev *dev = phy->dev; - u8 omac = mvif->mt76.omac_idx; + u8 omac = mvif->deflink.mt76.omac_idx; struct { u8 band_idx; u8 __rsv[3]; @@ -4162,7 +4162,7 @@ int mt7996_mcu_update_bss_color(struct mt7996_dev *dev, struct ieee80211_vif *vi struct sk_buff *skb; struct tlv *tlv; - skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, len); + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->deflink.mt76, len); if (IS_ERR(skb)) return PTR_ERR(skb); @@ -4212,12 +4212,12 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev, .len = cpu_to_le16(sizeof(req) - 4), .tbl_idx = flow->table_id, .cmd = cmd, - .own_mac_idx = mvif->mt76.omac_idx, + .own_mac_idx = mvif->deflink.mt76.omac_idx, .flowid = flow->id, .peer_id = cpu_to_le16(flow->wcid), .duration = flow->duration, - .bss = mvif->mt76.idx, - .bss_idx = mvif->mt76.idx, + .bss = mvif->deflink.mt76.idx, + .bss_idx = mvif->deflink.mt76.idx, .start_tsf = cpu_to_le64(flow->tsf), .mantissa = flow->mantissa, .exponent = flow->exp, @@ -4313,9 +4313,9 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev, struct mt7996_sta *msta; struct sk_buff *skb; - msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->sta; + msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->deflink.sta; - skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76, + skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->deflink.mt76, &msta->wcid, MT7996_STA_UPDATE_MAX_SIZE); if (IS_ERR(skb)) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 465e3d9fd26d..31d1fdd61de6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -199,7 +199,7 @@ struct mt7996_sta { } twt; }; -struct mt7996_vif { +struct mt7996_vif_link { struct mt76_vif_link mt76; /* must be first */ struct mt7996_sta sta; @@ -209,6 +209,11 @@ struct mt7996_vif { struct cfg80211_bitrate_mask bitrate_mask; }; +struct mt7996_vif { + struct mt7996_vif_link deflink; /* must be first */ + struct mt76_vif_data mt76; +}; + /* crash-dump */ struct mt7996_crash_data { guid_t guid; @@ -464,6 +469,20 @@ mt7996_has_background_radar(struct mt7996_dev *dev) return true; } +static inline struct mt7996_vif_link * +mt7996_vif_link(struct mt7996_dev *dev, struct ieee80211_vif *vif, int link_id) +{ + return (struct mt7996_vif_link *)mt76_vif_link(&dev->mt76, vif, link_id); +} + +static inline struct mt7996_vif_link * +mt7996_vif_conf_link(struct mt7996_dev *dev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +{ + return (struct mt7996_vif_link *)mt76_vif_conf_link(&dev->mt76, vif, + link_conf); +} + extern const struct ieee80211_ops mt7996_ops; extern struct pci_driver mt7996_pci_driver; extern struct pci_driver mt7996_hif_driver; -- 2.51.0 From cbf5e61da66028ea30b52515dc1f1af969589bf7 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:50 +0100 Subject: [PATCH 04/16] wifi: mt76: initialize more wcid fields mt76_wcid_init Reduces code duplication and ensures that the phy index is always set. Link: https://patch.msgid.link/20250102163508.52945-6-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mac80211.c | 12 ++++++++---- drivers/net/wireless/mediatek/mt76/mt76.h | 2 +- drivers/net/wireless/mediatek/mt76/mt7603/main.c | 4 +--- drivers/net/wireless/mediatek/mt76/mt7615/main.c | 4 +--- drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 3 +-- drivers/net/wireless/mediatek/mt76/mt7915/main.c | 5 +---- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 4 +--- drivers/net/wireless/mediatek/mt76/mt7925/main.c | 10 +++------- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 5 +---- 9 files changed, 18 insertions(+), 31 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 5a77f94b7f82..8863d60dbd9f 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -742,7 +742,7 @@ int mt76_register_device(struct mt76_dev *dev, bool vht, int ret; dev_set_drvdata(dev->dev, dev); - mt76_wcid_init(&dev->global_wcid); + mt76_wcid_init(&dev->global_wcid, phy->band_idx); ret = mt76_phy_init(phy, hw); if (ret) return ret; @@ -1494,11 +1494,10 @@ mt76_sta_add(struct mt76_phy *phy, struct ieee80211_vif *vif, ewma_signal_init(&wcid->rssi); if (phy->band_idx == MT_BAND1) mt76_wcid_mask_set(dev->wcid_phy_mask, wcid->idx); - wcid->phy_idx = phy->band_idx; rcu_assign_pointer(dev->wcid[wcid->idx], wcid); phy->num_sta++; - mt76_wcid_init(wcid); + mt76_wcid_init(wcid, phy->band_idx); out: mutex_unlock(&dev->mutex); @@ -1588,14 +1587,19 @@ void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(mt76_sta_pre_rcu_remove); -void mt76_wcid_init(struct mt76_wcid *wcid) +void mt76_wcid_init(struct mt76_wcid *wcid, u8 band_idx) { + wcid->hw_key_idx = -1; + wcid->phy_idx = band_idx; + INIT_LIST_HEAD(&wcid->tx_list); skb_queue_head_init(&wcid->tx_pending); skb_queue_head_init(&wcid->tx_offchannel); INIT_LIST_HEAD(&wcid->list); idr_init(&wcid->pktid); + + INIT_LIST_HEAD(&wcid->poll_list); } EXPORT_SYMBOL_GPL(mt76_wcid_init); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 669cbd63f403..a9537131a074 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -1764,7 +1764,7 @@ mt76_token_put(struct mt76_dev *dev, int token) return txwi; } -void mt76_wcid_init(struct mt76_wcid *wcid); +void mt76_wcid_init(struct mt76_wcid *wcid, u8 band_idx); void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid); void mt76_wcid_add_poll(struct mt76_dev *dev, struct mt76_wcid *wcid); diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c index 574f74ad325d..3e8b1ec76169 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c @@ -66,11 +66,9 @@ mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) idx = MT7603_WTBL_RESERVED - 1 - mvif->idx; dev->mt76.vif_mask |= BIT_ULL(mvif->idx); - INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); mvif->sta.wcid.idx = idx; - mvif->sta.wcid.hw_key_idx = -1; mvif->sta.vif = mvif; - mt76_wcid_init(&mvif->sta.wcid); + mt76_wcid_init(&mvif->sta.wcid, 0); eth_broadcast_addr(bc_addr); mt7603_wtbl_init(dev, idx, mvif->idx, bc_addr); diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c index e883cf4e1095..7acf3f4ad3c9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c @@ -225,9 +225,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw, INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); mvif->sta.wcid.idx = idx; - mvif->sta.wcid.phy_idx = mvif->mt76.band_idx; - mvif->sta.wcid.hw_key_idx = -1; - mt76_wcid_init(&mvif->sta.wcid); + mt76_wcid_init(&mvif->sta.wcid, mvif->mt76.band_idx); mt7615_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c index 8020446be37b..4fb30589fa7a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c @@ -287,8 +287,7 @@ mt76x02_vif_init(struct mt76x02_dev *dev, struct ieee80211_vif *vif, mvif->idx = idx; mvif->group_wcid.idx = MT_VIF_WCID(idx); - mvif->group_wcid.hw_key_idx = -1; - mt76_wcid_init(&mvif->group_wcid); + mt76_wcid_init(&mvif->group_wcid, 0); mtxq = (struct mt76_txq *)vif->txq->drv_priv; rcu_assign_pointer(dev->mt76.wcid[MT_VIF_WCID(idx)], &mvif->group_wcid); diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/main.c b/drivers/net/wireless/mediatek/mt76/mt7915/main.c index 565d22019aac..3aa31c5cefa6 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -253,12 +253,9 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, } INIT_LIST_HEAD(&mvif->sta.rc_list); - INIT_LIST_HEAD(&mvif->sta.wcid.poll_list); mvif->sta.wcid.idx = idx; - mvif->sta.wcid.phy_idx = ext_phy; - mvif->sta.wcid.hw_key_idx = -1; mvif->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET; - mt76_wcid_init(&mvif->sta.wcid); + mt76_wcid_init(&mvif->sta.wcid, phy->mt76->band_idx); mt7915_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c index 8158357b86be..fccefda3bdb5 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c @@ -325,10 +325,8 @@ mt7921_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) INIT_LIST_HEAD(&mvif->sta.deflink.wcid.poll_list); mvif->sta.deflink.wcid.idx = idx; - mvif->sta.deflink.wcid.phy_idx = mvif->bss_conf.mt76.band_idx; - mvif->sta.deflink.wcid.hw_key_idx = -1; mvif->sta.deflink.wcid.tx_info |= MT_WCID_TX_INFO_SET; - mt76_wcid_init(&mvif->sta.deflink.wcid); + mt76_wcid_init(&mvif->sta.deflink.wcid, mvif->bss_conf.mt76.band_idx); mt7921_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index 230e4d20c885..58b0aaf5f0fd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -378,12 +378,9 @@ static int mt7925_mac_link_bss_add(struct mt792x_dev *dev, idx = MT792x_WTBL_RESERVED - mconf->mt76.idx; - INIT_LIST_HEAD(&mlink->wcid.poll_list); mlink->wcid.idx = idx; - mlink->wcid.phy_idx = 0; - mlink->wcid.hw_key_idx = -1; mlink->wcid.tx_info |= MT_WCID_TX_INFO_SET; - mt76_wcid_init(&mlink->wcid); + mt76_wcid_init(&mlink->wcid, 0); mt7925_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); @@ -850,10 +847,9 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *mdev, return -ENOSPC; mconf = mt792x_vif_to_link(mvif, link_id); - INIT_LIST_HEAD(&mlink->wcid.poll_list); + mt76_wcid_init(&mlink->wcid, 0); mlink->wcid.sta = 1; mlink->wcid.idx = idx; - mlink->wcid.phy_idx = 0; mlink->wcid.tx_info |= MT_WCID_TX_INFO_SET; mlink->last_txs = jiffies; mlink->wcid.link_id = link_sta->link_id; @@ -863,7 +859,7 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *mdev, wcid = &mlink->wcid; ewma_signal_init(&wcid->rssi); rcu_assign_pointer(dev->mt76.wcid[wcid->idx], wcid); - mt76_wcid_init(wcid); + mt76_wcid_init(wcid, 0); ewma_avg_signal_init(&mlink->avg_ack_signal); memset(mlink->airtime_ac, 0, sizeof(msta->deflink.airtime_ac)); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 8679f8a6d49f..9f1460eca4f4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -214,12 +214,9 @@ mt7996_vif_link_add(struct mt7996_phy *phy, struct ieee80211_vif *vif, idx = MT7996_WTBL_RESERVED - mlink->mt76.idx; INIT_LIST_HEAD(&mlink->sta.rc_list); - INIT_LIST_HEAD(&mlink->sta.wcid.poll_list); mlink->sta.wcid.idx = idx; - mlink->sta.wcid.phy_idx = band_idx; - mlink->sta.wcid.hw_key_idx = -1; mlink->sta.wcid.tx_info |= MT_WCID_TX_INFO_SET; - mt76_wcid_init(&mlink->sta.wcid); + mt76_wcid_init(&mlink->sta.wcid, band_idx); mt7996_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); -- 2.51.0 From 82334623af0cd2154633cdb007719a321048fafc Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:51 +0100 Subject: [PATCH 05/16] wifi: mt76: add chanctx functions for multi-channel phy support This adds an implementation for the chanctx functions, which can be used by multi-channel capable drivers. Preparation for adding MLO support. Link: https://patch.msgid.link/20250102163508.52945-7-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- drivers/net/wireless/mediatek/mt76/channel.c | 250 ++++++++++++++++++ drivers/net/wireless/mediatek/mt76/mac80211.c | 35 ++- drivers/net/wireless/mediatek/mt76/mt76.h | 64 ++++- drivers/net/wireless/mediatek/mt76/scan.c | 6 + 5 files changed, 342 insertions(+), 15 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/channel.c diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index f6e4de9334bf..87512d101a91 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_MT792x_USB) += mt792x-usb.o mt76-y := \ mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o \ - tx.o agg-rx.o mcu.o wed.o scan.o + tx.o agg-rx.o mcu.o wed.o scan.o channel.o mt76-$(CONFIG_PCI) += pci.o mt76-$(CONFIG_NL80211_TESTMODE) += testmode.o diff --git a/drivers/net/wireless/mediatek/mt76/channel.c b/drivers/net/wireless/mediatek/mt76/channel.c new file mode 100644 index 000000000000..1cfeb09b0054 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/channel.c @@ -0,0 +1,250 @@ +// SPDX-License-Identifier: ISC +/* + * Copyright (C) 2024 Felix Fietkau + */ +#include "mt76.h" + +static int +mt76_phy_update_channel(struct mt76_phy *phy, + struct ieee80211_chanctx_conf *conf) +{ + phy->radar_enabled = conf->radar_enabled; + phy->main_chandef = conf->def; + phy->chanctx = (struct mt76_chanctx *)conf->drv_priv; + + return __mt76_set_channel(phy, &phy->main_chandef, false); +} + +int mt76_add_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *conf) +{ + struct mt76_chanctx *ctx = (struct mt76_chanctx *)conf->drv_priv; + struct mt76_phy *phy = hw->priv; + struct mt76_dev *dev = phy->dev; + int ret = -EINVAL; + + phy = ctx->phy = dev->band_phys[conf->def.chan->band]; + if (WARN_ON_ONCE(!phy)) + return ret; + + if (dev->scan.phy == phy) + mt76_abort_scan(dev); + + mutex_lock(&dev->mutex); + if (!phy->chanctx) + ret = mt76_phy_update_channel(phy, conf); + else + ret = 0; + mutex_unlock(&dev->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(mt76_add_chanctx); + +void mt76_remove_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *conf) +{ + struct mt76_chanctx *ctx = (struct mt76_chanctx *)conf->drv_priv; + struct mt76_phy *phy = hw->priv; + struct mt76_dev *dev = phy->dev; + + phy = ctx->phy; + if (WARN_ON_ONCE(!phy)) + return; + + if (dev->scan.phy == phy) + mt76_abort_scan(dev); + + mutex_lock(&dev->mutex); + if (phy->chanctx == ctx) + phy->chanctx = NULL; + mutex_unlock(&dev->mutex); +} +EXPORT_SYMBOL_GPL(mt76_remove_chanctx); + +void mt76_change_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *conf, + u32 changed) +{ + struct mt76_chanctx *ctx = (struct mt76_chanctx *)conf->drv_priv; + struct mt76_phy *phy = ctx->phy; + struct mt76_dev *dev = phy->dev; + + if (!(changed & (IEEE80211_CHANCTX_CHANGE_WIDTH | + IEEE80211_CHANCTX_CHANGE_RADAR))) + return; + + cancel_delayed_work_sync(&phy->mac_work); + + mutex_lock(&dev->mutex); + mt76_phy_update_channel(phy, conf); + mutex_unlock(&dev->mutex); +} +EXPORT_SYMBOL_GPL(mt76_change_chanctx); + + +int mt76_assign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *conf) +{ + struct mt76_chanctx *ctx = (struct mt76_chanctx *)conf->drv_priv; + struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv; + struct mt76_vif_data *mvif = mlink->mvif; + int link_id = link_conf->link_id; + struct mt76_phy *phy = ctx->phy; + struct mt76_dev *dev = phy->dev; + bool mlink_alloc = false; + int ret = 0; + + if (dev->scan.vif == vif) + mt76_abort_scan(dev); + + mutex_lock(&dev->mutex); + + if (vif->type == NL80211_IFTYPE_MONITOR && + is_zero_ether_addr(vif->addr)) + goto out; + + mlink = mt76_vif_conf_link(dev, vif, link_conf); + if (!mlink) { + mlink = kzalloc(dev->drv->link_data_size, GFP_KERNEL); + if (!mlink) { + ret = -ENOMEM; + goto out; + } + mlink_alloc = true; + } + + mlink->ctx = conf; + ret = dev->drv->vif_link_add(phy, vif, link_conf, mlink); + if (ret) { + if (mlink_alloc) + kfree(mlink); + goto out; + } + + if (link_conf != &vif->bss_conf) + rcu_assign_pointer(mvif->link[link_id], mlink); + +out: + mutex_unlock(&dev->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(mt76_assign_vif_chanctx); + +void mt76_unassign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *conf) +{ + struct mt76_chanctx *ctx = (struct mt76_chanctx *)conf->drv_priv; + struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv; + struct mt76_vif_data *mvif = mlink->mvif; + int link_id = link_conf->link_id; + struct mt76_phy *phy = ctx->phy; + struct mt76_dev *dev = phy->dev; + + if (dev->scan.vif == vif) + mt76_abort_scan(dev); + + mutex_lock(&dev->mutex); + + if (vif->type == NL80211_IFTYPE_MONITOR && + is_zero_ether_addr(vif->addr)) + goto out; + + mlink = mt76_vif_conf_link(dev, vif, link_conf); + if (!mlink) + goto out; + + if (link_conf != &vif->bss_conf) + rcu_assign_pointer(mvif->link[link_id], NULL); + + dev->drv->vif_link_remove(phy, vif, link_conf, mlink); + mlink->ctx = NULL; + + if (link_conf != &vif->bss_conf) + kfree_rcu(mlink, rcu_head); + +out: + mutex_unlock(&dev->mutex); +} +EXPORT_SYMBOL_GPL(mt76_unassign_vif_chanctx); + +int mt76_switch_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif_chanctx_switch *vifs, + int n_vifs, + enum ieee80211_chanctx_switch_mode mode) +{ + struct mt76_chanctx *old_ctx = (struct mt76_chanctx *)vifs->old_ctx->drv_priv; + struct mt76_chanctx *new_ctx = (struct mt76_chanctx *)vifs->new_ctx->drv_priv; + struct ieee80211_chanctx_conf *conf = vifs->new_ctx; + struct mt76_phy *old_phy = old_ctx->phy; + struct mt76_phy *phy = hw->priv; + struct mt76_dev *dev = phy->dev; + struct mt76_vif_link *mlink; + bool update_chan; + int i, ret = 0; + + if (mode == CHANCTX_SWMODE_SWAP_CONTEXTS) + phy = new_ctx->phy = dev->band_phys[conf->def.chan->band]; + else + phy = new_ctx->phy; + if (!phy) + return -EINVAL; + + update_chan = phy->chanctx != new_ctx; + if (update_chan) { + if (dev->scan.phy == phy) + mt76_abort_scan(dev); + + cancel_delayed_work_sync(&phy->mac_work); + } + + mutex_lock(&dev->mutex); + + if (mode == CHANCTX_SWMODE_SWAP_CONTEXTS && + phy != old_phy && old_phy->chanctx == old_ctx) + old_phy->chanctx = NULL; + + if (update_chan) + ret = mt76_phy_update_channel(phy, vifs->new_ctx); + + if (ret) + goto out; + + if (old_phy == phy) + goto skip_link_replace; + + for (i = 0; i < n_vifs; i++) { + mlink = mt76_vif_conf_link(dev, vifs[i].vif, vifs[i].link_conf); + if (!mlink) + continue; + + dev->drv->vif_link_remove(old_phy, vifs[i].vif, + vifs[i].link_conf, mlink); + + ret = dev->drv->vif_link_add(phy, vifs[i].vif, + vifs[i].link_conf, mlink); + if (ret) + goto out; + + } + +skip_link_replace: + for (i = 0; i < n_vifs; i++) { + mlink = mt76_vif_conf_link(dev, vifs[i].vif, vifs[i].link_conf); + if (!mlink) + continue; + + mlink->ctx = vifs->new_ctx; + } + +out: + mutex_unlock(&dev->mutex); + + return ret; +} +EXPORT_SYMBOL_GPL(mt76_switch_vif_chanctx); diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 8863d60dbd9f..9549510057fa 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -414,6 +414,7 @@ mt76_check_sband(struct mt76_phy *phy, struct mt76_sband *msband, cfg80211_chandef_create(&phy->chandef, &sband->channels[0], NL80211_CHAN_HT20); phy->chan_state = &msband->chan[0]; + phy->dev->band_phys[band] = phy; return; } @@ -959,16 +960,13 @@ void mt76_update_survey(struct mt76_phy *phy) } EXPORT_SYMBOL_GPL(mt76_update_survey); -int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef, - bool offchannel) +int __mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef, + bool offchannel) { struct mt76_dev *dev = phy->dev; int timeout = HZ / 5; int ret; - cancel_delayed_work_sync(&phy->mac_work); - - mutex_lock(&dev->mutex); set_bit(MT76_RESET, &phy->state); mt76_worker_disable(&dev->tx_worker); @@ -995,6 +993,19 @@ int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef, mt76_worker_enable(&dev->tx_worker); mt76_worker_schedule(&dev->tx_worker); + return ret; +} + +int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef, + bool offchannel) +{ + struct mt76_dev *dev = phy->dev; + int ret; + + cancel_delayed_work_sync(&phy->mac_work); + + mutex_lock(&dev->mutex); + ret = __mt76_set_channel(phy, chandef, offchannel); mutex_unlock(&dev->mutex); return ret; @@ -1006,6 +1017,8 @@ int mt76_update_channel(struct mt76_phy *phy) struct cfg80211_chan_def *chandef = &hw->conf.chandef; bool offchannel = hw->conf.flags & IEEE80211_CONF_OFFCHANNEL; + phy->radar_enabled = hw->conf.radar_enabled; + return mt76_set_channel(phy, chandef, offchannel); } EXPORT_SYMBOL_GPL(mt76_update_channel); @@ -1919,7 +1932,7 @@ enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy) test_bit(MT76_SCANNING, &phy->state)) return MT_DFS_STATE_DISABLED; - if (!hw->conf.radar_enabled) { + if (!phy->radar_enabled) { if ((hw->conf.flags & IEEE80211_CONF_MONITOR) && (phy->chandef.chan->flags & IEEE80211_CHAN_RADAR)) return MT_DFS_STATE_ACTIVE; @@ -1933,3 +1946,13 @@ enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy) return MT_DFS_STATE_ACTIVE; } EXPORT_SYMBOL_GPL(mt76_phy_dfs_state); + +void mt76_vif_cleanup(struct mt76_dev *dev, struct ieee80211_vif *vif) +{ + struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv; + struct mt76_vif_data *mvif = mlink->mvif; + + rcu_assign_pointer(mvif->link[0], NULL); + mt76_abort_scan(dev); +} +EXPORT_SYMBOL_GPL(mt76_vif_cleanup); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index a9537131a074..307e6255f199 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -50,6 +50,8 @@ struct mt76_dev; struct mt76_phy; struct mt76_wcid; struct mt76s_intr; +struct mt76_chanctx; +struct mt76_vif_link; struct mt76_reg_pair { u32 reg; @@ -497,6 +499,8 @@ struct mt76_driver_ops { u16 token_size; u8 mcs_rates; + unsigned int link_data_size; + void (*update_survey)(struct mt76_phy *phy); int (*set_channel)(struct mt76_phy *phy); @@ -528,6 +532,15 @@ struct mt76_driver_ops { void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta); + + int (*vif_link_add)(struct mt76_phy *phy, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct mt76_vif_link *mlink); + + void (*vif_link_remove)(struct mt76_phy *phy, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct mt76_vif_link *mlink); }; struct mt76_channel_state { @@ -793,6 +806,9 @@ struct mt76_phy { struct cfg80211_chan_def chandef; struct cfg80211_chan_def main_chandef; bool offchannel; + bool radar_enabled; + + struct mt76_chanctx *chanctx; struct mt76_channel_state *chan_state; enum mt76_dfs_state dfs_state; @@ -837,6 +853,7 @@ struct mt76_phy { struct mt76_dev { struct mt76_phy phy; /* must be first */ struct mt76_phy *phys[__MT_MAX_BAND]; + struct mt76_phy *band_phys[NUM_NL80211_BANDS]; struct ieee80211_hw *hw; @@ -1057,6 +1074,10 @@ struct mt76_ethtool_worker_info { int sta_count; }; +struct mt76_chanctx { + struct mt76_phy *phy; +}; + #define CCK_RATE(_idx, _rate) { \ .bitrate = _rate, \ .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ @@ -1480,6 +1501,25 @@ void mt76_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void mt76_sw_scan_complete(struct ieee80211_hw *hw, struct ieee80211_vif *vif); enum mt76_dfs_state mt76_phy_dfs_state(struct mt76_phy *phy); +int mt76_add_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *conf); +void mt76_remove_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *conf); +void mt76_change_chanctx(struct ieee80211_hw *hw, + struct ieee80211_chanctx_conf *conf, + u32 changed); +int mt76_assign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *conf); +void mt76_unassign_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct ieee80211_chanctx_conf *conf); +int mt76_switch_vif_chanctx(struct ieee80211_hw *hw, + struct ieee80211_vif_chanctx_switch *vifs, + int n_vifs, + enum ieee80211_chanctx_switch_mode mode); int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void *data, int len); int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, @@ -1525,6 +1565,8 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames); void mt76_testmode_tx_pending(struct mt76_phy *phy); void mt76_queue_tx_complete(struct mt76_dev *dev, struct mt76_queue *q, struct mt76_queue_entry *e); +int __mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef, + bool offchannel); int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef, bool offchannel); void mt76_scan_work(struct work_struct *work); @@ -1777,14 +1819,7 @@ mt76_vif_init(struct ieee80211_vif *vif, struct mt76_vif_data *mvif) rcu_assign_pointer(mvif->link[0], mlink); } -static inline void -mt76_vif_cleanup(struct mt76_dev *dev, struct ieee80211_vif *vif) -{ - struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv; - struct mt76_vif_data *mvif = mlink->mvif; - - rcu_assign_pointer(mvif->link[0], NULL); -} +void mt76_vif_cleanup(struct mt76_dev *dev, struct ieee80211_vif *vif); static inline struct mt76_vif_link * mt76_vif_link(struct mt76_dev *dev, struct ieee80211_vif *vif, int link_id) @@ -1808,4 +1843,17 @@ mt76_vif_conf_link(struct mt76_dev *dev, struct ieee80211_vif *vif, return mt76_dereference(mvif->link[link_conf->link_id], dev); } +static inline struct mt76_phy * +mt76_vif_link_phy(struct mt76_vif_link *mlink) +{ + struct mt76_chanctx *ctx; + + if (!mlink->ctx) + return NULL; + + ctx = (struct mt76_chanctx *)mlink->ctx->drv_priv; + + return ctx->phy; +} + #endif diff --git a/drivers/net/wireless/mediatek/mt76/scan.c b/drivers/net/wireless/mediatek/mt76/scan.c index 70884faab905..d186a68b0fb8 100644 --- a/drivers/net/wireless/mediatek/mt76/scan.c +++ b/drivers/net/wireless/mediatek/mt76/scan.c @@ -124,6 +124,12 @@ int mt76_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mt76_dev *dev = phy->dev; int ret = 0; + if (hw->wiphy->n_radio > 1) { + phy = dev->band_phys[req->req.channels[0]->band]; + if (!phy) + return -EINVAL; + } + mutex_lock(&dev->mutex); if (dev->scan.req) { -- 2.51.0 From 38a45bead2be0bd481f3143dc4fe451cb9d09823 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:52 +0100 Subject: [PATCH 06/16] wifi: mt76: remove dev->wcid_phy_mask Explicitly check wcid->phy_idx instead. Reduces allocated data size. Link: https://patch.msgid.link/20250102163508.52945-8-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mac80211.c | 3 --- drivers/net/wireless/mediatek/mt76/mt76.h | 3 +-- drivers/net/wireless/mediatek/mt76/mt7603/mac.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 2 +- drivers/net/wireless/mediatek/mt76/mt76x2/phy.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7925/main.c | 1 - drivers/net/wireless/mediatek/mt76/util.c | 10 +++------- 7 files changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 9549510057fa..9173438f963e 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -1505,8 +1505,6 @@ mt76_sta_add(struct mt76_phy *phy, struct ieee80211_vif *vif, } ewma_signal_init(&wcid->rssi); - if (phy->band_idx == MT_BAND1) - mt76_wcid_mask_set(dev->wcid_phy_mask, wcid->idx); rcu_assign_pointer(dev->wcid[wcid->idx], wcid); phy->num_sta++; @@ -1533,7 +1531,6 @@ void __mt76_sta_remove(struct mt76_phy *phy, struct ieee80211_vif *vif, mt76_wcid_cleanup(dev, wcid); mt76_wcid_mask_clear(dev->wcid_mask, idx); - mt76_wcid_mask_clear(dev->wcid_phy_mask, idx); phy->num_sta--; } EXPORT_SYMBOL_GPL(__mt76_sta_remove); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 307e6255f199..85b2f21acd70 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -909,7 +909,6 @@ struct mt76_dev { spinlock_t status_lock; u32 wcid_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; - u32 wcid_phy_mask[DIV_ROUND_UP(MT76_N_WCIDS, 32)]; u64 vif_mask; @@ -1474,7 +1473,7 @@ void __mt76_sta_remove(struct mt76_phy *phy, struct ieee80211_vif *vif, void mt76_sta_pre_rcu_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta); -int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy); +int mt76_get_min_avg_rssi(struct mt76_dev *dev, u8 phy_idx); int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id, int *dbm); diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c index dafa4b05f623..a259f4dd9540 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c @@ -1788,7 +1788,7 @@ mt7603_false_cca_check(struct mt7603_dev *dev) mt7603_cca_stats_reset(dev); - min_signal = mt76_get_min_avg_rssi(&dev->mt76, false); + min_signal = mt76_get_min_avg_rssi(&dev->mt76, 0); if (!min_signal) { dev->sensitivity = 0; dev->last_cca_adj = jiffies; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c index d543ef3de65b..ec554a059216 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c @@ -1071,7 +1071,7 @@ mt76x0_phy_update_channel_gain(struct mt76x02_dev *dev) u8 gain_delta; int low_gain; - dev->cal.avg_rssi_all = mt76_get_min_avg_rssi(&dev->mt76, false); + dev->cal.avg_rssi_all = mt76_get_min_avg_rssi(&dev->mt76, 0); if (!dev->cal.avg_rssi_all) dev->cal.avg_rssi_all = -75; diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c index f84517d932dc..e2b4cf30dc44 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/phy.c @@ -280,7 +280,7 @@ void mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev) int low_gain; u32 val; - dev->cal.avg_rssi_all = mt76_get_min_avg_rssi(&dev->mt76, false); + dev->cal.avg_rssi_all = mt76_get_min_avg_rssi(&dev->mt76, 0); if (!dev->cal.avg_rssi_all) dev->cal.avg_rssi_all = -75; diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index 58b0aaf5f0fd..4aec10e94178 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -1188,7 +1188,6 @@ mt7925_mac_sta_remove_links(struct mt792x_dev *dev, struct ieee80211_vif *vif, if (link_sta != mlink->pri_link) { mt76_wcid_cleanup(mdev, wcid); mt76_wcid_mask_clear(mdev->wcid_mask, wcid->idx); - mt76_wcid_mask_clear(mdev->wcid_phy_mask, wcid->idx); } if (msta->deflink_id == link_id) diff --git a/drivers/net/wireless/mediatek/mt76/util.c b/drivers/net/wireless/mediatek/mt76/util.c index d6c01a2dd198..95b3dc96e4c4 100644 --- a/drivers/net/wireless/mediatek/mt76/util.c +++ b/drivers/net/wireless/mediatek/mt76/util.c @@ -64,7 +64,7 @@ int mt76_wcid_alloc(u32 *mask, int size) } EXPORT_SYMBOL_GPL(mt76_wcid_alloc); -int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy) +int mt76_get_min_avg_rssi(struct mt76_dev *dev, u8 phy_idx) { struct mt76_wcid *wcid; int i, j, min_rssi = 0; @@ -75,20 +75,16 @@ int mt76_get_min_avg_rssi(struct mt76_dev *dev, bool ext_phy) for (i = 0; i < ARRAY_SIZE(dev->wcid_mask); i++) { u32 mask = dev->wcid_mask[i]; - u32 phy_mask = dev->wcid_phy_mask[i]; if (!mask) continue; - for (j = i * 32; mask; j++, mask >>= 1, phy_mask >>= 1) { + for (j = i * 32; mask; j++, mask >>= 1) { if (!(mask & 1)) continue; - if (!!(phy_mask & 1) != ext_phy) - continue; - wcid = rcu_dereference(dev->wcid[j]); - if (!wcid) + if (!wcid || wcid->phy_idx != phy_idx) continue; spin_lock(&dev->rx_lock); -- 2.51.0 From 955e823102fe53b1d7949f9e3ab05a45fe84c316 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:53 +0100 Subject: [PATCH 07/16] wifi: mt76: add multi-radio support to a few core hw ops Iterate over all phys if multi-radio is supported by the driver Link: https://patch.msgid.link/20250102163508.52945-9-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mac80211.c | 88 ++++++++++++++----- 1 file changed, 68 insertions(+), 20 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 9173438f963e..590c60f30823 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -815,6 +815,22 @@ void mt76_free_device(struct mt76_dev *dev) } EXPORT_SYMBOL_GPL(mt76_free_device); +static struct mt76_phy * +mt76_vif_phy(struct ieee80211_hw *hw, struct ieee80211_vif *vif) +{ + struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv; + struct mt76_chanctx *ctx; + + if (!hw->wiphy->n_radio) + return hw->priv; + + if (!mlink->ctx) + return NULL; + + ctx = (struct mt76_chanctx *)mlink->ctx->drv_priv; + return ctx->phy; +} + static void mt76_rx_release_amsdu(struct mt76_phy *phy, enum mt76_rxq_id q) { struct sk_buff *skb = phy->rx_amsdu[q].head; @@ -1023,33 +1039,53 @@ int mt76_update_channel(struct mt76_phy *phy) } EXPORT_SYMBOL_GPL(mt76_update_channel); +static struct mt76_sband * +mt76_get_survey_sband(struct mt76_phy *phy, int *idx) +{ + if (*idx < phy->sband_2g.sband.n_channels) + return &phy->sband_2g; + + *idx -= phy->sband_2g.sband.n_channels; + if (*idx < phy->sband_5g.sband.n_channels) + return &phy->sband_5g; + + *idx -= phy->sband_5g.sband.n_channels; + if (*idx < phy->sband_6g.sband.n_channels) + return &phy->sband_6g; + + *idx -= phy->sband_6g.sband.n_channels; + return NULL; +} + int mt76_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) { struct mt76_phy *phy = hw->priv; struct mt76_dev *dev = phy->dev; - struct mt76_sband *sband; + struct mt76_sband *sband = NULL; struct ieee80211_channel *chan; struct mt76_channel_state *state; + int phy_idx = 0; int ret = 0; mutex_lock(&dev->mutex); - if (idx == 0 && dev->drv->update_survey) - mt76_update_survey(phy); - - if (idx >= phy->sband_2g.sband.n_channels + - phy->sband_5g.sband.n_channels) { - idx -= (phy->sband_2g.sband.n_channels + - phy->sband_5g.sband.n_channels); - sband = &phy->sband_6g; - } else if (idx >= phy->sband_2g.sband.n_channels) { - idx -= phy->sband_2g.sband.n_channels; - sband = &phy->sband_5g; - } else { - sband = &phy->sband_2g; + + for (phy_idx = 0; phy_idx < ARRAY_SIZE(dev->phys); phy_idx++) { + sband = NULL; + phy = dev->phys[phy_idx]; + if (!phy || phy->hw != hw) + continue; + + sband = mt76_get_survey_sband(phy, &idx); + + if (idx == 0 && phy->dev->drv->update_survey) + mt76_update_survey(phy); + + if (sband || !hw->wiphy->n_radio) + break; } - if (idx >= sband->sband.n_channels) { + if (!sband) { ret = -ENOENT; goto out; } @@ -1555,6 +1591,10 @@ int mt76_sta_state(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mt76_dev *dev = phy->dev; enum mt76_sta_event ev; + phy = mt76_vif_phy(hw, vif); + if (!phy) + return -EINVAL; + if (old_state == IEEE80211_STA_NOTEXIST && new_state == IEEE80211_STA_NONE) return mt76_sta_add(phy, vif, sta); @@ -1659,10 +1699,14 @@ EXPORT_SYMBOL_GPL(mt76_wcid_add_poll); int mt76_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id, int *dbm) { - struct mt76_phy *phy = hw->priv; - int n_chains = hweight16(phy->chainmask); - int delta = mt76_tx_power_nss_delta(n_chains); + struct mt76_phy *phy = mt76_vif_phy(hw, vif); + int n_chains, delta; + if (!phy) + return -EINVAL; + + n_chains = hweight16(phy->chainmask); + delta = mt76_tx_power_nss_delta(n_chains); *dbm = DIV_ROUND_UP(phy->txpower_cur + delta, 2); return 0; @@ -1837,10 +1881,14 @@ int mt76_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) { struct mt76_phy *phy = hw->priv; struct mt76_dev *dev = phy->dev; + int i; mutex_lock(&dev->mutex); - *tx_ant = phy->antenna_mask; - *rx_ant = phy->antenna_mask; + *tx_ant = 0; + for (i = 0; i < ARRAY_SIZE(dev->phys); i++) + if (dev->phys[i] && dev->phys[i]->hw == hw) + *tx_ant |= dev->phys[i]->chainmask; + *rx_ant = *tx_ant; mutex_unlock(&dev->mutex); return 0; -- 2.51.0 From 716cc146d58050cb277fefefe1002d634c4379cf Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:54 +0100 Subject: [PATCH 08/16] wifi: mt76: add multi-radio support to tx scheduling Look up the phy for each scheduled txq. Only run one scheduling loop per hw. Link: https://patch.msgid.link/20250102163508.52945-10-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/tx.c | 33 ++++++++++++++----------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c index ce193e625666..af0c50c983ec 100644 --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -489,7 +489,7 @@ mt76_txq_send_burst(struct mt76_phy *phy, struct mt76_queue *q, do { if (test_bit(MT76_RESET, &phy->state) || phy->offchannel) - return -EBUSY; + break; if (stop || mt76_txq_stopped(q)) break; @@ -522,24 +522,16 @@ mt76_txq_send_burst(struct mt76_phy *phy, struct mt76_queue *q, static int mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid) { - struct mt76_queue *q = phy->q_tx[qid]; struct mt76_dev *dev = phy->dev; struct ieee80211_txq *txq; struct mt76_txq *mtxq; struct mt76_wcid *wcid; + struct mt76_queue *q; int ret = 0; while (1) { int n_frames = 0; - if (test_bit(MT76_RESET, &phy->state) || phy->offchannel) - return -EBUSY; - - if (dev->queue_ops->tx_cleanup && - q->queued + 2 * MT_TXQ_FREE_THR >= q->ndesc) { - dev->queue_ops->tx_cleanup(dev, q, false); - } - txq = ieee80211_next_txq(phy->hw, qid); if (!txq) break; @@ -549,6 +541,16 @@ mt76_txq_schedule_list(struct mt76_phy *phy, enum mt76_txq_id qid) if (!wcid || test_bit(MT_WCID_FLAG_PS, &wcid->flags)) continue; + phy = mt76_dev_phy(dev, wcid->phy_idx); + if (test_bit(MT76_RESET, &phy->state) || phy->offchannel) + continue; + + q = phy->q_tx[qid]; + if (dev->queue_ops->tx_cleanup && + q->queued + 2 * MT_TXQ_FREE_THR >= q->ndesc) { + dev->queue_ops->tx_cleanup(dev, q, false); + } + if (mtxq->send_bar && mtxq->aggr) { struct ieee80211_txq *txq = mtxq_to_txq(mtxq); struct ieee80211_sta *sta = txq->sta; @@ -578,7 +580,7 @@ void mt76_txq_schedule(struct mt76_phy *phy, enum mt76_txq_id qid) { int len; - if (qid >= 4 || phy->offchannel) + if (qid >= 4) return; local_bh_disable(); @@ -680,9 +682,14 @@ static void mt76_txq_schedule_pending(struct mt76_phy *phy) void mt76_txq_schedule_all(struct mt76_phy *phy) { + struct mt76_phy *main_phy = &phy->dev->phy; int i; mt76_txq_schedule_pending(phy); + + if (phy != main_phy && phy->hw == main_phy->hw) + return; + for (i = 0; i <= MT_TXQ_BK; i++) mt76_txq_schedule(phy, i); } @@ -693,6 +700,7 @@ void mt76_tx_worker_run(struct mt76_dev *dev) struct mt76_phy *phy; int i; + mt76_txq_schedule_all(&dev->phy); for (i = 0; i < ARRAY_SIZE(dev->phys); i++) { phy = dev->phys[i]; if (!phy) @@ -748,9 +756,6 @@ void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq) struct mt76_phy *phy = hw->priv; struct mt76_dev *dev = phy->dev; - if (!test_bit(MT76_STATE_RUNNING, &phy->state)) - return; - mt76_worker_schedule(&dev->tx_worker); } EXPORT_SYMBOL_GPL(mt76_wake_tx_queue); -- 2.51.0 From e411b8190fe7c969c668eedb5b01f2865c89b1af Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:55 +0100 Subject: [PATCH 09/16] wifi: mt76: add multi-radio support to scanning code When scanning on a phy/vif combination that does not have an active link, create a temporary link in order to ensure that we have a valid wcid. Link: https://patch.msgid.link/20250102163508.52945-11-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/channel.c | 62 +++++++++++++++++++- drivers/net/wireless/mediatek/mt76/mt76.h | 6 ++ drivers/net/wireless/mediatek/mt76/scan.c | 11 +++- 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/channel.c b/drivers/net/wireless/mediatek/mt76/channel.c index 1cfeb09b0054..ddb36e958c33 100644 --- a/drivers/net/wireless/mediatek/mt76/channel.c +++ b/drivers/net/wireless/mediatek/mt76/channel.c @@ -4,6 +4,20 @@ */ #include "mt76.h" +static struct mt76_vif_link * +mt76_alloc_mlink(struct mt76_dev *dev, struct mt76_vif_data *mvif) +{ + struct mt76_vif_link *mlink; + + mlink = kzalloc(dev->drv->link_data_size, GFP_KERNEL); + if (!mlink) + return NULL; + + mlink->mvif = mvif; + + return mlink; +} + static int mt76_phy_update_channel(struct mt76_phy *phy, struct ieee80211_chanctx_conf *conf) @@ -108,7 +122,7 @@ int mt76_assign_vif_chanctx(struct ieee80211_hw *hw, mlink = mt76_vif_conf_link(dev, vif, link_conf); if (!mlink) { - mlink = kzalloc(dev->drv->link_data_size, GFP_KERNEL); + mlink = mt76_alloc_mlink(dev, mvif); if (!mlink) { ret = -ENOMEM; goto out; @@ -248,3 +262,49 @@ out: return ret; } EXPORT_SYMBOL_GPL(mt76_switch_vif_chanctx); + +struct mt76_vif_link *mt76_get_vif_phy_link(struct mt76_phy *phy, + struct ieee80211_vif *vif) +{ + struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv; + struct mt76_vif_data *mvif = mlink->mvif; + struct mt76_dev *dev = phy->dev; + int i, ret; + + for (i = 0; i < ARRAY_SIZE(mvif->link); i++) { + mlink = mt76_dereference(mvif->link[i], dev); + if (!mlink) + continue; + + if (mt76_vif_link_phy(mlink) == phy) + return mlink; + } + + if (!dev->drv->vif_link_add) + return ERR_PTR(-EINVAL); + + mlink = mt76_alloc_mlink(dev, mvif); + if (!mlink) + return ERR_PTR(-ENOMEM); + + mlink->offchannel = true; + ret = dev->drv->vif_link_add(phy, vif, &vif->bss_conf, mlink); + if (ret) { + kfree(mlink); + return ERR_PTR(ret); + } + + return mlink; +} + +void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif, + struct mt76_vif_link *mlink) +{ + struct mt76_dev *dev = phy->dev; + + if (IS_ERR_OR_NULL(mlink) || !mlink->offchannel) + return; + + dev->drv->vif_link_remove(phy, vif, &vif->bss_conf, mlink); + kfree(mlink); +} diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 85b2f21acd70..b61f1eb138e8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -777,6 +777,7 @@ struct mt76_vif_link { u8 basic_rates_idx; u8 mcast_rates_idx; u8 beacon_rates_idx; + bool offchannel; struct ieee80211_chanctx_conf *ctx; struct mt76_wcid *wcid; struct mt76_vif_data *mvif; @@ -942,6 +943,7 @@ struct mt76_dev { struct cfg80211_scan_request *req; struct ieee80211_channel *chan; struct ieee80211_vif *vif; + struct mt76_vif_link *mlink; struct mt76_phy *phy; int chan_idx; } scan; @@ -1570,6 +1572,10 @@ int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef, bool offchannel); void mt76_scan_work(struct work_struct *work); void mt76_abort_scan(struct mt76_dev *dev); +struct mt76_vif_link *mt76_get_vif_phy_link(struct mt76_phy *phy, + struct ieee80211_vif *vif); +void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif, + struct mt76_vif_link *mlink); /* usb */ static inline bool mt76u_urb_error(struct urb *urb) diff --git a/drivers/net/wireless/mediatek/mt76/scan.c b/drivers/net/wireless/mediatek/mt76/scan.c index d186a68b0fb8..9f3485be5747 100644 --- a/drivers/net/wireless/mediatek/mt76/scan.c +++ b/drivers/net/wireless/mediatek/mt76/scan.c @@ -18,6 +18,7 @@ static void mt76_scan_complete(struct mt76_dev *dev, bool abort) if (dev->scan.chan && phy->main_chandef.chan) mt76_set_channel(phy, &phy->main_chandef, false); + mt76_put_vif_phy_link(phy, dev->scan.vif, dev->scan.mlink); memset(&dev->scan, 0, sizeof(dev->scan)); ieee80211_scan_completed(phy->hw, &info); } @@ -33,7 +34,7 @@ mt76_scan_send_probe(struct mt76_dev *dev, struct cfg80211_ssid *ssid) { struct cfg80211_scan_request *req = dev->scan.req; struct ieee80211_vif *vif = dev->scan.vif; - struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; + struct mt76_vif_link *mvif = dev->scan.mlink; enum nl80211_band band = dev->scan.chan->band; struct mt76_phy *phy = dev->scan.phy; struct ieee80211_tx_info *info; @@ -122,6 +123,7 @@ int mt76_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct mt76_phy *phy = hw->priv; struct mt76_dev *dev = phy->dev; + struct mt76_vif_link *mlink; int ret = 0; if (hw->wiphy->n_radio > 1) { @@ -137,10 +139,17 @@ int mt76_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, goto out; } + mlink = mt76_get_vif_phy_link(phy, vif); + if (IS_ERR(mlink)) { + ret = PTR_ERR(mlink); + goto out; + } + memset(&dev->scan, 0, sizeof(dev->scan)); dev->scan.req = &req->req; dev->scan.vif = vif; dev->scan.phy = phy; + dev->scan.mlink = mlink; ieee80211_queue_delayed_work(dev->phy.hw, &dev->scan_work, 0); out: -- 2.51.0 From a8f424c1287cc79a06c21816658feea87dfcb83f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:56 +0100 Subject: [PATCH 10/16] wifi: mt76: add multi-radio remain_on_channel functions This allows a driver using the generic channel context functions to temporarily switch to another channel for off-channel rx/tx. Link: https://patch.msgid.link/20250102163508.52945-12-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/channel.c | 96 +++++++++++++++++++ drivers/net/wireless/mediatek/mt76/mac80211.c | 3 + drivers/net/wireless/mediatek/mt76/mt76.h | 12 +++ drivers/net/wireless/mediatek/mt76/scan.c | 2 +- 4 files changed, 112 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/mediatek/mt76/channel.c b/drivers/net/wireless/mediatek/mt76/channel.c index ddb36e958c33..6a35c6ebd823 100644 --- a/drivers/net/wireless/mediatek/mt76/channel.c +++ b/drivers/net/wireless/mediatek/mt76/channel.c @@ -308,3 +308,99 @@ void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif, dev->drv->vif_link_remove(phy, vif, &vif->bss_conf, mlink); kfree(mlink); } + +static void mt76_roc_complete(struct mt76_phy *phy) +{ + struct mt76_vif_link *mlink = phy->roc_link; + + if (!phy->roc_vif) + return; + + if (mlink) + mlink->mvif->roc_phy = NULL; + if (phy->main_chandef.chan) + mt76_set_channel(phy, &phy->main_chandef, false); + mt76_put_vif_phy_link(phy, phy->roc_vif, phy->roc_link); + phy->roc_vif = NULL; + phy->roc_link = NULL; + ieee80211_remain_on_channel_expired(phy->hw); +} + +void mt76_roc_complete_work(struct work_struct *work) +{ + struct mt76_phy *phy = container_of(work, struct mt76_phy, roc_work.work); + struct mt76_dev *dev = phy->dev; + + mutex_lock(&dev->mutex); + mt76_roc_complete(phy); + mutex_unlock(&dev->mutex); +} + +void mt76_abort_roc(struct mt76_phy *phy) +{ + struct mt76_dev *dev = phy->dev; + + cancel_delayed_work_sync(&phy->roc_work); + + mutex_lock(&dev->mutex); + mt76_roc_complete(phy); + mutex_unlock(&dev->mutex); +} + +int mt76_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_channel *chan, int duration, + enum ieee80211_roc_type type) +{ + struct cfg80211_chan_def chandef = {}; + struct mt76_phy *phy = hw->priv; + struct mt76_dev *dev = phy->dev; + struct mt76_vif_link *mlink; + int ret = 0; + + phy = dev->band_phys[chan->band]; + if (!phy) + return -EINVAL; + + mutex_lock(&dev->mutex); + + if (phy->roc_vif || dev->scan.phy == phy) { + ret = -EBUSY; + goto out; + } + + mlink = mt76_get_vif_phy_link(phy, vif); + if (IS_ERR(mlink)) { + ret = PTR_ERR(mlink); + goto out; + } + + mlink->mvif->roc_phy = phy; + phy->roc_vif = vif; + phy->roc_link = mlink; + cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20); + mt76_set_channel(phy, &chandef, true); + ieee80211_ready_on_channel(hw); + ieee80211_queue_delayed_work(phy->hw, &phy->roc_work, + msecs_to_jiffies(duration)); + +out: + mutex_unlock(&dev->mutex); + return ret; +} +EXPORT_SYMBOL_GPL(mt76_remain_on_channel); + +int mt76_cancel_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct mt76_vif_link *mlink = (struct mt76_vif_link *)vif->drv_priv; + struct mt76_vif_data *mvif = mlink->mvif; + struct mt76_phy *phy = mvif->roc_phy; + + if (!phy) + return 0; + + mt76_abort_roc(phy); + + return 0; +} +EXPORT_SYMBOL_GPL(mt76_cancel_remain_on_channel); diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c index 590c60f30823..508b472408c2 100644 --- a/drivers/net/wireless/mediatek/mt76/mac80211.c +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c @@ -431,6 +431,7 @@ mt76_phy_init(struct mt76_phy *phy, struct ieee80211_hw *hw) INIT_LIST_HEAD(&phy->tx_list); spin_lock_init(&phy->tx_lock); + INIT_DELAYED_WORK(&phy->roc_work, mt76_roc_complete_work); if ((void *)phy != hw->priv) return 0; @@ -1999,5 +2000,7 @@ void mt76_vif_cleanup(struct mt76_dev *dev, struct ieee80211_vif *vif) rcu_assign_pointer(mvif->link[0], NULL); mt76_abort_scan(dev); + if (mvif->roc_phy) + mt76_abort_roc(mvif->roc_phy); } EXPORT_SYMBOL_GPL(mt76_vif_cleanup); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index b61f1eb138e8..132148f7b107 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -787,6 +787,7 @@ struct mt76_vif_link { struct mt76_vif_data { struct mt76_vif_link __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS]; + struct mt76_phy *roc_phy; u16 valid_links; u8 deflink_id; }; @@ -809,6 +810,10 @@ struct mt76_phy { bool offchannel; bool radar_enabled; + struct delayed_work roc_work; + struct ieee80211_vif *roc_vif; + struct mt76_vif_link *roc_link; + struct mt76_chanctx *chanctx; struct mt76_channel_state *chan_state; @@ -1521,6 +1526,11 @@ int mt76_switch_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif_chanctx_switch *vifs, int n_vifs, enum ieee80211_chanctx_switch_mode mode); +int mt76_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_channel *chan, int duration, + enum ieee80211_roc_type type); +int mt76_cancel_remain_on_channel(struct ieee80211_hw *hw, + struct ieee80211_vif *vif); int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void *data, int len); int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, @@ -1572,6 +1582,8 @@ int mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef, bool offchannel); void mt76_scan_work(struct work_struct *work); void mt76_abort_scan(struct mt76_dev *dev); +void mt76_roc_complete_work(struct work_struct *work); +void mt76_abort_roc(struct mt76_phy *phy); struct mt76_vif_link *mt76_get_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif); void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif, diff --git a/drivers/net/wireless/mediatek/mt76/scan.c b/drivers/net/wireless/mediatek/mt76/scan.c index 9f3485be5747..1c4f9deaaada 100644 --- a/drivers/net/wireless/mediatek/mt76/scan.c +++ b/drivers/net/wireless/mediatek/mt76/scan.c @@ -134,7 +134,7 @@ int mt76_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&dev->mutex); - if (dev->scan.req) { + if (dev->scan.req || phy->roc_vif) { ret = -EBUSY; goto out; } -- 2.51.0 From c56d6edebc1f59afec7a59117ab50abd89879006 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:57 +0100 Subject: [PATCH 11/16] wifi: mt76: mt7996: use emulated hardware scan support Preparation for supporting multiple radios on a single wiphy Link: https://patch.msgid.link/20250102163508.52945-13-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/init.c | 3 +++ drivers/net/wireless/mediatek/mt76/mt7996/main.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c index 260cd1c34c64..400950aab9a9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c @@ -439,6 +439,9 @@ mt7996_init_wiphy(struct ieee80211_hw *hw, struct mtk_wed_device *wed) wiphy->available_antennas_rx = phy->mt76->antenna_mask; wiphy->available_antennas_tx = phy->mt76->antenna_mask; + + wiphy->max_scan_ssids = 4; + wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; } static void diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 9f1460eca4f4..d7e33e3b04ac 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -1522,8 +1522,8 @@ const struct ieee80211_ops mt7996_ops = { .ampdu_action = mt7996_ampdu_action, .set_rts_threshold = mt7996_set_rts_threshold, .wake_tx_queue = mt76_wake_tx_queue, - .sw_scan_start = mt76_sw_scan, - .sw_scan_complete = mt76_sw_scan_complete, + .hw_scan = mt76_hw_scan, + .cancel_hw_scan = mt76_cancel_hw_scan, .release_buffered_frames = mt76_release_buffered_frames, .get_txpower = mt76_get_txpower, .channel_switch_beacon = mt7996_channel_switch_beacon, -- 2.51.0 From 0b57e944cee3d49eab33a8cf9e95b0862a90f441 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:58 +0100 Subject: [PATCH 12/16] wifi: mt76: mt7996: pass wcid to mt7996_mcu_sta_hdr_trans_tlv Preparation for MLO support. Link: https://patch.msgid.link/20250102163508.52945-14-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index 1f0090c97e9c..ebb2ff15a8d8 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -1795,11 +1795,9 @@ mt7996_mcu_sta_hdrt_tlv(struct mt7996_dev *dev, struct sk_buff *skb) static void mt7996_mcu_sta_hdr_trans_tlv(struct mt7996_dev *dev, struct sk_buff *skb, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) + struct ieee80211_vif *vif, struct mt76_wcid *wcid) { struct sta_rec_hdr_trans *hdr_trans; - struct mt76_wcid *wcid; struct tlv *tlv; tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HDR_TRANS, sizeof(*hdr_trans)); @@ -1811,10 +1809,9 @@ mt7996_mcu_sta_hdr_trans_tlv(struct mt7996_dev *dev, struct sk_buff *skb, else hdr_trans->from_ds = true; - if (!sta) + if (!wcid) return; - wcid = (struct mt76_wcid *)sta->drv_priv; hdr_trans->dis_rx_hdr_tran = !test_bit(MT_WCID_FLAG_HDR_TRANS, &wcid->flags); if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) { hdr_trans->to_ds = true; @@ -2194,7 +2191,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif, goto out; /* starec hdr trans */ - mt7996_mcu_sta_hdr_trans_tlv(dev, skb, vif, sta); + mt7996_mcu_sta_hdr_trans_tlv(dev, skb, vif, &msta->wcid); /* starec tx proc */ mt7996_mcu_sta_tx_proc_tlv(skb); @@ -4322,7 +4319,7 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev, return PTR_ERR(skb); /* starec hdr trans */ - mt7996_mcu_sta_hdr_trans_tlv(dev, skb, vif, sta); + mt7996_mcu_sta_hdr_trans_tlv(dev, skb, vif, &msta->wcid); return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true); } -- 2.51.0 From 34a41bfbcb71f2fba26255c0552959efdcab742f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:34:59 +0100 Subject: [PATCH 13/16] wifi: mt76: mt7996: prepare mt7996_mcu_add_dev/bss_info for MLO support Add extra arguments for struct ieee80211_bss_conf and mt76_vif_link. Link: https://patch.msgid.link/20250102163508.52945-15-nbd@nbd.name Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7996/main.c | 38 +++-- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 146 ++++++++---------- .../wireless/mediatek/mt76/mt7996/mt7996.h | 11 +- 3 files changed, 99 insertions(+), 96 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index d7e33e3b04ac..6e90ecfecd8f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -204,7 +204,7 @@ mt7996_vif_link_add(struct mt7996_phy *phy, struct ieee80211_vif *vif, mlink->mt76.wmm_idx = vif->type == NL80211_IFTYPE_AP ? 0 : 3; mlink->mt76.wcid = &mlink->sta.wcid; - ret = mt7996_mcu_add_dev_info(phy, vif, true); + ret = mt7996_mcu_add_dev_info(phy, vif, link_conf, &mlink->mt76, true); if (ret) return ret; @@ -237,12 +237,13 @@ mt7996_vif_link_add(struct mt7996_phy *phy, struct ieee80211_vif *vif, mt7996_init_bitrate_mask(vif, mlink); - mt7996_mcu_add_bss_info(phy, vif, true); + mt7996_mcu_add_bss_info(phy, vif, link_conf, &mlink->mt76, true); /* defer the first STA_REC of BMC entry to BSS_CHANGED_BSSID for STA * interface, since firmware only records BSSID when the entry is new */ if (vif->type != NL80211_IFTYPE_STATION) - mt7996_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, true); + mt7996_mcu_add_sta(dev, vif, &mlink->mt76, NULL, + CONN_STATE_PORT_SECURE, true); rcu_assign_pointer(dev->mt76.wcid[idx], &mlink->sta.wcid); return 0; @@ -264,10 +265,11 @@ mt7996_vif_link_remove(struct mt7996_phy *phy, struct ieee80211_vif *vif, mlink->phy = NULL; msta = &mlink->sta; idx = msta->wcid.idx; - mt7996_mcu_add_sta(dev, vif, NULL, CONN_STATE_DISCONNECT, false); - mt7996_mcu_add_bss_info(phy, vif, false); + mt7996_mcu_add_sta(dev, vif, &mlink->mt76, NULL, CONN_STATE_DISCONNECT, + false); + mt7996_mcu_add_bss_info(phy, vif, link_conf, &mlink->mt76, false); - mt7996_mcu_add_dev_info(phy, vif, false); + mt7996_mcu_add_dev_info(phy, vif, link_conf, &mlink->mt76, false); rcu_assign_pointer(dev->mt76.wcid[idx], NULL); @@ -397,7 +399,8 @@ static int mt7996_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (cmd == SET_KEY && !sta && !mlink->mt76.cipher) { mlink->mt76.cipher = mt76_connac_mcu_get_cipher(key->cipher); - mt7996_mcu_add_bss_info(phy, vif, true); + mt7996_mcu_add_bss_info(phy, vif, &vif->bss_conf, &mlink->mt76, + true); } if (cmd == SET_KEY) { @@ -626,8 +629,8 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw, if ((changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid)) || (changed & BSS_CHANGED_ASSOC && vif->cfg.assoc) || (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon)) { - mt7996_mcu_add_bss_info(phy, vif, true); - mt7996_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, + mt7996_mcu_add_bss_info(phy, vif, info, mvif, true); + mt7996_mcu_add_sta(dev, vif, mvif, NULL, CONN_STATE_PORT_SECURE, !!(changed & BSS_CHANGED_BSSID)); } @@ -697,7 +700,8 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76); struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - u8 band_idx = mvif->deflink.phy->mt76->band_idx; + struct mt7996_vif_link *link = &mvif->deflink; + u8 band_idx = link->phy->mt76->band_idx; int idx; idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7996_WTBL_STA); @@ -715,7 +719,8 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, mt7996_mac_wtbl_update(dev, idx, MT_WTBL_UPDATE_ADM_COUNT_CLEAR); - mt7996_mcu_add_sta(dev, vif, sta, CONN_STATE_DISCONNECT, true); + mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, CONN_STATE_DISCONNECT, + true); return 0; } @@ -725,11 +730,14 @@ int mt7996_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif, { struct mt7996_dev *dev = container_of(mdev, struct mt7996_dev, mt76); struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt7996_vif_link *link = &mvif->deflink; int i, ret; switch (ev) { case MT76_STA_EVENT_ASSOC: - ret = mt7996_mcu_add_sta(dev, vif, sta, CONN_STATE_CONNECT, true); + ret = mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, + CONN_STATE_CONNECT, true); if (ret) return ret; @@ -743,13 +751,15 @@ int mt7996_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif, return 0; case MT76_STA_EVENT_AUTHORIZE: - return mt7996_mcu_add_sta(dev, vif, sta, CONN_STATE_PORT_SECURE, false); + return mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, + CONN_STATE_PORT_SECURE, false); case MT76_STA_EVENT_DISASSOC: for (i = 0; i < ARRAY_SIZE(msta->twt.flow); i++) mt7996_mac_twt_teardown_flow(dev, msta, i); - mt7996_mcu_add_sta(dev, vif, sta, CONN_STATE_DISCONNECT, false); + mt7996_mcu_add_sta(dev, vif, &link->mt76, sta, + CONN_STATE_DISCONNECT, false); msta->wcid.sta_disabled = 1; msta->wcid.sta = 0; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index ebb2ff15a8d8..43c728d39077 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -756,8 +756,7 @@ mt7996_mcu_add_uni_tlv(struct sk_buff *skb, u16 tag, u16 len) } static void -mt7996_mcu_bss_rfch_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, - struct mt7996_phy *phy) +mt7996_mcu_bss_rfch_tlv(struct sk_buff *skb, struct mt7996_phy *phy) { static const u8 rlm_ch_band[] = { [NL80211_BAND_2GHZ] = 1, @@ -787,8 +786,7 @@ mt7996_mcu_bss_rfch_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, } static void -mt7996_mcu_bss_ra_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, - struct mt7996_phy *phy) +mt7996_mcu_bss_ra_tlv(struct sk_buff *skb, struct mt7996_phy *phy) { struct bss_ra_tlv *ra; struct tlv *tlv; @@ -801,6 +799,7 @@ mt7996_mcu_bss_ra_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, static void mt7996_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, struct mt7996_phy *phy) { #define DEFAULT_HE_PE_DURATION 4 @@ -814,11 +813,11 @@ mt7996_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_HE_BASIC, sizeof(*he)); he = (struct bss_info_uni_he *)tlv; - he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext; + he->he_pe_duration = link_conf->htc_trig_based_pkt_ext; 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); + he->he_rts_thres = cpu_to_le16(link_conf->frame_time_rts_th); if (!he->he_rts_thres) he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES); @@ -828,13 +827,13 @@ mt7996_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, } static void -mt7996_mcu_bss_mbssid_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, - struct mt7996_phy *phy, int enable) +mt7996_mcu_bss_mbssid_tlv(struct sk_buff *skb, struct ieee80211_bss_conf *link_conf, + bool enable) { struct bss_info_uni_mbssid *mbssid; struct tlv *tlv; - if (!vif->bss_conf.bssid_indicator && enable) + if (!link_conf->bssid_indicator && enable) return; tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_11V_MBSSID, sizeof(*mbssid)); @@ -842,23 +841,22 @@ mt7996_mcu_bss_mbssid_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, mbssid = (struct bss_info_uni_mbssid *)tlv; if (enable) { - mbssid->max_indicator = vif->bss_conf.bssid_indicator; - mbssid->mbss_idx = vif->bss_conf.bssid_index; + mbssid->max_indicator = link_conf->bssid_indicator; + mbssid->mbss_idx = link_conf->bssid_index; mbssid->tx_bss_omac_idx = 0; } } static void -mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, +mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct mt76_vif_link *mlink, struct mt7996_phy *phy) { - struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct bss_rate_tlv *bmc; struct cfg80211_chan_def *chandef = &phy->mt76->chandef; enum nl80211_band band = chandef->chan->band; struct tlv *tlv; - u8 idx = mvif->mcast_rates_idx ? - mvif->mcast_rates_idx : mvif->basic_rates_idx; + u8 idx = mlink->mcast_rates_idx ? + mlink->mcast_rates_idx : mlink->basic_rates_idx; tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_RATE, sizeof(*bmc)); @@ -882,9 +880,8 @@ mt7996_mcu_bss_txcmd_tlv(struct sk_buff *skb, bool en) } static void -mt7996_mcu_bss_mld_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) +mt7996_mcu_bss_mld_tlv(struct sk_buff *skb, struct mt76_vif_link *mlink) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; struct bss_mld_tlv *mld; struct tlv *tlv; @@ -892,33 +889,28 @@ mt7996_mcu_bss_mld_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) mld = (struct bss_mld_tlv *)tlv; mld->group_mld_id = 0xff; - mld->own_mld_id = mvif->deflink.mt76.idx; + mld->own_mld_id = mlink->idx; mld->remap_idx = 0xff; } static void -mt7996_mcu_bss_sec_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) +mt7996_mcu_bss_sec_tlv(struct sk_buff *skb, struct mt76_vif_link *mlink) { - struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct bss_sec_tlv *sec; struct tlv *tlv; tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_SEC, sizeof(*sec)); sec = (struct bss_sec_tlv *)tlv; - sec->cipher = mvif->cipher; + sec->cipher = mlink->cipher; } static int -mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif, - bool bssid, bool enable) +mt7996_mcu_muar_config(struct mt7996_dev *dev, struct mt76_vif_link *mlink, + const u8 *addr, bool bssid, bool enable) { #define UNI_MUAR_ENTRY 2 - struct mt7996_dev *dev = phy->dev; - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - u32 idx = mvif->deflink.mt76.omac_idx - REPEATER_BSSID_START; - const u8 *addr = vif->addr; - + u32 idx = mlink->omac_idx - REPEATER_BSSID_START; struct { struct { u8 band; @@ -935,7 +927,7 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif, u8 addr[ETH_ALEN]; u8 __rsv[2]; } __packed req = { - .hdr.band = phy->mt76->band_idx, + .hdr.band = mlink->band_idx, .tag = cpu_to_le16(UNI_MUAR_ENTRY), .len = cpu_to_le16(sizeof(req) - sizeof(req.hdr)), .smesh = false, @@ -943,9 +935,6 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif, .entry_add = true, }; - if (bssid) - addr = vif->bss_conf.bssid; - if (enable) memcpy(req.addr, addr, ETH_ALEN); @@ -954,10 +943,8 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif, } static void -mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) +mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct mt7996_phy *phy) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct mt7996_phy *phy = mvif->deflink.phy; struct bss_ifs_time_tlv *ifs_time; struct tlv *tlv; bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ; @@ -984,15 +971,16 @@ mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) static int mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, + struct ieee80211_bss_conf *link_conf, + struct mt76_vif_link *mvif, struct mt76_phy *phy, u16 wlan_idx, bool enable) { - struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; struct cfg80211_chan_def *chandef = &phy->chandef; struct mt76_connac_bss_basic_tlv *bss; u32 type = CONNECTION_INFRA_AP; u16 sta_wlan_idx = wlan_idx; + struct ieee80211_sta *sta; struct tlv *tlv; int idx; @@ -1004,9 +992,7 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, case NL80211_IFTYPE_STATION: if (enable) { rcu_read_lock(); - if (!sta) - sta = ieee80211_find_sta(vif, - vif->bss_conf.bssid); + sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); /* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */ if (sta) { struct mt76_wcid *wcid; @@ -1029,8 +1015,8 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_BASIC, sizeof(*bss)); bss = (struct mt76_connac_bss_basic_tlv *)tlv; - bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int); - bss->dtim_period = vif->bss_conf.dtim_period; + bss->bcn_interval = cpu_to_le16(link_conf->beacon_int); + bss->dtim_period = link_conf->dtim_period; bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx); bss->sta_idx = cpu_to_le16(sta_wlan_idx); bss->conn_type = cpu_to_le32(type); @@ -1048,8 +1034,8 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, return 0; } - memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN); - bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int); + memcpy(bss->bssid, link_conf->bssid, ETH_ALEN); + bss->bcn_interval = cpu_to_le16(link_conf->beacon_int); bss->dtim_period = vif->bss_conf.dtim_period; bss->phymode = mt76_connac_get_phy_mode(phy, vif, chandef->chan->band, NULL); @@ -1076,46 +1062,46 @@ __mt7996_mcu_alloc_bss_req(struct mt76_dev *dev, struct mt76_vif_link *mvif, int return skb; } -int mt7996_mcu_add_bss_info(struct mt7996_phy *phy, - struct ieee80211_vif *vif, int enable) +int mt7996_mcu_add_bss_info(struct mt7996_phy *phy, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct mt76_vif_link *mlink, int enable) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; struct mt7996_dev *dev = phy->dev; struct sk_buff *skb; - if (mvif->deflink.mt76.omac_idx >= REPEATER_BSSID_START) { - mt7996_mcu_muar_config(phy, vif, false, enable); - mt7996_mcu_muar_config(phy, vif, true, enable); + if (mlink->omac_idx >= REPEATER_BSSID_START) { + mt7996_mcu_muar_config(dev, mlink, link_conf->addr, false, enable); + mt7996_mcu_muar_config(dev, mlink, link_conf->bssid, true, enable); } - skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->deflink.mt76, + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, mlink, MT7996_BSS_UPDATE_MAX_SIZE); if (IS_ERR(skb)) return PTR_ERR(skb); /* bss_basic must be first */ - mt7996_mcu_bss_basic_tlv(skb, vif, NULL, phy->mt76, - mvif->deflink.sta.wcid.idx, enable); - mt7996_mcu_bss_sec_tlv(skb, vif); + mt7996_mcu_bss_basic_tlv(skb, vif, link_conf, mlink, phy->mt76, + mlink->wcid->idx, enable); + mt7996_mcu_bss_sec_tlv(skb, mlink); if (vif->type == NL80211_IFTYPE_MONITOR) goto out; if (enable) { - mt7996_mcu_bss_rfch_tlv(skb, vif, phy); - mt7996_mcu_bss_bmc_tlv(skb, vif, phy); - mt7996_mcu_bss_ra_tlv(skb, vif, phy); + mt7996_mcu_bss_rfch_tlv(skb, phy); + mt7996_mcu_bss_bmc_tlv(skb, mlink, phy); + mt7996_mcu_bss_ra_tlv(skb, phy); mt7996_mcu_bss_txcmd_tlv(skb, true); - mt7996_mcu_bss_ifs_timing_tlv(skb, vif); + mt7996_mcu_bss_ifs_timing_tlv(skb, phy); if (vif->bss_conf.he_support) - mt7996_mcu_bss_he_tlv(skb, vif, phy); + mt7996_mcu_bss_he_tlv(skb, vif, link_conf, phy); /* this tag is necessary no matter if the vif is MLD */ - mt7996_mcu_bss_mld_tlv(skb, vif); + mt7996_mcu_bss_mld_tlv(skb, mlink); } - mt7996_mcu_bss_mbssid_tlv(skb, vif, phy, enable); + mt7996_mcu_bss_mbssid_tlv(skb, link_conf, enable); out: return mt76_mcu_skb_send_msg(&dev->mt76, skb, @@ -1133,7 +1119,7 @@ int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif) if (IS_ERR(skb)) return PTR_ERR(skb); - mt7996_mcu_bss_ifs_timing_tlv(skb, vif); + mt7996_mcu_bss_ifs_timing_tlv(skb, phy); return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); @@ -2166,19 +2152,22 @@ mt7996_mcu_add_group(struct mt7996_dev *dev, struct ieee80211_vif *vif, } int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif, + struct mt76_vif_link *mlink, struct ieee80211_sta *sta, int conn_state, bool newly) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; - struct ieee80211_link_sta *link_sta; - struct mt7996_sta *msta; + struct ieee80211_link_sta *link_sta = NULL; + struct mt76_wcid *wcid = mlink->wcid; struct sk_buff *skb; int ret; - msta = sta ? (struct mt7996_sta *)sta->drv_priv : &mvif->deflink.sta; - link_sta = sta ? &sta->deflink : NULL; + if (sta) { + struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv; - skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->deflink.mt76, - &msta->wcid, + wcid = &msta->wcid; + link_sta = &sta->deflink; + } + + skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, mlink, wcid, MT7996_STA_UPDATE_MAX_SIZE); if (IS_ERR(skb)) return PTR_ERR(skb); @@ -2191,7 +2180,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif, goto out; /* starec hdr trans */ - mt7996_mcu_sta_hdr_trans_tlv(dev, skb, vif, &msta->wcid); + mt7996_mcu_sta_hdr_trans_tlv(dev, skb, vif, wcid); /* starec tx proc */ mt7996_mcu_sta_tx_proc_tlv(skb); @@ -2382,11 +2371,12 @@ int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, struct ieee80211_vif *vif return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); } -int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, - struct ieee80211_vif *vif, bool enable) + +int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct mt76_vif_link *mlink, bool enable) { struct mt7996_dev *dev = phy->dev; - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; struct { struct req_hdr { u8 omac_idx; @@ -2402,8 +2392,8 @@ int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, } __packed tlv; } data = { .hdr = { - .omac_idx = mvif->deflink.mt76.omac_idx, - .band_idx = mvif->deflink.mt76.band_idx, + .omac_idx = mlink->omac_idx, + .band_idx = mlink->band_idx, }, .tlv = { .tag = cpu_to_le16(DEV_INFO_ACTIVE), @@ -2412,10 +2402,10 @@ int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, }, }; - if (mvif->deflink.mt76.omac_idx >= REPEATER_BSSID_START) - return mt7996_mcu_muar_config(phy, vif, false, enable); + if (mlink->omac_idx >= REPEATER_BSSID_START) + return mt7996_mcu_muar_config(dev, mlink, link_conf->addr, false, enable); - memcpy(data.tlv.omac_addr, vif->addr, ETH_ALEN); + memcpy(data.tlv.omac_addr, link_conf->addr, ETH_ALEN); return mt76_mcu_send_msg(&dev->mt76, MCU_WMWA_UNI_CMD(DEV_INFO_UPDATE), &data, sizeof(data), true); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 31d1fdd61de6..006269d75e5e 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -516,11 +516,14 @@ int mt7996_mcu_twt_agrt_update(struct mt7996_dev *dev, struct mt7996_vif *mvif, struct mt7996_twt_flow *flow, int cmd); -int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, - struct ieee80211_vif *vif, bool enable); -int mt7996_mcu_add_bss_info(struct mt7996_phy *phy, - struct ieee80211_vif *vif, int enable); +int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct mt76_vif_link *mlink, bool enable); +int mt7996_mcu_add_bss_info(struct mt7996_phy *phy, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, + struct mt76_vif_link *mlink, int enable); int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif, + struct mt76_vif_link *mlink, struct ieee80211_sta *sta, int conn_state, bool newly); int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev, struct ieee80211_ampdu_params *params, -- 2.51.0 From 747fe944506ff21118f627a8c05b475cc7a9f9fb Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:35:00 +0100 Subject: [PATCH 14/16] wifi: mt76: mt7996: prepare mt7996_mcu_add_beacon for MLO support Pass in struct ieee80211_bss_conf. Link: https://patch.msgid.link/20250102163508.52945-16-nbd@nbd.name Signed-off-by: Felix Fietkau --- .../net/wireless/mediatek/mt76/mt7996/mac.c | 2 +- .../net/wireless/mediatek/mt76/mt7996/main.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 51 ++++++++++--------- .../wireless/mediatek/mt76/mt7996/mt7996.h | 2 +- 4 files changed, 30 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c index 2656e3f85bdc..89523afa4aca 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -1593,7 +1593,7 @@ mt7996_update_vif_beacon(void *priv, u8 *mac, struct ieee80211_vif *vif) case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_AP: - mt7996_mcu_add_beacon(hw, vif, vif->bss_conf.enable_beacon); + mt7996_mcu_add_beacon(hw, vif, &vif->bss_conf); break; default: break; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 6e90ecfecd8f..ae4fad290785 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -669,7 +669,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw, mvif->beacon_rates_idx = mt7996_get_rates_table(hw, vif, true, false); - mt7996_mcu_add_beacon(hw, vif, info->enable_beacon); + mt7996_mcu_add_beacon(hw, vif, info); } if (changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | @@ -690,7 +690,7 @@ mt7996_channel_switch_beacon(struct ieee80211_hw *hw, struct mt7996_dev *dev = mt7996_hw_dev(hw); mutex_lock(&dev->mt76.mutex); - mt7996_mcu_add_beacon(hw, vif, true); + mt7996_mcu_add_beacon(hw, vif, &vif->bss_conf); mutex_unlock(&dev->mt76.mutex); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index 43c728d39077..a66ccc2512af 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -2411,9 +2411,9 @@ int mt7996_mcu_add_dev_info(struct mt7996_phy *phy, struct ieee80211_vif *vif, } static void -mt7996_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb, - struct sk_buff *skb, - struct ieee80211_mutable_offsets *offs) +mt7996_mcu_beacon_cntdwn(struct sk_buff *rskb, struct sk_buff *skb, + struct ieee80211_mutable_offsets *offs, + bool csa) { struct bss_bcn_cntdwn_tlv *info; struct tlv *tlv; @@ -2422,7 +2422,7 @@ mt7996_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb, if (!offs->cntdwn_counter_offs[0]) return; - tag = vif->bss_conf.csa_active ? UNI_BSS_INFO_BCN_CSA : UNI_BSS_INFO_BCN_BCC; + tag = csa ? UNI_BSS_INFO_BCN_CSA : UNI_BSS_INFO_BCN_BCC; tlv = mt7996_mcu_add_uni_tlv(rskb, tag, sizeof(*info)); @@ -2432,16 +2432,13 @@ mt7996_mcu_beacon_cntdwn(struct ieee80211_vif *vif, struct sk_buff *rskb, static void mt7996_mcu_beacon_mbss(struct sk_buff *rskb, struct sk_buff *skb, - struct ieee80211_vif *vif, struct bss_bcn_content_tlv *bcn, + struct bss_bcn_content_tlv *bcn, struct ieee80211_mutable_offsets *offs) { struct bss_bcn_mbss_tlv *mbss; const struct element *elem; struct tlv *tlv; - if (!vif->bss_conf.bssid_indicator) - return; - tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_MBSSID, sizeof(*mbss)); mbss = (struct bss_bcn_mbss_tlv *)tlv; @@ -2484,7 +2481,8 @@ mt7996_mcu_beacon_mbss(struct sk_buff *rskb, struct sk_buff *skb, } static void -mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif, +mt7996_mcu_beacon_cont(struct mt7996_dev *dev, + struct ieee80211_bss_conf *link_conf, struct sk_buff *rskb, struct sk_buff *skb, struct bss_bcn_content_tlv *bcn, struct ieee80211_mutable_offsets *offs) @@ -2498,9 +2496,9 @@ mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif, if (offs->cntdwn_counter_offs[0]) { u16 offset = offs->cntdwn_counter_offs[0]; - if (vif->bss_conf.csa_active) + if (link_conf->csa_active) bcn->csa_ie_pos = cpu_to_le16(offset - 4); - if (vif->bss_conf.color_change_active) + if (link_conf->color_change_active) bcn->bcc_ie_pos = cpu_to_le16(offset - 3); } @@ -2511,12 +2509,11 @@ mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif, memcpy(buf + MT_TXD_SIZE, skb->data, skb->len); } -int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, int en) +int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) { struct mt7996_dev *dev = mt7996_hw_dev(hw); - struct mt7996_phy *phy = mt7996_hw_phy(hw); - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt76_vif_link *mlink = mt76_vif_conf_link(&dev->mt76, vif, link_conf); struct ieee80211_mutable_offsets offs; struct ieee80211_tx_info *info; struct sk_buff *skb, *rskb; @@ -2524,15 +2521,18 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, struct bss_bcn_content_tlv *bcn; int len; - if (vif->bss_conf.nontransmitted) + if (link_conf->nontransmitted) return 0; - rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->deflink.mt76, + if (!mlink) + return -EINVAL; + + rskb = __mt7996_mcu_alloc_bss_req(&dev->mt76, mlink, MT7996_MAX_BSS_OFFLOAD_SIZE); if (IS_ERR(rskb)) return PTR_ERR(rskb); - skb = ieee80211_beacon_get_template(hw, vif, &offs, 0); + skb = ieee80211_beacon_get_template(hw, vif, &offs, link_conf->link_id); if (!skb) { dev_kfree_skb(rskb); return -EINVAL; @@ -2546,21 +2546,22 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, } info = IEEE80211_SKB_CB(skb); - info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, phy->mt76->band_idx); + info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, mlink->band_idx); len = ALIGN(sizeof(*bcn) + MT_TXD_SIZE + skb->len, 4); tlv = mt7996_mcu_add_uni_tlv(rskb, UNI_BSS_INFO_BCN_CONTENT, len); bcn = (struct bss_bcn_content_tlv *)tlv; - bcn->enable = en; - if (!en) + bcn->enable = link_conf->enable_beacon; + if (!bcn->enable) goto out; - mt7996_mcu_beacon_cont(dev, vif, rskb, skb, bcn, &offs); - mt7996_mcu_beacon_mbss(rskb, skb, vif, bcn, &offs); - mt7996_mcu_beacon_cntdwn(vif, rskb, skb, &offs); + mt7996_mcu_beacon_cont(dev, link_conf, rskb, skb, bcn, &offs); + if (link_conf->bssid_indicator) + mt7996_mcu_beacon_mbss(rskb, skb, bcn, &offs); + mt7996_mcu_beacon_cntdwn(rskb, skb, &offs, link_conf->csa_active); out: dev_kfree_skb(skb); - return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb, + return mt76_mcu_skb_send_msg(&dev->mt76, rskb, MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 006269d75e5e..7b12b1f8898b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -534,7 +534,7 @@ int mt7996_mcu_add_rx_ba(struct mt7996_dev *dev, int mt7996_mcu_update_bss_color(struct mt7996_dev *dev, struct ieee80211_vif *vif, struct cfg80211_he_bss_color *he_bss_color); int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - int enable); + struct ieee80211_bss_conf *link_conf); int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev, struct ieee80211_vif *vif, u32 changed); int mt7996_mcu_add_obss_spr(struct mt7996_phy *phy, struct ieee80211_vif *vif, -- 2.51.0 From c0df2f0caa8dde0d50f36649ee28a54c5079281b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:35:01 +0100 Subject: [PATCH 15/16] wifi: mt76: mt7996: prepare mt7996_mcu_set_tx for MLO support Pass in struct ieee80211_bss_conf in order to use link specific data. Link: https://patch.msgid.link/20250102163508.52945-17-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 7 ++++--- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +++++---- drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 3 ++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index ae4fad290785..a1f1dee56dea 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -469,7 +469,8 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, unsigned int link_id, u16 queue, const struct ieee80211_tx_queue_params *params) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt7996_dev *dev = mt7996_hw_dev(hw); + struct mt7996_vif_link *mlink = mt7996_vif_link(dev, vif, link_id); static const u8 mq_to_aci[] = { [IEEE80211_AC_VO] = 3, [IEEE80211_AC_VI] = 2, @@ -478,7 +479,7 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, }; /* firmware uses access class index */ - mvif->deflink.queue_params[mq_to_aci[queue]] = *params; + mlink->queue_params[mq_to_aci[queue]] = *params; /* no need to update right away, we'll get BSS_CHANGED_QOS */ return 0; @@ -656,7 +657,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw, /* ensure that enable txcmd_mode after bss_info */ if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED)) - mt7996_mcu_set_tx(dev, vif); + mt7996_mcu_set_tx(dev, vif, info); if (changed & BSS_CHANGED_HE_OBSS_PD) mt7996_mcu_add_obss_spr(phy, vif, &info->he_obss_pd); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index a66ccc2512af..e694edf4fa9b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -3145,7 +3145,8 @@ int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans) MCU_WM_UNI_CMD(RX_HDR_TRANS), true); } -int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif) +int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) { #define MCU_EDCA_AC_PARAM 0 #define WMM_AIFS_SET BIT(0) @@ -3154,12 +3155,12 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif) #define WMM_TXOP_SET BIT(3) #define WMM_PARAM_SET (WMM_AIFS_SET | WMM_CW_MIN_SET | \ WMM_CW_MAX_SET | WMM_TXOP_SET) - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt7996_vif_link *link = mt7996_vif_conf_link(dev, vif, link_conf); struct { u8 bss_idx; u8 __rsv[3]; } __packed hdr = { - .bss_idx = mvif->deflink.mt76.idx, + .bss_idx = link->mt76.idx, }; struct sk_buff *skb; int len = sizeof(hdr) + IEEE80211_NUM_ACS * sizeof(struct edca); @@ -3172,7 +3173,7 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif) skb_put_data(skb, &hdr, sizeof(hdr)); for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { - struct ieee80211_tx_queue_params *q = &mvif->deflink.queue_params[ac]; + struct ieee80211_tx_queue_params *q = &link->queue_params[ac]; struct edca *e; struct tlv *tlv; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 7b12b1f8898b..2b5c7cb7e817 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -543,7 +543,8 @@ int mt7996_mcu_add_rate_ctrl(struct mt7996_dev *dev, struct ieee80211_vif *vif, struct ieee80211_sta *sta, bool changed); int mt7996_set_channel(struct mt76_phy *mphy); int mt7996_mcu_set_chan_info(struct mt7996_phy *phy, u16 tag); -int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif); +int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf); int mt7996_mcu_set_fixed_rate_ctrl(struct mt7996_dev *dev, void *data, u16 version); int mt7996_mcu_set_fixed_field(struct mt7996_dev *dev, struct ieee80211_vif *vif, -- 2.51.0 From 97a1beb84c1c3a75db04279f7ceba882f94e25b4 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 2 Jan 2025 17:35:02 +0100 Subject: [PATCH 16/16] wifi: mt76: mt7996: prepare mt7996_mcu_set_timing for MLO support Pass in struct ieee80211_bss_conf in order to use link specific data. Link: https://patch.msgid.link/20250102163508.52945-18-nbd@nbd.name Signed-off-by: Felix Fietkau --- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 7 ++++--- drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index a1f1dee56dea..95d915045cf7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -643,7 +643,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw, if (slottime != phy->slottime) { phy->slottime = slottime; - mt7996_mcu_set_timing(phy, vif); + mt7996_mcu_set_timing(phy, vif, info); } } diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index e694edf4fa9b..e9d449bd55ef 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -1108,13 +1108,14 @@ out: MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); } -int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif) +int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; struct mt7996_dev *dev = phy->dev; + struct mt76_vif_link *mlink = mt76_vif_conf_link(&dev->mt76, vif, link_conf); struct sk_buff *skb; - skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->deflink.mt76, + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, mlink, MT7996_BSS_UPDATE_MAX_SIZE); if (IS_ERR(skb)) return PTR_ERR(skb); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 2b5c7cb7e817..604b67ea12e4 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -562,7 +562,8 @@ int mt7996_mcu_set_radar_th(struct mt7996_dev *dev, int index, const struct mt7996_dfs_pattern *pattern); int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable); int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val); -int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif); +int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf); int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch); int mt7996_mcu_get_temperature(struct mt7996_phy *phy); int mt7996_mcu_set_thermal_throttling(struct mt7996_phy *phy, u8 state); -- 2.51.0