developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 1 | From abadd35e16e05493cadfadde59956327312b762d Mon Sep 17 00:00:00 2001 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 2 | From: Shayne Chen <shayne.chen@mediatek.com> |
| 3 | Date: Fri, 8 Dec 2023 18:08:13 +0800 |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 4 | Subject: [PATCH 093/193] mtk: mt76: mt7996: handle mapping for hw and vif |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 5 | |
| 6 | We have several temporal workarounds for ieee80211_hw and mt76_phy |
| 7 | mappings. For legacy MBSS cases, we also need a method to do the |
| 8 | hw and vif mappings. |
| 9 | This is a preliminary patch to add MLO support for mt7996 chipsets. |
| 10 | |
| 11 | Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com> |
| 12 | Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com> |
| 13 | Signed-off-by: Shayne Chen <shayne.chen@mediatek.com> |
| 14 | --- |
| 15 | dma.c | 2 +- |
| 16 | mac80211.c | 2 +- |
| 17 | mt76.h | 14 ++++++++++++-- |
| 18 | mt7996/mac.c | 24 +++++++++++++++++++++++- |
| 19 | mt7996/main.c | 1 + |
| 20 | mt7996/mcu.c | 4 ++-- |
| 21 | mt7996/mmio.c | 1 + |
| 22 | mt7996/mt7996.h | 3 +++ |
| 23 | tx.c | 4 ++-- |
| 24 | 9 files changed, 46 insertions(+), 9 deletions(-) |
| 25 | |
| 26 | diff --git a/dma.c b/dma.c |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 27 | index 38701c7..3f1fb6c 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 28 | --- a/dma.c |
| 29 | +++ b/dma.c |
| 30 | @@ -685,7 +685,7 @@ free: |
| 31 | |
| 32 | free_skb: |
| 33 | status.skb = tx_info.skb; |
| 34 | - hw = mt76_tx_status_get_hw(dev, tx_info.skb); |
| 35 | + hw = mt76_tx_status_get_hw(dev, tx_info.skb, wcid); |
| 36 | spin_lock_bh(&dev->rx_lock); |
| 37 | ieee80211_tx_status_ext(hw, &status); |
| 38 | spin_unlock_bh(&dev->rx_lock); |
| 39 | diff --git a/mac80211.c b/mac80211.c |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 40 | index 0363227..b1af346 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 41 | --- a/mac80211.c |
| 42 | +++ b/mac80211.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 43 | @@ -1546,7 +1546,7 @@ void mt76_wcid_cleanup(struct mt76_dev *dev, struct mt76_wcid *wcid) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 44 | spin_unlock_bh(&phy->tx_lock); |
| 45 | |
| 46 | while ((skb = __skb_dequeue(&list)) != NULL) { |
| 47 | - hw = mt76_tx_status_get_hw(dev, skb); |
| 48 | + hw = mt76_tx_status_get_hw(dev, skb, wcid); |
| 49 | ieee80211_free_txskb(hw, skb); |
| 50 | } |
| 51 | } |
| 52 | diff --git a/mt76.h b/mt76.h |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 53 | index 9fa411c..2dea07a 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 54 | --- a/mt76.h |
| 55 | +++ b/mt76.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 56 | @@ -567,6 +567,9 @@ struct mt76_driver_ops { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 57 | |
| 58 | void (*sta_remove)(struct mt76_dev *dev, struct ieee80211_vif *vif, |
| 59 | struct ieee80211_sta *sta); |
| 60 | + |
| 61 | + void (*get_hw)(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 phy_idx, |
| 62 | + struct ieee80211_hw **hw); |
| 63 | }; |
| 64 | |
| 65 | struct mt76_channel_state { |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 66 | @@ -1602,14 +1605,21 @@ extern const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS]; |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 67 | |
| 68 | /* internal */ |
| 69 | static inline struct ieee80211_hw * |
| 70 | -mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) |
| 71 | +mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb, |
| 72 | + struct mt76_wcid *wcid) |
| 73 | { |
| 74 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
| 75 | u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2; |
| 76 | - struct ieee80211_hw *hw = mt76_phy_hw(dev, phy_idx); |
| 77 | + struct ieee80211_hw *hw; |
| 78 | |
| 79 | info->hw_queue &= ~MT_TX_HW_QUEUE_PHY; |
| 80 | |
| 81 | + if (dev->drv->get_hw) { |
| 82 | + dev->drv->get_hw(dev, wcid, phy_idx, &hw); |
| 83 | + } else { |
| 84 | + hw = mt76_phy_hw(dev, phy_idx); |
| 85 | + } |
| 86 | + |
| 87 | return hw; |
| 88 | } |
| 89 | |
| 90 | diff --git a/mt7996/mac.c b/mt7996/mac.c |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 91 | index f9aa0e5..a48e4f4 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 92 | --- a/mt7996/mac.c |
| 93 | +++ b/mt7996/mac.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 94 | @@ -2857,13 +2857,23 @@ static void mt7996_scan_check_sta(void *data, struct ieee80211_sta *sta) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 95 | void mt7996_scan_work(struct work_struct *work) |
| 96 | { |
| 97 | struct mt7996_phy *phy = container_of(work, struct mt7996_phy, scan_work.work); |
| 98 | - struct ieee80211_hw *hw = phy->mt76->hw; |
| 99 | + struct ieee80211_vif *vif = phy->scan_vif; |
| 100 | + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| 101 | + struct ieee80211_hw *hw = mvif->hw; |
| 102 | struct cfg80211_scan_request *req = phy->scan_req; |
| 103 | struct cfg80211_chan_def chandef = {}; |
| 104 | int duration; |
| 105 | bool has_sta = false, active_scan = false; |
| 106 | |
| 107 | mutex_lock(&phy->dev->mt76.mutex); |
| 108 | + /* don't let non-MLD AP scan other bands */ |
| 109 | + if (vif->type != NL80211_IFTYPE_STATION && !ieee80211_vif_is_mld(vif) && |
| 110 | + phy != mt7996_hw_phy(hw)) { |
| 111 | + mt7996_scan_complete(phy, false); |
| 112 | + mutex_unlock(&phy->dev->mt76.mutex); |
| 113 | + return; |
| 114 | + } |
| 115 | + |
| 116 | if (phy->scan_chan_idx >= req->n_channels) { |
| 117 | mt7996_scan_complete(phy, false); |
| 118 | mutex_unlock(&phy->dev->mt76.mutex); |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 119 | @@ -2923,3 +2933,15 @@ void mt7996_scan_work(struct work_struct *work) |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 120 | |
| 121 | ieee80211_queue_delayed_work(hw, &phy->scan_work, duration); |
| 122 | } |
| 123 | + |
| 124 | +void mt7996_get_hw(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 phy_idx, |
| 125 | + struct ieee80211_hw **hw) |
| 126 | +{ |
| 127 | + struct mt7996_link_sta *mlink = wcid_to_mlink(wcid); |
| 128 | + |
| 129 | + if (mlink) { |
| 130 | + *hw = mlink->sta->vif->hw; |
| 131 | + } else { |
| 132 | + *hw = mt76_phy_hw(dev, phy_idx); |
| 133 | + } |
| 134 | +} |
| 135 | diff --git a/mt7996/main.c b/mt7996/main.c |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 136 | index bfa78e3..02b6798 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 137 | --- a/mt7996/main.c |
| 138 | +++ b/mt7996/main.c |
| 139 | @@ -444,6 +444,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, |
| 140 | phy->monitor_vif = vif; |
| 141 | |
| 142 | mvif->dev = dev; |
| 143 | + mvif->hw = hw; |
| 144 | mvif->sta.vif = mvif; |
| 145 | |
| 146 | ret = mt7996_add_bss_conf(phy, vif, &vif->bss_conf); |
| 147 | diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 148 | index f4493c9..3ecaa0d 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 149 | --- a/mt7996/mcu.c |
| 150 | +++ b/mt7996/mcu.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 151 | @@ -2955,11 +2955,11 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 152 | |
| 153 | if (changed & BSS_CHANGED_FILS_DISCOVERY) { |
| 154 | interval = conf->fils_discovery.max_interval; |
| 155 | - skb = ieee80211_get_fils_discovery_tmpl(hw, vif); |
| 156 | + skb = ieee80211_get_fils_discovery_tmpl(mvif->hw, vif); |
| 157 | } else if (changed & BSS_CHANGED_UNSOL_BCAST_PROBE_RESP && |
| 158 | conf->unsol_bcast_probe_resp_interval) { |
| 159 | interval = conf->unsol_bcast_probe_resp_interval; |
| 160 | - skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(hw, vif); |
| 161 | + skb = ieee80211_get_unsol_bcast_probe_resp_tmpl(mvif->hw, vif); |
| 162 | } |
| 163 | |
| 164 | if (!skb) { |
| 165 | diff --git a/mt7996/mmio.c b/mt7996/mmio.c |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 166 | index 8ac1b12..ee5ee5a 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 167 | --- a/mt7996/mmio.c |
| 168 | +++ b/mt7996/mmio.c |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 169 | @@ -659,6 +659,7 @@ struct mt7996_dev *mt7996_mmio_probe(struct device *pdev, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 170 | .sta_remove = mt7996_mac_sta_remove, |
| 171 | .update_survey = mt7996_update_channel, |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 172 | // .set_channel = mt7996_set_channel, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 173 | + .get_hw = mt7996_get_hw, |
| 174 | }; |
| 175 | struct mt7996_dev *dev; |
| 176 | struct mt76_dev *mdev; |
| 177 | diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 178 | index f83308d..9dd4d47 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 179 | --- a/mt7996/mt7996.h |
| 180 | +++ b/mt7996/mt7996.h |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 181 | @@ -355,6 +355,7 @@ struct mt7996_vif { |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 182 | |
| 183 | struct mt7996_sta sta; |
| 184 | struct mt7996_dev *dev; |
| 185 | + struct ieee80211_hw *hw; |
| 186 | |
| 187 | u8 master_link_id; |
| 188 | u8 group_mld_id; |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 189 | @@ -905,6 +906,8 @@ int mt7996_init_tx_queues(struct mt7996_phy *phy, int idx, |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 190 | void mt7996_init_txpower(struct mt7996_phy *phy); |
| 191 | int mt7996_txbf_init(struct mt7996_dev *dev); |
| 192 | int mt7996_get_chip_sku(struct mt7996_dev *dev); |
| 193 | +void mt7996_get_hw(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 phy_idx, |
| 194 | + struct ieee80211_hw **hw); |
| 195 | void mt7996_reset(struct mt7996_dev *dev); |
| 196 | void mt7996_coredump(struct mt7996_dev *dev, u8 state); |
| 197 | int mt7996_run(struct ieee80211_hw *hw); |
| 198 | diff --git a/tx.c b/tx.c |
developer | 1f55fcf | 2024-10-17 14:52:33 +0800 | [diff] [blame^] | 199 | index 330b8d3..7906023 100644 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 200 | --- a/tx.c |
| 201 | +++ b/tx.c |
| 202 | @@ -76,7 +76,7 @@ mt76_tx_status_unlock(struct mt76_dev *dev, struct sk_buff_head *list) |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | - hw = mt76_tx_status_get_hw(dev, skb); |
| 207 | + hw = mt76_tx_status_get_hw(dev, skb, wcid); |
| 208 | spin_lock_bh(&dev->rx_lock); |
| 209 | ieee80211_tx_status_ext(hw, &status); |
| 210 | spin_unlock_bh(&dev->rx_lock); |
| 211 | @@ -272,7 +272,7 @@ void __mt76_tx_complete_skb(struct mt76_dev *dev, u16 wcid_idx, struct sk_buff * |
| 212 | if (cb->pktid < MT_PACKET_ID_FIRST) { |
| 213 | struct ieee80211_rate_status rs = {}; |
| 214 | |
| 215 | - hw = mt76_tx_status_get_hw(dev, skb); |
| 216 | + hw = mt76_tx_status_get_hw(dev, skb, wcid); |
| 217 | status.sta = wcid_to_sta(wcid); |
| 218 | if (status.sta && (wcid->rate.flags || wcid->rate.legacy)) { |
| 219 | rs.rate_idx = wcid->rate; |
| 220 | -- |
developer | d0c8945 | 2024-10-11 16:53:27 +0800 | [diff] [blame] | 221 | 2.45.2 |
developer | 66e89bc | 2024-04-23 14:50:01 +0800 | [diff] [blame] | 222 | |