From: Shayne Chen <shayne.chen@xxxxxxxxxxxx> This is a preliminary patch in order to enable MLO for MT7996 driver. Co-developed-by: Bo Jiao <Bo.Jiao@xxxxxxxxxxxx> Signed-off-by: Bo Jiao <Bo.Jiao@xxxxxxxxxxxx> Co-developed-by: Peter Chiu <chui-hao.chiu@xxxxxxxxxxxx> Signed-off-by: Peter Chiu <chui-hao.chiu@xxxxxxxxxxxx> Signed-off-by: Shayne Chen <shayne.chen@xxxxxxxxxxxx> Co-developed-by: Lorenzo Bianconi <lorenzo@xxxxxxxxxx> Signed-off-by: Lorenzo Bianconi <lorenzo@xxxxxxxxxx> --- drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 48 ++++++++++++++-------- drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 2 +- 3 files changed, 33 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c index 6870ee189dca61a989d4b7cfde741588c8f18482..a52b4e71b267e9a72b69cb2ffbc95befb1cca655 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -2732,7 +2732,7 @@ void mt7996_mac_add_twt_setup(struct ieee80211_hw *hw, flow->sched = true; flow->start_tsf = mt7996_mac_twt_sched_list_add(dev, flow); - curr_tsf = __mt7996_get_tsf(hw, msta->vif); + curr_tsf = __mt7996_get_tsf(hw, &msta->vif->deflink); div_u64_rem(curr_tsf - flow->start_tsf, interval, &rem); flow_tsf = curr_tsf + interval - rem; twt_agrt->twt = cpu_to_le64(flow_tsf); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index 40efba5bcaac364f8aa1ebf528e283494178616b..8bcb4b8e3ef58c23294c16c10d38384bfba87e30 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -1336,10 +1336,10 @@ mt7996_get_stats(struct ieee80211_hw *hw, return 0; } -u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif) +u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif_link *link) { struct mt7996_dev *dev = mt7996_hw_dev(hw); - struct mt7996_phy *phy = mt7996_vif_link_phy(&mvif->deflink); + struct mt7996_phy *phy = link->phy; union { u64 t64; u32 t32[2]; @@ -1351,8 +1351,8 @@ u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif) lockdep_assert_held(&dev->mt76.mutex); - n = mvif->deflink.mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0 - : mvif->deflink.mt76.omac_idx; + n = link->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0 + : link->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); @@ -1370,7 +1370,7 @@ mt7996_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) u64 ret; mutex_lock(&dev->mt76.mutex); - ret = __mt7996_get_tsf(hw, mvif); + ret = __mt7996_get_tsf(hw, &mvif->deflink); mutex_unlock(&dev->mt76.mutex); return ret; @@ -1382,26 +1382,33 @@ mt7996_set_tsf(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_vif_link_phy(&mvif->deflink); + struct mt7996_vif_link *link; + struct mt7996_phy *phy; union { u64 t64; u32 t32[2]; } tsf = { .t64 = timestamp, }; u16 n; - if (!phy) - return; - mutex_lock(&dev->mt76.mutex); - n = mvif->deflink.mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0 - : mvif->deflink.mt76.omac_idx; + link = mt7996_vif_link(dev, vif, mvif->mt76.deflink_id); + if (!link) + goto unlock; + + n = link->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0 + : link->mt76.omac_idx; + phy = link->phy; + if (!phy) + goto unlock; + 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 */ mt76_rmw(dev, MT_LPON_TCR(phy->mt76->band_idx, n), MT_LPON_TCR_SW_MODE, MT_LPON_TCR_SW_WRITE); +unlock: mutex_unlock(&dev->mt76.mutex); } @@ -1411,26 +1418,33 @@ mt7996_offset_tsf(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_vif_link_phy(&mvif->deflink); + struct mt7996_vif_link *link; + struct mt7996_phy *phy; union { u64 t64; u32 t32[2]; } tsf = { .t64 = timestamp, }; u16 n; - if (!phy) - return; - mutex_lock(&dev->mt76.mutex); - n = mvif->deflink.mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0 - : mvif->deflink.mt76.omac_idx; + link = mt7996_vif_link(dev, vif, mvif->mt76.deflink_id); + if (!link) + goto unlock; + + phy = link->phy; + if (!phy) + goto unlock; + + n = link->mt76.omac_idx > HW_BSSID_MAX ? HW_BSSID_0 + : link->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*/ mt76_rmw(dev, MT_LPON_TCR(phy->mt76->band_idx, n), MT_LPON_TCR_SW_MODE, MT_LPON_TCR_SW_ADJUST); +unlock: mutex_unlock(&dev->mt76.mutex); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 124a48e2706e412afc91af5e1c057fca40fe5e3c..815a3c68b8723469e32e74b85979eaf75c1b176a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -535,7 +535,7 @@ struct mt7996_dev *mt7996_mmio_probe(struct device *pdev, void __iomem *mem_base, u32 device_id); void mt7996_wfsys_reset(struct mt7996_dev *dev); irqreturn_t mt7996_irq_handler(int irq, void *dev_instance); -u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif *mvif); +u64 __mt7996_get_tsf(struct ieee80211_hw *hw, struct mt7996_vif_link *link); int mt7996_register_device(struct mt7996_dev *dev); void mt7996_unregister_device(struct mt7996_dev *dev); int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, -- 2.48.1