mt76: introduce connac3_mac support
Subsystems (2)
Lorenzo Bianconi
maintainerv2 cover mt76: introduce connac3_mac support
Introduce connac3_mac in mt76_connac library to reuse mac code shared between WiFi7 chipsets.
Move the following common mac fields in mt76_struct/mt76_wcid:
- sta_poll_list
- sta_poll_lock
- poll_list
- ampdu_state
Move the following routines in mt76-connac lib since they are shared between mt7915 and mt7921:
- mt76_connac2_tx_check_aggr
- mt76_connac2_txwi_free
- mt76_connac2_tx_token_put
Changes since v1:
- rebase on top wireless-next tree
- fix connac3_mac library
- fix compilation warnings
Lorenzo Bianconi (15):
wifi: mt76: mt7915: move sta_poll_list and sta_poll_lock in mt76_dev
wifi: mt76: mt7603: rely on shared sta_poll_list and sta_poll_lock
wifi: mt76: mt7615: rely on shared sta_poll_list and sta_poll_lock
wifi: mt76: mt7996: rely on shared sta_poll_list and sta_poll_lock
wifi: mt76: mt7921: rely on shared sta_poll_list and sta_poll_lock
wifi: mt76: mt7915: move poll_list in mt76_wcid
wifi: mt76: mt7603: rely on shared poll_list field
wifi: mt76: mt7615: rely on shared poll_list field
wifi: mt76: mt7996: rely on shared poll_list field
wifi: mt76: mt7921: rely on shared poll_list field
wifi: mt76: move ampdu_state in mt76_wcid
mt76: connac: move more mt7921/mt7915 mac shared code in connac lib
wifi: mt76: move rate info in mt76_vif
wifi: mt76: connac: move connac3 definitions in mt76_connac3_mac.h
wifi: mt76: connac: add connac3 mac library
drivers/net/wireless/mediatek/mt76/Makefile | 2 +- drivers/net/wireless/mediatek/mt76/mac80211.c | 2 + drivers/net/wireless/mediatek/mt76/mt76.h | 9 + .../net/wireless/mediatek/mt76/mt7603/init.c | 2 - .../net/wireless/mediatek/mt76/mt7603/mac.c | 22 +- .../net/wireless/mediatek/mt76/mt7603/main.c | 20 +- .../wireless/mediatek/mt76/mt7603/mt7603.h | 4 - .../net/wireless/mediatek/mt76/mt7615/init.c | 2 - .../net/wireless/mediatek/mt76/mt7615/mac.c | 31 +- .../net/wireless/mediatek/mt76/mt7615/main.c | 20 +- .../wireless/mediatek/mt76/mt7615/mt7615.h | 4 - .../net/wireless/mediatek/mt76/mt76_connac.h | 24 + .../wireless/mediatek/mt76/mt76_connac3_mac.c | 742 ++++++++++++++++ .../wireless/mediatek/mt76/mt76_connac3_mac.h | 343 ++++++++ .../wireless/mediatek/mt76/mt76_connac_mac.c | 82 ++ .../net/wireless/mediatek/mt76/mt7915/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7915/mac.c | 140 +-- .../net/wireless/mediatek/mt76/mt7915/main.c | 30 +- .../wireless/mediatek/mt76/mt7915/mt7915.h | 5 - .../net/wireless/mediatek/mt76/mt7921/init.c | 2 - .../net/wireless/mediatek/mt76/mt7921/mac.c | 104 +-- .../net/wireless/mediatek/mt76/mt7921/main.c | 26 +- .../wireless/mediatek/mt76/mt7921/mt7921.h | 9 - .../net/wireless/mediatek/mt76/mt7921/pci.c | 2 +- .../wireless/mediatek/mt76/mt7921/pci_mac.c | 16 +- .../net/wireless/mediatek/mt76/mt7996/init.c | 6 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 803 +----------------- .../net/wireless/mediatek/mt76/mt7996/mac.h | 315 +------ .../net/wireless/mediatek/mt76/mt7996/main.c | 42 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 11 +- .../wireless/mediatek/mt76/mt7996/mt7996.h | 36 +- 31 files changed, 1403 insertions(+), 1457 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c create mode 100644 drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 1/15 wifi: mt76: mt7915: move sta_poll_list and sta_poll_lock in mt76_dev
sta_poll_list and sta_poll_lock are used by most of the drivers, so move them in mt76_dev structure.
--- drivers/net/wireless/mediatek/mt76/mac80211.c | 2 + drivers/net/wireless/mediatek/mt76/mt76.h | 3 ++ .../net/wireless/mediatek/mt76/mt7915/init.c | 2 - .../net/wireless/mediatek/mt76/mt7915/mac.c | 47 ++++++++++--------- .../net/wireless/mediatek/mt76/mt7915/main.c | 12 ++--- .../wireless/mediatek/mt76/mt7915/mt7915.h | 2 - 6 files changed, 36 insertions(+), 32 deletions(-)
drivers/net/wireless/mediatek/mt76/mac80211.c +2 -0
@@ -660,6 +660,8 @@ mt76_alloc_device(struct device *pdev, unsigned int size,idr_init (&dev->rx_token);INIT_LIST_HEAD (&dev->wcid_list); +INIT_LIST_HEAD (&dev->sta_poll_list); +spin_lock_init (&dev->sta_poll_lock);INIT_LIST_HEAD (&dev->txwi_cache);INIT_LIST_HEAD (&dev->rxwi_cache);
drivers/net/wireless/mediatek/mt76/mt76.h +3 -0
@@ -823,6 +823,9 @@ struct mt76_dev {struct mt76_wcid __rcu *wcid[MT76_N_WCIDS ];struct list_head wcid_list; +struct list_head sta_poll_list; +spinlock_t sta_poll_lock; +u32 rev;struct tasklet_struct pre_tbtt_tasklet;
drivers/net/wireless/mediatek/mt76/mt7915/init.c +0 -2
@@ -1177,9 +1177,7 @@ int mt7915_register_device(struct mt7915_dev *dev)INIT_WORK (&dev->rc_work, mt7915_mac_sta_rc_work);INIT_DELAYED_WORK (&dev->mphy.mac_work, mt7915_mac_work);INIT_LIST_HEAD (&dev->sta_rc_list); -INIT_LIST_HEAD (&dev->sta_poll_list);INIT_LIST_HEAD (&dev->twt_list); -spin_lock_init (&dev->sta_poll_lock);init_waitqueue_head (&dev->reset_wait);INIT_WORK (&dev->reset_work, mt7915_mac_reset_work);
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +25 -22
113 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7915/main.c +6 -6
@@ -308,10 +308,10 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw, phy->omac_mask &= ~BIT_ULL (mvif->mt76.omac_idx);mutex_unlock (&dev->mt76.mutex); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (!list_empty (&msta->poll_list))list_del_init (&msta->poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock);mt76_packet_id_flush (&dev->mt76, &msta->wcid); }
@@ -715,12 +715,12 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,for (i =0 ; i <ARRAY_SIZE (msta->twt.flow); i++)mt7915_mac_twt_teardown_flow (dev, msta, i); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&mdev->sta_poll_lock);if (!list_empty (&msta->poll_list))list_del_init (&msta->poll_list);if (!list_empty (&msta->rc_list))list_del_init (&msta->rc_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&mdev->sta_poll_lock); } static void mt7915_tx(struct ieee80211_hw *hw,
@@ -1074,11 +1074,11 @@ static void mt7915_sta_rc_work(void *data, struct ieee80211_sta *sta)struct mt7915_dev *dev = msta->vif->phy->dev;u32 *changed = data; -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock); msta->changed |= *changed;if (list_empty (&msta->rc_list))list_add_tail (&msta->rc_list, &dev->sta_rc_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock); } static void mt7915_sta_rc_update(struct ieee80211_hw *hw,
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +0 -2
@@ -328,9 +328,7 @@ struct mt7915_dev {#endif struct list_head sta_rc_list; -struct list_head sta_poll_list;struct list_head twt_list; -spinlock_t sta_poll_lock;u32 hw_pattern;
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 2/15 wifi: mt76: mt7603: rely on shared sta_poll_list and sta_poll_lock
In reply to Lorenzo BianconiRely on sta_poll_list and sta_poll_lock fields in mt76_dev structure and get rid of private copies.
--- .../net/wireless/mediatek/mt76/mt7603/init.c | 2 -- .../net/wireless/mediatek/mt76/mt7603/mac.c | 18 +++++++++--------- .../net/wireless/mediatek/mt76/mt7603/main.c | 8 ++++---- .../net/wireless/mediatek/mt76/mt7603/mt7603.h | 3 --- 4 files changed, 13 insertions(+), 18 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7603/init.c +0 -2
@@ -500,8 +500,6 @@ int mt7603_register_device(struct mt7603_dev *dev) bus_ops->rmw = mt7603_rmw; dev->mt76.bus = bus_ops; -INIT_LIST_HEAD (&dev->sta_poll_list); -spin_lock_init (&dev->sta_poll_lock);spin_lock_init (&dev->ps_lock);INIT_DELAYED_WORK (&dev->mphy.mac_work, mt7603_mac_work);
drivers/net/wireless/mediatek/mt76/mt7603/mac.c +9 -9
@@ -412,16 +412,16 @@ void mt7603_mac_sta_poll(struct mt7603_dev *dev)while (1 ) {bool clear = false; -spin_lock_bh (&dev->sta_poll_lock); -if (list_empty (&dev->sta_poll_list)) { -spin_unlock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock); +if (list_empty (&dev->mt76.sta_poll_list)) { +spin_unlock_bh (&dev->mt76.sta_poll_lock);break ; } - msta = list_first_entry(&dev->sta_poll_list, struct mt7603_sta, - poll_list); + msta =list_first_entry (&dev->mt76.sta_poll_list, + struct mt7603_sta, poll_list);list_del_init (&msta->poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock); addr =mt7603_wtbl4_addr (msta->wcid.idx);for (i =0 ; i <4 ; i++) {
@@ -1268,9 +1268,9 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data) sta =wcid_to_sta (wcid);if (list_empty (&msta->poll_list)) { -spin_lock_bh (&dev->sta_poll_lock); -list_add_tail (&msta->poll_list, &dev->sta_poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock); +list_add_tail (&msta->poll_list, &dev->mt76.sta_poll_list); +spin_unlock_bh (&dev->mt76.sta_poll_lock); }if (mt7603_mac_add_txs_skb (dev, msta, pid, txs_data))
drivers/net/wireless/mediatek/mt76/mt7603/main.c +4 -4
@@ -100,10 +100,10 @@ mt7603_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)rcu_assign_pointer (dev->mt76.wcid[idx],NULL ); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (!list_empty (&msta->poll_list))list_del_init (&msta->poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock);mutex_lock (&dev->mt76.mutex); dev->mt76.vif_mask &= ~BIT_ULL (mvif->idx);
@@ -388,10 +388,10 @@ mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,mt7603_filter_tx (dev, wcid->idx, true);spin_unlock_bh (&dev->ps_lock); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&mdev->sta_poll_lock);if (!list_empty (&msta->poll_list))list_del_init (&msta->poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&mdev->sta_poll_lock);mt7603_wtbl_clear (dev, wcid->idx); }
drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h +0 -3
@@ -110,9 +110,6 @@ struct mt7603_dev {u32 rxfilter; -struct list_head sta_poll_list; -spinlock_t sta_poll_lock; -struct mt7603_sta global_sta;u32 agc0, agc3;
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 3/15 wifi: mt76: mt7615: rely on shared sta_poll_list and sta_poll_lock
In reply to Lorenzo BianconiRely on sta_poll_list and sta_poll_lock fields in mt76_dev structure and get rid of private copies.
--- .../net/wireless/mediatek/mt76/mt7615/init.c | 2 -- .../net/wireless/mediatek/mt76/mt7615/mac.c | 23 ++++++++++--------- .../net/wireless/mediatek/mt76/mt7615/main.c | 8 +++---- .../wireless/mediatek/mt76/mt7615/mt7615.h | 3 --- 4 files changed, 16 insertions(+), 20 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7615/init.c +0 -2
@@ -626,8 +626,6 @@ void mt7615_init_device(struct mt7615_dev *dev)INIT_DELAYED_WORK (&dev->coredump.work, mt7615_coredump_work);skb_queue_head_init (&dev->phy.scan_event_list);skb_queue_head_init (&dev->coredump.msg_list); -INIT_LIST_HEAD (&dev->sta_poll_list); -spin_lock_init (&dev->sta_poll_lock);init_waitqueue_head (&dev->reset_wait);init_waitqueue_head (&dev->phy.roc_wait);
drivers/net/wireless/mediatek/mt76/mt7615/mac.c +12 -11
@@ -387,10 +387,11 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb)struct mt7615_sta *msta; msta = container_of(status->wcid, struct mt7615_sta, wcid); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, &dev->sta_poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +list_add_tail (&msta->poll_list, + &dev->mt76.sta_poll_list); +spin_unlock_bh (&dev->mt76.sta_poll_lock); } if (mt76_is_mmio(&dev->mt76) && (rxd0 & csum_mask) == csum_mask &&
@@ -905,9 +906,9 @@ void mt7615_mac_sta_poll(struct mt7615_dev *dev)int i;INIT_LIST_HEAD (&sta_poll_list); -spin_lock_bh (&dev->sta_poll_lock); -list_splice_init (&dev->sta_poll_list, &sta_poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock); +list_splice_init (&dev->mt76.sta_poll_list, &sta_poll_list); +spin_unlock_bh (&dev->mt76.sta_poll_lock);while (!list_empty (&sta_poll_list)) {bool clear = false;
@@ -915,9 +916,9 @@ void mt7615_mac_sta_poll(struct mt7615_dev *dev) msta = list_first_entry(&sta_poll_list, struct mt7615_sta, poll_list); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);list_del_init (&msta->poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock); addr =mt7615_mac_wtbl_addr (dev, msta->wcid.idx) +19 *4 ;
@@ -1542,10 +1543,10 @@ static void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data) msta = container_of(wcid, struct mt7615_sta, wcid); sta =wcid_to_sta (wcid); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, &dev->sta_poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +list_add_tail (&msta->poll_list, &dev->mt76.sta_poll_list); +spin_unlock_bh (&dev->mt76.sta_poll_lock);if (mt7615_mac_add_txs_skb (dev, msta, pid, txs_data)) goto out;
drivers/net/wireless/mediatek/mt76/mt7615/main.c +4 -4
@@ -274,10 +274,10 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw,mt7615_mutex_release (dev); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (!list_empty (&msta->poll_list))list_del_init (&msta->poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock);mt76_packet_id_flush (&dev->mt76, &mvif->sta.wcid); }
@@ -677,10 +677,10 @@ void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,if (vif->type ==NL80211_IFTYPE_STATION && !sta->tdls)mt7615_mcu_add_bss_info (phy, vif, sta, false); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&mdev->sta_poll_lock);if (!list_empty (&msta->poll_list))list_del_init (&msta->poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&mdev->sta_poll_lock);mt76_connac_power_save_sched (phy->mt76, &dev->pm); }
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +0 -3
@@ -262,9 +262,6 @@ struct mt7615_dev {wait_queue_head_t reset_wait;u32 reset_state; -struct list_head sta_poll_list; -spinlock_t sta_poll_lock; -struct {u8 n_pulses;u32 period;
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 4/15 wifi: mt76: mt7996: rely on shared sta_poll_list and sta_poll_lock
In reply to Lorenzo BianconiRely on sta_poll_list and sta_poll_lock fields in mt76_dev structure and get rid of private copies.
--- .../net/wireless/mediatek/mt76/mt7996/init.c | 2 - .../net/wireless/mediatek/mt76/mt7996/mac.c | 40 ++++++++++--------- .../net/wireless/mediatek/mt76/mt7996/main.c | 12 +++--- .../wireless/mediatek/mt76/mt7996/mt7996.h | 2 - 4 files changed, 27 insertions(+), 29 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/init.c +0 -2
@@ -853,9 +853,7 @@ int mt7996_register_device(struct mt7996_dev *dev)INIT_WORK (&dev->rc_work, mt7996_mac_sta_rc_work);INIT_DELAYED_WORK (&dev->mphy.mac_work, mt7996_mac_work);INIT_LIST_HEAD (&dev->sta_rc_list); -INIT_LIST_HEAD (&dev->sta_poll_list);INIT_LIST_HEAD (&dev->twt_list); -spin_lock_init (&dev->sta_poll_lock);init_waitqueue_head (&dev->reset_wait);INIT_WORK (&dev->reset_work, mt7996_mac_reset_work);
drivers/net/wireless/mediatek/mt76/mt7996/mac.c +21 -19
@@ -111,9 +111,9 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)LIST_HEAD (sta_poll_list);int i; -spin_lock_bh (&dev->sta_poll_lock); -list_splice_init (&dev->sta_poll_list, &sta_poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock); +list_splice_init (&dev->mt76.sta_poll_list, &sta_poll_list); +spin_unlock_bh (&dev->mt76.sta_poll_lock);rcu_read_lock ();
@@ -124,15 +124,15 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)s8 rssi[4 ];u8 bw; -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (list_empty (&sta_poll_list)) { -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock);break ; } msta =list_first_entry (&sta_poll_list, struct mt7996_sta, poll_list);list_del_init (&msta->poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock); idx = msta->wcid.idx;
@@ -681,10 +681,11 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb)struct mt7996_sta *msta; msta = container_of(status->wcid, struct mt7996_sta, wcid); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, &dev->sta_poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +list_add_tail (&msta->poll_list, + &dev->mt76.sta_poll_list); +spin_unlock_bh (&dev->mt76.sta_poll_lock); } status->freq = mphy->chandef.chan->center_freq;
@@ -1286,10 +1287,11 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len)continue ; msta = container_of(wcid, struct mt7996_sta, wcid); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&mdev->sta_poll_lock);if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, &dev->sta_poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +list_add_tail (&msta->poll_list, + &mdev->sta_poll_list); +spin_unlock_bh (&mdev->sta_poll_lock);continue ; }
@@ -1494,10 +1496,10 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data)if (!wcid->sta) goto out; -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, &dev->sta_poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +list_add_tail (&msta->poll_list, &dev->mt76.sta_poll_list); +spin_unlock_bh (&dev->mt76.sta_poll_lock); out:rcu_read_unlock ();
@@ -2340,7 +2342,7 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)u32 changed;LIST_HEAD (list); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);list_splice_init (&dev->sta_rc_list, &list);while (!list_empty (&list)) {
@@ -2348,7 +2350,7 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)list_del_init (&msta->rc_list); changed = msta->changed; msta->changed =0 ; -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock); sta = container_of((void *)msta, struct ieee80211_sta, drv_priv); vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
@@ -2360,10 +2362,10 @@ void mt7996_mac_sta_rc_work(struct work_struct *work)/* TODO: smps change */ -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock); } -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock); }void mt7996_mac_work (struct work_struct *work)
drivers/net/wireless/mediatek/mt76/mt7996/main.c +6 -6
@@ -262,10 +262,10 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw, phy->omac_mask &= ~BIT_ULL (mvif->mt76.omac_idx);mutex_unlock (&dev->mt76.mutex); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (!list_empty (&msta->poll_list))list_del_init (&msta->poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock);mt76_packet_id_flush (&dev->mt76, &msta->wcid); }
@@ -667,12 +667,12 @@ void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,for (i =0 ; i <ARRAY_SIZE (msta->twt.flow); i++)mt7996_mac_twt_teardown_flow (dev, msta, i); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&mdev->sta_poll_lock);if (!list_empty (&msta->poll_list))list_del_init (&msta->poll_list);if (!list_empty (&msta->rc_list))list_del_init (&msta->rc_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&mdev->sta_poll_lock); } static void mt7996_tx(struct ieee80211_hw *hw,
@@ -982,11 +982,11 @@ static void mt7996_sta_rc_work(void *data, struct ieee80211_sta *sta)struct mt7996_dev *dev = msta->vif->phy->dev;u32 *changed = data; -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock); msta->changed |= *changed;if (list_empty (&msta->rc_list))list_add_tail (&msta->rc_list, &dev->sta_rc_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock); } static void mt7996_sta_rc_update(struct ieee80211_hw *hw,
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +0 -2
@@ -270,9 +270,7 @@ struct mt7996_dev {#endif struct list_head sta_rc_list; -struct list_head sta_poll_list;struct list_head twt_list; -spinlock_t sta_poll_lock;u32 hw_pattern;
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 5/15 wifi: mt76: mt7921: rely on shared sta_poll_list and sta_poll_lock
In reply to Lorenzo BianconiRely on sta_poll_list and sta_poll_lock fields in mt76_dev structure and get rid of private copies.
--- .../net/wireless/mediatek/mt76/mt7921/init.c | 2 -- .../net/wireless/mediatek/mt76/mt7921/mac.c | 32 ++++++++++--------- .../net/wireless/mediatek/mt76/mt7921/main.c | 8 ++--- .../wireless/mediatek/mt76/mt7921/mt7921.h | 3 -- 4 files changed, 21 insertions(+), 24 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7921/init.c +0 -2
@@ -392,8 +392,6 @@ int mt7921_register_device(struct mt7921_dev *dev)#endif skb_queue_head_init (&dev->phy.scan_event_list);skb_queue_head_init (&dev->coredump.msg_list); -INIT_LIST_HEAD (&dev->sta_poll_list); -spin_lock_init (&dev->sta_poll_lock);INIT_WORK (&dev->reset_work, mt7921_mac_reset_work);INIT_WORK (&dev->init_work, mt7921_init_work);
drivers/net/wireless/mediatek/mt76/mt7921/mac.c +17 -15
@@ -68,9 +68,9 @@ static void mt7921_mac_sta_poll(struct mt7921_dev *dev)s8 rssi[4 ];int i; -spin_lock_bh (&dev->sta_poll_lock); -list_splice_init (&dev->sta_poll_list, &sta_poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock); +list_splice_init (&dev->mt76.sta_poll_list, &sta_poll_list); +spin_unlock_bh (&dev->mt76.sta_poll_lock);while (true) {bool clear = false;
@@ -78,15 +78,15 @@ static void mt7921_mac_sta_poll(struct mt7921_dev *dev)u16 idx;u8 bw; -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (list_empty (&sta_poll_list)) { -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock);break ; } msta =list_first_entry (&sta_poll_list, struct mt7921_sta, poll_list);list_del_init (&msta->poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock); idx = msta->wcid.idx; addr =mt7921_mac_wtbl_lmac_addr (idx,MT_WTBL_AC0_CTT_OFFSET );
@@ -280,10 +280,11 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)if (status->wcid) { msta = container_of(status->wcid, struct mt7921_sta, wcid); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, &dev->sta_poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +list_add_tail (&msta->poll_list, + &dev->mt76.sta_poll_list); +spin_unlock_bh (&dev->mt76.sta_poll_lock); }mt7921_get_status_freq_info (dev, mphy, status, chfreq);
@@ -566,10 +567,10 @@ void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data)if (!wcid->sta) goto out; -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, &dev->sta_poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +list_add_tail (&msta->poll_list, &dev->mt76.sta_poll_list); +spin_unlock_bh (&dev->mt76.sta_poll_lock); out:rcu_read_unlock ();
@@ -647,10 +648,11 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len)continue ; msta = container_of(wcid, struct mt7921_sta, wcid); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&mdev->sta_poll_lock);if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, &dev->sta_poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +list_add_tail (&msta->poll_list, + &mdev->sta_poll_list); +spin_unlock_bh (&mdev->sta_poll_lock);continue ; }
drivers/net/wireless/mediatek/mt76/mt7921/main.c +4 -4
@@ -357,10 +357,10 @@ static void mt7921_remove_interface(struct ieee80211_hw *hw, phy->omac_mask &= ~BIT_ULL (mvif->mt76.omac_idx);mt7921_mutex_release (dev); -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (!list_empty (&msta->poll_list))list_del_init (&msta->poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock);mt76_packet_id_flush (&dev->mt76, &msta->wcid); }
@@ -843,10 +843,10 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, mvif->ctx); } -spin_lock_bh (&dev->sta_poll_lock); +spin_lock_bh (&dev->mt76.sta_poll_lock);if (!list_empty (&msta->poll_list))list_del_init (&msta->poll_list); -spin_unlock_bh (&dev->sta_poll_lock); +spin_unlock_bh (&dev->mt76.sta_poll_lock);mt76_connac_power_save_sched (&dev->mphy, &dev->pm); }
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +0 -3
@@ -303,9 +303,6 @@ struct mt7921_dev { bool hw_init_done:1; bool fw_assert:1; -struct list_head sta_poll_list; -spinlock_t sta_poll_lock; -struct work_struct init_work;u8 fw_debug;
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 6/15 wifi: mt76: mt7915: move poll_list in mt76_wcid
In reply to Lorenzo Bianconipoll_list field is used by most of the drivers, so move it in mt76_wcid structure.
--- drivers/net/wireless/mediatek/mt76/mt76.h | 2 ++ .../net/wireless/mediatek/mt76/mt7915/mac.c | 20 +++++++++---------- .../net/wireless/mediatek/mt76/mt7915/main.c | 12 +++++------ .../wireless/mediatek/mt76/mt7915/mt7915.h | 1 - 4 files changed, 18 insertions(+), 17 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76.h +2 -0
@@ -336,6 +336,8 @@ struct mt76_wcid {struct idr pktid;struct mt76_sta_stats stats; + +struct list_head poll_list; };struct mt76_txq {
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +10 -10
@@ -124,8 +124,8 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)break ; } msta =list_first_entry (&sta_poll_list, - struct mt7915_sta, poll_list); -list_del_init (&msta->poll_list); + struct mt7915_sta, wcid.poll_list); +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); idx = msta->wcid.idx;
@@ -327,8 +327,8 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb,if (status->wcid) { msta = container_of(status->wcid, struct mt7915_sta, wcid);spin_lock_bh (&dev->mt76.sta_poll_lock); -if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, +if (list_empty (&msta->wcid.poll_list)) +list_add_tail (&msta->wcid.poll_list, &dev->mt76.sta_poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); }
@@ -894,8 +894,8 @@ mt7915_txwi_free(struct mt7915_dev *dev, struct mt76_txwi_cache *t, sta = container_of((void *)msta, struct ieee80211_sta, drv_priv);spin_lock_bh (&mdev->sta_poll_lock); -if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, +if (list_empty (&msta->wcid.poll_list)) +list_add_tail (&msta->wcid.poll_list, &mdev->sta_poll_list);spin_unlock_bh (&mdev->sta_poll_lock); }
@@ -990,8 +990,8 @@ mt7915_mac_tx_free(struct mt7915_dev *dev, void *data, int len) msta = container_of(wcid, struct mt7915_sta, wcid);spin_lock_bh (&mdev->sta_poll_lock); -if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, +if (list_empty (&msta->wcid.poll_list)) +list_add_tail (&msta->wcid.poll_list, &mdev->sta_poll_list);spin_unlock_bh (&mdev->sta_poll_lock);continue ;
@@ -1085,8 +1085,8 @@ static void mt7915_mac_add_txs(struct mt7915_dev *dev, void *data) goto out;spin_lock_bh (&dev->mt76.sta_poll_lock); -if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, &dev->mt76.sta_poll_list); +if (list_empty (&msta->wcid.poll_list)) +list_add_tail (&msta->wcid.poll_list, &dev->mt76.sta_poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); out:
drivers/net/wireless/mediatek/mt76/mt7915/main.c +6 -6
@@ -248,7 +248,7 @@ static int mt7915_add_interface(struct ieee80211_hw *hw, idx =MT7915_WTBL_RESERVED - mvif->mt76.idx;INIT_LIST_HEAD (&mvif->sta.rc_list); -INIT_LIST_HEAD (&mvif->sta.poll_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 ;
@@ -309,8 +309,8 @@ static void mt7915_remove_interface(struct ieee80211_hw *hw,mutex_unlock (&dev->mt76.mutex);spin_lock_bh (&dev->mt76.sta_poll_lock); -if (!list_empty (&msta->poll_list)) -list_del_init (&msta->poll_list); +if (!list_empty (&msta->wcid.poll_list)) +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock);mt76_packet_id_flush (&dev->mt76, &msta->wcid);
@@ -680,7 +680,7 @@ int mt7915_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,return -ENOSPC ;INIT_LIST_HEAD (&msta->rc_list); -INIT_LIST_HEAD (&msta->poll_list); +INIT_LIST_HEAD (&msta->wcid.poll_list); msta->vif = mvif; msta->wcid.sta =1 ; msta->wcid.idx = idx;
@@ -716,8 +716,8 @@ void mt7915_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,mt7915_mac_twt_teardown_flow (dev, msta, i);spin_lock_bh (&mdev->sta_poll_lock); -if (!list_empty (&msta->poll_list)) -list_del_init (&msta->poll_list); +if (!list_empty (&msta->wcid.poll_list)) +list_del_init (&msta->wcid.poll_list);if (!list_empty (&msta->rc_list))list_del_init (&msta->rc_list);spin_unlock_bh (&mdev->sta_poll_lock);
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +0 -1
@@ -129,7 +129,6 @@ struct mt7915_sta {struct mt7915_vif *vif; -struct list_head poll_list;struct list_head rc_list;u32 airtime_ac[8 ];
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 7/15 wifi: mt76: mt7603: rely on shared poll_list field
In reply to Lorenzo BianconiRely on poll_list field in mt76_wcid structure and get rid of private copy.
--- drivers/net/wireless/mediatek/mt76/mt7603/mac.c | 8 ++++---- drivers/net/wireless/mediatek/mt76/mt7603/main.c | 12 ++++++------ drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h | 1 - 3 files changed, 10 insertions(+), 11 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7603/mac.c +4 -4
@@ -419,8 +419,8 @@ void mt7603_mac_sta_poll(struct mt7603_dev *dev) } msta =list_first_entry (&dev->mt76.sta_poll_list, - struct mt7603_sta, poll_list); -list_del_init (&msta->poll_list); + struct mt7603_sta, wcid.poll_list); +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); addr =mt7603_wtbl4_addr (msta->wcid.idx);
@@ -1267,9 +1267,9 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data) msta = container_of(wcid, struct mt7603_sta, wcid); sta =wcid_to_sta (wcid); -if (list_empty (&msta->poll_list)) { +if (list_empty (&msta->wcid.poll_list)) {spin_lock_bh (&dev->mt76.sta_poll_lock); -list_add_tail (&msta->poll_list, &dev->mt76.sta_poll_list); +list_add_tail (&msta->wcid.poll_list, &dev->mt76.sta_poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); }
drivers/net/wireless/mediatek/mt76/mt7603/main.c +6 -6
@@ -66,7 +66,7 @@ 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.poll_list); +INIT_LIST_HEAD (&mvif->sta.wcid.poll_list); mvif->sta.wcid.idx = idx; mvif->sta.wcid.hw_key_idx =-1 ;mt76_packet_id_init (&mvif->sta.wcid);
@@ -101,8 +101,8 @@ mt7603_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)rcu_assign_pointer (dev->mt76.wcid[idx],NULL );spin_lock_bh (&dev->mt76.sta_poll_lock); -if (!list_empty (&msta->poll_list)) -list_del_init (&msta->poll_list); +if (!list_empty (&msta->wcid.poll_list)) +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock);mutex_lock (&dev->mt76.mutex);
@@ -351,7 +351,7 @@ mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,if (idx <0 )return -ENOSPC ; -INIT_LIST_HEAD (&msta->poll_list); +INIT_LIST_HEAD (&msta->wcid.poll_list);__skb_queue_head_init (&msta->psq); msta->ps = ~0 ; msta->smps = ~0 ;
@@ -389,8 +389,8 @@ mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,spin_unlock_bh (&dev->ps_lock);spin_lock_bh (&mdev->sta_poll_lock); -if (!list_empty (&msta->poll_list)) -list_del_init (&msta->poll_list); +if (!list_empty (&msta->wcid.poll_list)) +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&mdev->sta_poll_lock);mt7603_wtbl_clear (dev, wcid->idx);
drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h +0 -1
@@ -64,7 +64,6 @@ struct mt7603_sta {struct mt7603_vif *vif; -struct list_head poll_list;u32 tx_airtime_ac[4 ];struct sk_buff_head psq;
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 8/15 wifi: mt76: mt7615: rely on shared poll_list field
In reply to Lorenzo BianconiRely on poll_list field in mt76_wcid structure and get rid of private copy.
--- drivers/net/wireless/mediatek/mt76/mt7615/mac.c | 12 ++++++------ drivers/net/wireless/mediatek/mt76/mt7615/main.c | 12 ++++++------ drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h | 1 - 3 files changed, 12 insertions(+), 13 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7615/mac.c +6 -6
@@ -388,8 +388,8 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb) msta = container_of(status->wcid, struct mt7615_sta, wcid);spin_lock_bh (&dev->mt76.sta_poll_lock); -if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, +if (list_empty (&msta->wcid.poll_list)) +list_add_tail (&msta->wcid.poll_list, &dev->mt76.sta_poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); }
@@ -914,10 +914,10 @@ void mt7615_mac_sta_poll(struct mt7615_dev *dev)bool clear = false; msta = list_first_entry(&sta_poll_list, struct mt7615_sta, - poll_list); + wcid.poll_list);spin_lock_bh (&dev->mt76.sta_poll_lock); -list_del_init (&msta->poll_list); +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); addr =mt7615_mac_wtbl_addr (dev, msta->wcid.idx) +19 *4 ;
@@ -1544,8 +1544,8 @@ static void mt7615_mac_add_txs(struct mt7615_dev *dev, void *data) sta =wcid_to_sta (wcid);spin_lock_bh (&dev->mt76.sta_poll_lock); -if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, &dev->mt76.sta_poll_list); +if (list_empty (&msta->wcid.poll_list)) +list_add_tail (&msta->wcid.poll_list, &dev->mt76.sta_poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock);if (mt7615_mac_add_txs_skb (dev, msta, pid, txs_data))
drivers/net/wireless/mediatek/mt76/mt7615/main.c +6 -6
@@ -222,7 +222,7 @@ static int mt7615_add_interface(struct ieee80211_hw *hw, idx =MT7615_WTBL_RESERVED - mvif->mt76.idx; -INIT_LIST_HEAD (&mvif->sta.poll_list); +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 ;
@@ -275,8 +275,8 @@ static void mt7615_remove_interface(struct ieee80211_hw *hw,mt7615_mutex_release (dev);spin_lock_bh (&dev->mt76.sta_poll_lock); -if (!list_empty (&msta->poll_list)) -list_del_init (&msta->poll_list); +if (!list_empty (&msta->wcid.poll_list)) +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock);mt76_packet_id_flush (&dev->mt76, &mvif->sta.wcid);
@@ -629,7 +629,7 @@ int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,if (idx <0 )return -ENOSPC ; -INIT_LIST_HEAD (&msta->poll_list); +INIT_LIST_HEAD (&msta->wcid.poll_list); msta->vif = mvif; msta->wcid.sta =1 ; msta->wcid.idx = idx;
@@ -678,8 +678,8 @@ void mt7615_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,mt7615_mcu_add_bss_info (phy, vif, sta, false);spin_lock_bh (&mdev->sta_poll_lock); -if (!list_empty (&msta->poll_list)) -list_del_init (&msta->poll_list); +if (!list_empty (&msta->wcid.poll_list)) +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&mdev->sta_poll_lock);mt76_connac_power_save_sched (phy->mt76, &dev->pm);
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +0 -1
@@ -125,7 +125,6 @@ struct mt7615_sta {struct mt7615_vif *vif; -struct list_head poll_list;u32 airtime_ac[8 ];struct ieee80211_tx_rate rates[4 ];
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 9/15 wifi: mt76: mt7996: rely on shared poll_list field
In reply to Lorenzo BianconiRely on poll_list field in mt76_wcid structure and get rid of private copy.
--- drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 16 ++++++++-------- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 12 ++++++------ .../net/wireless/mediatek/mt76/mt7996/mt7996.h | 1 - 3 files changed, 14 insertions(+), 15 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7996/mac.c +8 -8
@@ -130,8 +130,8 @@ static void mt7996_mac_sta_poll(struct mt7996_dev *dev)break ; } msta =list_first_entry (&sta_poll_list, - struct mt7996_sta, poll_list); -list_del_init (&msta->poll_list); + struct mt7996_sta, wcid.poll_list); +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); idx = msta->wcid.idx;
@@ -682,8 +682,8 @@ mt7996_mac_fill_rx(struct mt7996_dev *dev, struct sk_buff *skb) msta = container_of(status->wcid, struct mt7996_sta, wcid);spin_lock_bh (&dev->mt76.sta_poll_lock); -if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, +if (list_empty (&msta->wcid.poll_list)) +list_add_tail (&msta->wcid.poll_list, &dev->mt76.sta_poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); }
@@ -1288,8 +1288,8 @@ mt7996_mac_tx_free(struct mt7996_dev *dev, void *data, int len) msta = container_of(wcid, struct mt7996_sta, wcid);spin_lock_bh (&mdev->sta_poll_lock); -if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, +if (list_empty (&msta->wcid.poll_list)) +list_add_tail (&msta->wcid.poll_list, &mdev->sta_poll_list);spin_unlock_bh (&mdev->sta_poll_lock);continue ;
@@ -1497,8 +1497,8 @@ static void mt7996_mac_add_txs(struct mt7996_dev *dev, void *data) goto out;spin_lock_bh (&dev->mt76.sta_poll_lock); -if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, &dev->mt76.sta_poll_list); +if (list_empty (&msta->wcid.poll_list)) +list_add_tail (&msta->wcid.poll_list, &dev->mt76.sta_poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); out:
drivers/net/wireless/mediatek/mt76/mt7996/main.c +6 -6
@@ -200,7 +200,7 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, idx =MT7996_WTBL_RESERVED - mvif->mt76.idx;INIT_LIST_HEAD (&mvif->sta.rc_list); -INIT_LIST_HEAD (&mvif->sta.poll_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 ;
@@ -263,8 +263,8 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,mutex_unlock (&dev->mt76.mutex);spin_lock_bh (&dev->mt76.sta_poll_lock); -if (!list_empty (&msta->poll_list)) -list_del_init (&msta->poll_list); +if (!list_empty (&msta->wcid.poll_list)) +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock);mt76_packet_id_flush (&dev->mt76, &msta->wcid);
@@ -632,7 +632,7 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,return -ENOSPC ;INIT_LIST_HEAD (&msta->rc_list); -INIT_LIST_HEAD (&msta->poll_list); +INIT_LIST_HEAD (&msta->wcid.poll_list); msta->vif = mvif; msta->wcid.sta =1 ; msta->wcid.idx = idx;
@@ -668,8 +668,8 @@ void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,mt7996_mac_twt_teardown_flow (dev, msta, i);spin_lock_bh (&mdev->sta_poll_lock); -if (!list_empty (&msta->poll_list)) -list_del_init (&msta->poll_list); +if (!list_empty (&msta->wcid.poll_list)) +list_del_init (&msta->wcid.poll_list);if (!list_empty (&msta->rc_list))list_del_init (&msta->rc_list);spin_unlock_bh (&mdev->sta_poll_lock);
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +0 -1
@@ -95,7 +95,6 @@ struct mt7996_sta {struct mt7996_vif *vif; -struct list_head poll_list;struct list_head rc_list;u32 airtime_ac[8 ];
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 10/15 wifi: mt76: mt7921: rely on shared poll_list field
In reply to Lorenzo BianconiRely on poll_list field in mt76_wcid structure and get rid of private copy.
--- drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 16 ++++++++-------- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 12 ++++++------ .../net/wireless/mediatek/mt76/mt7921/mt7921.h | 1 - 3 files changed, 14 insertions(+), 15 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7921/mac.c +8 -8
@@ -84,8 +84,8 @@ static void mt7921_mac_sta_poll(struct mt7921_dev *dev)break ; } msta =list_first_entry (&sta_poll_list, - struct mt7921_sta, poll_list); -list_del_init (&msta->poll_list); + struct mt7921_sta, wcid.poll_list); +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); idx = msta->wcid.idx;
@@ -281,8 +281,8 @@ mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)if (status->wcid) { msta = container_of(status->wcid, struct mt7921_sta, wcid);spin_lock_bh (&dev->mt76.sta_poll_lock); -if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, +if (list_empty (&msta->wcid.poll_list)) +list_add_tail (&msta->wcid.poll_list, &dev->mt76.sta_poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); }
@@ -568,8 +568,8 @@ void mt7921_mac_add_txs(struct mt7921_dev *dev, void *data) goto out;spin_lock_bh (&dev->mt76.sta_poll_lock); -if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, &dev->mt76.sta_poll_list); +if (list_empty (&msta->wcid.poll_list)) +list_add_tail (&msta->wcid.poll_list, &dev->mt76.sta_poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock); out:
@@ -649,8 +649,8 @@ static void mt7921_mac_tx_free(struct mt7921_dev *dev, void *data, int len) msta = container_of(wcid, struct mt7921_sta, wcid);spin_lock_bh (&mdev->sta_poll_lock); -if (list_empty (&msta->poll_list)) -list_add_tail (&msta->poll_list, +if (list_empty (&msta->wcid.poll_list)) +list_add_tail (&msta->wcid.poll_list, &mdev->sta_poll_list);spin_unlock_bh (&mdev->sta_poll_lock);continue ;
drivers/net/wireless/mediatek/mt76/mt7921/main.c +6 -6
@@ -313,7 +313,7 @@ static int mt7921_add_interface(struct ieee80211_hw *hw, idx =MT7921_WTBL_RESERVED - mvif->mt76.idx; -INIT_LIST_HEAD (&mvif->sta.poll_list); +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 ;
@@ -358,8 +358,8 @@ static void mt7921_remove_interface(struct ieee80211_hw *hw,mt7921_mutex_release (dev);spin_lock_bh (&dev->mt76.sta_poll_lock); -if (!list_empty (&msta->poll_list)) -list_del_init (&msta->poll_list); +if (!list_empty (&msta->wcid.poll_list)) +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock);mt76_packet_id_flush (&dev->mt76, &msta->wcid);
@@ -765,7 +765,7 @@ int mt7921_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,if (idx <0 )return -ENOSPC ; -INIT_LIST_HEAD (&msta->poll_list); +INIT_LIST_HEAD (&msta->wcid.poll_list); msta->vif = mvif; msta->wcid.sta =1 ; msta->wcid.idx = idx;
@@ -844,8 +844,8 @@ void mt7921_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, }spin_lock_bh (&dev->mt76.sta_poll_lock); -if (!list_empty (&msta->poll_list)) -list_del_init (&msta->poll_list); +if (!list_empty (&msta->wcid.poll_list)) +list_del_init (&msta->wcid.poll_list);spin_unlock_bh (&dev->mt76.sta_poll_lock);mt76_connac_power_save_sched (&dev->mphy, &dev->pm);
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +0 -1
@@ -150,7 +150,6 @@ struct mt7921_sta {struct mt7921_vif *vif; -struct list_head poll_list;u32 airtime_ac[8 ];int ack_signal;
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 11/15 wifi: mt76: move ampdu_state in mt76_wcid
In reply to Lorenzo Bianconiampdu_state field is used by most of the drivers, so move it in mt76_wcid structure.
--- drivers/net/wireless/mediatek/mt76/mt76.h | 1 + drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7915/main.c | 6 +++--- drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h | 1 - drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7921/main.c | 6 +++--- drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h | 1 - drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 6 +++--- drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 1 - 10 files changed, 13 insertions(+), 15 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76.h +1 -0
@@ -316,6 +316,7 @@ struct mt76_wcid {int inactive_count;struct rate_info rate; +unsigned long ampdu_state;u16 idx;u8 hw_key_idx;
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +1 -1
@@ -863,7 +863,7 @@ mt7915_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)return ; msta = (struct mt7915_sta *)sta->drv_priv; -if (!test_and_set_bit (tid, &msta->ampdu_state)) +if (!test_and_set_bit (tid, &msta->wcid.ampdu_state))ieee80211_start_tx_ba_session (sta, tid,0 ); }
drivers/net/wireless/mediatek/mt76/mt7915/main.c +3 -3
@@ -802,16 +802,16 @@ mt7915_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,case IEEE80211_AMPDU_TX_STOP_FLUSH :case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT : mtxq->aggr = false; -clear_bit (tid, &msta->ampdu_state); +clear_bit (tid, &msta->wcid.ampdu_state); ret =mt7915_mcu_add_tx_ba (dev, params, false);break ;case IEEE80211_AMPDU_TX_START : -set_bit (tid, &msta->ampdu_state); +set_bit (tid, &msta->wcid.ampdu_state); ret =IEEE80211_AMPDU_TX_START_IMMEDIATE ;break ;case IEEE80211_AMPDU_TX_STOP_CONT : mtxq->aggr = false; -clear_bit (tid, &msta->ampdu_state); +clear_bit (tid, &msta->wcid.ampdu_state); ret =mt7915_mcu_add_tx_ba (dev, params, false);ieee80211_stop_tx_ba_cb_irqsafe (vif, sta->addr, tid);break ;
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +0 -1
@@ -137,7 +137,6 @@ struct mt7915_sta {unsigned long changed;unsigned long jiffies; -unsigned long ampdu_state;struct mt76_connac_sta_key_conf bip;struct {
drivers/net/wireless/mediatek/mt76/mt7921/mac.c +1 -1
@@ -531,7 +531,7 @@ static void mt7921_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)return ; msta = (struct mt7921_sta *)sta->drv_priv; -if (!test_and_set_bit (tid, &msta->ampdu_state)) +if (!test_and_set_bit (tid, &msta->wcid.ampdu_state))ieee80211_start_tx_ba_session (sta, tid,0 ); }
drivers/net/wireless/mediatek/mt76/mt7921/main.c +3 -3
@@ -955,16 +955,16 @@ mt7921_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,case IEEE80211_AMPDU_TX_STOP_FLUSH :case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT : mtxq->aggr = false; -clear_bit (tid, &msta->ampdu_state); +clear_bit (tid, &msta->wcid.ampdu_state);mt7921_mcu_uni_tx_ba (dev, params, false);break ;case IEEE80211_AMPDU_TX_START : -set_bit (tid, &msta->ampdu_state); +set_bit (tid, &msta->wcid.ampdu_state); ret =IEEE80211_AMPDU_TX_START_IMMEDIATE ;break ;case IEEE80211_AMPDU_TX_STOP_CONT : mtxq->aggr = false; -clear_bit (tid, &msta->ampdu_state); +clear_bit (tid, &msta->wcid.ampdu_state);mt7921_mcu_uni_tx_ba (dev, params, false);ieee80211_stop_tx_ba_cb_irqsafe (vif, sta->addr, tid);break ;
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +0 -1
@@ -156,7 +156,6 @@ struct mt7921_sta {struct ewma_avg_signal avg_ack_signal;unsigned long last_txs; -unsigned long ampdu_state;struct mt76_connac_sta_key_conf bip; };
drivers/net/wireless/mediatek/mt76/mt7996/mac.c +1 -1
@@ -1199,7 +1199,7 @@ mt7996_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)return ; msta = (struct mt7996_sta *)sta->drv_priv; -if (!test_and_set_bit (tid, &msta->ampdu_state)) +if (!test_and_set_bit (tid, &msta->wcid.ampdu_state))ieee80211_start_tx_ba_session (sta, tid,0 ); }
drivers/net/wireless/mediatek/mt76/mt7996/main.c +3 -3
@@ -752,16 +752,16 @@ mt7996_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,case IEEE80211_AMPDU_TX_STOP_FLUSH :case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT : mtxq->aggr = false; -clear_bit (tid, &msta->ampdu_state); +clear_bit (tid, &msta->wcid.ampdu_state); ret =mt7996_mcu_add_tx_ba (dev, params, false);break ;case IEEE80211_AMPDU_TX_START : -set_bit (tid, &msta->ampdu_state); +set_bit (tid, &msta->wcid.ampdu_state); ret =IEEE80211_AMPDU_TX_START_IMMEDIATE ;break ;case IEEE80211_AMPDU_TX_STOP_CONT : mtxq->aggr = false; -clear_bit (tid, &msta->ampdu_state); +clear_bit (tid, &msta->wcid.ampdu_state); ret =mt7996_mcu_add_tx_ba (dev, params, false);ieee80211_stop_tx_ba_cb_irqsafe (vif, sta->addr, tid);break ;
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +0 -1
@@ -103,7 +103,6 @@ struct mt7996_sta {unsigned long changed;unsigned long jiffies; -unsigned long ampdu_state;struct mt76_connac_sta_key_conf bip;
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 12/15 mt76: connac: move more mt7921/mt7915 mac shared code in connac lib
In reply to Lorenzo BianconiMove the following routines in mt76-connac lib since they are shared between mt7915 and mt7921:
- mt76_connac2_tx_check_aggr
- mt76_connac2_txwi_free
- mt76_connac2_tx_token_put
--- .../net/wireless/mediatek/mt76/mt76_connac.h | 5 + .../wireless/mediatek/mt76/mt76_connac_mac.c | 82 +++++++++++++++++ .../net/wireless/mediatek/mt76/mt7915/init.c | 2 +- .../net/wireless/mediatek/mt76/mt7915/mac.c | 91 +------------------ .../wireless/mediatek/mt76/mt7915/mt7915.h | 1 - .../net/wireless/mediatek/mt76/mt7921/mac.c | 62 +------------ .../wireless/mediatek/mt76/mt7921/mt7921.h | 4 - .../net/wireless/mediatek/mt76/mt7921/pci.c | 2 +- .../wireless/mediatek/mt76/mt7921/pci_mac.c | 16 +--- 9 files changed, 96 insertions(+), 169 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76_connac.h +5 -0
@@ -409,5 +409,10 @@ int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,struct mt76_rx_status *status, struct ieee80211_supported_band *sband, __le32 *rxv, u8 *mode); +void mt76_connac2_tx_check_aggr (struct ieee80211_sta *sta,__le32 *txwi); +void mt76_connac2_txwi_free (struct mt76_dev *dev,struct mt76_txwi_cache *t, +struct ieee80211_sta *sta, +struct list_head *free_list); +void mt76_connac2_tx_token_put (struct mt76_dev *dev);#endif /* __MT76_CONNAC_H */
drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +82 -0
85 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7915/init.c +1 -1
@@ -1158,7 +1158,7 @@ static void mt7915_unregister_ext_phy(struct mt7915_dev *dev)static void mt7915_stop_hardware (struct mt7915_dev *dev) {mt7915_mcu_exit (dev); -mt7915_tx_token_put (dev); +mt76_connac2_tx_token_put (&dev->mt76);mt7915_dma_cleanup (dev);tasklet_disable (&dev->mt76.irq_tasklet);
drivers/net/wireless/mediatek/mt76/mt7915/mac.c +4 -87
127 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +0 -1
@@ -608,7 +608,6 @@ int mt7915_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, enum mt76_txq_id qid, struct mt76_wcid *wcid, struct ieee80211_sta *sta, struct mt76_tx_info *tx_info); -void mt7915_tx_token_put (struct mt7915_dev *dev);void mt7915_queue_rx_skb (struct mt76_dev *mdev,enum mt76_rxq_id q,struct sk_buff *skb,u32 *info);bool mt7915_rx_check (struct mt76_dev *mdev,void *data,int len);
drivers/net/wireless/mediatek/mt76/mt7921/mac.c +2 -60
96 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +0 -4
@@ -471,7 +471,6 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, struct mt76_tx_info *tx_info);void mt7921_tx_worker (struct mt76_worker *w); -void mt7921_tx_token_put (struct mt7921_dev *dev);bool mt7921_rx_check (struct mt76_dev *mdev,void *data,int len);void mt7921_queue_rx_skb (struct mt76_dev *mdev,enum mt76_rxq_id q,struct sk_buff *skb,u32 *info);
@@ -504,9 +503,6 @@ int mt7921_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, void *data, int len);int mt7921_testmode_dump (struct ieee80211_hw *hw,struct sk_buff *msg,struct netlink_callback *cb,void *data,int len); -void mt7921_txwi_free (struct mt7921_dev *dev,struct mt76_txwi_cache *t, -struct ieee80211_sta *sta,bool clear_status, -struct list_head *free_list);int mt7921_mcu_parse_response (struct mt76_dev *mdev,int cmd,struct sk_buff *skb,int seq);
drivers/net/wireless/mediatek/mt76/mt7921/pci.c +1 -1
@@ -115,7 +115,7 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev)cancel_work_sync (&pm->wake_work);cancel_work_sync (&dev->reset_work); -mt7921_tx_token_put (dev); +mt76_connac2_tx_token_put (&dev->mt76);__mt7921_mcu_drv_pmctrl (dev);mt7921_dma_cleanup (dev);mt7921_wfsys_reset (dev);
drivers/net/wireless/mediatek/mt76/mt7921/pci_mac.c +1 -15
@@ -53,20 +53,6 @@ int mt7921e_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,return 0 ; } -void mt7921_tx_token_put (struct mt7921_dev *dev) -{ -struct mt76_txwi_cache *txwi; -int id; - -spin_lock_bh (&dev->mt76.token_lock); -idr_for_each_entry (&dev->mt76.token, txwi, id) { -mt7921_txwi_free (dev, txwi,NULL , false,NULL ); - dev->mt76.token_count--; - } -spin_unlock_bh (&dev->mt76.token_lock); -idr_destroy (&dev->mt76.token); -} -int mt7921e_mac_reset (struct mt7921_dev *dev) {int i, err;
@@ -91,7 +77,7 @@ int mt7921e_mac_reset(struct mt7921_dev *dev)napi_disable (&dev->mt76.napi[MT_RXQ_MCU_WA ]);napi_disable (&dev->mt76.tx_napi); -mt7921_tx_token_put (dev); +mt76_connac2_tx_token_put (&dev->mt76);idr_init (&dev->mt76.token);mt7921_wpdma_reset (dev, true);
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 13/15 wifi: mt76: move rate info in mt76_vif
In reply to Lorenzo BianconiThis is a preliminary patch to introduce mt76_connac3 mac library used by WiFi7 chipsets (e.g. mt7996).
--- drivers/net/wireless/mediatek/mt76/mt76.h | 3 +++ drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 10 +++++----- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 10 +++++----- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 2 +- drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 4 ---- 5 files changed, 14 insertions(+), 15 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76.h +3 -0
@@ -705,6 +705,9 @@ struct mt76_vif {u8 wmm_idx;u8 scan_seq_num;u8 cipher; +u8 basic_rates_idx; +u8 mcast_rates_idx; +u8 beacon_rates_idx; };struct mt76_phy {
drivers/net/wireless/mediatek/mt76/mt7996/mac.c +5 -5
@@ -1008,7 +1008,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 mt7996_vif *mvif; +struct mt76_vif *mvif;u16 tx_count =15 ;u32 val; bool beacon = !!(changed & (BSS_CHANGED_BEACON |
@@ -1016,11 +1016,11 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |BSS_CHANGED_FILS_DISCOVERY )); - mvif = vif ? (struct mt7996_vif *)vif->drv_priv :NULL ; + mvif = vif ? (struct mt76_vif *)vif->drv_priv :NULL ;if (mvif) { - omac_idx = mvif->mt76.omac_idx; - wmm_idx = mvif->mt76.wmm_idx; - band_idx = mvif->mt76.band_idx; + omac_idx = mvif->omac_idx; + wmm_idx = mvif->wmm_idx; + band_idx = mvif->band_idx; }if (inband_disc) {
drivers/net/wireless/mediatek/mt76/mt7996/main.c +5 -5
@@ -221,9 +221,9 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, vif->offload_flags |=IEEE80211_OFFLOAD_ENCAP_4ADDR ;if (phy->mt76->chandef.chan->band !=NL80211_BAND_2GHZ ) - mvif->basic_rates_idx =MT7996_BASIC_RATES_TBL +4 ; + mvif->mt76.basic_rates_idx =MT7996_BASIC_RATES_TBL +4 ;else - mvif->basic_rates_idx =MT7996_BASIC_RATES_TBL ; + mvif->mt76.basic_rates_idx =MT7996_BASIC_RATES_TBL ;mt7996_init_bitrate_mask (vif);
@@ -506,7 +506,7 @@ static u8 mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, bool beacon, bool mcast) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;struct mt76_phy *mphy = hw->priv;u16 rate;u8 i, idx, ht;
@@ -518,7 +518,7 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,struct mt7996_dev *dev =mt7996_hw_dev (hw);/* must odd index */ - idx =MT7996_BEACON_RATES_TBL +2 * (mvif->mt76.idx %20 ); + idx =MT7996_BEACON_RATES_TBL +2 * (mvif->idx %20 );mt7996_mac_set_fixed_rate_table (dev, idx, rate);return idx; }
@@ -536,7 +536,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_bss_conf *info, u64 changed) { -struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; +struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;struct mt7996_phy *phy =mt7996_hw_phy (hw);struct mt7996_dev *dev =mt7996_hw_dev (hw);
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +1 -1
@@ -600,7 +600,7 @@ static void mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif, struct mt7996_phy *phy) { - struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; + struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;struct bss_rate_tlv *bmc;struct cfg80211_chan_def *chandef = &phy->mt76->chandef;enum nl80211_band band = chandef->chan->band;
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +0 -4
@@ -120,10 +120,6 @@ struct mt7996_vif {struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS ];struct cfg80211_bitrate_mask bitrate_mask; - -u8 basic_rates_idx; -u8 mcast_rates_idx; -u8 beacon_rates_idx; };/* per-phy stats. */
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 14/15 wifi: mt76: connac: move connac3 definitions in mt76_connac3_mac.h
In reply to Lorenzo BianconiConnac3 mac definitions are shared between WiFi7 chipsets so move them in mt76_connac3_mac.h
--- .../wireless/mediatek/mt76/mt76_connac3_mac.h | 325 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7996/mac.h | 315 +---------------- 2 files changed, 326 insertions(+), 314 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h new file +325 -0
@@ -0,0 +1,325 @@ +/* SPDX-License-Identifier: ISC */ +/* Copyright (C) 2023 MediaTek Inc. */ + +#ifndef __MT76_CONNAC3_MAC_H +#define __MT76_CONNAC3_MAC_H + +#define MT_CT_PARSE_LEN 72 +#define MT_CT_DMA_BUF_NUM 2 + +#define MT_RXD0_LENGTH GENMASK(15, 0) +#define MT_RXD0_PKT_FLAG GENMASK(19, 16) +#define MT_RXD0_PKT_TYPE GENMASK(31, 27) + +#define MT_RXD0_MESH BIT(18) +#define MT_RXD0_MHCP BIT(19) +#define MT_RXD0_NORMAL_ETH_TYPE_OFS GENMASK(22, 16) +#define MT_RXD0_NORMAL_IP_SUM BIT(23) +#define MT_RXD0_NORMAL_UDP_TCP_SUM BIT(24) + +#define MT_RXD0_SW_PKT_TYPE_MASK GENMASK(31, 16) +#define MT_RXD0_SW_PKT_TYPE_MAP 0x380F +#define MT_RXD0_SW_PKT_TYPE_FRAME 0x3801 + +/* RXD DW1 */ +#define MT_RXD1_NORMAL_WLAN_IDX GENMASK(11, 0) +#define MT_RXD1_NORMAL_GROUP_1 BIT(16) +#define MT_RXD1_NORMAL_GROUP_2 BIT(17) +#define MT_RXD1_NORMAL_GROUP_3 BIT(18) +#define MT_RXD1_NORMAL_GROUP_4 BIT(19) +#define MT_RXD1_NORMAL_GROUP_5 BIT(20) +#define MT_RXD1_NORMAL_KEY_ID GENMASK(22, 21) +#define MT_RXD1_NORMAL_CM BIT(23) +#define MT_RXD1_NORMAL_CLM BIT(24) +#define MT_RXD1_NORMAL_ICV_ERR BIT(25) +#define MT_RXD1_NORMAL_TKIP_MIC_ERR BIT(26) +#define MT_RXD1_NORMAL_BAND_IDX GENMASK(28, 27) +#define MT_RXD1_NORMAL_SPP_EN BIT(29) +#define MT_RXD1_NORMAL_ADD_OM BIT(30) +#define MT_RXD1_NORMAL_SEC_DONE BIT(31) + +/* RXD DW2 */ +#define MT_RXD2_NORMAL_BSSID GENMASK(5, 0) +#define MT_RXD2_NORMAL_MAC_HDR_LEN GENMASK(12, 8) +#define MT_RXD2_NORMAL_HDR_TRANS BIT(7) +#define MT_RXD2_NORMAL_HDR_OFFSET GENMASK(15, 13) +#define MT_RXD2_NORMAL_SEC_MODE GENMASK(20, 16) +#define MT_RXD2_NORMAL_MU_BAR BIT(21) +#define MT_RXD2_NORMAL_SW_BIT BIT(22) +#define MT_RXD2_NORMAL_AMSDU_ERR BIT(23) +#define MT_RXD2_NORMAL_MAX_LEN_ERROR BIT(24) +#define MT_RXD2_NORMAL_HDR_TRANS_ERROR BIT(25) +#define MT_RXD2_NORMAL_INT_FRAME BIT(26) +#define MT_RXD2_NORMAL_FRAG BIT(27) +#define MT_RXD2_NORMAL_NULL_FRAME BIT(28) +#define MT_RXD2_NORMAL_NDATA BIT(29) +#define MT_RXD2_NORMAL_NON_AMPDU BIT(30) +#define MT_RXD2_NORMAL_BF_REPORT BIT(31) + +/* RXD DW3 */ +#define MT_RXD3_NORMAL_RXV_SEQ GENMASK(7, 0) +#define MT_RXD3_NORMAL_CH_FREQ GENMASK(15, 8) +#define MT_RXD3_NORMAL_ADDR_TYPE GENMASK(17, 16) +#define MT_RXD3_NORMAL_U2M BIT(0) +#define MT_RXD3_NORMAL_HTC_VLD BIT(18) +#define MT_RXD3_NORMAL_BEACON_MC BIT(20) +#define MT_RXD3_NORMAL_BEACON_UC BIT(21) +#define MT_RXD3_NORMAL_CO_ANT BIT(22) +#define MT_RXD3_NORMAL_FCS_ERR BIT(24) +#define MT_RXD3_NORMAL_VLAN2ETH BIT(31) + +/* RXD DW4 */ +#define MT_RXD4_NORMAL_PAYLOAD_FORMAT GENMASK(1, 0) +#define MT_RXD4_FIRST_AMSDU_FRAME GENMASK(1, 0) +#define MT_RXD4_MID_AMSDU_FRAME BIT(1) +#define MT_RXD4_LAST_AMSDU_FRAME BIT(0) + +#define MT_RXV_HDR_BAND_IDX BIT(24) + +/* RXD GROUP4 */ +#define MT_RXD8_FRAME_CONTROL GENMASK(15, 0) + +#define MT_RXD10_SEQ_CTRL GENMASK(15, 0) +#define MT_RXD10_QOS_CTL GENMASK(31, 16) + +#define MT_RXD11_HT_CONTROL GENMASK(31, 0) + +/* P-RXV */ +#define MT_PRXV_TX_RATE GENMASK(6, 0) +#define MT_PRXV_TX_DCM BIT(4) +#define MT_PRXV_TX_ER_SU_106T BIT(5) +#define MT_PRXV_NSTS GENMASK(10, 7) +#define MT_PRXV_TXBF BIT(11) +#define MT_PRXV_HT_AD_CODE BIT(12) +#define MT_PRXV_HE_RU_ALLOC GENMASK(30, 22) +#define MT_PRXV_RCPI3 GENMASK(31, 24) +#define MT_PRXV_RCPI2 GENMASK(23, 16) +#define MT_PRXV_RCPI1 GENMASK(15, 8) +#define MT_PRXV_RCPI0 GENMASK(7, 0) +#define MT_PRXV_HT_SHORT_GI GENMASK(4, 3) +#define MT_PRXV_HT_STBC GENMASK(10, 9) +#define MT_PRXV_TX_MODE GENMASK(14, 11) +#define MT_PRXV_FRAME_MODE GENMASK(2, 0) +#define MT_PRXV_DCM BIT(5) + +/* C-RXV */ +#define MT_CRXV_HE_NUM_USER GENMASK(26, 20) +#define MT_CRXV_HE_LTF_SIZE GENMASK(28, 27) +#define MT_CRXV_HE_LDPC_EXT_SYM BIT(30) + +#define MT_CRXV_HE_PE_DISAMBIG BIT(1) +#define MT_CRXV_HE_UPLINK BIT(2) + +#define MT_CRXV_HE_MU_AID GENMASK(27, 17) +#define MT_CRXV_HE_BEAM_CHNG BIT(29) + +#define MT_CRXV_HE_DOPPLER BIT(0) +#define MT_CRXV_HE_BSS_COLOR GENMASK(15, 10) +#define MT_CRXV_HE_TXOP_DUR GENMASK(19, 17) + +#define MT_CRXV_HE_SR_MASK GENMASK(11, 8) +#define MT_CRXV_HE_SR1_MASK GENMASK(16, 12) +#define MT_CRXV_HE_SR2_MASK GENMASK(20, 17) +#define MT_CRXV_HE_SR3_MASK GENMASK(24, 21) + +#define MT_CRXV_HE_RU0 GENMASK(8, 0) +#define MT_CRXV_HE_RU1 GENMASK(17, 9) +#define MT_CRXV_HE_RU2 GENMASK(26, 18) +#define MT_CRXV_HE_RU3_L GENMASK(31, 27) +#define MT_CRXV_HE_RU3_H GENMASK(3, 0) + +enum tx_header_format { +MT_HDR_FORMAT_802_3 , +MT_HDR_FORMAT_CMD , +MT_HDR_FORMAT_802_11 , +MT_HDR_FORMAT_802_11_EXT , +}; + +enum tx_pkt_type { +MT_TX_TYPE_CT , +MT_TX_TYPE_SF , +MT_TX_TYPE_CMD , +MT_TX_TYPE_FW , +}; + +enum tx_port_idx { +MT_TX_PORT_IDX_LMAC , +MT_TX_PORT_IDX_MCU +}; + +enum tx_mcu_port_q_idx { +MT_TX_MCU_PORT_RX_Q0 =0x20 , +MT_TX_MCU_PORT_RX_Q1 , +MT_TX_MCU_PORT_RX_Q2 , +MT_TX_MCU_PORT_RX_Q3 , +MT_TX_MCU_PORT_RX_FWDL =0x3e +}; + +enum tx_mgnt_type { +MT_TX_NORMAL , +MT_TX_TIMING , +MT_TX_ADDBA , +}; + +#define MT_CT_INFO_APPLY_TXD BIT(0) +#define MT_CT_INFO_COPY_HOST_TXD_ALL BIT(1) +#define MT_CT_INFO_MGMT_FRAME BIT(2) +#define MT_CT_INFO_NONE_CIPHER_FRAME BIT(3) +#define MT_CT_INFO_HSR2_TX BIT(4) +#define MT_CT_INFO_FROM_HOST BIT(7) + +#define MT_TXD_SIZE (8 * 4) + +#define MT_TXD0_Q_IDX GENMASK(31, 25) +#define MT_TXD0_PKT_FMT GENMASK(24, 23) +#define MT_TXD0_ETH_TYPE_OFFSET GENMASK(22, 16) +#define MT_TXD0_TX_BYTES GENMASK(15, 0) + +#define MT_TXD1_FIXED_RATE BIT(31) +#define MT_TXD1_OWN_MAC GENMASK(30, 25) +#define MT_TXD1_TID GENMASK(24, 21) +#define MT_TXD1_BIP BIT(24) +#define MT_TXD1_ETH_802_3 BIT(20) +#define MT_TXD1_HDR_INFO GENMASK(20, 16) +#define MT_TXD1_HDR_FORMAT GENMASK(15, 14) +#define MT_TXD1_TGID GENMASK(13, 12) +#define MT_TXD1_WLAN_IDX GENMASK(11, 0) + +#define MT_TXD2_POWER_OFFSET GENMASK(31, 26) +#define MT_TXD2_MAX_TX_TIME GENMASK(25, 16) +#define MT_TXD2_FRAG GENMASK(15, 14) +#define MT_TXD2_HTC_VLD BIT(13) +#define MT_TXD2_DURATION BIT(12) +#define MT_TXD2_HDR_PAD GENMASK(11, 10) +#define MT_TXD2_RTS BIT(9) +#define MT_TXD2_OWN_MAC_MAP BIT(8) +#define MT_TXD2_BF_TYPE GENMASK(6, 7) +#define MT_TXD2_FRAME_TYPE GENMASK(5, 4) +#define MT_TXD2_SUB_TYPE GENMASK(3, 0) + +#define MT_TXD3_SN_VALID BIT(31) +#define MT_TXD3_PN_VALID BIT(30) +#define MT_TXD3_SW_POWER_MGMT BIT(29) +#define MT_TXD3_BA_DISABLE BIT(28) +#define MT_TXD3_SEQ GENMASK(27, 16) +#define MT_TXD3_REM_TX_COUNT GENMASK(15, 11) +#define MT_TXD3_TX_COUNT GENMASK(10, 6) +#define MT_TXD3_HW_AMSDU BIT(5) +#define MT_TXD3_BCM BIT(4) +#define MT_TXD3_EEOSP BIT(3) +#define MT_TXD3_EMRD BIT(2) +#define MT_TXD3_PROTECT_FRAME BIT(1) +#define MT_TXD3_NO_ACK BIT(0) + +#define MT_TXD4_PN_LOW GENMASK(31, 0) + +#define MT_TXD5_PN_HIGH GENMASK(31, 16) +#define MT_TXD5_FL BIT(15) +#define MT_TXD5_BYPASS_TBB BIT(14) +#define MT_TXD5_BYPASS_RBB BIT(13) +#define MT_TXD5_BSS_COLOR_ZERO BIT(12) +#define MT_TXD5_TX_STATUS_HOST BIT(10) +#define MT_TXD5_TX_STATUS_MCU BIT(9) +#define MT_TXD5_TX_STATUS_FMT BIT(8) +#define MT_TXD5_PID GENMASK(7, 0) + +#define MT_TXD6_TX_SRC GENMASK(31, 30) +#define MT_TXD6_VTA BIT(28) +#define MT_TXD6_BW GENMASK(25, 22) +#define MT_TXD6_TX_RATE GENMASK(21, 16) +#define MT_TXD6_TIMESTAMP_OFS_EN BIT(15) +#define MT_TXD6_TIMESTAMP_OFS_IDX GENMASK(14, 10) +#define MT_TXD6_MSDU_CNT GENMASK(9, 4) +#define MT_TXD6_DIS_MAT BIT(3) +#define MT_TXD6_DAS BIT(2) +#define MT_TXD6_AMSDU_CAP BIT(1) + +#define MT_TXD7_TXD_LEN GENMASK(31, 30) +#define MT_TXD7_IP_SUM BIT(29) +#define MT_TXD7_DROP_BY_SDO BIT(28) +#define MT_TXD7_MAC_TXD BIT(27) +#define MT_TXD7_CTXD BIT(26) +#define MT_TXD7_CTXD_CNT GENMASK(25, 22) +#define MT_TXD7_UDP_TCP_SUM BIT(15) +#define MT_TXD7_TX_TIME GENMASK(9, 0) + +#define MT_TX_RATE_STBC BIT(14) +#define MT_TX_RATE_NSS GENMASK(13, 10) +#define MT_TX_RATE_MODE GENMASK(9, 6) +#define MT_TX_RATE_SU_EXT_TONE BIT(5) +#define MT_TX_RATE_DCM BIT(4) +/* VHT/HE only use bits 0-3 */ +#define MT_TX_RATE_IDX GENMASK(5, 0) + +#define MT_TXFREE0_PKT_TYPE GENMASK(31, 27) +#define MT_TXFREE0_MSDU_CNT GENMASK(25, 16) +#define MT_TXFREE0_RX_BYTE GENMASK(15, 0) + +#define MT_TXFREE1_VER GENMASK(18, 16) + +#define MT_TXFREE_INFO_PAIR BIT(31) +#define MT_TXFREE_INFO_HEADER BIT(30) +#define MT_TXFREE_INFO_WLAN_ID GENMASK(23, 12) +#define MT_TXFREE_INFO_MSDU_ID GENMASK(14, 0) +#define MT_TXFREE_INFO_COUNT GENMASK(27, 24) +#define MT_TXFREE_INFO_STAT GENMASK(29, 28) + +#define MT_TXS0_BW GENMASK(31, 29) +#define MT_TXS0_TID GENMASK(28, 26) +#define MT_TXS0_AMPDU BIT(25) +#define MT_TXS0_TXS_FORMAT GENMASK(24, 23) +#define MT_TXS0_BA_ERROR BIT(22) +#define MT_TXS0_PS_FLAG BIT(21) +#define MT_TXS0_TXOP_TIMEOUT BIT(20) +#define MT_TXS0_BIP_ERROR BIT(19) + +#define MT_TXS0_QUEUE_TIMEOUT BIT(18) +#define MT_TXS0_RTS_TIMEOUT BIT(17) +#define MT_TXS0_ACK_TIMEOUT BIT(16) +#define MT_TXS0_ACK_ERROR_MASK GENMASK(18, 16) + +#define MT_TXS0_TX_STATUS_HOST BIT(15) +#define MT_TXS0_TX_STATUS_MCU BIT(14) +#define MT_TXS0_TX_RATE GENMASK(13, 0) + +#define MT_TXS1_SEQNO GENMASK(31, 20) +#define MT_TXS1_RESP_RATE GENMASK(19, 16) +#define MT_TXS1_RXV_SEQNO GENMASK(15, 8) +#define MT_TXS1_TX_POWER_DBM GENMASK(7, 0) + +#define MT_TXS2_BF_STATUS GENMASK(31, 30) +#define MT_TXS2_BAND GENMASK(29, 28) +#define MT_TXS2_WCID GENMASK(27, 16) +#define MT_TXS2_TX_DELAY GENMASK(15, 0) + +#define MT_TXS3_PID GENMASK(31, 24) +#define MT_TXS3_RATE_STBC BIT(7) +#define MT_TXS3_FIXED_RATE BIT(6) +#define MT_TXS3_SRC GENMASK(5, 4) +#define MT_TXS3_SHARED_ANTENNA BIT(3) +#define MT_TXS3_LAST_TX_RATE GENMASK(2, 0) + +#define MT_TXS4_TIMESTAMP GENMASK(31, 0) + +#define MT_TXS5_F0_FINAL_MPDU BIT(31) +#define MT_TXS5_F0_QOS BIT(30) +#define MT_TXS5_F0_TX_COUNT GENMASK(29, 25) +#define MT_TXS5_F0_FRONT_TIME GENMASK(24, 0) +#define MT_TXS5_F1_MPDU_TX_COUNT GENMASK(31, 24) +#define MT_TXS5_F1_MPDU_TX_BYTES GENMASK(23, 0) + +#define MT_TXS6_F0_NOISE_3 GENMASK(31, 24) +#define MT_TXS6_F0_NOISE_2 GENMASK(23, 16) +#define MT_TXS6_F0_NOISE_1 GENMASK(15, 8) +#define MT_TXS6_F0_NOISE_0 GENMASK(7, 0) +#define MT_TXS6_F1_MPDU_FAIL_COUNT GENMASK(31, 24) +#define MT_TXS6_F1_MPDU_FAIL_BYTES GENMASK(23, 0) + +#define MT_TXS7_F0_RCPI_3 GENMASK(31, 24) +#define MT_TXS7_F0_RCPI_2 GENMASK(23, 16) +#define MT_TXS7_F0_RCPI_1 GENMASK(15, 8) +#define MT_TXS7_F0_RCPI_0 GENMASK(7, 0) +#define MT_TXS7_F1_MPDU_RETRY_COUNT GENMASK(31, 24) +#define MT_TXS7_F1_MPDU_RETRY_BYTES GENMASK(23, 0) + +#endif /* __MT76_CONNAC3_MAC_H */
drivers/net/wireless/mediatek/mt76/mt7996/mac.h +1 -314
321 lines not on this page · raw message
Signature · 1 line
2.40.1
Lorenzo Bianconi
maintainerPATCH v2 15/15 wifi: mt76: connac: add connac3 mac library
In reply to Lorenzo BianconiIntroduce connac3_mac in mt76_connac library to reuse mac code shared between WiFi7 chipsets.
--- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76_connac.h | 19 + .../wireless/mediatek/mt76/mt76_connac3_mac.c | 742 +++++++++++++++++ .../wireless/mediatek/mt76/mt76_connac3_mac.h | 18 + .../net/wireless/mediatek/mt76/mt7996/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 761 +----------------- .../net/wireless/mediatek/mt76/mt7996/main.c | 8 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +- .../wireless/mediatek/mt76/mt7996/mt7996.h | 28 +- 9 files changed, 807 insertions(+), 784 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
drivers/net/wireless/mediatek/mt76/Makefile +1 -1
@@ -27,7 +27,7 @@ mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \ mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o -mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o +mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o mt76_connac3_mac.o obj-$(CONFIG_MT76x0_COMMON) += mt76x0/ obj-$(CONFIG_MT76x2_COMMON) += mt76x2/
drivers/net/wireless/mediatek/mt76/mt76_connac.h +19 -0
@@ -415,4 +415,23 @@ void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t, struct list_head *free_list);void mt76_connac2_tx_token_put (struct mt76_dev *dev); +/* connac3 */ +void mt76_connac3_tx_check_aggr (struct ieee80211_sta *sta,__le32 *txwi); +void mt76_connac3_mac_decode_he_radiotap (struct sk_buff *skb,__le32 *rxv, +u8 mode); +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, +struct ieee80211_supported_band *sband, +__le32 *rxv,u8 *mode); +void mt76_connac3_mac_write_txwi (struct mt76_dev *dev,__le32 *txwi, +struct sk_buff *skb,struct mt76_wcid *wcid, +struct ieee80211_key_conf *key,int pid, +enum mt76_txq_id qid,u32 changed); +void mt76_connac3_txwi_free (struct mt76_dev *dev,struct mt76_txwi_cache *t, +struct ieee80211_sta *sta, +struct list_head *free_list); +void mt76_connac3_mac_add_txs (struct mt76_dev *dev,void *data, +u32 max_wtbl_size); +void mt76_connac3_tx_token_put (struct mt76_dev *dev); +#endif /* __MT76_CONNAC_H */
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +742 -0
742 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +18 -0
@@ -4,6 +4,24 @@#ifndef __MT76_CONNAC3_MAC_H#define __MT76_CONNAC3_MAC_H +/* NOTE: used to map mt76_rates. idx may change if firmware expands table */ +#define MT76_CONNAC3_BASIC_RATES_TBL 11 +#define MT76_CONNAC3_BEACON_RATES_TBL 25 + +enum { +MT_CTX0 , +MT_HIF0 =0x0 , + +MT_LMAC_AC00 =0x0 , +MT_LMAC_AC01 , +MT_LMAC_AC02 , +MT_LMAC_AC03 , +MT_LMAC_ALTX0 =0x10 , +MT_LMAC_BMC0 , +MT_LMAC_BCN0 , +MT_LMAC_PSMP0 , +}; +#define MT_CT_PARSE_LEN 72#define MT_CT_DMA_BUF_NUM 2
drivers/net/wireless/mediatek/mt76/mt7996/init.c +2 -2
@@ -262,7 +262,7 @@ static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)for (i =0 ; i <ARRAY_SIZE (mt76_rates); i++) {u16 rate = mt76_rates[i].hw_value; -u16 idx =MT7996_BASIC_RATES_TBL + i; +u16 idx =MT76_CONNAC3_BASIC_RATES_TBL + i; rate =FIELD_PREP (MT_TX_RATE_MODE , rate >>8 ) |FIELD_PREP (MT_TX_RATE_IDX , rate &GENMASK (7 ,0 ));
@@ -903,7 +903,7 @@ void mt7996_unregister_device(struct mt7996_dev *dev)mt7996_coredump_unregister (dev);mt76_unregister_device (&dev->mt76);mt7996_mcu_exit (dev); -mt7996_tx_token_put (dev); +mt76_connac3_tx_token_put (&dev->mt76);mt7996_dma_cleanup (dev);tasklet_disable (&dev->mt76.irq_tasklet);
drivers/net/wireless/mediatek/mt76/mt7996/mac.c +12 -749
851 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7996/main.c +4 -4
@@ -221,9 +221,9 @@ static int mt7996_add_interface(struct ieee80211_hw *hw, 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 ; + mvif->mt76.basic_rates_idx =MT76_CONNAC3_BASIC_RATES_TBL +4 ;else - mvif->mt76.basic_rates_idx =MT7996_BASIC_RATES_TBL ; + mvif->mt76.basic_rates_idx =MT76_CONNAC3_BASIC_RATES_TBL ;mt7996_init_bitrate_mask (vif);
@@ -518,7 +518,7 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif,struct mt7996_dev *dev =mt7996_hw_dev (hw);/* must odd index */ - idx =MT7996_BEACON_RATES_TBL +2 * (mvif->idx %20 ); + idx =MT76_CONNAC3_BEACON_RATES_TBL +2 * (mvif->idx %20 );mt7996_mac_set_fixed_rate_table (dev, idx, rate);return idx; }
@@ -526,7 +526,7 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, idx =FIELD_GET (MT_TX_RATE_IDX , rate);for (i =0 ; i <ARRAY_SIZE (mt76_rates); i++)if ((mt76_rates[i].hw_value &GENMASK (7 ,0 )) == idx) -return MT7996_BASIC_RATES_TBL + i; +return MT76_CONNAC3_BASIC_RATES_TBL + i;return mvif->basic_rates_idx; }
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +5 -4
@@ -1912,8 +1912,8 @@ mt7996_mcu_beacon_cont(struct mt7996_dev *dev, struct ieee80211_vif *vif, } buf = (u8 *)bcn +sizeof (*bcn) -MAX_BEACON_SIZE ; -mt7996_mac_write_txwi (dev, (__le32 *)buf, skb, wcid,NULL ,0 ,0 , -BSS_CHANGED_BEACON ); +mt76_connac3_mac_write_txwi (&dev->mt76, (__le32 *)buf, skb, wcid,NULL , +0 ,0 ,BSS_CHANGED_BEACON );memcpy (buf +MT_TXD_SIZE , skb->data, skb->len); }
@@ -2024,7 +2024,8 @@ int mt7996_mcu_beacon_inband_discov(struct mt7996_dev *dev, buf = (u8 *)tlv +sizeof (*discov) -MAX_INBAND_FRAME_SIZE ; -mt7996_mac_write_txwi (dev, (__le32 *)buf, skb, wcid,NULL ,0 ,0 , changed); +mt76_connac3_mac_write_txwi (&dev->mt76, (__le32 *)buf, skb, wcid, +NULL ,0 ,0 , changed);memcpy (buf +MT_TXD_SIZE , skb->data, skb->len);
@@ -2575,7 +2576,7 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif) e = (struct edca *)tlv; e->set =WMM_PARAM_SET ; - e->queue = ac + mvif->mt76.wmm_idx *MT7996_MAX_WMM_SETS ; + e->queue = ac + mvif->mt76.wmm_idx *MT76_CONNAC_MAX_WMM_SETS ; e->aifs = q->aifs; e->txop =cpu_to_le16 (q->txop);
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +4 -24
@@ -12,7 +12,6 @@#include "regs.h" #define MT7996_MAX_INTERFACES 19/* per-band */ -#define MT7996_MAX_WMM_SETS 4#define MT7996_WTBL_RESERVED (mt7996_wtbl_size(dev) - 1)#define MT7996_WTBL_STA (MT7996_WTBL_RESERVED - \ mt7996_max_interface_num(dev))
@@ -43,10 +42,6 @@#define MT7996_MAX_STA_TWT_AGRT 8#define MT7996_MAX_QUEUE (__MT_RXQ_MAX + __MT_MCUQ_MAX + 3) -/* NOTE: used to map mt76_rates. idx may change if firmware expands table */ -#define MT7996_BASIC_RATES_TBL 11 -#define MT7996_BEACON_RATES_TBL 25 -struct mt7996_vif ;struct mt7996_sta ;struct mt7996_dfs_pulse ;
@@ -300,20 +295,6 @@ enum { __MT_WFDMA_MAX, }; -enum { -MT_CTX0 , -MT_HIF0 =0x0 , - -MT_LMAC_AC00 =0x0 , -MT_LMAC_AC01 , -MT_LMAC_AC02 , -MT_LMAC_AC03 , -MT_LMAC_ALTX0 =0x10 , -MT_LMAC_BMC0 , -MT_LMAC_BCN0 , -MT_LMAC_PSMP0 , -}; -enum {MT_RX_SEL0 ,MT_RX_SEL1 ,
@@ -505,10 +486,10 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev, struct ieee80211_vif *vif, bool enable);void mt7996_mac_set_fixed_rate_table (struct mt7996_dev *dev,u8 tbl_idx,u16 rate_idx); -void mt7996_mac_write_txwi (struct mt7996_dev *dev,__le32 *txwi, -struct sk_buff *skb,struct mt76_wcid *wcid, -struct ieee80211_key_conf *key,int pid, -enum mt76_txq_id qid,u32 changed); +void mt76_connac3_mac_write_txwi (struct mt76_dev *dev,__le32 *txwi, +struct sk_buff *skb,struct mt76_wcid *wcid, +struct ieee80211_key_conf *key,int pid, +enum mt76_txq_id qid,u32 changed);void mt7996_mac_set_timing (struct mt7996_phy *phy);int mt7996_mac_sta_add (struct mt76_dev *mdev,struct ieee80211_vif *vif,struct ieee80211_sta *sta);
@@ -529,7 +510,6 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr, enum mt76_txq_id qid, struct mt76_wcid *wcid, struct ieee80211_sta *sta, struct mt76_tx_info *tx_info); -void mt7996_tx_token_put (struct mt7996_dev *dev);void mt7996_queue_rx_skb (struct mt76_dev *mdev,enum mt76_rxq_id q,struct sk_buff *skb,u32 *info);bool mt7996_rx_check (struct mt76_dev *mdev,void *data,int len);
Signature · 1 line
2.40.1
Ryder Lee
maintainerRe: [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library
Quoted 882 lines · Lorenzo Bianconi
External email : Please do not click links or open attachments until you have verified the sender or the content.
Introduceconnac3_macinmt76_connaclibrary to reuse mac code
shared
between WiFi7 chipsets.Signed-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76_connac.h | 19 + .../wireless/mediatek/mt76/mt76_connac3_mac.c | 742 +++++++++++++++++ .../wireless/mediatek/mt76/mt76_connac3_mac.h | 18 + .../net/wireless/mediatek/mt76/mt7996/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 761 +--------------- -- .../net/wireless/mediatek/mt76/mt7996/main.c | 8 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +- .../wireless/mediatek/mt76/mt7996/mt7996.h | 28 +- 9 files changed, 807 insertions(+), 784 deletions(-) create mode 100644
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cdrivers/net/wireless/mediatek/mt76/Makefile +1
-1@@ -27,7 +27,7 @@ mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \ mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o -mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o +mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.omt76_connac3_mac.o
obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
obj-$(CONFIG_MT76x2_COMMON) += mt76x2/drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0@@ -415,4 +415,23 @@ void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t, struct list_head *free_list);void mt76_connac2_tx_token_put (struct mt76_dev *dev); +/* connac3 */ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta, __le32*txwi);
+void mt76_connac3_mac_decode_he_radiotap(structsk_buff*skb,__le32*rxv,drivers/net/wireless/mediatek/mt76/mt76_connac.h +4
-0+ u8 mode); +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+ __le32 *rxv, u8 *mode); +void mt76_connac3_mac_write_txwi (struct mt76_dev *dev,__le32 *txwi, + struct sk_buff *skb, struct mt76_wcid*wcid,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+struct ieee80211_key_conf *key, intpid,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ enum mt76_txq_id qid, u32 changed); +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac.h +6
-0+struct ieee80211_sta *sta, + struct list_head *free_list); +void mt76_connac3_mac_add_txs (struct mt76_dev *dev,void *data, +u32 max_wtbl_size); +void mt76_connac3_tx_token_put (struct mt76_dev *dev); +#endif /* __MT76_CONNAC_H */ drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0@@ -0,0 +1,742 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include "mt76_connac.h" +#include "mt76_connac3_mac.h" +#include "dma.h" + +#define HE_BITS (f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f) +#define HE_PREP (f, m, v) le16_encode_bits(le32_get_bits(v,MT_CRXV_HE_##m),\
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+IEEE80211_RADIOTAP_HE_ ##f)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta, __le32*txwi)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+{ + struct mt76_wcid *wcid; + u16 fc, tid; + u32 val; + + if (!sta || + !(sta->deflink.ht_cap.ht_supported || sta-Quoted 1 line
deflink.he_cap.has_he))
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + + tid =le32_get_bits (txwi[1 ],MT_TXD1_TID ); +if (tid >=6 )/* skip VO queue */ +return ; + + val =le32_to_cpu (txwi[2 ]); + fc =FIELD_GET (MT_TXD2_FRAME_TYPE , val) <<2 | +FIELD_GET (MT_TXD2_SUB_TYPE , val) <<4 ; + if (unlikely(fc != (IEEE80211_FTYPE_DATA |
IEEE80211_STYPE_QOS_DATA)))drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + + wcid = (struct mt76_wcid *)sta->drv_priv; +if (!test_and_set_bit (tid, &wcid->ampdu_state)) +ieee80211_start_tx_ba_session (sta, tid,0 ); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_check_aggr); + +static void +mt76_connac3_mac_decode_he_radiotap_ru(struct mt76_rx_status*status,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+struct ieee80211_radiotap_he *he,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +39
-0+ __le32 *rxv) +{ +u32 ru =le32_get_bits (rxv[0 ],MT_PRXV_HE_RU_ALLOC ), offs =0 ; + + status->bw =RATE_INFO_BW_HE_RU ; + +switch (ru) { + case 0 ... 36: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_26 ; + offs = ru; +break ; + case 37 ... 52: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_52 ; + offs = ru -37 ; +break ; + case 53 ... 60: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_106 ; + offs = ru -53 ; +break ; + case 61 ... 64: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_242 ; + offs = ru -61 ; +break ; + case 65 ... 66: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_484 ; + offs = ru -65 ; +break ; +case 67 : + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_996 ; +break ; +case 68 : + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; +break ; + } + + he->data1 |=HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + he->data2 |=HE_BITS (DATA2_RU_OFFSET_KNOWN ) | +le16_encode_bits (offs, + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+} + +#define MU_PREP (f, v) le16_encode_bits(v,IEEE80211_RADIOTAP_HE_MU_##f)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+static void +mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32*rxv)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ + struct mt76_rx_status *status = (struct mt76_rx_status *)skb-Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+static const struct ieee80211_radiotap_he_mu mu_known = { + .flags1 =HE_BITS (MU_FLAGS1_SIG_B_MCS_KNOWN ) | +HE_BITS (MU_FLAGS1_SIG_B_DCM_KNOWN ) | +HE_BITS (MU_FLAGS1_CH1_RU_KNOWN ) | +HE_BITS (MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN ), + .flags2 =HE_BITS (MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN ), + }; +struct ieee80211_radiotap_he_mu *he_mu; + + status->flag |=RX_FLAG_RADIOTAP_HE_MU ; + + he_mu =skb_push (skb,sizeof (mu_known)); +memcpy (he_mu, &mu_known,sizeof (mu_known)); + + he_mu->flags1 |=MU_PREP (FLAGS1_SIG_B_MCS , status->rate_idx); +if (status->he_dcm) + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status-Quoted 1 line
he_dcm);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ + he_mu->flags2 |=MU_PREP (FLAGS2_BW_FROM_SIG_A_BW , status->bw) | + MU_PREP(FLAGS2_SIG_B_SYMS_USERS, + le32_get_bits(rxv[4],
MT_CRXV_HE_NUM_USER));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) &
0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ +if (status->bw >=RATE_INFO_BW_40 ) { + he_mu->flags1 |=HE_BITS (MU_FLAGS1_CH2_RU_KNOWN ); + he_mu->ru_ch2[0] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU1) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ } + +if (status->bw >=RATE_INFO_BW_80 ) { +u32 ru_h, ru_l; + + he_mu->ru_ch1[1] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU2) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+ + ru_l =le32_get_bits (rxv[16 ],MT_CRXV_HE_RU3_L ); + ru_h =le32_get_bits (rxv[17 ],MT_CRXV_HE_RU3_H ) &0x7 ; + he_mu->ru_ch2[1 ] = (u8)(ru_l | ru_h <<4 ); + } +} + +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb, __le32*rxv,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ u8 mode) +{ + struct mt76_rx_status *status = (struct mt76_rx_status *)skb-Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +28
-0+static const struct ieee80211_radiotap_he known = { + .data1 =HE_BITS (DATA1_DATA_MCS_KNOWN ) | +HE_BITS (DATA1_DATA_DCM_KNOWN ) | +HE_BITS (DATA1_STBC_KNOWN ) | +HE_BITS (DATA1_CODING_KNOWN ) | +HE_BITS (DATA1_LDPC_XSYMSEG_KNOWN ) | +HE_BITS (DATA1_DOPPLER_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE_KNOWN ) | +HE_BITS (DATA1_BSS_COLOR_KNOWN ), + .data2 =HE_BITS (DATA2_GI_KNOWN ) | +HE_BITS (DATA2_TXBF_KNOWN ) | +HE_BITS (DATA2_PE_DISAMBIG_KNOWN ) | +HE_BITS (DATA2_TXOP_KNOWN ), + }; +u32 ltf_size =le32_get_bits (rxv[4 ],MT_CRXV_HE_LTF_SIZE ) +1 ; +struct ieee80211_radiotap_he *he; + + status->flag |=RX_FLAG_RADIOTAP_HE ; + + he =skb_push (skb,sizeof (known)); +memcpy (he, &known,sizeof (known)); + + he->data3 =HE_PREP (DATA3_BSS_COLOR ,BSS_COLOR , rxv[9 ]) | +HE_PREP (DATA3_LDPC_XSYMSEG ,LDPC_EXT_SYM , rxv[4 ]); + he->data4 =HE_PREP (DATA4_SU_MU_SPTL_REUSE ,SR_MASK , rxv[13 ]); + he->data5 =HE_PREP (DATA5_PE_DISAMBIG ,PE_DISAMBIG , rxv[5 ]) | +le16_encode_bits (ltf_size, + IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+if (le32_to_cpu (rxv[0 ]) &MT_PRXV_TXBF ) + he->data5 |=HE_BITS (DATA5_TXBF ); + he->data6 =HE_PREP (DATA6_TXOP ,TXOP_DUR , rxv[9 ]) | +HE_PREP (DATA6_DOPPLER ,DOPPLER , rxv[9 ]); + +switch (mode) { +case MT_PHY_TYPE_HE_SU : + he->data1 |=HE_BITS (DATA1_FORMAT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BEAM_CHANGE_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + + he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG,rxv[8]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_EXT_SU : + he->data1 |=HE_BITS (DATA1_FORMAT_EXT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + + he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_MU : + he->data1 |=HE_BITS (DATA1_FORMAT_MU ) | +HE_BITS (DATA1_UL_DL_KNOWN ); + + he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); + he->data4 |=HE_PREP (DATA4_MU_STA_ID ,MU_AID , rxv[8 ]); + + mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+mt76_connac3_mac_decode_he_mu_radiotap (skb, rxv); +break ; +case MT_PHY_TYPE_HE_TB : + he->data1 |=HE_BITS (DATA1_FORMAT_TRIG ) | +HE_BITS (DATA1_SPTL_REUSE2_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE3_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE4_KNOWN ); + + he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK,rxv[13]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK,rxv[13]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK,rxv[13]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK,rxv[13]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+break ; +default : +break ; + } +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_decode_he_radiotap); + +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +119
-0+ __le32 *rxv, u8 *mode) +{ +u8 stbc, gi, bw, dcm, nss; +bool cck = false; +u32 v0, v2; +int i, idx; + + v0 =le32_to_cpu (rxv[0 ]); + v2 =le32_to_cpu (rxv[2 ]); + + idx =FIELD_GET (MT_PRXV_TX_RATE , v0); + i = idx; + nss =FIELD_GET (MT_PRXV_NSTS , v0) +1 ; + + stbc =FIELD_GET (MT_PRXV_HT_STBC , v2); + gi =FIELD_GET (MT_PRXV_HT_SHORT_GI , v2); + *mode =FIELD_GET (MT_PRXV_TX_MODE , v2); + dcm =FIELD_GET (MT_PRXV_DCM , v2); + bw =FIELD_GET (MT_PRXV_FRAME_MODE , v2); + +switch (*mode) { +case MT_PHY_TYPE_CCK : + cck = true; + fallthrough; +case MT_PHY_TYPE_OFDM : + i =mt76_get_rate (dev, sband, i, cck); +break ; +case MT_PHY_TYPE_HT_GF : +case MT_PHY_TYPE_HT : + status->encoding =RX_ENC_HT ; +if (gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >31 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_VHT : + status->nss = nss; + status->encoding =RX_ENC_VHT ; +if (gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >11 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_HE_MU : +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : + status->nss = nss; + status->encoding =RX_ENC_HE ; + i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_HE_GI_3_2 ) + status->he_gi = gi; + + status->he_dcm = dcm; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : + status->nss = nss; + status->encoding =RX_ENC_EHT ; + i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_EHT_GI_3_2 ) + status->eht.gi = gi; +break ; +default : +return -EINVAL ; + } + status->rate_idx = i; + +switch (bw) { +case IEEE80211_STA_RX_BW_20 : +break ; +case IEEE80211_STA_RX_BW_40 : +if (*mode &MT_PHY_TYPE_HE_EXT_SU && + (idx &MT_PRXV_TX_ER_SU_106T )) { + status->bw =RATE_INFO_BW_HE_RU ; + status->he_ru = +NL80211_RATE_INFO_HE_RU_ALLOC_106 ; + }else { + status->bw =RATE_INFO_BW_40 ; + } +break ; +case IEEE80211_STA_RX_BW_80 : + status->bw =RATE_INFO_BW_80 ; +break ; +case IEEE80211_STA_RX_BW_160 : + status->bw =RATE_INFO_BW_160 ; +break ; +case IEEE80211_STA_RX_BW_320 : + status->bw =RATE_INFO_BW_320 ; +break ; +default : +return -EINVAL ; + } + + status->enc_flags |=RX_ENC_FLAG_STBC_MASK * stbc; +if (*mode <MT_PHY_TYPE_HE_SU && gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; + +return 0 ; +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_fill_rx_rate); + +static void +mt76_connac3_mac_write_txwi_8023 (__le32 *txwi,struct sk_buff *skb, +struct mt76_wcid *wcid) +{ +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +u8 fc_type, fc_stype; +u16 ethertype; +bool wmm = false; +u32 val; + +if (wcid->sta) { +struct ieee80211_sta *sta; + + sta = container_of((void *)wcid, struct ieee80211_sta,
drv_priv);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +23
-0+ wmm = sta->wme; + } + + val =FIELD_PREP (MT_TXD1_HDR_FORMAT ,MT_HDR_FORMAT_802_3 ) | +FIELD_PREP (MT_TXD1_TID , tid); + + ethertype =get_unaligned_be16 (&skb->data[12 ]); +if (ethertype >=ETH_P_802_3_MIN ) + val |=MT_TXD1_ETH_802_3 ; + + txwi[1 ] |=cpu_to_le32 (val); + + fc_type =IEEE80211_FTYPE_DATA >>2 ; + fc_stype = wmm ?IEEE80211_STYPE_QOS_DATA >>4 :0 ; + + val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + + txwi[2 ] |=cpu_to_le32 (val); +} + +static void +mt76_connac3_mac_write_txwi_80211(struct mt76_dev *dev, __le32*txwi,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+struct sk_buff *skb, + struct ieee80211_key_conf *key) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb-Quoted 1 line
data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +bool multicast =is_multicast_ether_addr (hdr->addr1); +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +__le16 fc = hdr->frame_control; +u8 fc_type, fc_stype; +u32 val; + +if (ieee80211_is_action (fc) && + mgmt->u.action.category ==WLAN_CATEGORY_BACK && + mgmt->u.action.u.addba_req.action_code ==
WLAN_ACTION_ADDBA_REQ)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +47
-0+ tid =MT_TX_ADDBA ; + else if (ieee80211_is_mgmt(hdr->frame_control)) + tid =MT_TX_NORMAL ; + + val =FIELD_PREP (MT_TXD1_HDR_FORMAT ,MT_HDR_FORMAT_802_11 ) | +FIELD_PREP (MT_TXD1_HDR_INFO , +ieee80211_get_hdrlen_from_skb (skb) /2 ) | +FIELD_PREP (MT_TXD1_TID , tid); + +if (!ieee80211_is_data (fc) || multicast || + info->flags &IEEE80211_TX_CTL_USE_MINRATE ) + val |=MT_TXD1_FIXED_RATE ; + +if (key && multicast &&ieee80211_is_robust_mgmt_frame (skb) && + key->cipher ==WLAN_CIPHER_SUITE_AES_CMAC ) { + val |=MT_TXD1_BIP ; + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_PROTECT_FRAME ); + } + + txwi[1 ] |=cpu_to_le32 (val); + + fc_type = (le16_to_cpu (fc) &IEEE80211_FCTL_FTYPE ) >>2 ; + fc_stype = (le16_to_cpu (fc) &IEEE80211_FCTL_STYPE ) >>4 ; + + val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + + txwi[2 ] |=cpu_to_le32 (val); + + txwi[3 ] |=cpu_to_le32 (FIELD_PREP (MT_TXD3_BCM , multicast)); +if (ieee80211_is_beacon (fc)) { + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_SW_POWER_MGMT ); + txwi[3 ] |=cpu_to_le32 (MT_TXD3_REM_TX_COUNT ); + } + +if (info->flags &IEEE80211_TX_CTL_INJECTED ) { +u16 seqno =le16_to_cpu (hdr->seq_ctrl); + +if (ieee80211_is_back_req (hdr->frame_control)) { +struct ieee80211_bar *bar; + + bar = (struct ieee80211_bar *)skb->data; + seqno =le16_to_cpu (bar->start_seq_num); + } + + val =MT_TXD3_SN_VALID | + FIELD_PREP(MT_TXD3_SEQ,
IEEE80211_SEQ_TO_SN(seqno));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+ txwi[3 ] |=cpu_to_le32 (val); + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_HW_AMSDU ); + } +} + +void mt76_connac3_mac_write_txwi (struct mt76_dev *dev,__le32 *txwi, + struct sk_buff *skb, struct mt76_wcid*wcid,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+struct ieee80211_key_conf *key, intpid,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ enum mt76_txq_id qid, u32 changed) +{ + u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE :
MT_SDIO_TXD_SIZE;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +struct ieee80211_vif *vif = info->control.vif; +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; +u16 tx_count =15 ; +bool beacon = !!(changed & (BSS_CHANGED_BEACON | +BSS_CHANGED_BEACON_ENABLED )); + bool inband_disc = !!(changed &(
BSS_CHANGED_UNSOL_BCAST_PROBE_RESP|drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+ BSS_CHANGED_FILS_DISCOVERY)); + + mvif = vif ? (struct mt76_vif *)vif->drv_priv :NULL ; +if (mvif) { + omac_idx = mvif->omac_idx; + wmm_idx = mvif->wmm_idx; + band_idx = mvif->band_idx; + } + +if (inband_disc) { + p_fmt =MT_TX_TYPE_FW ; + q_idx =MT_LMAC_ALTX0 ; + }else if (beacon) { + p_fmt =MT_TX_TYPE_FW ; + q_idx =MT_LMAC_BCN0 ; + }else if (qid >=MT_TXQ_PSD ) { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ q_idx =MT_LMAC_ALTX0 ; + }else { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ q_idx = wmm_idx *MT76_CONNAC_MAX_WMM_SETS + + mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +45
-0+ } + + val =FIELD_PREP (MT_TXD0_TX_BYTES , skb->len + sz_txd) | +FIELD_PREP (MT_TXD0_PKT_FMT , p_fmt) | +FIELD_PREP (MT_TXD0_Q_IDX , q_idx); + txwi[0 ] =cpu_to_le32 (val); + + val =FIELD_PREP (MT_TXD1_WLAN_IDX , wcid->idx) | +FIELD_PREP (MT_TXD1_OWN_MAC , omac_idx); + +if (band_idx) + val |=FIELD_PREP (MT_TXD1_TGID , band_idx); + + txwi[1 ] =cpu_to_le32 (val); + txwi[2 ] =0 ; + + val =MT_TXD3_SW_POWER_MGMT | +FIELD_PREP (MT_TXD3_REM_TX_COUNT , tx_count); +if (key) + val |=MT_TXD3_PROTECT_FRAME ; +if (info->flags &IEEE80211_TX_CTL_NO_ACK ) + val |=MT_TXD3_NO_ACK ; +if (wcid->amsdu) + val |=MT_TXD3_HW_AMSDU ; + + txwi[3 ] =cpu_to_le32 (val); + txwi[4 ] =0 ; + + val =FIELD_PREP (MT_TXD5_PID , pid); +if (pid >=MT_PACKET_ID_FIRST ) + val |=MT_TXD5_TX_STATUS_HOST ; + txwi[5 ] =cpu_to_le32 (val); + + val =MT_TXD6_DIS_MAT |MT_TXD6_DAS | +FIELD_PREP (MT_TXD6_MSDU_CNT ,1 ); + txwi[6 ] =cpu_to_le32 (val); + txwi[7 ] =0 ; + +if (is_8023) +mt76_connac3_mac_write_txwi_8023 (txwi, skb, wcid); +else +mt76_connac3_mac_write_txwi_80211 (dev, txwi, skb, key); + +if (txwi[1 ] &cpu_to_le32 (MT_TXD1_FIXED_RATE )) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr*)skb->data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +14
-0+bool mcast =ieee80211_is_data (hdr->frame_control) && +is_multicast_ether_addr (hdr->addr1); +u8 idx =MT76_CONNAC3_BASIC_RATES_TBL ; + +if (mvif) { +if (mcast && mvif->mcast_rates_idx) + idx = mvif->mcast_rates_idx; +else if (beacon && mvif->beacon_rates_idx) + idx = mvif->beacon_rates_idx; +else + idx = mvif->basic_rates_idx; + } + + txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE,idx));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ txwi[3 ] |=cpu_to_le32 (MT_TXD3_BA_DISABLE ); + } +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_write_txwi); + +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+struct ieee80211_sta *sta, + struct list_head *free_list) +{ + __le32 *txwi; +u16 wcid_idx; + +mt76_connac_txp_skb_unmap (dev, t); +if (!t->skb) + goto out; + + txwi = (__le32 *)mt76_get_txwi_ptr (dev, t); +if (sta) { + struct mt76_wcid *wcid = (struct mt76_wcid *)sta-Quoted 1 line
drv_priv;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+ + wcid_idx = wcid->idx; +if (likely (t->skb->protocol !=cpu_to_be16 (ETH_P_PAE ))) +mt76_connac3_tx_check_aggr (sta, txwi); + }else { + wcid_idx =le32_get_bits (txwi[1 ],MT_TXD1_WLAN_IDX ); + } + +__mt76_tx_complete_skb (dev, wcid_idx, t->skb, free_list); +out: + t->skb =NULL ; +mt76_put_txwi (dev, t); +} +EXPORT_SYMBOL_GPL (mt76_connac3_txwi_free); + +static bool +mt76_connac3_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid*wcid,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +58
-0+ int pid, __le32 *txs_data) +{ + struct mt76_sta_stats *stats = &wcid->stats; +struct ieee80211_supported_band *sband; +struct ieee80211_tx_info *info; +u32 txrate, txs, mode, stbc; +struct rate_info rate = {}; +struct sk_buff_head list; +struct mt76_phy *mphy; +struct sk_buff *skb; +bool cck = false; + +mt76_tx_status_lock (dev, &list); + skb =mt76_tx_status_skb_get (dev, wcid, pid, &list); +if (!skb) + goto out_no_skb; + + txs =le32_to_cpu (txs_data[0 ]); + + info =IEEE80211_SKB_CB (skb); +if (!(txs &MT_TXS0_ACK_ERROR_MASK )) + info->flags |=IEEE80211_TX_STAT_ACK ; + + info->status.ampdu_len =1 ; + info->status.ampdu_ack_len = !!(info->flags & +IEEE80211_TX_STAT_ACK ); + info->status.rates[0 ].idx =-1 ; + + txrate =FIELD_GET (MT_TXS0_TX_RATE , txs); + + rate.mcs =FIELD_GET (MT_TX_RATE_IDX , txrate); + rate.nss =FIELD_GET (MT_TX_RATE_NSS , txrate) +1 ; + stbc =le32_get_bits (txs_data[3 ],MT_TXS3_RATE_STBC ); + +if (stbc && rate.nss >1 ) + rate.nss >>=1 ; + +if (rate.nss -1 <ARRAY_SIZE (stats->tx_nss)) + stats->tx_nss[rate.nss -1 ]++; +if (rate.mcs <ARRAY_SIZE (stats->tx_mcs)) + stats->tx_mcs[rate.mcs]++; + + mode =FIELD_GET (MT_TX_RATE_MODE , txrate); + switch (mode) { + case MT_PHY_TYPE_CCK: + cck = true; + fallthrough; + case MT_PHY_TYPE_OFDM: + mphy = mt76_dev_phy(dev, wcid->phy_idx); + + if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) + sband = &mphy->sband_5g.sband; + else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ) + sband = &mphy->sband_6g.sband; + else + sband = &mphy->sband_2g.sband; + + rate.mcs = mt76_get_rate(mphy->dev, sband, rate.mcs,cck);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +130
-0+ rate.legacy = sband->bitrates[rate.mcs].bitrate; +break ; +case MT_PHY_TYPE_HT : +case MT_PHY_TYPE_HT_GF : +if (rate.mcs >31 ) + goto out; + + rate.flags =RATE_INFO_FLAGS_MCS ; +if (wcid->rate.flags &RATE_INFO_FLAGS_SHORT_GI ) + rate.flags |=RATE_INFO_FLAGS_SHORT_GI ; +break ; +case MT_PHY_TYPE_VHT : +if (rate.mcs >9 ) + goto out; + + rate.flags =RATE_INFO_FLAGS_VHT_MCS ; +break ; +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : +case MT_PHY_TYPE_HE_MU : +if (rate.mcs >11 ) + goto out; + + rate.he_gi = wcid->rate.he_gi; + rate.he_dcm =FIELD_GET (MT_TX_RATE_DCM , txrate); + rate.flags =RATE_INFO_FLAGS_HE_MCS ; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : +if (rate.mcs >13 ) + goto out; + + rate.eht_gi = wcid->rate.eht_gi; + rate.flags =RATE_INFO_FLAGS_EHT_MCS ; +break ; +default : + goto out; + } + + stats->tx_mode[mode]++; + +switch (FIELD_GET (MT_TXS0_BW , txs)) { +case IEEE80211_STA_RX_BW_320 : + rate.bw =RATE_INFO_BW_320 ; + stats->tx_bw[4 ]++; +break ; +case IEEE80211_STA_RX_BW_160 : + rate.bw =RATE_INFO_BW_160 ; + stats->tx_bw[3 ]++; +break ; +case IEEE80211_STA_RX_BW_80 : + rate.bw =RATE_INFO_BW_80 ; + stats->tx_bw[2 ]++; +break ; +case IEEE80211_STA_RX_BW_40 : + rate.bw =RATE_INFO_BW_40 ; + stats->tx_bw[1 ]++; +break ; +default : + rate.bw =RATE_INFO_BW_20 ; + stats->tx_bw[0 ]++; +break ; + } + wcid->rate = rate; + +out: +mt76_tx_status_skb_done (dev, skb, &list); + +out_no_skb: +mt76_tx_status_unlock (dev, &list); + +return !!skb; +} + +void mt76_connac3_mac_add_txs (struct mt76_dev *dev,void *data, +u32 max_wtbl_size) +{ +struct mt76_wcid *wcid; +__le32 *txs_data = data; +u16 wcidx; +u8 pid; + +if (le32_get_bits (txs_data[0 ],MT_TXS0_TXS_FORMAT ) >1 ) +return ; + + wcidx =le32_get_bits (txs_data[2 ],MT_TXS2_WCID ); + pid =le32_get_bits (txs_data[3 ],MT_TXS3_PID ); + +if (pid <MT_PACKET_ID_FIRST ) +return ; + +if (wcidx >= max_wtbl_size) +return ; + +rcu_read_lock (); + + wcid =rcu_dereference (dev->wcid[wcidx]); +if (!wcid) + goto out; + +mt76_connac3_mac_add_txs_skb (dev, wcid, pid, txs_data); +if (!wcid->sta) + goto out; + +spin_lock_bh (&dev->sta_poll_lock); +if (list_empty (&wcid->poll_list)) +list_add_tail (&wcid->poll_list, &dev->sta_poll_list); +spin_unlock_bh (&dev->sta_poll_lock); + +out: +rcu_read_unlock (); +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_add_txs); + +void mt76_connac3_tx_token_put (struct mt76_dev *dev) +{ +struct mt76_txwi_cache *txwi; +int id; + +spin_lock_bh (&dev->token_lock); +idr_for_each_entry (&dev->token, txwi, id) { +mt76_connac3_txwi_free (dev, txwi,NULL ,NULL ); + dev->token_count--; + } +spin_unlock_bh (&dev->token_lock); +idr_destroy (&dev->token); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_token_put);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +1
-0@@ -4,6 +4,24 @@#ifndef __MT76_CONNAC3_MAC_H#define __MT76_CONNAC3_MAC_H +/* NOTE: used to map mt76_rates. idx may change if firmware expands table */
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h line 9
Quoted 2 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +2
-0+#define MT76_CONNAC3_BASIC_RATES_TBL 11 +#define MT76_CONNAC3_BEACON_RATES_TBL 25
Different devices may have different defined value.
I'm thinking if it's too early to create this patch for just moving mt7996 to connac3_lib?
Ryder
Re: [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library
Quoted 880 lines · Ryder Lee
Quoted 879 lines · Lorenzo Bianconi
External email : Please do not click links or open attachments until you have verified the sender or the content.
Introduceconnac3_macinmt76_connaclibrary to reuse mac code
shared
between WiFi7 chipsets.Signed-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76_connac.h | 19 + .../wireless/mediatek/mt76/mt76_connac3_mac.c | 742 +++++++++++++++++ .../wireless/mediatek/mt76/mt76_connac3_mac.h | 18 + .../net/wireless/mediatek/mt76/mt7996/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 761 +--------------- -- .../net/wireless/mediatek/mt76/mt7996/main.c | 8 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +- .../wireless/mediatek/mt76/mt7996/mt7996.h | 28 +- 9 files changed, 807 insertions(+), 784 deletions(-) create mode 100644
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cdrivers/net/wireless/mediatek/mt76/Makefile +1
-1@@ -27,7 +27,7 @@ mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \ mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o -mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o +mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.omt76_connac3_mac.o
obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
obj-$(CONFIG_MT76x2_COMMON) += mt76x2/drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0@@ -415,4 +415,23 @@ void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t, struct list_head *free_list);void mt76_connac2_tx_token_put (struct mt76_dev *dev); +/* connac3 */ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta, __le32*txwi);
+void mt76_connac3_mac_decode_he_radiotap(structsk_buff*skb,__le32*rxv,drivers/net/wireless/mediatek/mt76/mt76_connac.h +4
-0+ u8 mode); +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+ __le32 *rxv, u8 *mode); +void mt76_connac3_mac_write_txwi (struct mt76_dev *dev,__le32 *txwi, + struct sk_buff *skb, struct mt76_wcid*wcid,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+struct ieee80211_key_conf *key, intpid,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ enum mt76_txq_id qid, u32 changed); +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac.h +6
-0+struct ieee80211_sta *sta, + struct list_head *free_list); +void mt76_connac3_mac_add_txs (struct mt76_dev *dev,void *data, +u32 max_wtbl_size); +void mt76_connac3_tx_token_put (struct mt76_dev *dev); +#endif /* __MT76_CONNAC_H */ drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0@@ -0,0 +1,742 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include "mt76_connac.h" +#include "mt76_connac3_mac.h" +#include "dma.h" + +#define HE_BITS (f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f) +#define HE_PREP (f, m, v) le16_encode_bits(le32_get_bits(v,MT_CRXV_HE_##m),\
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+IEEE80211_RADIOTAP_HE_ ##f)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta, __le32*txwi)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+{ + struct mt76_wcid *wcid; + u16 fc, tid; + u32 val; + + if (!sta || + !(sta->deflink.ht_cap.ht_supported || sta-Quoted 1 line
deflink.he_cap.has_he))
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + + tid =le32_get_bits (txwi[1 ],MT_TXD1_TID ); +if (tid >=6 )/* skip VO queue */ +return ; + + val =le32_to_cpu (txwi[2 ]); + fc =FIELD_GET (MT_TXD2_FRAME_TYPE , val) <<2 | +FIELD_GET (MT_TXD2_SUB_TYPE , val) <<4 ; + if (unlikely(fc != (IEEE80211_FTYPE_DATA |
IEEE80211_STYPE_QOS_DATA)))drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + + wcid = (struct mt76_wcid *)sta->drv_priv; +if (!test_and_set_bit (tid, &wcid->ampdu_state)) +ieee80211_start_tx_ba_session (sta, tid,0 ); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_check_aggr); + +static void +mt76_connac3_mac_decode_he_radiotap_ru(struct mt76_rx_status*status,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+struct ieee80211_radiotap_he *he,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +39
-0+ __le32 *rxv) +{ +u32 ru =le32_get_bits (rxv[0 ],MT_PRXV_HE_RU_ALLOC ), offs =0 ; + + status->bw =RATE_INFO_BW_HE_RU ; + +switch (ru) { + case 0 ... 36: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_26 ; + offs = ru; +break ; + case 37 ... 52: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_52 ; + offs = ru -37 ; +break ; + case 53 ... 60: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_106 ; + offs = ru -53 ; +break ; + case 61 ... 64: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_242 ; + offs = ru -61 ; +break ; + case 65 ... 66: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_484 ; + offs = ru -65 ; +break ; +case 67 : + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_996 ; +break ; +case 68 : + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; +break ; + } + + he->data1 |=HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + he->data2 |=HE_BITS (DATA2_RU_OFFSET_KNOWN ) | +le16_encode_bits (offs, + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+} + +#define MU_PREP (f, v) le16_encode_bits(v,IEEE80211_RADIOTAP_HE_MU_##f)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+static void +mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff *skb, __le32*rxv)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ + struct mt76_rx_status *status = (struct mt76_rx_status *)skb-Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+static const struct ieee80211_radiotap_he_mu mu_known = { + .flags1 =HE_BITS (MU_FLAGS1_SIG_B_MCS_KNOWN ) | +HE_BITS (MU_FLAGS1_SIG_B_DCM_KNOWN ) | +HE_BITS (MU_FLAGS1_CH1_RU_KNOWN ) | +HE_BITS (MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN ), + .flags2 =HE_BITS (MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN ), + }; +struct ieee80211_radiotap_he_mu *he_mu; + + status->flag |=RX_FLAG_RADIOTAP_HE_MU ; + + he_mu =skb_push (skb,sizeof (mu_known)); +memcpy (he_mu, &mu_known,sizeof (mu_known)); + + he_mu->flags1 |=MU_PREP (FLAGS1_SIG_B_MCS , status->rate_idx); +if (status->he_dcm) + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status-Quoted 1 line
he_dcm);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ + he_mu->flags2 |=MU_PREP (FLAGS2_BW_FROM_SIG_A_BW , status->bw) | + MU_PREP(FLAGS2_SIG_B_SYMS_USERS, + le32_get_bits(rxv[4],
MT_CRXV_HE_NUM_USER));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) &
0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ +if (status->bw >=RATE_INFO_BW_40 ) { + he_mu->flags1 |=HE_BITS (MU_FLAGS1_CH2_RU_KNOWN ); + he_mu->ru_ch2[0] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU1) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ } + +if (status->bw >=RATE_INFO_BW_80 ) { +u32 ru_h, ru_l; + + he_mu->ru_ch1[1] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU2) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+ + ru_l =le32_get_bits (rxv[16 ],MT_CRXV_HE_RU3_L ); + ru_h =le32_get_bits (rxv[17 ],MT_CRXV_HE_RU3_H ) &0x7 ; + he_mu->ru_ch2[1 ] = (u8)(ru_l | ru_h <<4 ); + } +} + +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb, __le32*rxv,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ u8 mode) +{ + struct mt76_rx_status *status = (struct mt76_rx_status *)skb-Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +28
-0+static const struct ieee80211_radiotap_he known = { + .data1 =HE_BITS (DATA1_DATA_MCS_KNOWN ) | +HE_BITS (DATA1_DATA_DCM_KNOWN ) | +HE_BITS (DATA1_STBC_KNOWN ) | +HE_BITS (DATA1_CODING_KNOWN ) | +HE_BITS (DATA1_LDPC_XSYMSEG_KNOWN ) | +HE_BITS (DATA1_DOPPLER_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE_KNOWN ) | +HE_BITS (DATA1_BSS_COLOR_KNOWN ), + .data2 =HE_BITS (DATA2_GI_KNOWN ) | +HE_BITS (DATA2_TXBF_KNOWN ) | +HE_BITS (DATA2_PE_DISAMBIG_KNOWN ) | +HE_BITS (DATA2_TXOP_KNOWN ), + }; +u32 ltf_size =le32_get_bits (rxv[4 ],MT_CRXV_HE_LTF_SIZE ) +1 ; +struct ieee80211_radiotap_he *he; + + status->flag |=RX_FLAG_RADIOTAP_HE ; + + he =skb_push (skb,sizeof (known)); +memcpy (he, &known,sizeof (known)); + + he->data3 =HE_PREP (DATA3_BSS_COLOR ,BSS_COLOR , rxv[9 ]) | +HE_PREP (DATA3_LDPC_XSYMSEG ,LDPC_EXT_SYM , rxv[4 ]); + he->data4 =HE_PREP (DATA4_SU_MU_SPTL_REUSE ,SR_MASK , rxv[13 ]); + he->data5 =HE_PREP (DATA5_PE_DISAMBIG ,PE_DISAMBIG , rxv[5 ]) | +le16_encode_bits (ltf_size, + IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+if (le32_to_cpu (rxv[0 ]) &MT_PRXV_TXBF ) + he->data5 |=HE_BITS (DATA5_TXBF ); + he->data6 =HE_PREP (DATA6_TXOP ,TXOP_DUR , rxv[9 ]) | +HE_PREP (DATA6_DOPPLER ,DOPPLER , rxv[9 ]); + +switch (mode) { +case MT_PHY_TYPE_HE_SU : + he->data1 |=HE_BITS (DATA1_FORMAT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BEAM_CHANGE_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + + he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG,rxv[8]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_EXT_SU : + he->data1 |=HE_BITS (DATA1_FORMAT_EXT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + + he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_MU : + he->data1 |=HE_BITS (DATA1_FORMAT_MU ) | +HE_BITS (DATA1_UL_DL_KNOWN ); + + he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); + he->data4 |=HE_PREP (DATA4_MU_STA_ID ,MU_AID , rxv[8 ]); + + mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+mt76_connac3_mac_decode_he_mu_radiotap (skb, rxv); +break ; +case MT_PHY_TYPE_HE_TB : + he->data1 |=HE_BITS (DATA1_FORMAT_TRIG ) | +HE_BITS (DATA1_SPTL_REUSE2_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE3_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE4_KNOWN ); + + he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK,rxv[13]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK,rxv[13]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK,rxv[13]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK,rxv[13]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+break ; +default : +break ; + } +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_decode_he_radiotap); + +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +119
-0+ __le32 *rxv, u8 *mode) +{ +u8 stbc, gi, bw, dcm, nss; +bool cck = false; +u32 v0, v2; +int i, idx; + + v0 =le32_to_cpu (rxv[0 ]); + v2 =le32_to_cpu (rxv[2 ]); + + idx =FIELD_GET (MT_PRXV_TX_RATE , v0); + i = idx; + nss =FIELD_GET (MT_PRXV_NSTS , v0) +1 ; + + stbc =FIELD_GET (MT_PRXV_HT_STBC , v2); + gi =FIELD_GET (MT_PRXV_HT_SHORT_GI , v2); + *mode =FIELD_GET (MT_PRXV_TX_MODE , v2); + dcm =FIELD_GET (MT_PRXV_DCM , v2); + bw =FIELD_GET (MT_PRXV_FRAME_MODE , v2); + +switch (*mode) { +case MT_PHY_TYPE_CCK : + cck = true; + fallthrough; +case MT_PHY_TYPE_OFDM : + i =mt76_get_rate (dev, sband, i, cck); +break ; +case MT_PHY_TYPE_HT_GF : +case MT_PHY_TYPE_HT : + status->encoding =RX_ENC_HT ; +if (gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >31 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_VHT : + status->nss = nss; + status->encoding =RX_ENC_VHT ; +if (gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >11 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_HE_MU : +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : + status->nss = nss; + status->encoding =RX_ENC_HE ; + i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_HE_GI_3_2 ) + status->he_gi = gi; + + status->he_dcm = dcm; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : + status->nss = nss; + status->encoding =RX_ENC_EHT ; + i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_EHT_GI_3_2 ) + status->eht.gi = gi; +break ; +default : +return -EINVAL ; + } + status->rate_idx = i; + +switch (bw) { +case IEEE80211_STA_RX_BW_20 : +break ; +case IEEE80211_STA_RX_BW_40 : +if (*mode &MT_PHY_TYPE_HE_EXT_SU && + (idx &MT_PRXV_TX_ER_SU_106T )) { + status->bw =RATE_INFO_BW_HE_RU ; + status->he_ru = +NL80211_RATE_INFO_HE_RU_ALLOC_106 ; + }else { + status->bw =RATE_INFO_BW_40 ; + } +break ; +case IEEE80211_STA_RX_BW_80 : + status->bw =RATE_INFO_BW_80 ; +break ; +case IEEE80211_STA_RX_BW_160 : + status->bw =RATE_INFO_BW_160 ; +break ; +case IEEE80211_STA_RX_BW_320 : + status->bw =RATE_INFO_BW_320 ; +break ; +default : +return -EINVAL ; + } + + status->enc_flags |=RX_ENC_FLAG_STBC_MASK * stbc; +if (*mode <MT_PHY_TYPE_HE_SU && gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; + +return 0 ; +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_fill_rx_rate); + +static void +mt76_connac3_mac_write_txwi_8023 (__le32 *txwi,struct sk_buff *skb, +struct mt76_wcid *wcid) +{ +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +u8 fc_type, fc_stype; +u16 ethertype; +bool wmm = false; +u32 val; + +if (wcid->sta) { +struct ieee80211_sta *sta; + + sta = container_of((void *)wcid, struct ieee80211_sta,
drv_priv);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +23
-0+ wmm = sta->wme; + } + + val =FIELD_PREP (MT_TXD1_HDR_FORMAT ,MT_HDR_FORMAT_802_3 ) | +FIELD_PREP (MT_TXD1_TID , tid); + + ethertype =get_unaligned_be16 (&skb->data[12 ]); +if (ethertype >=ETH_P_802_3_MIN ) + val |=MT_TXD1_ETH_802_3 ; + + txwi[1 ] |=cpu_to_le32 (val); + + fc_type =IEEE80211_FTYPE_DATA >>2 ; + fc_stype = wmm ?IEEE80211_STYPE_QOS_DATA >>4 :0 ; + + val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + + txwi[2 ] |=cpu_to_le32 (val); +} + +static void +mt76_connac3_mac_write_txwi_80211(struct mt76_dev *dev, __le32*txwi,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+struct sk_buff *skb, + struct ieee80211_key_conf *key) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb-Quoted 1 line
data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +bool multicast =is_multicast_ether_addr (hdr->addr1); +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +__le16 fc = hdr->frame_control; +u8 fc_type, fc_stype; +u32 val; + +if (ieee80211_is_action (fc) && + mgmt->u.action.category ==WLAN_CATEGORY_BACK && + mgmt->u.action.u.addba_req.action_code ==
WLAN_ACTION_ADDBA_REQ)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +47
-0+ tid =MT_TX_ADDBA ; + else if (ieee80211_is_mgmt(hdr->frame_control)) + tid =MT_TX_NORMAL ; + + val =FIELD_PREP (MT_TXD1_HDR_FORMAT ,MT_HDR_FORMAT_802_11 ) | +FIELD_PREP (MT_TXD1_HDR_INFO , +ieee80211_get_hdrlen_from_skb (skb) /2 ) | +FIELD_PREP (MT_TXD1_TID , tid); + +if (!ieee80211_is_data (fc) || multicast || + info->flags &IEEE80211_TX_CTL_USE_MINRATE ) + val |=MT_TXD1_FIXED_RATE ; + +if (key && multicast &&ieee80211_is_robust_mgmt_frame (skb) && + key->cipher ==WLAN_CIPHER_SUITE_AES_CMAC ) { + val |=MT_TXD1_BIP ; + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_PROTECT_FRAME ); + } + + txwi[1 ] |=cpu_to_le32 (val); + + fc_type = (le16_to_cpu (fc) &IEEE80211_FCTL_FTYPE ) >>2 ; + fc_stype = (le16_to_cpu (fc) &IEEE80211_FCTL_STYPE ) >>4 ; + + val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + + txwi[2 ] |=cpu_to_le32 (val); + + txwi[3 ] |=cpu_to_le32 (FIELD_PREP (MT_TXD3_BCM , multicast)); +if (ieee80211_is_beacon (fc)) { + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_SW_POWER_MGMT ); + txwi[3 ] |=cpu_to_le32 (MT_TXD3_REM_TX_COUNT ); + } + +if (info->flags &IEEE80211_TX_CTL_INJECTED ) { +u16 seqno =le16_to_cpu (hdr->seq_ctrl); + +if (ieee80211_is_back_req (hdr->frame_control)) { +struct ieee80211_bar *bar; + + bar = (struct ieee80211_bar *)skb->data; + seqno =le16_to_cpu (bar->start_seq_num); + } + + val =MT_TXD3_SN_VALID | + FIELD_PREP(MT_TXD3_SEQ,
IEEE80211_SEQ_TO_SN(seqno));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+ txwi[3 ] |=cpu_to_le32 (val); + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_HW_AMSDU ); + } +} + +void mt76_connac3_mac_write_txwi (struct mt76_dev *dev,__le32 *txwi, + struct sk_buff *skb, struct mt76_wcid*wcid,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+struct ieee80211_key_conf *key, intpid,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ enum mt76_txq_id qid, u32 changed) +{ + u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE :
MT_SDIO_TXD_SIZE;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +struct ieee80211_vif *vif = info->control.vif; +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; +u16 tx_count =15 ; +bool beacon = !!(changed & (BSS_CHANGED_BEACON | +BSS_CHANGED_BEACON_ENABLED )); + bool inband_disc = !!(changed &(
BSS_CHANGED_UNSOL_BCAST_PROBE_RESP|drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+ BSS_CHANGED_FILS_DISCOVERY)); + + mvif = vif ? (struct mt76_vif *)vif->drv_priv :NULL ; +if (mvif) { + omac_idx = mvif->omac_idx; + wmm_idx = mvif->wmm_idx; + band_idx = mvif->band_idx; + } + +if (inband_disc) { + p_fmt =MT_TX_TYPE_FW ; + q_idx =MT_LMAC_ALTX0 ; + }else if (beacon) { + p_fmt =MT_TX_TYPE_FW ; + q_idx =MT_LMAC_BCN0 ; + }else if (qid >=MT_TXQ_PSD ) { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ q_idx =MT_LMAC_ALTX0 ; + }else { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ q_idx = wmm_idx *MT76_CONNAC_MAX_WMM_SETS + + mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +45
-0+ } + + val =FIELD_PREP (MT_TXD0_TX_BYTES , skb->len + sz_txd) | +FIELD_PREP (MT_TXD0_PKT_FMT , p_fmt) | +FIELD_PREP (MT_TXD0_Q_IDX , q_idx); + txwi[0 ] =cpu_to_le32 (val); + + val =FIELD_PREP (MT_TXD1_WLAN_IDX , wcid->idx) | +FIELD_PREP (MT_TXD1_OWN_MAC , omac_idx); + +if (band_idx) + val |=FIELD_PREP (MT_TXD1_TGID , band_idx); + + txwi[1 ] =cpu_to_le32 (val); + txwi[2 ] =0 ; + + val =MT_TXD3_SW_POWER_MGMT | +FIELD_PREP (MT_TXD3_REM_TX_COUNT , tx_count); +if (key) + val |=MT_TXD3_PROTECT_FRAME ; +if (info->flags &IEEE80211_TX_CTL_NO_ACK ) + val |=MT_TXD3_NO_ACK ; +if (wcid->amsdu) + val |=MT_TXD3_HW_AMSDU ; + + txwi[3 ] =cpu_to_le32 (val); + txwi[4 ] =0 ; + + val =FIELD_PREP (MT_TXD5_PID , pid); +if (pid >=MT_PACKET_ID_FIRST ) + val |=MT_TXD5_TX_STATUS_HOST ; + txwi[5 ] =cpu_to_le32 (val); + + val =MT_TXD6_DIS_MAT |MT_TXD6_DAS | +FIELD_PREP (MT_TXD6_MSDU_CNT ,1 ); + txwi[6 ] =cpu_to_le32 (val); + txwi[7 ] =0 ; + +if (is_8023) +mt76_connac3_mac_write_txwi_8023 (txwi, skb, wcid); +else +mt76_connac3_mac_write_txwi_80211 (dev, txwi, skb, key); + +if (txwi[1 ] &cpu_to_le32 (MT_TXD1_FIXED_RATE )) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr*)skb->data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +14
-0+bool mcast =ieee80211_is_data (hdr->frame_control) && +is_multicast_ether_addr (hdr->addr1); +u8 idx =MT76_CONNAC3_BASIC_RATES_TBL ; + +if (mvif) { +if (mcast && mvif->mcast_rates_idx) + idx = mvif->mcast_rates_idx; +else if (beacon && mvif->beacon_rates_idx) + idx = mvif->beacon_rates_idx; +else + idx = mvif->basic_rates_idx; + } + + txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE,idx));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ txwi[3 ] |=cpu_to_le32 (MT_TXD3_BA_DISABLE ); + } +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_write_txwi); + +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+struct ieee80211_sta *sta, + struct list_head *free_list) +{ + __le32 *txwi; +u16 wcid_idx; + +mt76_connac_txp_skb_unmap (dev, t); +if (!t->skb) + goto out; + + txwi = (__le32 *)mt76_get_txwi_ptr (dev, t); +if (sta) { + struct mt76_wcid *wcid = (struct mt76_wcid *)sta-Quoted 1 line
drv_priv;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+ + wcid_idx = wcid->idx; +if (likely (t->skb->protocol !=cpu_to_be16 (ETH_P_PAE ))) +mt76_connac3_tx_check_aggr (sta, txwi); + }else { + wcid_idx =le32_get_bits (txwi[1 ],MT_TXD1_WLAN_IDX ); + } + +__mt76_tx_complete_skb (dev, wcid_idx, t->skb, free_list); +out: + t->skb =NULL ; +mt76_put_txwi (dev, t); +} +EXPORT_SYMBOL_GPL (mt76_connac3_txwi_free); + +static bool +mt76_connac3_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid*wcid,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +58
-0+ int pid, __le32 *txs_data) +{ + struct mt76_sta_stats *stats = &wcid->stats; +struct ieee80211_supported_band *sband; +struct ieee80211_tx_info *info; +u32 txrate, txs, mode, stbc; +struct rate_info rate = {}; +struct sk_buff_head list; +struct mt76_phy *mphy; +struct sk_buff *skb; +bool cck = false; + +mt76_tx_status_lock (dev, &list); + skb =mt76_tx_status_skb_get (dev, wcid, pid, &list); +if (!skb) + goto out_no_skb; + + txs =le32_to_cpu (txs_data[0 ]); + + info =IEEE80211_SKB_CB (skb); +if (!(txs &MT_TXS0_ACK_ERROR_MASK )) + info->flags |=IEEE80211_TX_STAT_ACK ; + + info->status.ampdu_len =1 ; + info->status.ampdu_ack_len = !!(info->flags & +IEEE80211_TX_STAT_ACK ); + info->status.rates[0 ].idx =-1 ; + + txrate =FIELD_GET (MT_TXS0_TX_RATE , txs); + + rate.mcs =FIELD_GET (MT_TX_RATE_IDX , txrate); + rate.nss =FIELD_GET (MT_TX_RATE_NSS , txrate) +1 ; + stbc =le32_get_bits (txs_data[3 ],MT_TXS3_RATE_STBC ); + +if (stbc && rate.nss >1 ) + rate.nss >>=1 ; + +if (rate.nss -1 <ARRAY_SIZE (stats->tx_nss)) + stats->tx_nss[rate.nss -1 ]++; +if (rate.mcs <ARRAY_SIZE (stats->tx_mcs)) + stats->tx_mcs[rate.mcs]++; + + mode =FIELD_GET (MT_TX_RATE_MODE , txrate); + switch (mode) { + case MT_PHY_TYPE_CCK: + cck = true; + fallthrough; + case MT_PHY_TYPE_OFDM: + mphy = mt76_dev_phy(dev, wcid->phy_idx); + + if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) + sband = &mphy->sband_5g.sband; + else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ) + sband = &mphy->sband_6g.sband; + else + sband = &mphy->sband_2g.sband; + + rate.mcs = mt76_get_rate(mphy->dev, sband, rate.mcs,cck);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +130
-0+ rate.legacy = sband->bitrates[rate.mcs].bitrate; +break ; +case MT_PHY_TYPE_HT : +case MT_PHY_TYPE_HT_GF : +if (rate.mcs >31 ) + goto out; + + rate.flags =RATE_INFO_FLAGS_MCS ; +if (wcid->rate.flags &RATE_INFO_FLAGS_SHORT_GI ) + rate.flags |=RATE_INFO_FLAGS_SHORT_GI ; +break ; +case MT_PHY_TYPE_VHT : +if (rate.mcs >9 ) + goto out; + + rate.flags =RATE_INFO_FLAGS_VHT_MCS ; +break ; +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : +case MT_PHY_TYPE_HE_MU : +if (rate.mcs >11 ) + goto out; + + rate.he_gi = wcid->rate.he_gi; + rate.he_dcm =FIELD_GET (MT_TX_RATE_DCM , txrate); + rate.flags =RATE_INFO_FLAGS_HE_MCS ; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : +if (rate.mcs >13 ) + goto out; + + rate.eht_gi = wcid->rate.eht_gi; + rate.flags =RATE_INFO_FLAGS_EHT_MCS ; +break ; +default : + goto out; + } + + stats->tx_mode[mode]++; + +switch (FIELD_GET (MT_TXS0_BW , txs)) { +case IEEE80211_STA_RX_BW_320 : + rate.bw =RATE_INFO_BW_320 ; + stats->tx_bw[4 ]++; +break ; +case IEEE80211_STA_RX_BW_160 : + rate.bw =RATE_INFO_BW_160 ; + stats->tx_bw[3 ]++; +break ; +case IEEE80211_STA_RX_BW_80 : + rate.bw =RATE_INFO_BW_80 ; + stats->tx_bw[2 ]++; +break ; +case IEEE80211_STA_RX_BW_40 : + rate.bw =RATE_INFO_BW_40 ; + stats->tx_bw[1 ]++; +break ; +default : + rate.bw =RATE_INFO_BW_20 ; + stats->tx_bw[0 ]++; +break ; + } + wcid->rate = rate; + +out: +mt76_tx_status_skb_done (dev, skb, &list); + +out_no_skb: +mt76_tx_status_unlock (dev, &list); + +return !!skb; +} + +void mt76_connac3_mac_add_txs (struct mt76_dev *dev,void *data, +u32 max_wtbl_size) +{ +struct mt76_wcid *wcid; +__le32 *txs_data = data; +u16 wcidx; +u8 pid; + +if (le32_get_bits (txs_data[0 ],MT_TXS0_TXS_FORMAT ) >1 ) +return ; + + wcidx =le32_get_bits (txs_data[2 ],MT_TXS2_WCID ); + pid =le32_get_bits (txs_data[3 ],MT_TXS3_PID ); + +if (pid <MT_PACKET_ID_FIRST ) +return ; + +if (wcidx >= max_wtbl_size) +return ; + +rcu_read_lock (); + + wcid =rcu_dereference (dev->wcid[wcidx]); +if (!wcid) + goto out; + +mt76_connac3_mac_add_txs_skb (dev, wcid, pid, txs_data); +if (!wcid->sta) + goto out; + +spin_lock_bh (&dev->sta_poll_lock); +if (list_empty (&wcid->poll_list)) +list_add_tail (&wcid->poll_list, &dev->sta_poll_list); +spin_unlock_bh (&dev->sta_poll_lock); + +out: +rcu_read_unlock (); +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_add_txs); + +void mt76_connac3_tx_token_put (struct mt76_dev *dev) +{ +struct mt76_txwi_cache *txwi; +int id; + +spin_lock_bh (&dev->token_lock); +idr_for_each_entry (&dev->token, txwi, id) { +mt76_connac3_txwi_free (dev, txwi,NULL ,NULL ); + dev->token_count--; + } +spin_unlock_bh (&dev->token_lock); +idr_destroy (&dev->token); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_token_put);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +0
-0@@ -4,6 +4,24 @@#ifndef __MT76_CONNAC3_MAC_H#define __MT76_CONNAC3_MAC_H
Quoted 7 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h line 9
Quoted 5 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +1
-0+/* NOTE: used to map mt76_rates. idx may change if firmware expands table */
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +2
-0+#define MT76_CONNAC3_BASIC_RATES_TBL 11 +#define MT76_CONNAC3_BEACON_RATES_TBL 25Different devices may have different defined value.
The other WiFi7 device I am working on relies on the values I moved in mt76_connac3_mac.h (in common with mt7996). Moreover you can still have per-device values in mt7996/mac.h (I have not removed it).
Quoted 3 lines
I'm thinking if it's too early to create this patch for just moving mt7996 to
connac3_lib?
The code I moved is used by the other device as well. This series is a preliminary series to support it.
Regards,
Lorenzo
Quoted 3 lines
Ryder
Ryder Lee
maintainerRe: [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library
Quoted 910 lines · On Fri, 2023-06-09 at 18:34 +0200, [email protected] wrote:
Quoted 900 lines · Ryder Lee
Quoted 899 lines · Lorenzo Bianconi
External email : Please do not click links or open attachments until
you have verified the sender or the content.
Introduceconnac3_macinmt76_connaclibrary to reuse mac code
shared
between WiFi7 chipsets.Signed-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76_connac.h | 19 + .../wireless/mediatek/mt76/mt76_connac3_mac.c | 742 +++++++++++++++++ .../wireless/mediatek/mt76/mt76_connac3_mac.h | 18 + .../net/wireless/mediatek/mt76/mt7996/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 761 +----------- ---- -- .../net/wireless/mediatek/mt76/mt7996/main.c | 8 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +- .../wireless/mediatek/mt76/mt7996/mt7996.h | 28 +- 9 files changed, 807 insertions(+), 784 deletions(-) create mode 100644
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cdrivers/net/wireless/mediatek/mt76/Makefile +1
-1@@ -27,7 +27,7 @@ mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \ mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o -mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o +mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.omt76_connac3_mac.o
obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
obj-$(CONFIG_MT76x2_COMMON) += mt76x2/drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0@@ -415,4 +415,23 @@ void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t, struct list_head *free_list);void mt76_connac2_tx_token_put (struct mt76_dev *dev); +/* connac3 */ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
__le32
*txwi);
+void mt76_connac3_mac_decode_he_radiotap(structsk_buff*skb,__le32
*rxv,drivers/net/wireless/mediatek/mt76/mt76_connac.h +4
-0+ u8 mode); +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ __le32 *rxv, u8 *mode); +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev, __le32*txwi,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+ struct sk_buff *skb, struct mt76_wcid*wcid,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+struct ieee80211_key_conf *key, intpid,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ enum mt76_txq_id qid, u32 changed); +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac.h +6
-0+struct ieee80211_sta *sta, + struct list_head *free_list); +void mt76_connac3_mac_add_txs (struct mt76_dev *dev,void *data, +u32 max_wtbl_size); +void mt76_connac3_tx_token_put (struct mt76_dev *dev); +#endif /* __MT76_CONNAC_H */ diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cnew file mode 100644
index 000000000000..4b745bb74ca0drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0@@ -0,0 +1,742 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include "mt76_connac.h" +#include "mt76_connac3_mac.h" +#include "dma.h" + +#define HE_BITS (f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
+#defineHE_PREP(f, m, v)le16_encode_bits(le32_get_bits(v,
MT_CRXV_HE_##m),\drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+IEEE80211_RADIOTAP_HE_ ##f)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
__le32
*txwi)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+{ + struct mt76_wcid *wcid; + u16 fc, tid; + u32 val; + + if (!sta || + !(sta->deflink.ht_cap.ht_supported || sta-Quoted 1 line
deflink.he_cap.has_he))
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + + tid =le32_get_bits (txwi[1 ],MT_TXD1_TID ); +if (tid >=6 )/* skip VO queue */ +return ; + + val =le32_to_cpu (txwi[2 ]); + fc =FIELD_GET (MT_TXD2_FRAME_TYPE , val) <<2 | +FIELD_GET (MT_TXD2_SUB_TYPE , val) <<4 ; + if (unlikely(fc != (IEEE80211_FTYPE_DATA |
IEEE80211_STYPE_QOS_DATA)))drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + + wcid = (struct mt76_wcid *)sta->drv_priv; +if (!test_and_set_bit (tid, &wcid->ampdu_state)) +ieee80211_start_tx_ba_session (sta, tid,0 ); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_check_aggr); + +static void +mt76_connac3_mac_decode_he_radiotap_ru(struct mt76_rx_status*status,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+struct ieee80211_radiotap_he *he,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +39
-0+ __le32 *rxv) +{ +u32 ru =le32_get_bits (rxv[0 ],MT_PRXV_HE_RU_ALLOC ), offs =0 ; + + status->bw =RATE_INFO_BW_HE_RU ; + +switch (ru) { + case 0 ... 36: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_26 ; + offs = ru; +break ; + case 37 ... 52: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_52 ; + offs = ru -37 ; +break ; + case 53 ... 60: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_106 ; + offs = ru -53 ; +break ; + case 61 ... 64: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_242 ; + offs = ru -61 ; +break ; + case 65 ... 66: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_484 ; + offs = ru -65 ; +break ; +case 67 : + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_996 ; +break ; +case 68 : + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; +break ; + } + + he->data1 |=HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + he->data2 |=HE_BITS (DATA2_RU_OFFSET_KNOWN ) | +le16_encode_bits (offs, + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+} + +#define MU_PREP (f, v) le16_encode_bits(v,IEEE80211_RADIOTAP_HE_MU_##f)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+static void +mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff *skb,
__le32
*rxv)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ + struct mt76_rx_status *status = (struct mt76_rx_status *)skb-Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+static const struct ieee80211_radiotap_he_mu mu_known = { + .flags1 =HE_BITS (MU_FLAGS1_SIG_B_MCS_KNOWN ) | +HE_BITS (MU_FLAGS1_SIG_B_DCM_KNOWN ) | +HE_BITS (MU_FLAGS1_CH1_RU_KNOWN ) | +HE_BITS (MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN ), + .flags2 =HE_BITS (MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN ), + }; +struct ieee80211_radiotap_he_mu *he_mu; + + status->flag |=RX_FLAG_RADIOTAP_HE_MU ; + + he_mu =skb_push (skb,sizeof (mu_known)); +memcpy (he_mu, &mu_known,sizeof (mu_known)); + + he_mu->flags1 |=MU_PREP (FLAGS1_SIG_B_MCS , status->rate_idx); +if (status->he_dcm) + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status-Quoted 1 line
he_dcm);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ + he_mu->flags2 |=MU_PREP (FLAGS2_BW_FROM_SIG_A_BW , status->bw) | + MU_PREP(FLAGS2_SIG_B_SYMS_USERS, + le32_get_bits(rxv[4],
MT_CRXV_HE_NUM_USER));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) &
0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ +if (status->bw >=RATE_INFO_BW_40 ) { + he_mu->flags1 |=HE_BITS (MU_FLAGS1_CH2_RU_KNOWN ); + he_mu->ru_ch2[0] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU1) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ } + +if (status->bw >=RATE_INFO_BW_80 ) { +u32 ru_h, ru_l; + + he_mu->ru_ch1[1] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU2) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+ + ru_l =le32_get_bits (rxv[16 ],MT_CRXV_HE_RU3_L ); + ru_h =le32_get_bits (rxv[17 ],MT_CRXV_HE_RU3_H ) &0x7 ; + he_mu->ru_ch2[1 ] = (u8)(ru_l | ru_h <<4 ); + } +} + +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb,
__le32
*rxv,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ u8 mode) +{ + struct mt76_rx_status *status = (struct mt76_rx_status *)skb-Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +28
-0+static const struct ieee80211_radiotap_he known = { + .data1 =HE_BITS (DATA1_DATA_MCS_KNOWN ) | +HE_BITS (DATA1_DATA_DCM_KNOWN ) | +HE_BITS (DATA1_STBC_KNOWN ) | +HE_BITS (DATA1_CODING_KNOWN ) | +HE_BITS (DATA1_LDPC_XSYMSEG_KNOWN ) | +HE_BITS (DATA1_DOPPLER_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE_KNOWN ) | +HE_BITS (DATA1_BSS_COLOR_KNOWN ), + .data2 =HE_BITS (DATA2_GI_KNOWN ) | +HE_BITS (DATA2_TXBF_KNOWN ) | +HE_BITS (DATA2_PE_DISAMBIG_KNOWN ) | +HE_BITS (DATA2_TXOP_KNOWN ), + }; +u32 ltf_size =le32_get_bits (rxv[4 ],MT_CRXV_HE_LTF_SIZE ) +1 ; +struct ieee80211_radiotap_he *he; + + status->flag |=RX_FLAG_RADIOTAP_HE ; + + he =skb_push (skb,sizeof (known)); +memcpy (he, &known,sizeof (known)); + + he->data3 =HE_PREP (DATA3_BSS_COLOR ,BSS_COLOR , rxv[9 ]) | +HE_PREP (DATA3_LDPC_XSYMSEG ,LDPC_EXT_SYM , rxv[4 ]); + he->data4 =HE_PREP (DATA4_SU_MU_SPTL_REUSE ,SR_MASK , rxv[13 ]); + he->data5 =HE_PREP (DATA5_PE_DISAMBIG ,PE_DISAMBIG , rxv[5 ]) | +le16_encode_bits (ltf_size, + IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+if (le32_to_cpu (rxv[0 ]) &MT_PRXV_TXBF ) + he->data5 |=HE_BITS (DATA5_TXBF ); + he->data6 =HE_PREP (DATA6_TXOP ,TXOP_DUR , rxv[9 ]) | +HE_PREP (DATA6_DOPPLER ,DOPPLER , rxv[9 ]); + +switch (mode) { +case MT_PHY_TYPE_HE_SU : + he->data1 |=HE_BITS (DATA1_FORMAT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BEAM_CHANGE_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + + he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG,rxv[8]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_EXT_SU : + he->data1 |=HE_BITS (DATA1_FORMAT_EXT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + + he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_MU : + he->data1 |=HE_BITS (DATA1_FORMAT_MU ) | +HE_BITS (DATA1_UL_DL_KNOWN ); + + he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); + he->data4 |=HE_PREP (DATA4_MU_STA_ID ,MU_AID , rxv[8 ]); + + mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+mt76_connac3_mac_decode_he_mu_radiotap (skb, rxv); +break ; +case MT_PHY_TYPE_HE_TB : + he->data1 |=HE_BITS (DATA1_FORMAT_TRIG ) | +HE_BITS (DATA1_SPTL_REUSE2_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE3_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE4_KNOWN ); + + he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK,rxv[13]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK,rxv[13]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK,rxv[13]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK,rxv[13]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+break ; +default : +break ; + } +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_decode_he_radiotap); + +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +107
-0+ __le32 *rxv, u8 *mode) +{ +u8 stbc, gi, bw, dcm, nss; +bool cck = false; +u32 v0, v2; +int i, idx; + + v0 =le32_to_cpu (rxv[0 ]); + v2 =le32_to_cpu (rxv[2 ]); + + idx =FIELD_GET (MT_PRXV_TX_RATE , v0); + i = idx; + nss =FIELD_GET (MT_PRXV_NSTS , v0) +1 ; + + stbc =FIELD_GET (MT_PRXV_HT_STBC , v2); + gi =FIELD_GET (MT_PRXV_HT_SHORT_GI , v2); + *mode =FIELD_GET (MT_PRXV_TX_MODE , v2); + dcm =FIELD_GET (MT_PRXV_DCM , v2); + bw =FIELD_GET (MT_PRXV_FRAME_MODE , v2); + +switch (*mode) { +case MT_PHY_TYPE_CCK : + cck = true; + fallthrough; +case MT_PHY_TYPE_OFDM : + i =mt76_get_rate (dev, sband, i, cck); +break ; +case MT_PHY_TYPE_HT_GF : +case MT_PHY_TYPE_HT : + status->encoding =RX_ENC_HT ; +if (gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >31 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_VHT : + status->nss = nss; + status->encoding =RX_ENC_VHT ; +if (gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >11 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_HE_MU : +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : + status->nss = nss; + status->encoding =RX_ENC_HE ; + i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_HE_GI_3_2 ) + status->he_gi = gi; + + status->he_dcm = dcm; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : + status->nss = nss; + status->encoding =RX_ENC_EHT ; + i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_EHT_GI_3_2 ) + status->eht.gi = gi; +break ; +default : +return -EINVAL ; + } + status->rate_idx = i; + +switch (bw) { +case IEEE80211_STA_RX_BW_20 : +break ; +case IEEE80211_STA_RX_BW_40 : +if (*mode &MT_PHY_TYPE_HE_EXT_SU && + (idx &MT_PRXV_TX_ER_SU_106T )) { + status->bw =RATE_INFO_BW_HE_RU ; + status->he_ru = +NL80211_RATE_INFO_HE_RU_ALLOC_106 ; + }else { + status->bw =RATE_INFO_BW_40 ; + } +break ; +case IEEE80211_STA_RX_BW_80 : + status->bw =RATE_INFO_BW_80 ; +break ; +case IEEE80211_STA_RX_BW_160 : + status->bw =RATE_INFO_BW_160 ; +break ; +case IEEE80211_STA_RX_BW_320 : + status->bw =RATE_INFO_BW_320 ; +break ; +default : +return -EINVAL ; + } + + status->enc_flags |=RX_ENC_FLAG_STBC_MASK * stbc; +if (*mode <MT_PHY_TYPE_HE_SU && gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; + +return 0 ; +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_fill_rx_rate); + +static void +mt76_connac3_mac_write_txwi_8023(__le32 *txwi, struct sk_buff*skb,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +12
-0+ struct mt76_wcid *wcid) +{ +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +u8 fc_type, fc_stype; +u16 ethertype; +bool wmm = false; +u32 val; + +if (wcid->sta) { +struct ieee80211_sta *sta; + + sta = container_of((void *)wcid, struct ieee80211_sta,
drv_priv);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +23
-0+ wmm = sta->wme; + } + + val =FIELD_PREP (MT_TXD1_HDR_FORMAT ,MT_HDR_FORMAT_802_3 ) | +FIELD_PREP (MT_TXD1_TID , tid); + + ethertype =get_unaligned_be16 (&skb->data[12 ]); +if (ethertype >=ETH_P_802_3_MIN ) + val |=MT_TXD1_ETH_802_3 ; + + txwi[1 ] |=cpu_to_le32 (val); + + fc_type =IEEE80211_FTYPE_DATA >>2 ; + fc_stype = wmm ?IEEE80211_STYPE_QOS_DATA >>4 :0 ; + + val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + + txwi[2 ] |=cpu_to_le32 (val); +} + +static void +mt76_connac3_mac_write_txwi_80211(struct mt76_dev *dev, __le32*txwi,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+struct sk_buff *skb, + struct ieee80211_key_conf *key) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb-Quoted 1 line
data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +bool multicast =is_multicast_ether_addr (hdr->addr1); +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +__le16 fc = hdr->frame_control; +u8 fc_type, fc_stype; +u32 val; + +if (ieee80211_is_action (fc) && + mgmt->u.action.category ==WLAN_CATEGORY_BACK && + mgmt->u.action.u.addba_req.action_code ==
WLAN_ACTION_ADDBA_REQ)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +47
-0+ tid =MT_TX_ADDBA ; + else if (ieee80211_is_mgmt(hdr->frame_control)) + tid =MT_TX_NORMAL ; + + val =FIELD_PREP (MT_TXD1_HDR_FORMAT ,MT_HDR_FORMAT_802_11 ) | +FIELD_PREP (MT_TXD1_HDR_INFO , +ieee80211_get_hdrlen_from_skb (skb) /2 ) | +FIELD_PREP (MT_TXD1_TID , tid); + +if (!ieee80211_is_data (fc) || multicast || + info->flags &IEEE80211_TX_CTL_USE_MINRATE ) + val |=MT_TXD1_FIXED_RATE ; + +if (key && multicast &&ieee80211_is_robust_mgmt_frame (skb) && + key->cipher ==WLAN_CIPHER_SUITE_AES_CMAC ) { + val |=MT_TXD1_BIP ; + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_PROTECT_FRAME ); + } + + txwi[1 ] |=cpu_to_le32 (val); + + fc_type = (le16_to_cpu (fc) &IEEE80211_FCTL_FTYPE ) >>2 ; + fc_stype = (le16_to_cpu (fc) &IEEE80211_FCTL_STYPE ) >>4 ; + + val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + + txwi[2 ] |=cpu_to_le32 (val); + + txwi[3 ] |=cpu_to_le32 (FIELD_PREP (MT_TXD3_BCM , multicast)); +if (ieee80211_is_beacon (fc)) { + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_SW_POWER_MGMT ); + txwi[3 ] |=cpu_to_le32 (MT_TXD3_REM_TX_COUNT ); + } + +if (info->flags &IEEE80211_TX_CTL_INJECTED ) { +u16 seqno =le16_to_cpu (hdr->seq_ctrl); + +if (ieee80211_is_back_req (hdr->frame_control)) { +struct ieee80211_bar *bar; + + bar = (struct ieee80211_bar *)skb->data; + seqno =le16_to_cpu (bar->start_seq_num); + } + + val =MT_TXD3_SN_VALID | + FIELD_PREP(MT_TXD3_SEQ,
IEEE80211_SEQ_TO_SN(seqno));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ txwi[3 ] |=cpu_to_le32 (val); + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_HW_AMSDU ); + } +} + +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev, __le32*txwi,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ struct sk_buff *skb, struct mt76_wcid*wcid,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+struct ieee80211_key_conf *key, intpid,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ enum mt76_txq_id qid, u32 changed) +{ + u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE :
MT_SDIO_TXD_SIZE;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +struct ieee80211_vif *vif = info->control.vif; +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; +u16 tx_count =15 ; +bool beacon = !!(changed & (BSS_CHANGED_BEACON | +BSS_CHANGED_BEACON_ENABLED )); + bool inband_disc = !!(changed &(
BSS_CHANGED_UNSOL_BCAST_PROBE_RESP|drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+ BSS_CHANGED_FILS_DISCOVERY)); + + mvif = vif ? (struct mt76_vif *)vif->drv_priv :NULL ; +if (mvif) { + omac_idx = mvif->omac_idx; + wmm_idx = mvif->wmm_idx; + band_idx = mvif->band_idx; + } + +if (inband_disc) { + p_fmt =MT_TX_TYPE_FW ; + q_idx =MT_LMAC_ALTX0 ; + }else if (beacon) { + p_fmt =MT_TX_TYPE_FW ; + q_idx =MT_LMAC_BCN0 ; + }else if (qid >=MT_TXQ_PSD ) { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ q_idx =MT_LMAC_ALTX0 ; + }else { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ q_idx = wmm_idx *MT76_CONNAC_MAX_WMM_SETS + + mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +45
-0+ } + + val =FIELD_PREP (MT_TXD0_TX_BYTES , skb->len + sz_txd) | +FIELD_PREP (MT_TXD0_PKT_FMT , p_fmt) | +FIELD_PREP (MT_TXD0_Q_IDX , q_idx); + txwi[0 ] =cpu_to_le32 (val); + + val =FIELD_PREP (MT_TXD1_WLAN_IDX , wcid->idx) | +FIELD_PREP (MT_TXD1_OWN_MAC , omac_idx); + +if (band_idx) + val |=FIELD_PREP (MT_TXD1_TGID , band_idx); + + txwi[1 ] =cpu_to_le32 (val); + txwi[2 ] =0 ; + + val =MT_TXD3_SW_POWER_MGMT | +FIELD_PREP (MT_TXD3_REM_TX_COUNT , tx_count); +if (key) + val |=MT_TXD3_PROTECT_FRAME ; +if (info->flags &IEEE80211_TX_CTL_NO_ACK ) + val |=MT_TXD3_NO_ACK ; +if (wcid->amsdu) + val |=MT_TXD3_HW_AMSDU ; + + txwi[3 ] =cpu_to_le32 (val); + txwi[4 ] =0 ; + + val =FIELD_PREP (MT_TXD5_PID , pid); +if (pid >=MT_PACKET_ID_FIRST ) + val |=MT_TXD5_TX_STATUS_HOST ; + txwi[5 ] =cpu_to_le32 (val); + + val =MT_TXD6_DIS_MAT |MT_TXD6_DAS | +FIELD_PREP (MT_TXD6_MSDU_CNT ,1 ); + txwi[6 ] =cpu_to_le32 (val); + txwi[7 ] =0 ; + +if (is_8023) +mt76_connac3_mac_write_txwi_8023 (txwi, skb, wcid); +else +mt76_connac3_mac_write_txwi_80211 (dev, txwi, skb, key); + +if (txwi[1 ] &cpu_to_le32 (MT_TXD1_FIXED_RATE )) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr*)skb->data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +14
-0+bool mcast =ieee80211_is_data (hdr->frame_control) && +is_multicast_ether_addr (hdr->addr1); +u8 idx =MT76_CONNAC3_BASIC_RATES_TBL ; + +if (mvif) { +if (mcast && mvif->mcast_rates_idx) + idx = mvif->mcast_rates_idx; +else if (beacon && mvif->beacon_rates_idx) + idx = mvif->beacon_rates_idx; +else + idx = mvif->basic_rates_idx; + } + + txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE,idx));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ txwi[3 ] |=cpu_to_le32 (MT_TXD3_BA_DISABLE ); + } +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_write_txwi); + +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+struct ieee80211_sta *sta, + struct list_head *free_list) +{ + __le32 *txwi; +u16 wcid_idx; + +mt76_connac_txp_skb_unmap (dev, t); +if (!t->skb) + goto out; + + txwi = (__le32 *)mt76_get_txwi_ptr (dev, t); +if (sta) { + struct mt76_wcid *wcid = (struct mt76_wcid *)sta-Quoted 1 line
drv_priv;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+ + wcid_idx = wcid->idx; +if (likely (t->skb->protocol !=cpu_to_be16 (ETH_P_PAE ))) +mt76_connac3_tx_check_aggr (sta, txwi); + }else { + wcid_idx =le32_get_bits (txwi[1 ],MT_TXD1_WLAN_IDX ); + } + +__mt76_tx_complete_skb (dev, wcid_idx, t->skb, free_list); +out: + t->skb =NULL ; +mt76_put_txwi (dev, t); +} +EXPORT_SYMBOL_GPL (mt76_connac3_txwi_free); + +static bool +mt76_connac3_mac_add_txs_skb(struct mt76_dev *dev, struct
mt76_wcid
*wcid,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +58
-0+ int pid, __le32 *txs_data) +{ + struct mt76_sta_stats *stats = &wcid->stats; +struct ieee80211_supported_band *sband; +struct ieee80211_tx_info *info; +u32 txrate, txs, mode, stbc; +struct rate_info rate = {}; +struct sk_buff_head list; +struct mt76_phy *mphy; +struct sk_buff *skb; +bool cck = false; + +mt76_tx_status_lock (dev, &list); + skb =mt76_tx_status_skb_get (dev, wcid, pid, &list); +if (!skb) + goto out_no_skb; + + txs =le32_to_cpu (txs_data[0 ]); + + info =IEEE80211_SKB_CB (skb); +if (!(txs &MT_TXS0_ACK_ERROR_MASK )) + info->flags |=IEEE80211_TX_STAT_ACK ; + + info->status.ampdu_len =1 ; + info->status.ampdu_ack_len = !!(info->flags & +IEEE80211_TX_STAT_ACK ); + info->status.rates[0 ].idx =-1 ; + + txrate =FIELD_GET (MT_TXS0_TX_RATE , txs); + + rate.mcs =FIELD_GET (MT_TX_RATE_IDX , txrate); + rate.nss =FIELD_GET (MT_TX_RATE_NSS , txrate) +1 ; + stbc =le32_get_bits (txs_data[3 ],MT_TXS3_RATE_STBC ); + +if (stbc && rate.nss >1 ) + rate.nss >>=1 ; + +if (rate.nss -1 <ARRAY_SIZE (stats->tx_nss)) + stats->tx_nss[rate.nss -1 ]++; +if (rate.mcs <ARRAY_SIZE (stats->tx_mcs)) + stats->tx_mcs[rate.mcs]++; + + mode =FIELD_GET (MT_TX_RATE_MODE , txrate); + switch (mode) { + case MT_PHY_TYPE_CCK: + cck = true; + fallthrough; + case MT_PHY_TYPE_OFDM: + mphy = mt76_dev_phy(dev, wcid->phy_idx); + + if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) + sband = &mphy->sband_5g.sband; + else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ) + sband = &mphy->sband_6g.sband; + else + sband = &mphy->sband_2g.sband; + + rate.mcs = mt76_get_rate(mphy->dev, sband, rate.mcs,cck);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +130
-0+ rate.legacy = sband->bitrates[rate.mcs].bitrate; +break ; +case MT_PHY_TYPE_HT : +case MT_PHY_TYPE_HT_GF : +if (rate.mcs >31 ) + goto out; + + rate.flags =RATE_INFO_FLAGS_MCS ; +if (wcid->rate.flags &RATE_INFO_FLAGS_SHORT_GI ) + rate.flags |=RATE_INFO_FLAGS_SHORT_GI ; +break ; +case MT_PHY_TYPE_VHT : +if (rate.mcs >9 ) + goto out; + + rate.flags =RATE_INFO_FLAGS_VHT_MCS ; +break ; +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : +case MT_PHY_TYPE_HE_MU : +if (rate.mcs >11 ) + goto out; + + rate.he_gi = wcid->rate.he_gi; + rate.he_dcm =FIELD_GET (MT_TX_RATE_DCM , txrate); + rate.flags =RATE_INFO_FLAGS_HE_MCS ; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : +if (rate.mcs >13 ) + goto out; + + rate.eht_gi = wcid->rate.eht_gi; + rate.flags =RATE_INFO_FLAGS_EHT_MCS ; +break ; +default : + goto out; + } + + stats->tx_mode[mode]++; + +switch (FIELD_GET (MT_TXS0_BW , txs)) { +case IEEE80211_STA_RX_BW_320 : + rate.bw =RATE_INFO_BW_320 ; + stats->tx_bw[4 ]++; +break ; +case IEEE80211_STA_RX_BW_160 : + rate.bw =RATE_INFO_BW_160 ; + stats->tx_bw[3 ]++; +break ; +case IEEE80211_STA_RX_BW_80 : + rate.bw =RATE_INFO_BW_80 ; + stats->tx_bw[2 ]++; +break ; +case IEEE80211_STA_RX_BW_40 : + rate.bw =RATE_INFO_BW_40 ; + stats->tx_bw[1 ]++; +break ; +default : + rate.bw =RATE_INFO_BW_20 ; + stats->tx_bw[0 ]++; +break ; + } + wcid->rate = rate; + +out: +mt76_tx_status_skb_done (dev, skb, &list); + +out_no_skb: +mt76_tx_status_unlock (dev, &list); + +return !!skb; +} + +void mt76_connac3_mac_add_txs (struct mt76_dev *dev,void *data, +u32 max_wtbl_size) +{ +struct mt76_wcid *wcid; +__le32 *txs_data = data; +u16 wcidx; +u8 pid; + +if (le32_get_bits (txs_data[0 ],MT_TXS0_TXS_FORMAT ) >1 ) +return ; + + wcidx =le32_get_bits (txs_data[2 ],MT_TXS2_WCID ); + pid =le32_get_bits (txs_data[3 ],MT_TXS3_PID ); + +if (pid <MT_PACKET_ID_FIRST ) +return ; + +if (wcidx >= max_wtbl_size) +return ; + +rcu_read_lock (); + + wcid =rcu_dereference (dev->wcid[wcidx]); +if (!wcid) + goto out; + +mt76_connac3_mac_add_txs_skb (dev, wcid, pid, txs_data); +if (!wcid->sta) + goto out; + +spin_lock_bh (&dev->sta_poll_lock); +if (list_empty (&wcid->poll_list)) +list_add_tail (&wcid->poll_list, &dev->sta_poll_list); +spin_unlock_bh (&dev->sta_poll_lock); + +out: +rcu_read_unlock (); +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_add_txs); + +void mt76_connac3_tx_token_put (struct mt76_dev *dev) +{ +struct mt76_txwi_cache *txwi; +int id; + +spin_lock_bh (&dev->token_lock); +idr_for_each_entry (&dev->token, txwi, id) { +mt76_connac3_txwi_free (dev, txwi,NULL ,NULL ); + dev->token_count--; + } +spin_unlock_bh (&dev->token_lock); +idr_destroy (&dev->token); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_token_put);diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hindex6663a0b46541..bcc1d976b2b0100644drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +0
-0@@ -4,6 +4,24 @@#ifndef __MT76_CONNAC3_MAC_H#define __MT76_CONNAC3_MAC_HQuoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h line 9
Quoted 6 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +1
-0+/* NOTE: used to map mt76_rates. idx may change if firmware expands
table */drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +2
-0+#define MT76_CONNAC3_BASIC_RATES_TBL 11 +#define MT76_CONNAC3_BEACON_RATES_TBL 25Different devices may have different defined value.
Quoted 5 lines
The other WiFi7 device I am working on relies on the values I moved in
mt76_connac3_mac.h(in common with mt7996). Moreover you can still have per-device values inmt7996/mac.h(I have not removed it).
Please double check with the mtk folk you work with. The 11 and 25 is the value I discussed with firmware folks to avoid overlapping the tbl mt7996 use (MU/other algo in fw), or it causes something hardly solving issue
Quoted 14 lines
Quoted 3 lines
I'm thinking if it's too early to create this patch for just moving mt7996 to
connac3_lib?The code I moved is used by the other device as well. This series is a
preliminary series to support it.Regards,
LorenzoQuoted 3 lines
Ryder
[email protected]
maintainerRe: [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library
Quoted 917 lines · On Fri, 2023-06-09 at 18:34 +0200, [email protected] wrote:
Quoted 910 lines · Ryder Lee
Quoted 900 lines · Lorenzo Bianconi
Quoted 899 lines
External email : Please do not click links or open attachments until
you have verified the sender or the content.
Introduceconnac3_macinmt76_connaclibrary to reuse mac code
shared
between WiFi7 chipsets.Signed-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76_connac.h | 19 + .../wireless/mediatek/mt76/mt76_connac3_mac.c | 742 +++++++++++++++++ .../wireless/mediatek/mt76/mt76_connac3_mac.h | 18 + .../net/wireless/mediatek/mt76/mt7996/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 761 +----------- ---- -- .../net/wireless/mediatek/mt76/mt7996/main.c | 8 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +- .../wireless/mediatek/mt76/mt7996/mt7996.h | 28 +- 9 files changed, 807 insertions(+), 784 deletions(-) create mode 100644
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cdrivers/net/wireless/mediatek/mt76/Makefile +1
-1@@ -27,7 +27,7 @@ mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \ mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o -mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o +mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.omt76_connac3_mac.o
obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
obj-$(CONFIG_MT76x2_COMMON) += mt76x2/drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0@@ -415,4 +415,23 @@ void mt76_connac2_txwi_free(struct mt76_dev *dev, struct mt76_txwi_cache *t, struct list_head *free_list);void mt76_connac2_tx_token_put (struct mt76_dev *dev); +/* connac3 */ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
__le32
*txwi);
+void mt76_connac3_mac_decode_he_radiotap(structsk_buff*skb,__le32
*rxv,drivers/net/wireless/mediatek/mt76/mt76_connac.h +4
-0+ u8 mode); +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ __le32 *rxv, u8 *mode); +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev, __le32*txwi,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+ struct sk_buff *skb, struct mt76_wcid*wcid,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+struct ieee80211_key_conf *key, intpid,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ enum mt76_txq_id qid, u32 changed); +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac.h +6
-0+struct ieee80211_sta *sta, + struct list_head *free_list); +void mt76_connac3_mac_add_txs (struct mt76_dev *dev,void *data, +u32 max_wtbl_size); +void mt76_connac3_tx_token_put (struct mt76_dev *dev); +#endif /* __MT76_CONNAC_H */ diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cnew file mode 100644
index 000000000000..4b745bb74ca0drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0@@ -0,0 +1,742 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include "mt76_connac.h" +#include "mt76_connac3_mac.h" +#include "dma.h" + +#define HE_BITS (f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
+#defineHE_PREP(f, m, v)le16_encode_bits(le32_get_bits(v,
MT_CRXV_HE_##m),\drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+IEEE80211_RADIOTAP_HE_ ##f)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
__le32
*txwi)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+{ + struct mt76_wcid *wcid; + u16 fc, tid; + u32 val; + + if (!sta || + !(sta->deflink.ht_cap.ht_supported || sta-Quoted 1 line
deflink.he_cap.has_he))
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + + tid =le32_get_bits (txwi[1 ],MT_TXD1_TID ); +if (tid >=6 )/* skip VO queue */ +return ; + + val =le32_to_cpu (txwi[2 ]); + fc =FIELD_GET (MT_TXD2_FRAME_TYPE , val) <<2 | +FIELD_GET (MT_TXD2_SUB_TYPE , val) <<4 ; + if (unlikely(fc != (IEEE80211_FTYPE_DATA |
IEEE80211_STYPE_QOS_DATA)))drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + + wcid = (struct mt76_wcid *)sta->drv_priv; +if (!test_and_set_bit (tid, &wcid->ampdu_state)) +ieee80211_start_tx_ba_session (sta, tid,0 ); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_check_aggr); + +static void +mt76_connac3_mac_decode_he_radiotap_ru(struct mt76_rx_status*status,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+struct ieee80211_radiotap_he *he,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +39
-0+ __le32 *rxv) +{ +u32 ru =le32_get_bits (rxv[0 ],MT_PRXV_HE_RU_ALLOC ), offs =0 ; + + status->bw =RATE_INFO_BW_HE_RU ; + +switch (ru) { + case 0 ... 36: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_26 ; + offs = ru; +break ; + case 37 ... 52: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_52 ; + offs = ru -37 ; +break ; + case 53 ... 60: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_106 ; + offs = ru -53 ; +break ; + case 61 ... 64: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_242 ; + offs = ru -61 ; +break ; + case 65 ... 66: + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_484 ; + offs = ru -65 ; +break ; +case 67 : + status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_996 ; +break ; +case 68 : + status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; +break ; + } + + he->data1 |=HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + he->data2 |=HE_BITS (DATA2_RU_OFFSET_KNOWN ) | +le16_encode_bits (offs, + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+} + +#define MU_PREP (f, v) le16_encode_bits(v,IEEE80211_RADIOTAP_HE_MU_##f)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+static void +mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff *skb,
__le32
*rxv)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ + struct mt76_rx_status *status = (struct mt76_rx_status *)skb-Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+static const struct ieee80211_radiotap_he_mu mu_known = { + .flags1 =HE_BITS (MU_FLAGS1_SIG_B_MCS_KNOWN ) | +HE_BITS (MU_FLAGS1_SIG_B_DCM_KNOWN ) | +HE_BITS (MU_FLAGS1_CH1_RU_KNOWN ) | +HE_BITS (MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN ), + .flags2 =HE_BITS (MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN ), + }; +struct ieee80211_radiotap_he_mu *he_mu; + + status->flag |=RX_FLAG_RADIOTAP_HE_MU ; + + he_mu =skb_push (skb,sizeof (mu_known)); +memcpy (he_mu, &mu_known,sizeof (mu_known)); + + he_mu->flags1 |=MU_PREP (FLAGS1_SIG_B_MCS , status->rate_idx); +if (status->he_dcm) + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status-Quoted 1 line
he_dcm);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ + he_mu->flags2 |=MU_PREP (FLAGS2_BW_FROM_SIG_A_BW , status->bw) | + MU_PREP(FLAGS2_SIG_B_SYMS_USERS, + le32_get_bits(rxv[4],
MT_CRXV_HE_NUM_USER));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + he_mu->ru_ch1[0] = le32_get_bits(rxv[16], MT_CRXV_HE_RU0) &
0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ +if (status->bw >=RATE_INFO_BW_40 ) { + he_mu->flags1 |=HE_BITS (MU_FLAGS1_CH2_RU_KNOWN ); + he_mu->ru_ch2[0] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU1) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ } + +if (status->bw >=RATE_INFO_BW_80 ) { +u32 ru_h, ru_l; + + he_mu->ru_ch1[1] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU2) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+ + ru_l =le32_get_bits (rxv[16 ],MT_CRXV_HE_RU3_L ); + ru_h =le32_get_bits (rxv[17 ],MT_CRXV_HE_RU3_H ) &0x7 ; + he_mu->ru_ch2[1 ] = (u8)(ru_l | ru_h <<4 ); + } +} + +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff *skb,
__le32
*rxv,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ u8 mode) +{ + struct mt76_rx_status *status = (struct mt76_rx_status *)skb-Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +28
-0+static const struct ieee80211_radiotap_he known = { + .data1 =HE_BITS (DATA1_DATA_MCS_KNOWN ) | +HE_BITS (DATA1_DATA_DCM_KNOWN ) | +HE_BITS (DATA1_STBC_KNOWN ) | +HE_BITS (DATA1_CODING_KNOWN ) | +HE_BITS (DATA1_LDPC_XSYMSEG_KNOWN ) | +HE_BITS (DATA1_DOPPLER_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE_KNOWN ) | +HE_BITS (DATA1_BSS_COLOR_KNOWN ), + .data2 =HE_BITS (DATA2_GI_KNOWN ) | +HE_BITS (DATA2_TXBF_KNOWN ) | +HE_BITS (DATA2_PE_DISAMBIG_KNOWN ) | +HE_BITS (DATA2_TXOP_KNOWN ), + }; +u32 ltf_size =le32_get_bits (rxv[4 ],MT_CRXV_HE_LTF_SIZE ) +1 ; +struct ieee80211_radiotap_he *he; + + status->flag |=RX_FLAG_RADIOTAP_HE ; + + he =skb_push (skb,sizeof (known)); +memcpy (he, &known,sizeof (known)); + + he->data3 =HE_PREP (DATA3_BSS_COLOR ,BSS_COLOR , rxv[9 ]) | +HE_PREP (DATA3_LDPC_XSYMSEG ,LDPC_EXT_SYM , rxv[4 ]); + he->data4 =HE_PREP (DATA4_SU_MU_SPTL_REUSE ,SR_MASK , rxv[13 ]); + he->data5 =HE_PREP (DATA5_PE_DISAMBIG ,PE_DISAMBIG , rxv[5 ]) | +le16_encode_bits (ltf_size, + IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+if (le32_to_cpu (rxv[0 ]) &MT_PRXV_TXBF ) + he->data5 |=HE_BITS (DATA5_TXBF ); + he->data6 =HE_PREP (DATA6_TXOP ,TXOP_DUR , rxv[9 ]) | +HE_PREP (DATA6_DOPPLER ,DOPPLER , rxv[9 ]); + +switch (mode) { +case MT_PHY_TYPE_HE_SU : + he->data1 |=HE_BITS (DATA1_FORMAT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BEAM_CHANGE_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + + he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG,rxv[8]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_EXT_SU : + he->data1 |=HE_BITS (DATA1_FORMAT_EXT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + + he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_MU : + he->data1 |=HE_BITS (DATA1_FORMAT_MU ) | +HE_BITS (DATA1_UL_DL_KNOWN ); + + he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); + he->data4 |=HE_PREP (DATA4_MU_STA_ID ,MU_AID , rxv[8 ]); + + mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+mt76_connac3_mac_decode_he_mu_radiotap (skb, rxv); +break ; +case MT_PHY_TYPE_HE_TB : + he->data1 |=HE_BITS (DATA1_FORMAT_TRIG ) | +HE_BITS (DATA1_SPTL_REUSE2_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE3_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE4_KNOWN ); + + he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK,rxv[13]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK,rxv[13]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK,rxv[13]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK,rxv[13]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+break ; +default : +break ; + } +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_decode_he_radiotap); + +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +107
-0+ __le32 *rxv, u8 *mode) +{ +u8 stbc, gi, bw, dcm, nss; +bool cck = false; +u32 v0, v2; +int i, idx; + + v0 =le32_to_cpu (rxv[0 ]); + v2 =le32_to_cpu (rxv[2 ]); + + idx =FIELD_GET (MT_PRXV_TX_RATE , v0); + i = idx; + nss =FIELD_GET (MT_PRXV_NSTS , v0) +1 ; + + stbc =FIELD_GET (MT_PRXV_HT_STBC , v2); + gi =FIELD_GET (MT_PRXV_HT_SHORT_GI , v2); + *mode =FIELD_GET (MT_PRXV_TX_MODE , v2); + dcm =FIELD_GET (MT_PRXV_DCM , v2); + bw =FIELD_GET (MT_PRXV_FRAME_MODE , v2); + +switch (*mode) { +case MT_PHY_TYPE_CCK : + cck = true; + fallthrough; +case MT_PHY_TYPE_OFDM : + i =mt76_get_rate (dev, sband, i, cck); +break ; +case MT_PHY_TYPE_HT_GF : +case MT_PHY_TYPE_HT : + status->encoding =RX_ENC_HT ; +if (gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >31 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_VHT : + status->nss = nss; + status->encoding =RX_ENC_VHT ; +if (gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >11 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_HE_MU : +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : + status->nss = nss; + status->encoding =RX_ENC_HE ; + i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_HE_GI_3_2 ) + status->he_gi = gi; + + status->he_dcm = dcm; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : + status->nss = nss; + status->encoding =RX_ENC_EHT ; + i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_EHT_GI_3_2 ) + status->eht.gi = gi; +break ; +default : +return -EINVAL ; + } + status->rate_idx = i; + +switch (bw) { +case IEEE80211_STA_RX_BW_20 : +break ; +case IEEE80211_STA_RX_BW_40 : +if (*mode &MT_PHY_TYPE_HE_EXT_SU && + (idx &MT_PRXV_TX_ER_SU_106T )) { + status->bw =RATE_INFO_BW_HE_RU ; + status->he_ru = +NL80211_RATE_INFO_HE_RU_ALLOC_106 ; + }else { + status->bw =RATE_INFO_BW_40 ; + } +break ; +case IEEE80211_STA_RX_BW_80 : + status->bw =RATE_INFO_BW_80 ; +break ; +case IEEE80211_STA_RX_BW_160 : + status->bw =RATE_INFO_BW_160 ; +break ; +case IEEE80211_STA_RX_BW_320 : + status->bw =RATE_INFO_BW_320 ; +break ; +default : +return -EINVAL ; + } + + status->enc_flags |=RX_ENC_FLAG_STBC_MASK * stbc; +if (*mode <MT_PHY_TYPE_HE_SU && gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; + +return 0 ; +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_fill_rx_rate); + +static void +mt76_connac3_mac_write_txwi_8023(__le32 *txwi, struct sk_buff*skb,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +12
-0+ struct mt76_wcid *wcid) +{ +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +u8 fc_type, fc_stype; +u16 ethertype; +bool wmm = false; +u32 val; + +if (wcid->sta) { +struct ieee80211_sta *sta; + + sta = container_of((void *)wcid, struct ieee80211_sta,
drv_priv);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +23
-0+ wmm = sta->wme; + } + + val =FIELD_PREP (MT_TXD1_HDR_FORMAT ,MT_HDR_FORMAT_802_3 ) | +FIELD_PREP (MT_TXD1_TID , tid); + + ethertype =get_unaligned_be16 (&skb->data[12 ]); +if (ethertype >=ETH_P_802_3_MIN ) + val |=MT_TXD1_ETH_802_3 ; + + txwi[1 ] |=cpu_to_le32 (val); + + fc_type =IEEE80211_FTYPE_DATA >>2 ; + fc_stype = wmm ?IEEE80211_STYPE_QOS_DATA >>4 :0 ; + + val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + + txwi[2 ] |=cpu_to_le32 (val); +} + +static void +mt76_connac3_mac_write_txwi_80211(struct mt76_dev *dev, __le32*txwi,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+struct sk_buff *skb, + struct ieee80211_key_conf *key) +{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb-Quoted 1 line
data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +bool multicast =is_multicast_ether_addr (hdr->addr1); +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +__le16 fc = hdr->frame_control; +u8 fc_type, fc_stype; +u32 val; + +if (ieee80211_is_action (fc) && + mgmt->u.action.category ==WLAN_CATEGORY_BACK && + mgmt->u.action.u.addba_req.action_code ==
WLAN_ACTION_ADDBA_REQ)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +47
-0+ tid =MT_TX_ADDBA ; + else if (ieee80211_is_mgmt(hdr->frame_control)) + tid =MT_TX_NORMAL ; + + val =FIELD_PREP (MT_TXD1_HDR_FORMAT ,MT_HDR_FORMAT_802_11 ) | +FIELD_PREP (MT_TXD1_HDR_INFO , +ieee80211_get_hdrlen_from_skb (skb) /2 ) | +FIELD_PREP (MT_TXD1_TID , tid); + +if (!ieee80211_is_data (fc) || multicast || + info->flags &IEEE80211_TX_CTL_USE_MINRATE ) + val |=MT_TXD1_FIXED_RATE ; + +if (key && multicast &&ieee80211_is_robust_mgmt_frame (skb) && + key->cipher ==WLAN_CIPHER_SUITE_AES_CMAC ) { + val |=MT_TXD1_BIP ; + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_PROTECT_FRAME ); + } + + txwi[1 ] |=cpu_to_le32 (val); + + fc_type = (le16_to_cpu (fc) &IEEE80211_FCTL_FTYPE ) >>2 ; + fc_stype = (le16_to_cpu (fc) &IEEE80211_FCTL_STYPE ) >>4 ; + + val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + + txwi[2 ] |=cpu_to_le32 (val); + + txwi[3 ] |=cpu_to_le32 (FIELD_PREP (MT_TXD3_BCM , multicast)); +if (ieee80211_is_beacon (fc)) { + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_SW_POWER_MGMT ); + txwi[3 ] |=cpu_to_le32 (MT_TXD3_REM_TX_COUNT ); + } + +if (info->flags &IEEE80211_TX_CTL_INJECTED ) { +u16 seqno =le16_to_cpu (hdr->seq_ctrl); + +if (ieee80211_is_back_req (hdr->frame_control)) { +struct ieee80211_bar *bar; + + bar = (struct ieee80211_bar *)skb->data; + seqno =le16_to_cpu (bar->start_seq_num); + } + + val =MT_TXD3_SN_VALID | + FIELD_PREP(MT_TXD3_SEQ,
IEEE80211_SEQ_TO_SN(seqno));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ txwi[3 ] |=cpu_to_le32 (val); + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_HW_AMSDU ); + } +} + +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev, __le32*txwi,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ struct sk_buff *skb, struct mt76_wcid*wcid,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+struct ieee80211_key_conf *key, intpid,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ enum mt76_txq_id qid, u32 changed) +{ + u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE :
MT_SDIO_TXD_SIZE;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +struct ieee80211_vif *vif = info->control.vif; +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; +u16 tx_count =15 ; +bool beacon = !!(changed & (BSS_CHANGED_BEACON | +BSS_CHANGED_BEACON_ENABLED )); + bool inband_disc = !!(changed &(
BSS_CHANGED_UNSOL_BCAST_PROBE_RESP|drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+ BSS_CHANGED_FILS_DISCOVERY)); + + mvif = vif ? (struct mt76_vif *)vif->drv_priv :NULL ; +if (mvif) { + omac_idx = mvif->omac_idx; + wmm_idx = mvif->wmm_idx; + band_idx = mvif->band_idx; + } + +if (inband_disc) { + p_fmt =MT_TX_TYPE_FW ; + q_idx =MT_LMAC_ALTX0 ; + }else if (beacon) { + p_fmt =MT_TX_TYPE_FW ; + q_idx =MT_LMAC_BCN0 ; + }else if (qid >=MT_TXQ_PSD ) { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ q_idx =MT_LMAC_ALTX0 ; + }else { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ q_idx = wmm_idx *MT76_CONNAC_MAX_WMM_SETS + + mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +45
-0+ } + + val =FIELD_PREP (MT_TXD0_TX_BYTES , skb->len + sz_txd) | +FIELD_PREP (MT_TXD0_PKT_FMT , p_fmt) | +FIELD_PREP (MT_TXD0_Q_IDX , q_idx); + txwi[0 ] =cpu_to_le32 (val); + + val =FIELD_PREP (MT_TXD1_WLAN_IDX , wcid->idx) | +FIELD_PREP (MT_TXD1_OWN_MAC , omac_idx); + +if (band_idx) + val |=FIELD_PREP (MT_TXD1_TGID , band_idx); + + txwi[1 ] =cpu_to_le32 (val); + txwi[2 ] =0 ; + + val =MT_TXD3_SW_POWER_MGMT | +FIELD_PREP (MT_TXD3_REM_TX_COUNT , tx_count); +if (key) + val |=MT_TXD3_PROTECT_FRAME ; +if (info->flags &IEEE80211_TX_CTL_NO_ACK ) + val |=MT_TXD3_NO_ACK ; +if (wcid->amsdu) + val |=MT_TXD3_HW_AMSDU ; + + txwi[3 ] =cpu_to_le32 (val); + txwi[4 ] =0 ; + + val =FIELD_PREP (MT_TXD5_PID , pid); +if (pid >=MT_PACKET_ID_FIRST ) + val |=MT_TXD5_TX_STATUS_HOST ; + txwi[5 ] =cpu_to_le32 (val); + + val =MT_TXD6_DIS_MAT |MT_TXD6_DAS | +FIELD_PREP (MT_TXD6_MSDU_CNT ,1 ); + txwi[6 ] =cpu_to_le32 (val); + txwi[7 ] =0 ; + +if (is_8023) +mt76_connac3_mac_write_txwi_8023 (txwi, skb, wcid); +else +mt76_connac3_mac_write_txwi_80211 (dev, txwi, skb, key); + +if (txwi[1 ] &cpu_to_le32 (MT_TXD1_FIXED_RATE )) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr*)skb->data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +14
-0+bool mcast =ieee80211_is_data (hdr->frame_control) && +is_multicast_ether_addr (hdr->addr1); +u8 idx =MT76_CONNAC3_BASIC_RATES_TBL ; + +if (mvif) { +if (mcast && mvif->mcast_rates_idx) + idx = mvif->mcast_rates_idx; +else if (beacon && mvif->beacon_rates_idx) + idx = mvif->beacon_rates_idx; +else + idx = mvif->basic_rates_idx; + } + + txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE,idx));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ txwi[3 ] |=cpu_to_le32 (MT_TXD3_BA_DISABLE ); + } +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_write_txwi); + +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+struct ieee80211_sta *sta, + struct list_head *free_list) +{ + __le32 *txwi; +u16 wcid_idx; + +mt76_connac_txp_skb_unmap (dev, t); +if (!t->skb) + goto out; + + txwi = (__le32 *)mt76_get_txwi_ptr (dev, t); +if (sta) { + struct mt76_wcid *wcid = (struct mt76_wcid *)sta-Quoted 1 line
drv_priv;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+ + wcid_idx = wcid->idx; +if (likely (t->skb->protocol !=cpu_to_be16 (ETH_P_PAE ))) +mt76_connac3_tx_check_aggr (sta, txwi); + }else { + wcid_idx =le32_get_bits (txwi[1 ],MT_TXD1_WLAN_IDX ); + } + +__mt76_tx_complete_skb (dev, wcid_idx, t->skb, free_list); +out: + t->skb =NULL ; +mt76_put_txwi (dev, t); +} +EXPORT_SYMBOL_GPL (mt76_connac3_txwi_free); + +static bool +mt76_connac3_mac_add_txs_skb(struct mt76_dev *dev, struct
mt76_wcid
*wcid,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +58
-0+ int pid, __le32 *txs_data) +{ + struct mt76_sta_stats *stats = &wcid->stats; +struct ieee80211_supported_band *sband; +struct ieee80211_tx_info *info; +u32 txrate, txs, mode, stbc; +struct rate_info rate = {}; +struct sk_buff_head list; +struct mt76_phy *mphy; +struct sk_buff *skb; +bool cck = false; + +mt76_tx_status_lock (dev, &list); + skb =mt76_tx_status_skb_get (dev, wcid, pid, &list); +if (!skb) + goto out_no_skb; + + txs =le32_to_cpu (txs_data[0 ]); + + info =IEEE80211_SKB_CB (skb); +if (!(txs &MT_TXS0_ACK_ERROR_MASK )) + info->flags |=IEEE80211_TX_STAT_ACK ; + + info->status.ampdu_len =1 ; + info->status.ampdu_ack_len = !!(info->flags & +IEEE80211_TX_STAT_ACK ); + info->status.rates[0 ].idx =-1 ; + + txrate =FIELD_GET (MT_TXS0_TX_RATE , txs); + + rate.mcs =FIELD_GET (MT_TX_RATE_IDX , txrate); + rate.nss =FIELD_GET (MT_TX_RATE_NSS , txrate) +1 ; + stbc =le32_get_bits (txs_data[3 ],MT_TXS3_RATE_STBC ); + +if (stbc && rate.nss >1 ) + rate.nss >>=1 ; + +if (rate.nss -1 <ARRAY_SIZE (stats->tx_nss)) + stats->tx_nss[rate.nss -1 ]++; +if (rate.mcs <ARRAY_SIZE (stats->tx_mcs)) + stats->tx_mcs[rate.mcs]++; + + mode =FIELD_GET (MT_TX_RATE_MODE , txrate); + switch (mode) { + case MT_PHY_TYPE_CCK: + cck = true; + fallthrough; + case MT_PHY_TYPE_OFDM: + mphy = mt76_dev_phy(dev, wcid->phy_idx); + + if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) + sband = &mphy->sband_5g.sband; + else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ) + sband = &mphy->sband_6g.sband; + else + sband = &mphy->sband_2g.sband; + + rate.mcs = mt76_get_rate(mphy->dev, sband, rate.mcs,cck);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +130
-0+ rate.legacy = sband->bitrates[rate.mcs].bitrate; +break ; +case MT_PHY_TYPE_HT : +case MT_PHY_TYPE_HT_GF : +if (rate.mcs >31 ) + goto out; + + rate.flags =RATE_INFO_FLAGS_MCS ; +if (wcid->rate.flags &RATE_INFO_FLAGS_SHORT_GI ) + rate.flags |=RATE_INFO_FLAGS_SHORT_GI ; +break ; +case MT_PHY_TYPE_VHT : +if (rate.mcs >9 ) + goto out; + + rate.flags =RATE_INFO_FLAGS_VHT_MCS ; +break ; +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : +case MT_PHY_TYPE_HE_MU : +if (rate.mcs >11 ) + goto out; + + rate.he_gi = wcid->rate.he_gi; + rate.he_dcm =FIELD_GET (MT_TX_RATE_DCM , txrate); + rate.flags =RATE_INFO_FLAGS_HE_MCS ; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : +if (rate.mcs >13 ) + goto out; + + rate.eht_gi = wcid->rate.eht_gi; + rate.flags =RATE_INFO_FLAGS_EHT_MCS ; +break ; +default : + goto out; + } + + stats->tx_mode[mode]++; + +switch (FIELD_GET (MT_TXS0_BW , txs)) { +case IEEE80211_STA_RX_BW_320 : + rate.bw =RATE_INFO_BW_320 ; + stats->tx_bw[4 ]++; +break ; +case IEEE80211_STA_RX_BW_160 : + rate.bw =RATE_INFO_BW_160 ; + stats->tx_bw[3 ]++; +break ; +case IEEE80211_STA_RX_BW_80 : + rate.bw =RATE_INFO_BW_80 ; + stats->tx_bw[2 ]++; +break ; +case IEEE80211_STA_RX_BW_40 : + rate.bw =RATE_INFO_BW_40 ; + stats->tx_bw[1 ]++; +break ; +default : + rate.bw =RATE_INFO_BW_20 ; + stats->tx_bw[0 ]++; +break ; + } + wcid->rate = rate; + +out: +mt76_tx_status_skb_done (dev, skb, &list); + +out_no_skb: +mt76_tx_status_unlock (dev, &list); + +return !!skb; +} + +void mt76_connac3_mac_add_txs (struct mt76_dev *dev,void *data, +u32 max_wtbl_size) +{ +struct mt76_wcid *wcid; +__le32 *txs_data = data; +u16 wcidx; +u8 pid; + +if (le32_get_bits (txs_data[0 ],MT_TXS0_TXS_FORMAT ) >1 ) +return ; + + wcidx =le32_get_bits (txs_data[2 ],MT_TXS2_WCID ); + pid =le32_get_bits (txs_data[3 ],MT_TXS3_PID ); + +if (pid <MT_PACKET_ID_FIRST ) +return ; + +if (wcidx >= max_wtbl_size) +return ; + +rcu_read_lock (); + + wcid =rcu_dereference (dev->wcid[wcidx]); +if (!wcid) + goto out; + +mt76_connac3_mac_add_txs_skb (dev, wcid, pid, txs_data); +if (!wcid->sta) + goto out; + +spin_lock_bh (&dev->sta_poll_lock); +if (list_empty (&wcid->poll_list)) +list_add_tail (&wcid->poll_list, &dev->sta_poll_list); +spin_unlock_bh (&dev->sta_poll_lock); + +out: +rcu_read_unlock (); +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_add_txs); + +void mt76_connac3_tx_token_put (struct mt76_dev *dev) +{ +struct mt76_txwi_cache *txwi; +int id; + +spin_lock_bh (&dev->token_lock); +idr_for_each_entry (&dev->token, txwi, id) { +mt76_connac3_txwi_free (dev, txwi,NULL ,NULL ); + dev->token_count--; + } +spin_unlock_bh (&dev->token_lock); +idr_destroy (&dev->token); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_token_put);diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hindex6663a0b46541..bcc1d976b2b0100644drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +0
-0@@ -4,6 +4,24 @@#ifndef __MT76_CONNAC3_MAC_H#define __MT76_CONNAC3_MAC_HQuoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h line 9
Quoted 6 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +1
-0+/* NOTE: used to map mt76_rates. idx may change if firmware expands
table */drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +2
-0+#define MT76_CONNAC3_BASIC_RATES_TBL 11 +#define MT76_CONNAC3_BEACON_RATES_TBL 25Different devices may have different defined value.
Quoted 5 lines
The other WiFi7 device I am working on relies on the values I moved in
mt76_connac3_mac.h(in common with mt7996). Moreover you can still have per-device values inmt7996/mac.h(I have not removed it).
Quoted 4 lines
Please double check with the mtk folk you work with. The 11 and 25 is the value I discussed with firmware folks to avoid overlapping the tbl mt7996 use (MU/other algo in fw), or it causes something hardly solving issue
sure, thx for pointing this out.
@Deren: can you please double check?
Regards,
Lorenzo
Quoted 15 lines
Quoted 15 lines
Quoted 4 lines
I'm thinking if it's too early to create this patch for just moving mt7996 to
connac3_lib?The code I moved is used by the other device as well. This series is a
preliminary series to support it.Regards,
LorenzoQuoted 3 lines
Ryder
A message that is not in the archive (sent off-list or not yet received): PH8PR12MB7230DC95457EF9C667E679AEAC51A@PH8PR12MB7230.namprd12.prod.outlook.com
A message that is not in the archive (sent off-list or not yet received): [email protected]
[email protected]
reviewerRe: [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library
Quoted 28 lines · Shayne Chen
Quoted 6 lines
Quoted 1 line
On Fri, 2023-06-09 at 18:34 +0200, [email protected]
Quoted 3 lines · wrote:
Quoted 3 lines · Ryder Lee
Quoted 2 lines · Lorenzo Bianconi
Quoted 1 line
Quoted 10 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
External email : Please do not click links or open
attachments
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
until you have verified the sender or the content.
Introduceconnac3_macinmt76_connaclibrary to reuse maccode
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
shared between WiFi7 chipsets.
Signed-off-by Lorenzo Bianconi <[email protected]>Hi Lorenzo,
I don't think it's a good idea to start sharing mac or mcu functions for all WiFi7 chipsets at such early stage.
The driver is still under many processes of bug fixing, performance tuning, and new features development.
Chipsets that mainly used for AP or STA segment have different designs
and should face different problems.
Quoted 8 lines
Start sharing the code at early stage will break the independence, make
it more hard to develop and do verifications, since many changes will affect chipsets of both segments.Thanks,
Shayne
(Resend for missing CC)
Quoted 1,001 lines
Quoted 1,001 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
--- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76_connac.h | 19 + .../wireless/mediatek/mt76/mt76_connac3_mac.c | 742 +++++++++++++++++ .../wireless/mediatek/mt76/mt76_connac3_mac.h | 18 + .../net/wireless/mediatek/mt76/mt7996/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 761 +-------
----
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
----
--.../net/wireless/mediatek/mt76/mt7996/main.c | 8 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +- .../wireless/mediatek/mt76/mt7996/mt7996.h | 28 +- 9 files changed, 807 insertions(+), 784 deletions(-) create
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
drivers/net/wireless/mediatek/mt76/Makefile mt76x02-lib-y := mt76x02_util.o
Quoted 9 lines
mode 100644
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cdrivers/net/wireless/mediatek/mt76/Makefile +0
-0@@ -27,7 +27,7 @@ mt76x02-lib-y := mt76x02_util.omt76x02_mac.o
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/Makefile +1
-1mt76x02_mcu.o \ mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o -mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o +mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.omt76_connac3_mac.o
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h void mt76_connac2_txwi_free(struct
Quoted 8 lines
obj-$(CONFIG_MT76x0_COMMON) += mt76x0/ obj-$(CONFIG_MT76x2_COMMON) += mt76x2/ diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac.hb/drivers/net/wireless/mediatek/mt76/mt76_connac.hindex68bdeada1421..20111678537b100644drivers/net/wireless/mediatek/mt76/mt76_connac.h +0
-0@@ -415,4 +415,23 @@ void mt76_connac2_txwi_free(struct
mt76_devQuoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0*dev, struct mt76_txwi_cache *t, struct list_head *free_list); voidmt76_connac2_tx_token_put (struct mt76_dev *dev); +/* connac3 */ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
__le32
*txwi);
+void mt76_connac3_mac_decode_he_radiotap(structsk_buff*skb,
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h
Quoted 9 lines
__le32
*rxv,
+ u8 mode);drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ __le32 *rxv, u8 *mode); +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev,
__le32Quoted 69 lines
Quoted 69 lines
Quoted 69 lines
Quoted 69 lines
*txwi,
+ structsk_buff*skb, structmt76_wcid*wcid,
+ structieee80211_key_conf*key, int
pid,
+ enummt76_txq_idqid, u32 changed); void +mt76_connac3_txwi_free(structmt76_dev*dev, structmt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac.h +6
-0+struct ieee80211_sta *sta, + struct list_head *free_list); void +mt76_connac3_mac_add_txs (struct mt76_dev *dev,void *data, +u32 max_wtbl_size); +void mt76_connac3_tx_token_put (struct mt76_dev *dev); +#endif /* __MT76_CONNAC_H */ diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cnew file mode 100644
index 000000000000..4b745bb74ca0drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0@@ -0,0 +1,742 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include "mt76_connac.h" +#include "mt76_connac3_mac.h" +#include "dma.h" + +#define HE_BITS (f)cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
+#defineHE_PREP(f, m, v)le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\
+IEEE80211_RADIOTAP_HE_
##f)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
__le32
*txwi)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+{ +struct mt76_wcid *wcid; +u16 fc, tid; +u32 val; + +if (!sta || + !(sta->deflink.ht_cap.ht_supported || sta-Quoted 1 line
deflink.he_cap.has_he))
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + +tid =le32_get_bits (txwi[1 ],MT_TXD1_TID ); +if (tid >=6 )/* skip VO queue */ +return ; + +val =le32_to_cpu (txwi[2 ]); +fc =FIELD_GET (MT_TXD2_FRAME_TYPE , val) <<2 | +FIELD_GET (MT_TXD2_SUB_TYPE , val) <<4 ; +if (unlikely(fc != (IEEE80211_FTYPE_DATA |
IEEE80211_STYPE_QOS_DATA)))drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+return ; + +wcid = (struct mt76_wcid *)sta->drv_priv; +if (!test_and_set_bit (tid, &wcid->ampdu_state)) +ieee80211_start_tx_ba_session (sta, tid,0 ); } +EXPORT_SYMBOL_GPL (mt76_connac3_tx_check_aggr); + +static void +mt76_connac3_mac_decode_he_radiotap_ru(structQuoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
mt76_rx_status
*status,
+ structieee80211_radiotap_he
*he,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ __le32 *rxv) +{ +u32 ru =le32_get_bits (rxv[0 ],MT_PRXV_HE_RU_ALLOC ), offs=
0;
Quoted 40 lines
Quoted 40 lines
Quoted 40 lines
Quoted 40 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +36
-0+ +status->bw =RATE_INFO_BW_HE_RU ; + +switch (ru) { +case 0 ... 36: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_26 ; +offs = ru; +break ; +case 37 ... 52: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_52 ; +offs = ru -37 ; +break ; +case 53 ... 60: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_106 ; +offs = ru -53 ; +break ; +case 61 ... 64: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_242 ; +offs = ru -61 ; +break ; +case 65 ... 66: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_484 ; +offs = ru -65 ; +break ; +case 67 : +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_996 ; +break ; +case 68 : +status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; +break ; +} + +he->data1 |=HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); +he->data2 |=HE_BITS (DATA2_RU_OFFSET_KNOWN ) | +le16_encode_bits (offs, + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+} + +#define MU_PREP (f, v)le16_encode_bits(v,Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
IEEE80211_RADIOTAP_HE_MU_##f)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+static void +mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff*skb,
__le32
*rxv)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ +struct mt76_rx_status *status = (struct mt76_rx_status*)skb-
Quoted 46 lines
Quoted 17 lines
Quoted 17 lines
Quoted 7 lines
Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+static const struct ieee80211_radiotap_he_mu mu_known = { +.flags1 =HE_BITS (MU_FLAGS1_SIG_B_MCS_KNOWN ) | +HE_BITS (MU_FLAGS1_SIG_B_DCM_KNOWN ) | +HE_BITS (MU_FLAGS1_CH1_RU_KNOWN ) | +HE_BITS (MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN ),drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+.flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), +}; +struct ieee80211_radiotap_he_mu *he_mu; + +status->flag |=RX_FLAG_RADIOTAP_HE_MU ; + +he_mu =skb_push (skb,sizeof (mu_known)); +memcpy (he_mu, &mu_known,sizeof (mu_known)); + +he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status-
rate_idx);Quoted 6 lines
Quoted 6 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 6 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+if (status->he_dcm) +he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status-Quoted 1 line
he_dcm);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status-bw) |
Quoted 19 lines
Quoted 19 lines
Quoted 19 lines
+ MU_PREP(FLAGS2_SIG_B_SYMS_USERS,
+ le32_get_bits(rxv[4],MT_CRXV_HE_NUM_USER));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +he_mu->ru_ch1[0 ] =le32_get_bits (rxv[16 ],MT_CRXV_HE_RU0 )&
0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ +if (status->bw >=RATE_INFO_BW_40 ) { +he_mu->flags1 |=HE_BITS (MU_FLAGS1_CH2_RU_KNOWN ); +he_mu->ru_ch2[0] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU1) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+} + +if (status->bw >=RATE_INFO_BW_80 ) { +u32 ru_h, ru_l; + +he_mu->ru_ch1[1] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU2) &0xff;Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+ +ru_l =le32_get_bits (rxv[16 ],MT_CRXV_HE_RU3_L ); +ru_h =le32_get_bits (rxv[17 ],MT_CRXV_HE_RU3_H ) &0x7 ; +he_mu->ru_ch2[1 ] = (u8)(ru_l | ru_h <<4 ); +} +} + +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff*skb,
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 5 lines
__le32
*rxv,
+ u8 mode)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ +struct mt76_rx_status *status = (struct mt76_rx_status*)skb-
Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
Quoted 8 lines
Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+static const struct ieee80211_radiotap_he known = { +.data1 =HE_BITS (DATA1_DATA_MCS_KNOWN ) | +HE_BITS (DATA1_DATA_DCM_KNOWN ) | +HE_BITS (DATA1_STBC_KNOWN ) | +HE_BITS (DATA1_CODING_KNOWN ) | + HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+HE_BITS (DATA1_DOPPLER_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE_KNOWN ) | + HE_BITS(DATA1_BSS_COLOR_KNOWN), +.data2 =HE_BITS (DATA2_GI_KNOWN ) | +HE_BITS (DATA2_TXBF_KNOWN ) | +HE_BITS (DATA2_PE_DISAMBIG_KNOWN ) | + HE_BITS(DATA2_TXOP_KNOWN), +}; +u32 ltf_size =le32_get_bits (rxv[4 ],MT_CRXV_HE_LTF_SIZE ) +1;
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_radiotap_he *he; + +status->flag |=RX_FLAG_RADIOTAP_HE ; + +he =skb_push (skb,sizeof (known)); +memcpy (he, &known,sizeof (known)); + +he->data3 =HE_PREP (DATA3_BSS_COLOR ,BSS_COLOR , rxv[9 ]) | +HE_PREP (DATA3_LDPC_XSYMSEG ,LDPC_EXT_SYM , rxv[4 ]); +he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK,rxv[13]);
Quoted 166 lines
Quoted 166 lines
Quoted 166 lines
Quoted 166 lines
+he->data5 =
HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5])drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+le16_encode_bits (ltf_size, + IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+if (le32_to_cpu (rxv[0 ]) &MT_PRXV_TXBF ) +he->data5 |=HE_BITS (DATA5_TXBF ); +he->data6 =HE_PREP (DATA6_TXOP ,TXOP_DUR , rxv[9 ]) | +HE_PREP (DATA6_DOPPLER ,DOPPLER , rxv[9 ]); + +switch (mode) { +case MT_PHY_TYPE_HE_SU : +he->data1 |=HE_BITS (DATA1_FORMAT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BEAM_CHANGE_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + +he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG,rxv[8]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_EXT_SU : +he->data1 |=HE_BITS (DATA1_FORMAT_EXT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + +he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_MU : +he->data1 |=HE_BITS (DATA1_FORMAT_MU ) | +HE_BITS (DATA1_UL_DL_KNOWN ); + +he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +he->data4 |=HE_PREP (DATA4_MU_STA_ID ,MU_AID , rxv[8 ]); + +mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+mt76_connac3_mac_decode_he_mu_radiotap (skb, rxv); +break ; +case MT_PHY_TYPE_HE_TB : +he->data1 |=HE_BITS (DATA1_FORMAT_TRIG ) | +HE_BITS (DATA1_SPTL_REUSE2_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE3_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE4_KNOWN ); + +he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK,rxv[13]) |
+ HE_PREP(DATA4_TB_SPTL_REUSE2,SR1_MASK,
rxv[13]) |
+ HE_PREP(DATA4_TB_SPTL_REUSE3,SR2_MASK,
rxv[13]) |
+ HE_PREP(DATA4_TB_SPTL_REUSE4,SR3_MASK,
rxv[13]);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+break ; +default : +break ; +} +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_decode_he_radiotap); + +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +99
-0+ __le32 *rxv, u8 *mode) +{ +u8 stbc, gi, bw, dcm, nss; +bool cck = false; +u32 v0, v2; +int i, idx; + +v0 =le32_to_cpu (rxv[0 ]); +v2 =le32_to_cpu (rxv[2 ]); + +idx =FIELD_GET (MT_PRXV_TX_RATE , v0); +i = idx; +nss =FIELD_GET (MT_PRXV_NSTS , v0) +1 ; + +stbc =FIELD_GET (MT_PRXV_HT_STBC , v2); +gi =FIELD_GET (MT_PRXV_HT_SHORT_GI , v2); +*mode =FIELD_GET (MT_PRXV_TX_MODE , v2); +dcm =FIELD_GET (MT_PRXV_DCM , v2); +bw =FIELD_GET (MT_PRXV_FRAME_MODE , v2); + +switch (*mode) { +case MT_PHY_TYPE_CCK : +cck = true; +fallthrough; +case MT_PHY_TYPE_OFDM : +i =mt76_get_rate (dev, sband, i, cck); +break ; +case MT_PHY_TYPE_HT_GF : +case MT_PHY_TYPE_HT : +status->encoding =RX_ENC_HT ; +if (gi) +status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >31 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_VHT : +status->nss = nss; +status->encoding =RX_ENC_VHT ; +if (gi) +status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >11 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_HE_MU : +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : +status->nss = nss; +status->encoding =RX_ENC_HE ; +i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_HE_GI_3_2 ) +status->he_gi = gi; + +status->he_dcm = dcm; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : +status->nss = nss; +status->encoding =RX_ENC_EHT ; +i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_EHT_GI_3_2 ) +status->eht.gi = gi; +break ; +default : +return -EINVAL ; +} +status->rate_idx = i; + +switch (bw) { +case IEEE80211_STA_RX_BW_20 : +break ; +case IEEE80211_STA_RX_BW_40 : +if (*mode &MT_PHY_TYPE_HE_EXT_SU && + (idx &MT_PRXV_TX_ER_SU_106T )) { +status->bw =RATE_INFO_BW_HE_RU ; +status->he_ru = +NL80211_RATE_INFO_HE_RU_ALLOC_106 ; +}else { +status->bw =RATE_INFO_BW_40 ; +} +break ; +case IEEE80211_STA_RX_BW_80 : +status->bw =RATE_INFO_BW_80 ; +break ; +case IEEE80211_STA_RX_BW_160 : +status->bw =RATE_INFO_BW_160 ; +break ; +case IEEE80211_STA_RX_BW_320 : +status->bw =RATE_INFO_BW_320 ; +break ; +default : +return -EINVAL ; +} + +status->enc_flags |=RX_ENC_FLAG_STBC_MASK * stbc; +if (*mode <MT_PHY_TYPE_HE_SU && gi)Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; + +return 0 ; +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_fill_rx_rate); + +static void +mt76_connac3_mac_write_txwi_8023(__le32 *txwi, struct
sk_buffQuoted 30 lines
Quoted 30 lines
Quoted 30 lines
Quoted 30 lines
*skb,
+ structmt76_wcid*wcid)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +11
-0+{ +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +u8 fc_type, fc_stype; +u16 ethertype; +bool wmm = false; +u32 val; + +if (wcid->sta) { +struct ieee80211_sta *sta; + +sta = container_of((void *)wcid, struct ieee80211_sta,
drv_priv);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+wmm = sta->wme; +} + +val =FIELD_PREP (MT_TXD1_HDR_FORMAT ,MT_HDR_FORMAT_802_3 )|
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +11
-0+FIELD_PREP (MT_TXD1_TID , tid); + +ethertype =get_unaligned_be16 (&skb->data[12 ]); +if (ethertype >=ETH_P_802_3_MIN ) +val |=MT_TXD1_ETH_802_3 ; + +txwi[1 ] |=cpu_to_le32 (val); + +fc_type =IEEE80211_FTYPE_DATA >>2 ; +fc_stype = wmm ?IEEE80211_STYPE_QOS_DATA >>4 :0 ; +Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + +txwi[2 ] |=cpu_to_le32 (val); +} + +static void +mt76_connac3_mac_write_txwi_80211(struct mt76_dev *dev,
__le32Quoted 29 lines
Quoted 4 lines
Quoted 4 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 4 lines
*txwi,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+struct sk_buff *skb, + struct ieee80211_key_conf *key) { +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb-data;
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
+struct
ieee80211_mgmt*mgmt = (structieee80211_mgmt*)skb-Quoted 1 line
data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +bool multicast =is_multicast_ether_addr (hdr->addr1); +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +__le16 fc = hdr->frame_control; +u8 fc_type, fc_stype; +u32 val; + +if (ieee80211_is_action (fc) && + mgmt->u.action.category ==WLAN_CATEGORY_BACK && + mgmt->u.action.u.addba_req.action_code ==
WLAN_ACTION_ADDBA_REQ)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+tid =MT_TX_ADDBA ; +else if (ieee80211_is_mgmt(hdr->frame_control)) +tid =MT_TX_NORMAL ; + +val =FIELD_PREP (MT_TXD1_HDR_FORMAT ,MT_HDR_FORMAT_802_11 )|
+ FIELD_PREP(MT_TXD1_HDR_INFO,
+ieee80211_get_hdrlen_from_skb(skb)/ 2) |Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+FIELD_PREP (MT_TXD1_TID , tid); + +if (!ieee80211_is_data (fc) || multicast || + info->flags &IEEE80211_TX_CTL_USE_MINRATE ) +val |=MT_TXD1_FIXED_RATE ; + +if (key && multicast &&
ieee80211_is_robust_mgmt_frame(skb)&&
Quoted 33 lines
Quoted 33 lines
Quoted 33 lines
Quoted 33 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +16
-0+ key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { +val |=MT_TXD1_BIP ; +txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_PROTECT_FRAME ); +} + +txwi[1 ] |=cpu_to_le32 (val); + +fc_type = (le16_to_cpu (fc) &IEEE80211_FCTL_FTYPE ) >>2 ; +fc_stype = (le16_to_cpu (fc) &IEEE80211_FCTL_STYPE ) >>4 ; + +val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + +txwi[2 ] |=cpu_to_le32 (val); + +txwi[3] |= cpu_to_le32(FIELD_PREP(MT_TXD3_BCM,multicast));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +16
-0+if (ieee80211_is_beacon (fc)) { +txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_SW_POWER_MGMT ); +txwi[3 ] |=cpu_to_le32 (MT_TXD3_REM_TX_COUNT ); +} + +if (info->flags &IEEE80211_TX_CTL_INJECTED ) { +u16 seqno =le16_to_cpu (hdr->seq_ctrl); + +if (ieee80211_is_back_req (hdr->frame_control)) { +struct ieee80211_bar *bar; + +bar = (struct ieee80211_bar *)skb->data; +seqno =le16_to_cpu (bar->start_seq_num); +} + +val = MT_TXD3_SN_VALID |Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
+ FIELD_PREP(MT_TXD3_SEQ,
IEEE80211_SEQ_TO_SN(seqno));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+txwi[3 ] |=cpu_to_le32 (val); +txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_HW_AMSDU ); +} +} + +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev,
__le32Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
*txwi,
+ structsk_buff*skb, structmt76_wcid
*wcid,
+ structieee80211_key_conf*key, int
pid,
+ enummt76_txq_idqid, u32 changed)Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ +u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE :
MT_SDIO_TXD_SIZE;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +struct ieee80211_vif *vif = info->control.vif; +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;Quoted 261 lines
Quoted 261 lines
Quoted 261 lines
Quoted 261 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+struct mt76_vif *mvif; +u16 tx_count =15 ; +bool beacon = !!(changed & (BSS_CHANGED_BEACON | +BSS_CHANGED_BEACON_ENABLED )); +bool inband_disc = !!(changed &(
BSS_CHANGED_UNSOL_BCAST_PROBE_RESP|
+BSS_CHANGED_FILS_DISCOVERY));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +16
-0+ +mvif = vif ? (struct mt76_vif *)vif->drv_priv :NULL ; +if (mvif) { +omac_idx = mvif->omac_idx; +wmm_idx = mvif->wmm_idx; +band_idx = mvif->band_idx; +} + +if (inband_disc) { +p_fmt =MT_TX_TYPE_FW ; +q_idx =MT_LMAC_ALTX0 ; +}else if (beacon) { +p_fmt =MT_TX_TYPE_FW ; +q_idx =MT_LMAC_BCN0 ; +}else if (qid >=MT_TXQ_PSD ) { +p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+q_idx =MT_LMAC_ALTX0 ; +}else { +p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+q_idx = wmm_idx *MT76_CONNAC_MAX_WMM_SETS + +mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +45
-0+} + +val =FIELD_PREP (MT_TXD0_TX_BYTES , skb->len + sz_txd) | +FIELD_PREP (MT_TXD0_PKT_FMT , p_fmt) | +FIELD_PREP (MT_TXD0_Q_IDX , q_idx); +txwi[0 ] =cpu_to_le32 (val); + +val =FIELD_PREP (MT_TXD1_WLAN_IDX , wcid->idx) | +FIELD_PREP (MT_TXD1_OWN_MAC , omac_idx); + +if (band_idx) +val |=FIELD_PREP (MT_TXD1_TGID , band_idx); + +txwi[1 ] =cpu_to_le32 (val); +txwi[2 ] =0 ; + +val =MT_TXD3_SW_POWER_MGMT | +FIELD_PREP (MT_TXD3_REM_TX_COUNT , tx_count); +if (key) +val |=MT_TXD3_PROTECT_FRAME ; +if (info->flags &IEEE80211_TX_CTL_NO_ACK ) +val |=MT_TXD3_NO_ACK ; +if (wcid->amsdu) +val |=MT_TXD3_HW_AMSDU ; + +txwi[3 ] =cpu_to_le32 (val); +txwi[4 ] =0 ; + +val =FIELD_PREP (MT_TXD5_PID , pid); +if (pid >=MT_PACKET_ID_FIRST ) +val |=MT_TXD5_TX_STATUS_HOST ; +txwi[5 ] =cpu_to_le32 (val); + +val =MT_TXD6_DIS_MAT |MT_TXD6_DAS | +FIELD_PREP (MT_TXD6_MSDU_CNT ,1 ); +txwi[6 ] =cpu_to_le32 (val); +txwi[7 ] =0 ; + +if (is_8023) +mt76_connac3_mac_write_txwi_8023 (txwi, skb, wcid); +else +mt76_connac3_mac_write_txwi_80211 (dev, txwi, skb, key); + +if (txwi[1 ] &cpu_to_le32 (MT_TXD1_FIXED_RATE )) { +struct ieee80211_hdr *hdr = (struct ieee80211_hdr*)skb->data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +14
-0+bool mcast =ieee80211_is_data (hdr->frame_control) && +is_multicast_ether_addr (hdr->addr1); +u8 idx =MT76_CONNAC3_BASIC_RATES_TBL ; + +if (mvif) { +if (mcast && mvif->mcast_rates_idx) +idx = mvif->mcast_rates_idx; +else if (beacon && mvif->beacon_rates_idx) +idx = mvif->beacon_rates_idx; +else +idx = mvif->basic_rates_idx; +} + +txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE,idx));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+txwi[3 ] |=cpu_to_le32 (MT_TXD3_BA_DISABLE ); +} +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_write_txwi); + +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+struct ieee80211_sta *sta, + struct list_head *free_list) +{ +__le32 *txwi; +u16 wcid_idx; + +mt76_connac_txp_skb_unmap (dev, t); +if (!t->skb) +goto out; + +txwi = (__le32 *)mt76_get_txwi_ptr (dev, t); +if (sta) { +struct mt76_wcid *wcid = (struct mt76_wcid *)sta-Quoted 1 line
drv_priv;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+ +wcid_idx = wcid->idx; +if (likely (t->skb->protocol !=cpu_to_be16 (ETH_P_PAE ))) +mt76_connac3_tx_check_aggr (sta, txwi); +}else { +wcid_idx =le32_get_bits (txwi[1 ],MT_TXD1_WLAN_IDX ); +} + +__mt76_tx_complete_skb (dev, wcid_idx, t->skb, free_list); +out: +t->skb =NULL ; +mt76_put_txwi (dev, t); +} +EXPORT_SYMBOL_GPL (mt76_connac3_txwi_free); + +static bool +mt76_connac3_mac_add_txs_skb(struct mt76_dev *dev, struct
mt76_wcid
*wcid,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +58
-0+ int pid, __le32 *txs_data) +{ +struct mt76_sta_stats *stats = &wcid->stats; +struct ieee80211_supported_band *sband; +struct ieee80211_tx_info *info; +u32 txrate, txs, mode, stbc; +struct rate_info rate = {}; +struct sk_buff_head list; +struct mt76_phy *mphy; +struct sk_buff *skb; +bool cck = false; + +mt76_tx_status_lock (dev, &list); +skb =mt76_tx_status_skb_get (dev, wcid, pid, &list); +if (!skb) +goto out_no_skb; + +txs =le32_to_cpu (txs_data[0 ]); + +info =IEEE80211_SKB_CB (skb); +if (!(txs &MT_TXS0_ACK_ERROR_MASK )) +info->flags |=IEEE80211_TX_STAT_ACK ; + +info->status.ampdu_len =1 ; +info->status.ampdu_ack_len = !!(info->flags & +IEEE80211_TX_STAT_ACK ); +info->status.rates[0 ].idx =-1 ; + +txrate =FIELD_GET (MT_TXS0_TX_RATE , txs); + +rate.mcs =FIELD_GET (MT_TX_RATE_IDX , txrate); +rate.nss =FIELD_GET (MT_TX_RATE_NSS , txrate) +1 ; +stbc =le32_get_bits (txs_data[3 ],MT_TXS3_RATE_STBC ); + +if (stbc && rate.nss >1 ) +rate.nss >>=1 ; + +if (rate.nss -1 <ARRAY_SIZE (stats->tx_nss)) +stats->tx_nss[rate.nss -1 ]++; +if (rate.mcs <ARRAY_SIZE (stats->tx_mcs)) +stats->tx_mcs[rate.mcs]++; + +mode =FIELD_GET (MT_TX_RATE_MODE , txrate); +switch (mode) { +case MT_PHY_TYPE_CCK: +cck = true; +fallthrough; +case MT_PHY_TYPE_OFDM: +mphy = mt76_dev_phy(dev, wcid->phy_idx); + +if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) +sband = &mphy->sband_5g.sband; +else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ) +sband = &mphy->sband_6g.sband; +else +sband = &mphy->sband_2g.sband; + +rate.mcs = mt76_get_rate(mphy->dev, sband, rate.mcs,cck);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +69
-0+rate.legacy = sband->bitrates[rate.mcs].bitrate; +break ; +case MT_PHY_TYPE_HT : +case MT_PHY_TYPE_HT_GF : +if (rate.mcs >31 ) +goto out; + +rate.flags =RATE_INFO_FLAGS_MCS ; +if (wcid->rate.flags &RATE_INFO_FLAGS_SHORT_GI ) +rate.flags |=RATE_INFO_FLAGS_SHORT_GI ; +break ; +case MT_PHY_TYPE_VHT : +if (rate.mcs >9 ) +goto out; + +rate.flags =RATE_INFO_FLAGS_VHT_MCS ; +break ; +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : +case MT_PHY_TYPE_HE_MU : +if (rate.mcs >11 ) +goto out; + +rate.he_gi = wcid->rate.he_gi; +rate.he_dcm =FIELD_GET (MT_TX_RATE_DCM , txrate); +rate.flags =RATE_INFO_FLAGS_HE_MCS ; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : +if (rate.mcs >13 ) +goto out; + +rate.eht_gi = wcid->rate.eht_gi; +rate.flags =RATE_INFO_FLAGS_EHT_MCS ; +break ; +default : +goto out; +} + +stats->tx_mode[mode]++; + +switch (FIELD_GET (MT_TXS0_BW , txs)) { +case IEEE80211_STA_RX_BW_320 : +rate.bw =RATE_INFO_BW_320 ; +stats->tx_bw[4 ]++; +break ; +case IEEE80211_STA_RX_BW_160 : +rate.bw =RATE_INFO_BW_160 ; +stats->tx_bw[3 ]++; +break ; +case IEEE80211_STA_RX_BW_80 : +rate.bw =RATE_INFO_BW_80 ; +stats->tx_bw[2 ]++; +break ; +case IEEE80211_STA_RX_BW_40 : +rate.bw =RATE_INFO_BW_40 ; +stats->tx_bw[1 ]++; +break ; +default : +rate.bw =RATE_INFO_BW_20 ; +stats->tx_bw[0 ]++; +break ; +} +wcid->rate = rate; + +out: +mt76_tx_status_skb_done (dev, skb, &list);Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+ +out_no_skb: +mt76_tx_status_unlock (dev, &list); + +return !!skb; +} + +void mt76_connac3_mac_add_txs(struct mt76_dev *dev, void*data,
Quoted 73 lines
Quoted 73 lines
Quoted 72 lines
Quoted 68 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +53
-0+ u32 max_wtbl_size) +{ +struct mt76_wcid *wcid; +__le32 *txs_data = data; +u16 wcidx; +u8 pid; + +if (le32_get_bits (txs_data[0 ],MT_TXS0_TXS_FORMAT ) >1 ) +return ; + +wcidx =le32_get_bits (txs_data[2 ],MT_TXS2_WCID ); +pid =le32_get_bits (txs_data[3 ],MT_TXS3_PID ); + +if (pid <MT_PACKET_ID_FIRST ) +return ; + +if (wcidx >= max_wtbl_size) +return ; + +rcu_read_lock (); + +wcid =rcu_dereference (dev->wcid[wcidx]); +if (!wcid) +goto out; + +mt76_connac3_mac_add_txs_skb (dev, wcid, pid, txs_data); +if (!wcid->sta) +goto out; + +spin_lock_bh (&dev->sta_poll_lock); +if (list_empty (&wcid->poll_list)) +list_add_tail (&wcid->poll_list, &dev->sta_poll_list); +spin_unlock_bh (&dev->sta_poll_lock); + +out: +rcu_read_unlock (); +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_add_txs); + +void mt76_connac3_tx_token_put (struct mt76_dev *dev) +{ +struct mt76_txwi_cache *txwi; +int id; + +spin_lock_bh (&dev->token_lock); +idr_for_each_entry(&dev->token, txwi, id) { +mt76_connac3_txwi_free (dev, txwi,NULL ,NULL ); +dev->token_count--; +} +spin_unlock_bh (&dev->token_lock); +idr_destroy (&dev->token); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_token_put);diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hindex6663a0b46541..bcc1d976b2b0100644drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +1
-0@@ -4,6 +4,24 @@#ifndef __MT76_CONNAC3_MAC_H#define __MT76_CONNAC3_MAC_H +/* NOTE: used to map mt76_rates. idx may change if firmware
expands
table */drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
Quoted 2 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +2
-0+#define MT76_CONNAC3_BASIC_RATES_TBL11 +#define MT76_CONNAC3_BEACON_RATES_TBL25 Different devices may have different defined value.
Quoted 1 line
Quoted 1 line
The other WiFi7 device I am working on relies on the values I
moved
Quoted 2 lines
Quoted 2 lines
in
mt76_connac3_mac.h(in common with mt7996). Moreover you canstill
Quoted 5 lines
Quoted 2 lines
have per-device values in
mt7996/mac.h(I have not removed it).Please double check with the mtk folk you work with. The 11 and 25
is
Quoted 2 lines
the value I discussed with firmware folks to avoid overlapping the
tbl
Quoted 1 line
mt7996 use (MU/other algo in fw), or it causes something hardly
solving
Quoted 1 line
issue
sure, thx for pointing this out.
@Deren: can you please double check?Regards,
LorenzoQuoted 3 lines
Quoted 3 lines
Quoted 3 lines
I'm thinking if it's too early to create this patch for just
moving
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
mt7996 to
connac3_lib?The code I moved is used by the other device as well. This series
is
Quoted 9 lines
Quoted 9 lines
a
preliminary series to support it.Regards,
LorenzoQuoted 3 lines
Ryder
[email protected]
maintainerRe: [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library
Quoted 13 lines · Shayne Chen
Quoted 12 lines
Quoted 12 lines
Quoted 1 line
On Fri, 2023-06-09 at 18:34 +0200, [email protected]
Quoted 4 lines · wrote:
Quoted 4 lines · Ryder Lee
Quoted 3 lines · Lorenzo Bianconi
Quoted 2 lines
External email : Please do not click links or open
attachments
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
until you have verified the sender or the content.
Introduceconnac3_macinmt76_connaclibrary to reuse mac
Quoted 6 lines
Quoted 6 lines
Quoted 4 lines
code
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
shared between WiFi7 chipsets.
Signed-off-by Lorenzo Bianconi <[email protected]>Hi Lorenzo,
Hi Shayne,
Quoted 10 lines
Quoted 10 lines
I don't think it's a good idea to start sharing mac or mcu functions for all WiFi7 chipsets at such early stage.
The driver is still under many processes of bug fixing, performance tuning, and new features development.
Chipsets that mainly used for AP or STA segment have different designs
and should face different problems.
Quoted 4 lines
Quoted 4 lines
Start sharing the code at early stage will break the independence, make
it more hard to develop and do verifications, since many changes will affect chipsets of both segments.
my goal is to share the code that hardly will be changed (or that will have very few changes in the future, i.e. I have not changed mcu codebase). If you consider for example the routines below:
- mt76_connac*_mac_write_txwi_8023()
- mt76_connac*_mac_write_txwi_80211()
- mt76_connac*_mac_add_txs_skb()
- mt76_connac*_txwi_free()
- ...
they are the same for mt7615/mt7663, mt7921/mt7915, mt7996/.. , what is changing is just register map between versions (e.g. mt7615/mt7663 and mt7915/mt7921). I think it is not a good idea to copy-paste the code because it will just make the code much harder to maintain, and this will be more difficult to address in the future.
If you consider the commit below:
commit ead449023d3acb1424886d7b8cc672ed69bdd27e
Author: Lorenzo Bianconi <[email protected]> Date: Sun May 28 12:28:49 2023 +0200
wifi: mt76: mt7996: fix possible NULL pointer dereference in mt7996_mac_write_txwi()
Fix possible NULL pointer dereference on mvif pointer in mt7996_mac_write_txwi routine.
Deren will needs to monitor the ML and apply the same fix for the other WiFi7 chipset too.
Moreover I kept mt7996/mac.{c,h} to put the per-chipset codebase. If you think MT76_CONNAC3_BASIC_RATES_TBL11 and MT76_CONNAC3_BEACON_RATES_TBL25 are sensible, we can put them in mt7996/mac.h
Regards,
Lorenzo
Quoted 1,007 lines
Quoted 4 lines
Thanks,
Shayne(Resend for missing CC)
Quoted 1,001 lines
Quoted 1,001 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
--- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76_connac.h | 19 + .../wireless/mediatek/mt76/mt76_connac3_mac.c | 742 +++++++++++++++++ .../wireless/mediatek/mt76/mt76_connac3_mac.h | 18 + .../net/wireless/mediatek/mt76/mt7996/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 761 +-------
----
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
----
--.../net/wireless/mediatek/mt76/mt7996/main.c | 8 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +- .../wireless/mediatek/mt76/mt7996/mt7996.h | 28 +- 9 files changed, 807 insertions(+), 784 deletions(-) create
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
drivers/net/wireless/mediatek/mt76/Makefile mt76x02-lib-y := mt76x02_util.o
Quoted 9 lines
mode 100644
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cdrivers/net/wireless/mediatek/mt76/Makefile +0
-0@@ -27,7 +27,7 @@ mt76x02-lib-y := mt76x02_util.omt76x02_mac.o
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/Makefile +1
-1mt76x02_mcu.o \ mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o -mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o +mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.omt76_connac3_mac.o
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h void mt76_connac2_txwi_free(struct
Quoted 8 lines
obj-$(CONFIG_MT76x0_COMMON) += mt76x0/ obj-$(CONFIG_MT76x2_COMMON) += mt76x2/ diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac.hb/drivers/net/wireless/mediatek/mt76/mt76_connac.hindex68bdeada1421..20111678537b100644drivers/net/wireless/mediatek/mt76/mt76_connac.h +0
-0@@ -415,4 +415,23 @@ void mt76_connac2_txwi_free(struct
mt76_devQuoted 9 lines
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0*dev, struct mt76_txwi_cache *t, struct list_head *free_list); voidmt76_connac2_tx_token_put (struct mt76_dev *dev); +/* connac3 */ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
__le32
*txwi);
+void mt76_connac3_mac_decode_he_radiotap(structsk_buff*skb,
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h
Quoted 9 lines
__le32
*rxv,
+ u8 mode);drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ __le32 *rxv, u8 *mode); +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev,
__le32Quoted 69 lines
Quoted 69 lines
Quoted 69 lines
Quoted 69 lines
*txwi,
+ structsk_buff*skb, structmt76_wcid*wcid,
+ structieee80211_key_conf*key, int
pid,
+ enummt76_txq_idqid, u32 changed); void +mt76_connac3_txwi_free(structmt76_dev*dev, structmt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac.h +6
-0+struct ieee80211_sta *sta, + struct list_head *free_list); void +mt76_connac3_mac_add_txs (struct mt76_dev *dev,void *data, +u32 max_wtbl_size); +void mt76_connac3_tx_token_put (struct mt76_dev *dev); +#endif /* __MT76_CONNAC_H */ diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cnew file mode 100644
index 000000000000..4b745bb74ca0drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0@@ -0,0 +1,742 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include "mt76_connac.h" +#include "mt76_connac3_mac.h" +#include "dma.h" + +#define HE_BITS (f)cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
+#defineHE_PREP(f, m, v)le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\
+IEEE80211_RADIOTAP_HE_
##f)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
__le32
*txwi)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+{ +struct mt76_wcid *wcid; +u16 fc, tid; +u32 val; + +if (!sta || + !(sta->deflink.ht_cap.ht_supported || sta-Quoted 1 line
deflink.he_cap.has_he))
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + +tid =le32_get_bits (txwi[1 ],MT_TXD1_TID ); +if (tid >=6 )/* skip VO queue */ +return ; + +val =le32_to_cpu (txwi[2 ]); +fc =FIELD_GET (MT_TXD2_FRAME_TYPE , val) <<2 | +FIELD_GET (MT_TXD2_SUB_TYPE , val) <<4 ; +if (unlikely(fc != (IEEE80211_FTYPE_DATA |
IEEE80211_STYPE_QOS_DATA)))drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+return ; + +wcid = (struct mt76_wcid *)sta->drv_priv; +if (!test_and_set_bit (tid, &wcid->ampdu_state)) +ieee80211_start_tx_ba_session (sta, tid,0 ); } +EXPORT_SYMBOL_GPL (mt76_connac3_tx_check_aggr); + +static void +mt76_connac3_mac_decode_he_radiotap_ru(structQuoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
mt76_rx_status
*status,
+ structieee80211_radiotap_he
*he,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ __le32 *rxv) +{ +u32 ru =le32_get_bits (rxv[0 ],MT_PRXV_HE_RU_ALLOC ), offs=
0;
Quoted 40 lines
Quoted 40 lines
Quoted 40 lines
Quoted 40 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +36
-0+ +status->bw =RATE_INFO_BW_HE_RU ; + +switch (ru) { +case 0 ... 36: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_26 ; +offs = ru; +break ; +case 37 ... 52: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_52 ; +offs = ru -37 ; +break ; +case 53 ... 60: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_106 ; +offs = ru -53 ; +break ; +case 61 ... 64: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_242 ; +offs = ru -61 ; +break ; +case 65 ... 66: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_484 ; +offs = ru -65 ; +break ; +case 67 : +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_996 ; +break ; +case 68 : +status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; +break ; +} + +he->data1 |=HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); +he->data2 |=HE_BITS (DATA2_RU_OFFSET_KNOWN ) | +le16_encode_bits (offs, + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+} + +#define MU_PREP (f, v)le16_encode_bits(v,Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
IEEE80211_RADIOTAP_HE_MU_##f)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+static void +mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff*skb,
__le32
*rxv)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ +struct mt76_rx_status *status = (struct mt76_rx_status*)skb-
Quoted 46 lines
Quoted 17 lines
Quoted 17 lines
Quoted 7 lines
Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+static const struct ieee80211_radiotap_he_mu mu_known = { +.flags1 =HE_BITS (MU_FLAGS1_SIG_B_MCS_KNOWN ) | +HE_BITS (MU_FLAGS1_SIG_B_DCM_KNOWN ) | +HE_BITS (MU_FLAGS1_CH1_RU_KNOWN ) | +HE_BITS (MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN ),drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+.flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), +}; +struct ieee80211_radiotap_he_mu *he_mu; + +status->flag |=RX_FLAG_RADIOTAP_HE_MU ; + +he_mu =skb_push (skb,sizeof (mu_known)); +memcpy (he_mu, &mu_known,sizeof (mu_known)); + +he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status-
rate_idx);Quoted 6 lines
Quoted 6 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 6 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+if (status->he_dcm) +he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status-Quoted 1 line
he_dcm);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status-bw) |
Quoted 19 lines
Quoted 19 lines
Quoted 19 lines
+ MU_PREP(FLAGS2_SIG_B_SYMS_USERS,
+ le32_get_bits(rxv[4],MT_CRXV_HE_NUM_USER));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +he_mu->ru_ch1[0 ] =le32_get_bits (rxv[16 ],MT_CRXV_HE_RU0 )&
0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ +if (status->bw >=RATE_INFO_BW_40 ) { +he_mu->flags1 |=HE_BITS (MU_FLAGS1_CH2_RU_KNOWN ); +he_mu->ru_ch2[0] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU1) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+} + +if (status->bw >=RATE_INFO_BW_80 ) { +u32 ru_h, ru_l; + +he_mu->ru_ch1[1] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU2) &0xff;Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+ +ru_l =le32_get_bits (rxv[16 ],MT_CRXV_HE_RU3_L ); +ru_h =le32_get_bits (rxv[17 ],MT_CRXV_HE_RU3_H ) &0x7 ; +he_mu->ru_ch2[1 ] = (u8)(ru_l | ru_h <<4 ); +} +} + +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff*skb,
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 5 lines
__le32
*rxv,
+ u8 mode)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ +struct mt76_rx_status *status = (struct mt76_rx_status*)skb-
Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
Quoted 8 lines
Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+static const struct ieee80211_radiotap_he known = { +.data1 =HE_BITS (DATA1_DATA_MCS_KNOWN ) | +HE_BITS (DATA1_DATA_DCM_KNOWN ) | +HE_BITS (DATA1_STBC_KNOWN ) | +HE_BITS (DATA1_CODING_KNOWN ) | + HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+HE_BITS (DATA1_DOPPLER_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE_KNOWN ) | + HE_BITS(DATA1_BSS_COLOR_KNOWN), +.data2 =HE_BITS (DATA2_GI_KNOWN ) | +HE_BITS (DATA2_TXBF_KNOWN ) | +HE_BITS (DATA2_PE_DISAMBIG_KNOWN ) | + HE_BITS(DATA2_TXOP_KNOWN), +}; +u32 ltf_size =le32_get_bits (rxv[4 ],MT_CRXV_HE_LTF_SIZE ) +1;
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_radiotap_he *he; + +status->flag |=RX_FLAG_RADIOTAP_HE ; + +he =skb_push (skb,sizeof (known)); +memcpy (he, &known,sizeof (known)); + +he->data3 =HE_PREP (DATA3_BSS_COLOR ,BSS_COLOR , rxv[9 ]) | +HE_PREP (DATA3_LDPC_XSYMSEG ,LDPC_EXT_SYM , rxv[4 ]); +he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK,rxv[13]);
Quoted 166 lines
Quoted 166 lines
Quoted 166 lines
Quoted 166 lines
+he->data5 =
HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5])drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+le16_encode_bits (ltf_size, + IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+if (le32_to_cpu (rxv[0 ]) &MT_PRXV_TXBF ) +he->data5 |=HE_BITS (DATA5_TXBF ); +he->data6 =HE_PREP (DATA6_TXOP ,TXOP_DUR , rxv[9 ]) | +HE_PREP (DATA6_DOPPLER ,DOPPLER , rxv[9 ]); + +switch (mode) { +case MT_PHY_TYPE_HE_SU : +he->data1 |=HE_BITS (DATA1_FORMAT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BEAM_CHANGE_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + +he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG,rxv[8]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_EXT_SU : +he->data1 |=HE_BITS (DATA1_FORMAT_EXT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + +he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_MU : +he->data1 |=HE_BITS (DATA1_FORMAT_MU ) | +HE_BITS (DATA1_UL_DL_KNOWN ); + +he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +he->data4 |=HE_PREP (DATA4_MU_STA_ID ,MU_AID , rxv[8 ]); + +mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+mt76_connac3_mac_decode_he_mu_radiotap (skb, rxv); +break ; +case MT_PHY_TYPE_HE_TB : +he->data1 |=HE_BITS (DATA1_FORMAT_TRIG ) | +HE_BITS (DATA1_SPTL_REUSE2_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE3_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE4_KNOWN ); + +he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK,rxv[13]) |
+ HE_PREP(DATA4_TB_SPTL_REUSE2,SR1_MASK,
rxv[13]) |
+ HE_PREP(DATA4_TB_SPTL_REUSE3,SR2_MASK,
rxv[13]) |
+ HE_PREP(DATA4_TB_SPTL_REUSE4,SR3_MASK,
rxv[13]);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+break ; +default : +break ; +} +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_decode_he_radiotap); + +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, +struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +99
-0+ __le32 *rxv, u8 *mode) +{ +u8 stbc, gi, bw, dcm, nss; +bool cck = false; +u32 v0, v2; +int i, idx; + +v0 =le32_to_cpu (rxv[0 ]); +v2 =le32_to_cpu (rxv[2 ]); + +idx =FIELD_GET (MT_PRXV_TX_RATE , v0); +i = idx; +nss =FIELD_GET (MT_PRXV_NSTS , v0) +1 ; + +stbc =FIELD_GET (MT_PRXV_HT_STBC , v2); +gi =FIELD_GET (MT_PRXV_HT_SHORT_GI , v2); +*mode =FIELD_GET (MT_PRXV_TX_MODE , v2); +dcm =FIELD_GET (MT_PRXV_DCM , v2); +bw =FIELD_GET (MT_PRXV_FRAME_MODE , v2); + +switch (*mode) { +case MT_PHY_TYPE_CCK : +cck = true; +fallthrough; +case MT_PHY_TYPE_OFDM : +i =mt76_get_rate (dev, sband, i, cck); +break ; +case MT_PHY_TYPE_HT_GF : +case MT_PHY_TYPE_HT : +status->encoding =RX_ENC_HT ; +if (gi) +status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >31 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_VHT : +status->nss = nss; +status->encoding =RX_ENC_VHT ; +if (gi) +status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >11 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_HE_MU : +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : +status->nss = nss; +status->encoding =RX_ENC_HE ; +i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_HE_GI_3_2 ) +status->he_gi = gi; + +status->he_dcm = dcm; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : +status->nss = nss; +status->encoding =RX_ENC_EHT ; +i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_EHT_GI_3_2 ) +status->eht.gi = gi; +break ; +default : +return -EINVAL ; +} +status->rate_idx = i; + +switch (bw) { +case IEEE80211_STA_RX_BW_20 : +break ; +case IEEE80211_STA_RX_BW_40 : +if (*mode &MT_PHY_TYPE_HE_EXT_SU && + (idx &MT_PRXV_TX_ER_SU_106T )) { +status->bw =RATE_INFO_BW_HE_RU ; +status->he_ru = +NL80211_RATE_INFO_HE_RU_ALLOC_106 ; +}else { +status->bw =RATE_INFO_BW_40 ; +} +break ; +case IEEE80211_STA_RX_BW_80 : +status->bw =RATE_INFO_BW_80 ; +break ; +case IEEE80211_STA_RX_BW_160 : +status->bw =RATE_INFO_BW_160 ; +break ; +case IEEE80211_STA_RX_BW_320 : +status->bw =RATE_INFO_BW_320 ; +break ; +default : +return -EINVAL ; +} + +status->enc_flags |=RX_ENC_FLAG_STBC_MASK * stbc; +if (*mode <MT_PHY_TYPE_HE_SU && gi)Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; + +return 0 ; +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_fill_rx_rate); + +static void +mt76_connac3_mac_write_txwi_8023(__le32 *txwi, struct
sk_buffQuoted 30 lines
Quoted 30 lines
Quoted 30 lines
Quoted 30 lines
*skb,
+ structmt76_wcid*wcid)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +11
-0+{ +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +u8 fc_type, fc_stype; +u16 ethertype; +bool wmm = false; +u32 val; + +if (wcid->sta) { +struct ieee80211_sta *sta; + +sta = container_of((void *)wcid, struct ieee80211_sta,
drv_priv);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+wmm = sta->wme; +} + +val =FIELD_PREP (MT_TXD1_HDR_FORMAT ,MT_HDR_FORMAT_802_3 )|
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +11
-0+FIELD_PREP (MT_TXD1_TID , tid); + +ethertype =get_unaligned_be16 (&skb->data[12 ]); +if (ethertype >=ETH_P_802_3_MIN ) +val |=MT_TXD1_ETH_802_3 ; + +txwi[1 ] |=cpu_to_le32 (val); + +fc_type =IEEE80211_FTYPE_DATA >>2 ; +fc_stype = wmm ?IEEE80211_STYPE_QOS_DATA >>4 :0 ; +Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + +txwi[2 ] |=cpu_to_le32 (val); +} + +static void +mt76_connac3_mac_write_txwi_80211(struct mt76_dev *dev,
__le32Quoted 29 lines
Quoted 4 lines
Quoted 4 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 4 lines
*txwi,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+struct sk_buff *skb, + struct ieee80211_key_conf *key) { +struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb-data;
Quoted 23 lines
Quoted 23 lines
Quoted 23 lines
+struct
ieee80211_mgmt*mgmt = (structieee80211_mgmt*)skb-Quoted 1 line
data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +bool multicast =is_multicast_ether_addr (hdr->addr1); +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +__le16 fc = hdr->frame_control; +u8 fc_type, fc_stype; +u32 val; + +if (ieee80211_is_action (fc) && + mgmt->u.action.category ==WLAN_CATEGORY_BACK && + mgmt->u.action.u.addba_req.action_code ==
WLAN_ACTION_ADDBA_REQ)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+tid =MT_TX_ADDBA ; +else if (ieee80211_is_mgmt(hdr->frame_control)) +tid =MT_TX_NORMAL ; + +val =FIELD_PREP (MT_TXD1_HDR_FORMAT ,MT_HDR_FORMAT_802_11 )|
+ FIELD_PREP(MT_TXD1_HDR_INFO,
+ieee80211_get_hdrlen_from_skb(skb)/ 2) |Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+FIELD_PREP (MT_TXD1_TID , tid); + +if (!ieee80211_is_data (fc) || multicast || + info->flags &IEEE80211_TX_CTL_USE_MINRATE ) +val |=MT_TXD1_FIXED_RATE ; + +if (key && multicast &&
ieee80211_is_robust_mgmt_frame(skb)&&
Quoted 33 lines
Quoted 33 lines
Quoted 33 lines
Quoted 33 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +16
-0+ key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { +val |=MT_TXD1_BIP ; +txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_PROTECT_FRAME ); +} + +txwi[1 ] |=cpu_to_le32 (val); + +fc_type = (le16_to_cpu (fc) &IEEE80211_FCTL_FTYPE ) >>2 ; +fc_stype = (le16_to_cpu (fc) &IEEE80211_FCTL_STYPE ) >>4 ; + +val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + +txwi[2 ] |=cpu_to_le32 (val); + +txwi[3] |= cpu_to_le32(FIELD_PREP(MT_TXD3_BCM,multicast));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +16
-0+if (ieee80211_is_beacon (fc)) { +txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_SW_POWER_MGMT ); +txwi[3 ] |=cpu_to_le32 (MT_TXD3_REM_TX_COUNT ); +} + +if (info->flags &IEEE80211_TX_CTL_INJECTED ) { +u16 seqno =le16_to_cpu (hdr->seq_ctrl); + +if (ieee80211_is_back_req (hdr->frame_control)) { +struct ieee80211_bar *bar; + +bar = (struct ieee80211_bar *)skb->data; +seqno =le16_to_cpu (bar->start_seq_num); +} + +val = MT_TXD3_SN_VALID |Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
+ FIELD_PREP(MT_TXD3_SEQ,
IEEE80211_SEQ_TO_SN(seqno));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+txwi[3 ] |=cpu_to_le32 (val); +txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_HW_AMSDU ); +} +} + +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev,
__le32Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
*txwi,
+ structsk_buff*skb, structmt76_wcid
*wcid,
+ structieee80211_key_conf*key, int
pid,
+ enummt76_txq_idqid, u32 changed)Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ +u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE :
MT_SDIO_TXD_SIZE;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +struct ieee80211_vif *vif = info->control.vif; +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;Quoted 261 lines
Quoted 261 lines
Quoted 261 lines
Quoted 261 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+struct mt76_vif *mvif; +u16 tx_count =15 ; +bool beacon = !!(changed & (BSS_CHANGED_BEACON | +BSS_CHANGED_BEACON_ENABLED )); +bool inband_disc = !!(changed &(
BSS_CHANGED_UNSOL_BCAST_PROBE_RESP|
+BSS_CHANGED_FILS_DISCOVERY));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +16
-0+ +mvif = vif ? (struct mt76_vif *)vif->drv_priv :NULL ; +if (mvif) { +omac_idx = mvif->omac_idx; +wmm_idx = mvif->wmm_idx; +band_idx = mvif->band_idx; +} + +if (inband_disc) { +p_fmt =MT_TX_TYPE_FW ; +q_idx =MT_LMAC_ALTX0 ; +}else if (beacon) { +p_fmt =MT_TX_TYPE_FW ; +q_idx =MT_LMAC_BCN0 ; +}else if (qid >=MT_TXQ_PSD ) { +p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+q_idx =MT_LMAC_ALTX0 ; +}else { +p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+q_idx = wmm_idx *MT76_CONNAC_MAX_WMM_SETS + +mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +45
-0+} + +val =FIELD_PREP (MT_TXD0_TX_BYTES , skb->len + sz_txd) | +FIELD_PREP (MT_TXD0_PKT_FMT , p_fmt) | +FIELD_PREP (MT_TXD0_Q_IDX , q_idx); +txwi[0 ] =cpu_to_le32 (val); + +val =FIELD_PREP (MT_TXD1_WLAN_IDX , wcid->idx) | +FIELD_PREP (MT_TXD1_OWN_MAC , omac_idx); + +if (band_idx) +val |=FIELD_PREP (MT_TXD1_TGID , band_idx); + +txwi[1 ] =cpu_to_le32 (val); +txwi[2 ] =0 ; + +val =MT_TXD3_SW_POWER_MGMT | +FIELD_PREP (MT_TXD3_REM_TX_COUNT , tx_count); +if (key) +val |=MT_TXD3_PROTECT_FRAME ; +if (info->flags &IEEE80211_TX_CTL_NO_ACK ) +val |=MT_TXD3_NO_ACK ; +if (wcid->amsdu) +val |=MT_TXD3_HW_AMSDU ; + +txwi[3 ] =cpu_to_le32 (val); +txwi[4 ] =0 ; + +val =FIELD_PREP (MT_TXD5_PID , pid); +if (pid >=MT_PACKET_ID_FIRST ) +val |=MT_TXD5_TX_STATUS_HOST ; +txwi[5 ] =cpu_to_le32 (val); + +val =MT_TXD6_DIS_MAT |MT_TXD6_DAS | +FIELD_PREP (MT_TXD6_MSDU_CNT ,1 ); +txwi[6 ] =cpu_to_le32 (val); +txwi[7 ] =0 ; + +if (is_8023) +mt76_connac3_mac_write_txwi_8023 (txwi, skb, wcid); +else +mt76_connac3_mac_write_txwi_80211 (dev, txwi, skb, key); + +if (txwi[1 ] &cpu_to_le32 (MT_TXD1_FIXED_RATE )) { +struct ieee80211_hdr *hdr = (struct ieee80211_hdr*)skb->data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +14
-0+bool mcast =ieee80211_is_data (hdr->frame_control) && +is_multicast_ether_addr (hdr->addr1); +u8 idx =MT76_CONNAC3_BASIC_RATES_TBL ; + +if (mvif) { +if (mcast && mvif->mcast_rates_idx) +idx = mvif->mcast_rates_idx; +else if (beacon && mvif->beacon_rates_idx) +idx = mvif->beacon_rates_idx; +else +idx = mvif->basic_rates_idx; +} + +txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE,idx));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+txwi[3 ] |=cpu_to_le32 (MT_TXD3_BA_DISABLE ); +} +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_write_txwi); + +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+struct ieee80211_sta *sta, + struct list_head *free_list) +{ +__le32 *txwi; +u16 wcid_idx; + +mt76_connac_txp_skb_unmap (dev, t); +if (!t->skb) +goto out; + +txwi = (__le32 *)mt76_get_txwi_ptr (dev, t); +if (sta) { +struct mt76_wcid *wcid = (struct mt76_wcid *)sta-Quoted 1 line
drv_priv;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+ +wcid_idx = wcid->idx; +if (likely (t->skb->protocol !=cpu_to_be16 (ETH_P_PAE ))) +mt76_connac3_tx_check_aggr (sta, txwi); +}else { +wcid_idx =le32_get_bits (txwi[1 ],MT_TXD1_WLAN_IDX ); +} + +__mt76_tx_complete_skb (dev, wcid_idx, t->skb, free_list); +out: +t->skb =NULL ; +mt76_put_txwi (dev, t); +} +EXPORT_SYMBOL_GPL (mt76_connac3_txwi_free); + +static bool +mt76_connac3_mac_add_txs_skb(struct mt76_dev *dev, struct
mt76_wcid
*wcid,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +58
-0+ int pid, __le32 *txs_data) +{ +struct mt76_sta_stats *stats = &wcid->stats; +struct ieee80211_supported_band *sband; +struct ieee80211_tx_info *info; +u32 txrate, txs, mode, stbc; +struct rate_info rate = {}; +struct sk_buff_head list; +struct mt76_phy *mphy; +struct sk_buff *skb; +bool cck = false; + +mt76_tx_status_lock (dev, &list); +skb =mt76_tx_status_skb_get (dev, wcid, pid, &list); +if (!skb) +goto out_no_skb; + +txs =le32_to_cpu (txs_data[0 ]); + +info =IEEE80211_SKB_CB (skb); +if (!(txs &MT_TXS0_ACK_ERROR_MASK )) +info->flags |=IEEE80211_TX_STAT_ACK ; + +info->status.ampdu_len =1 ; +info->status.ampdu_ack_len = !!(info->flags & +IEEE80211_TX_STAT_ACK ); +info->status.rates[0 ].idx =-1 ; + +txrate =FIELD_GET (MT_TXS0_TX_RATE , txs); + +rate.mcs =FIELD_GET (MT_TX_RATE_IDX , txrate); +rate.nss =FIELD_GET (MT_TX_RATE_NSS , txrate) +1 ; +stbc =le32_get_bits (txs_data[3 ],MT_TXS3_RATE_STBC ); + +if (stbc && rate.nss >1 ) +rate.nss >>=1 ; + +if (rate.nss -1 <ARRAY_SIZE (stats->tx_nss)) +stats->tx_nss[rate.nss -1 ]++; +if (rate.mcs <ARRAY_SIZE (stats->tx_mcs)) +stats->tx_mcs[rate.mcs]++; + +mode =FIELD_GET (MT_TX_RATE_MODE , txrate); +switch (mode) { +case MT_PHY_TYPE_CCK: +cck = true; +fallthrough; +case MT_PHY_TYPE_OFDM: +mphy = mt76_dev_phy(dev, wcid->phy_idx); + +if (mphy->chandef.chan->band == NL80211_BAND_5GHZ) +sband = &mphy->sband_5g.sband; +else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ) +sband = &mphy->sband_6g.sband; +else +sband = &mphy->sband_2g.sband; + +rate.mcs = mt76_get_rate(mphy->dev, sband, rate.mcs,cck);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +69
-0+rate.legacy = sband->bitrates[rate.mcs].bitrate; +break ; +case MT_PHY_TYPE_HT : +case MT_PHY_TYPE_HT_GF : +if (rate.mcs >31 ) +goto out; + +rate.flags =RATE_INFO_FLAGS_MCS ; +if (wcid->rate.flags &RATE_INFO_FLAGS_SHORT_GI ) +rate.flags |=RATE_INFO_FLAGS_SHORT_GI ; +break ; +case MT_PHY_TYPE_VHT : +if (rate.mcs >9 ) +goto out; + +rate.flags =RATE_INFO_FLAGS_VHT_MCS ; +break ; +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : +case MT_PHY_TYPE_HE_MU : +if (rate.mcs >11 ) +goto out; + +rate.he_gi = wcid->rate.he_gi; +rate.he_dcm =FIELD_GET (MT_TX_RATE_DCM , txrate); +rate.flags =RATE_INFO_FLAGS_HE_MCS ; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : +if (rate.mcs >13 ) +goto out; + +rate.eht_gi = wcid->rate.eht_gi; +rate.flags =RATE_INFO_FLAGS_EHT_MCS ; +break ; +default : +goto out; +} + +stats->tx_mode[mode]++; + +switch (FIELD_GET (MT_TXS0_BW , txs)) { +case IEEE80211_STA_RX_BW_320 : +rate.bw =RATE_INFO_BW_320 ; +stats->tx_bw[4 ]++; +break ; +case IEEE80211_STA_RX_BW_160 : +rate.bw =RATE_INFO_BW_160 ; +stats->tx_bw[3 ]++; +break ; +case IEEE80211_STA_RX_BW_80 : +rate.bw =RATE_INFO_BW_80 ; +stats->tx_bw[2 ]++; +break ; +case IEEE80211_STA_RX_BW_40 : +rate.bw =RATE_INFO_BW_40 ; +stats->tx_bw[1 ]++; +break ; +default : +rate.bw =RATE_INFO_BW_20 ; +stats->tx_bw[0 ]++; +break ; +} +wcid->rate = rate; + +out: +mt76_tx_status_skb_done (dev, skb, &list);Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+ +out_no_skb: +mt76_tx_status_unlock (dev, &list); + +return !!skb; +} + +void mt76_connac3_mac_add_txs(struct mt76_dev *dev, void*data,
Quoted 73 lines
Quoted 73 lines
Quoted 72 lines
Quoted 68 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +53
-0+ u32 max_wtbl_size) +{ +struct mt76_wcid *wcid; +__le32 *txs_data = data; +u16 wcidx; +u8 pid; + +if (le32_get_bits (txs_data[0 ],MT_TXS0_TXS_FORMAT ) >1 ) +return ; + +wcidx =le32_get_bits (txs_data[2 ],MT_TXS2_WCID ); +pid =le32_get_bits (txs_data[3 ],MT_TXS3_PID ); + +if (pid <MT_PACKET_ID_FIRST ) +return ; + +if (wcidx >= max_wtbl_size) +return ; + +rcu_read_lock (); + +wcid =rcu_dereference (dev->wcid[wcidx]); +if (!wcid) +goto out; + +mt76_connac3_mac_add_txs_skb (dev, wcid, pid, txs_data); +if (!wcid->sta) +goto out; + +spin_lock_bh (&dev->sta_poll_lock); +if (list_empty (&wcid->poll_list)) +list_add_tail (&wcid->poll_list, &dev->sta_poll_list); +spin_unlock_bh (&dev->sta_poll_lock); + +out: +rcu_read_unlock (); +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_add_txs); + +void mt76_connac3_tx_token_put (struct mt76_dev *dev) +{ +struct mt76_txwi_cache *txwi; +int id; + +spin_lock_bh (&dev->token_lock); +idr_for_each_entry(&dev->token, txwi, id) { +mt76_connac3_txwi_free (dev, txwi,NULL ,NULL ); +dev->token_count--; +} +spin_unlock_bh (&dev->token_lock); +idr_destroy (&dev->token); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_token_put);diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hindex6663a0b46541..bcc1d976b2b0100644drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +1
-0@@ -4,6 +4,24 @@#ifndef __MT76_CONNAC3_MAC_H#define __MT76_CONNAC3_MAC_H +/* NOTE: used to map mt76_rates. idx may change if firmware
expands
table */drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
Quoted 2 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +2
-0+#define MT76_CONNAC3_BASIC_RATES_TBL11 +#define MT76_CONNAC3_BEACON_RATES_TBL25 Different devices may have different defined value.
Quoted 1 line
Quoted 1 line
The other WiFi7 device I am working on relies on the values I
moved
Quoted 2 lines
Quoted 2 lines
in
mt76_connac3_mac.h(in common with mt7996). Moreover you canstill
Quoted 5 lines
Quoted 2 lines
have per-device values in
mt7996/mac.h(I have not removed it).Please double check with the mtk folk you work with. The 11 and 25
is
Quoted 2 lines
the value I discussed with firmware folks to avoid overlapping the
tbl
Quoted 1 line
mt7996 use (MU/other algo in fw), or it causes something hardly
solving
Quoted 1 line
issue
sure, thx for pointing this out.
@Deren: can you please double check?Regards,
LorenzoQuoted 3 lines
Quoted 3 lines
Quoted 3 lines
I'm thinking if it's too early to create this patch for just
moving
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
mt7996 to
connac3_lib?The code I moved is used by the other device as well. This series
is
Quoted 9 lines
Quoted 9 lines
a
preliminary series to support it.Regards,
LorenzoQuoted 3 lines
Ryder
[email protected]
reviewerRe: [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library
Quoted 16 lines · On Sat, 2023-06-10 at 12:06 +0200, [email protected] wrote:
Quoted 16 lines · Shayne Chen
Quoted 15 lines
Quoted 15 lines
Quoted 2 lines
On Fri, 2023-06-09 at 18:34 +0200,
[email protected]Quoted 5 lines · wrote:
Quoted 5 lines · Ryder Lee
Quoted 4 lines
Quoted 2 lines · Lorenzo Bianconi
External email : Please do not click links or open
attachments
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
until you have verified the sender or the content.
Introduceconnac3_macinmt76_connaclibrary to reuse
mac
Quoted 9 lines
Quoted 6 lines
Quoted 6 lines
Quoted 4 lines
code
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
Quoted 3 lines
shared between WiFi7 chipsets.
Signed-off-by Lorenzo Bianconi <[email protected]>Hi Lorenzo,
Hi Shayne,
Hi Lorenzo,
Quoted 51 lines
Quoted 12 lines
Quoted 12 lines
I don't think it's a good idea to start sharing mac or mcu functions
for all WiFi7 chipsets at such early stage.The driver is still under many processes of bug fixing, performance
tuning, and new features development.
Chipsets that mainly used for AP or STA segment have different designs
and should face different problems.Quoted 6 lines
Quoted 6 lines
Start sharing the code at early stage will break the independence,
make
it more hard to develop and do verifications, since many changes will
affect chipsets of both segments.my goal is to share the code that hardly will be changed (or that will have
very few changes in the future, i.e. I have not changed mcu codebase).
If you consider for example the routines below:- mt76_connac*_mac_write_txwi_8023()
- mt76_connac*_mac_write_txwi_80211()
- mt76_connac*_mac_add_txs_skb()
- mt76_connac*_txwi_free()
- ...they are the same for mt7615/mt7663, mt7921/mt7915, mt7996/.. , what is
changing is just register map between versions (e.g. mt7615/mt7663 and
mt7915/mt7921). I think it is not a good idea to copy-paste the code because it will just make the code much harder to maintain, and this will be
more difficult to address in the future.
If you consider the commit below:commit
ead449023d3acb1424886d7b8cc672ed69bdd27eAuthor: Lorenzo Bianconi <[email protected]> Date: Sun May 28 12:28:49 2023 +0200wifi: mt76: mt7996: fix possible NULL pointer dereference in
mt7996_mac_write_txwi()Fix possible NULL pointer dereference on mvif pointer in
mt7996_mac_write_txwiroutine.
Quoted 8 lines
Deren will needs to monitor the ML and apply the same fix for the other WiFi7
chipset too.Moreover I kept mt7996/mac.{c,h} to put the per-chipset codebase. If you think
MT76_CONNAC3_BASIC_RATES_TBL11andMT76_CONNAC3_BEACON_RATES_TBL25
are sensible, we can put them inmt7996/mac.h
I understand your concern, but if the code starts to be shared at early stage, we may need to add several is_mt7996() to split different parts temporarily or permanently, since we have different development procedure and focusing, on devices of different segements.
Below are some examples I concern:
- We're doing some tests about switching all TXS to PPDU TXS, and the code in mac_add_txs_skb() needs to be changed. If devices of STA segement don't want to change or won't switch in short time, we may need to add is_mt7996() to split.
- When adding MLO support, there will be many changes in mac_write_txwi() and txwi_free(), compared to previous chipsets. To prevent from adding side effects to other devices, we may also need to add is_mt7996() to split code at least for temporary.
I would like to know is it fine with you to add some is_mt7996() to the shared code for the above examples?
I think this could help to balance the trade off between sharing code and assuring the driver stability on different segements.
Thanks,
Shayne
Quoted 1,063 lines
Regards,
LorenzoQuoted 1,059 lines
Quoted 4 lines
Thanks,
Shayne(Resend for missing CC)
Quoted 1,052 lines
Quoted 1,052 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
--- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76_connac.h | 19 + .../wireless/mediatek/mt76/mt76_connac3_mac.c | 742 +++++++++++++++++ .../wireless/mediatek/mt76/mt76_connac3_mac.h | 18 + .../net/wireless/mediatek/mt76/mt7996/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 761 +-----
------
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
----
--.../net/wireless/mediatek/mt76/mt7996/main.c | 8 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +- .../wireless/mediatek/mt76/mt7996/mt7996.h | 28 +- 9 files changed, 807 insertions(+), 784 deletions(-) create
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/Makefile mt76x02-lib-y := mt76x02_util.o
Quoted 10 lines
mode 100644
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cdiff --git
a/drivers/net/wireless/mediatek/mt76/Makefile
b/drivers/net/wireless/mediatek/mt76/Makefile
index84c99b7e57f9..d8e8079c8b54100644drivers/net/wireless/mediatek/mt76/Makefile +0
-0@@ -27,7 +27,7 @@ mt76x02-lib-y := mt76x02_util.omt76x02_mac.o
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/Makefile +0
-1mt76x02_mcu.o \ mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o -mt76-connac-lib-y := mt76_connac_mcu.omt76_connac_mac.o
+mt76-connac-lib-y := mt76_connac_mcu.o
mt76_connac_mac.o
mt76_connac3_mac.oQuoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h void mt76_connac2_txwi_free(struct
Quoted 8 lines
obj-$(CONFIG_MT76x0_COMMON) += mt76x0/ obj-$(CONFIG_MT76x2_COMMON) += mt76x2/ diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac.hb/drivers/net/wireless/mediatek/mt76/mt76_connac.hindex68bdeada1421..20111678537b100644drivers/net/wireless/mediatek/mt76/mt76_connac.h +0
-0@@ -415,4 +415,23 @@ void mt76_connac2_txwi_free(struct
mt76_devQuoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0*dev, struct mt76_txwi_cache *t, struct list_head *free_list); voidmt76_connac2_tx_token_put (struct mt76_dev *dev); +/* connac3 */ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta*sta,
__le32
*txwi);
+void mt76_connac3_mac_decode_he_radiotap(structsk_buff*skb,
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h
Quoted 10 lines
__le32
*rxv,
+ u8 mode);
+int mt76_connac3_mac_fill_rx_rate(structmt76_dev*dev,drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ __le32 *rxv, u8 *mode); +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev,
__le32Quoted 74 lines
Quoted 74 lines
Quoted 74 lines
Quoted 74 lines
*txwi,
+ structsk_buff*skb, structmt76_wcid*wcid,
+ structieee80211_key_conf*key, int
pid,
+ enummt76_txq_idqid, u32 changed); void +mt76_connac3_txwi_free(structmt76_dev*dev, structmt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+struct ieee80211_sta *sta, + struct list_head *free_list); void +mt76_connac3_mac_add_txs(struct mt76_dev *dev, void*data,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+ u32 max_wtbl_size); +void mt76_connac3_tx_token_put (struct mt76_dev *dev); +#endif /* __MT76_CONNAC_H */ diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cnew file mode 100644
index 000000000000..4b745bb74ca0
---/dev/null
+++b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cdrivers/net/wireless/mediatek/mt76/mt76_connac.h +8
-0@@ -0,0 +1,742 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include "mt76_connac.h" +#include "mt76_connac3_mac.h" +#include "dma.h" + +#define HE_BITS (f)cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
+#define HE_PREP(f, m,
v)le16_encode_bits(le32_get_bits(v,
MT_CRXV_HE_##m),\
+IEEE80211_RADIOTAP_HE_
##f)drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta*sta,
__le32
*txwi)drivers/net/wireless/mediatek/mt76/mt76_connac.h +7
-0+{ +struct mt76_wcid *wcid; +u16 fc, tid; +u32 val; + +if (!sta || + !(sta->deflink.ht_cap.ht_supported || sta-Quoted 1 line
deflink.he_cap.has_he))
drivers/net/wireless/mediatek/mt76/mt76_connac.h +10
-0+return ; + +tid =le32_get_bits (txwi[1 ],MT_TXD1_TID ); +if (tid >=6 )/* skip VO queue */ +return ; + +val =le32_to_cpu (txwi[2 ]); +fc =FIELD_GET (MT_TXD2_FRAME_TYPE , val) <<2 | +FIELD_GET (MT_TXD2_SUB_TYPE , val) <<4 ; +if (unlikely(fc != (IEEE80211_FTYPE_DATA |
IEEE80211_STYPE_QOS_DATA)))drivers/net/wireless/mediatek/mt76/mt76_connac.h +9
-0+return ; + +wcid = (struct mt76_wcid *)sta->drv_priv; +if (!test_and_set_bit (tid, &wcid->ampdu_state)) +ieee80211_start_tx_ba_session (sta, tid,0 ); } +EXPORT_SYMBOL_GPL (mt76_connac3_tx_check_aggr); + +static void +mt76_connac3_mac_decode_he_radiotap_ru(struct
mt76_rx_statusQuoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
*status,
+ structieee80211_radiotap_he
*he,drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+ __le32 *rxv) +{ +u32 ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC),offs
=0;
Quoted 40 lines
Quoted 40 lines
Quoted 40 lines
Quoted 40 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +36
-0+ +status->bw =RATE_INFO_BW_HE_RU ; + +switch (ru) { +case 0 ... 36: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_26 ; +offs = ru; +break ; +case 37 ... 52: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_52 ; +offs = ru -37 ; +break ; +case 53 ... 60: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_106 ; +offs = ru -53 ; +break ; +case 61 ... 64: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_242 ; +offs = ru -61 ; +break ; +case 65 ... 66: +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_484 ; +offs = ru -65 ; +break ; +case 67 : +status->he_ru =NL80211_RATE_INFO_HE_RU_ALLOC_996 ; +break ; +case 68 : +status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996; +break ; +} + +he->data1 |=HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); +he->data2 |=HE_BITS (DATA2_RU_OFFSET_KNOWN ) | +le16_encode_bits (offs, + IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+} + +#define MU_PREP (f, v)le16_encode_bits(v,Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h
Quoted 8 lines
IEEE80211_RADIOTAP_HE_MU_##f)
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+static void +mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff*skb,
__le32
*rxv)drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+{ +struct mt76_rx_status *status = (struct mt76_rx_status*)skb-
Quoted 50 lines
Quoted 18 lines
Quoted 18 lines
Quoted 8 lines
Quoted 1 line
cb;
+static const struct
ieee80211_radiotap_he_mumu_known= {
+.flags1 =HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN)|drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+HE_BITS (MU_FLAGS1_SIG_B_DCM_KNOWN ) | +HE_BITS (MU_FLAGS1_CH1_RU_KNOWN ) | + HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN),drivers/net/wireless/mediatek/mt76/mt76_connac.h
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +10
-0+.flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN), +}; +struct ieee80211_radiotap_he_mu *he_mu; + +status->flag |=RX_FLAG_RADIOTAP_HE_MU ; + +he_mu =skb_push (skb,sizeof (mu_known)); +memcpy (he_mu, &mu_known,sizeof (mu_known)); + +he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status-
rate_idx);Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+if (status->he_dcm) +he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status-Quoted 1 line
he_dcm);drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ +he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW,status-
bw) |
Quoted 21 lines
Quoted 21 lines
Quoted 21 lines
+ MU_PREP(FLAGS2_SIG_B_SYMS_USERS,
+ le32_get_bits(rxv[4],MT_CRXV_HE_NUM_USER));drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ +he_mu->ru_ch1[0] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU0)
&0xff;drivers/net/wireless/mediatek/mt76/mt76_connac.h +4
-0+ +if (status->bw >=RATE_INFO_BW_40 ) { +he_mu->flags1 |=HE_BITS (MU_FLAGS1_CH2_RU_KNOWN ); +he_mu->ru_ch2[0] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU1) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac.h +6
-0+} + +if (status->bw >=RATE_INFO_BW_80 ) { +u32 ru_h, ru_l; + +he_mu->ru_ch1[1] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU2) &0xff;
+Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +7
-0+ru_l =le32_get_bits (rxv[16 ],MT_CRXV_HE_RU3_L ); +ru_h =le32_get_bits (rxv[17 ],MT_CRXV_HE_RU3_H ) &0x7 ; +he_mu->ru_ch2[1 ] = (u8)(ru_l | ru_h <<4 ); +} +} + +void mt76_connac3_mac_decode_he_radiotap(struct
sk_buff*skb,
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h
Quoted 5 lines
__le32
*rxv,
+ u8 mode)drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+{ +struct mt76_rx_status *status = (struct mt76_rx_status*)skb-
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
Quoted 1 line
cb;
+static const struct
ieee80211_radiotap_heknown = { +.data1 =HE_BITS(DATA1_DATA_MCS_KNOWN)|
+HE_BITS(DATA1_DATA_DCM_KNOWN)|
+HE_BITS(DATA1_STBC_KNOWN)|
+HE_BITS(DATA1_CODING_KNOWN)|
+HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN)|
+HE_BITS(DATA1_DOPPLER_KNOWN)|
+HE_BITS(DATA1_SPTL_REUSE_KNOWN)|
+HE_BITS(DATA1_BSS_COLOR_KNOWN),Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
+.data2 =
HE_BITS(DATA2_GI_KNOWN)|
+HE_BITS(DATA2_TXBF_KNOWN)|
+HE_BITS(DATA2_PE_DISAMBIG_KNOWN)|
+HE_BITS(DATA2_TXOP_KNOWN),drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+}; +u32 ltf_size = le32_get_bits(rxv[4],
MT_CRXV_HE_LTF_SIZE)
+1;
Quoted 11 lines
Quoted 11 lines
Quoted 11 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h
Quoted 11 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +8
-0+struct ieee80211_radiotap_he *he; + +status->flag |=RX_FLAG_RADIOTAP_HE ; + +he =skb_push (skb,sizeof (known)); +memcpy (he, &known,sizeof (known)); + +he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR,rxv[9]) |
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+HE_PREP (DATA3_LDPC_XSYMSEG ,LDPC_EXT_SYM , rxv[4 ]); +he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK,rxv[13]);
Quoted 168 lines
Quoted 168 lines
Quoted 168 lines
Quoted 168 lines
+he->data5 =
HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[5])drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+le16_encode_bits (ltf_size, + IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
drivers/net/wireless/mediatek/mt76/mt76_connac.h +13
-0+if (le32_to_cpu (rxv[0 ]) &MT_PRXV_TXBF ) +he->data5 |=HE_BITS (DATA5_TXBF ); +he->data6 =HE_PREP (DATA6_TXOP ,TXOP_DUR , rxv[9 ]) | +HE_PREP (DATA6_DOPPLER ,DOPPLER , rxv[9 ]); + +switch (mode) { +case MT_PHY_TYPE_HE_SU : +he->data1 |=HE_BITS (DATA1_FORMAT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BEAM_CHANGE_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + +he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG,rxv[8]) |
drivers/net/wireless/mediatek/mt76/mt76_connac.h +17
-0+HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_EXT_SU : +he->data1 |=HE_BITS (DATA1_FORMAT_EXT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + +he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +break ; +case MT_PHY_TYPE_HE_MU : +he->data1 |=HE_BITS (DATA1_FORMAT_MU ) | +HE_BITS (DATA1_UL_DL_KNOWN ); + +he->data3 |=HE_PREP (DATA3_UL_DL ,UPLINK , rxv[5 ]); +he->data4 |=HE_PREP (DATA4_MU_STA_ID ,MU_AID , rxv[8 ]); + +mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac.h +9
-0+mt76_connac3_mac_decode_he_mu_radiotap (skb, rxv); +break ; +case MT_PHY_TYPE_HE_TB : +he->data1 |=HE_BITS (DATA1_FORMAT_TRIG ) | +HE_BITS (DATA1_SPTL_REUSE2_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE3_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE4_KNOWN ); + +he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK,rxv[13]) |
+ HE_PREP(DATA4_TB_SPTL_REUSE2,SR1_MASK,
rxv[13]) |
+ HE_PREP(DATA4_TB_SPTL_REUSE3,SR2_MASK,
rxv[13]) |
+ HE_PREP(DATA4_TB_SPTL_REUSE4,SR3_MASK,
rxv[13]);drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ +mt76_connac3_mac_decode_he_radiotap_ru(status, he,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac.h +6
-0+break ; +default : +break ; +} +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_decode_he_radiotap);
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ +int mt76_connac3_mac_fill_rx_rate(struct mt76_dev*dev,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+struct mt76_rx_status *status, + struct ieee80211_supported_band*sband,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +99
-0+ __le32 *rxv, u8 *mode) +{ +u8 stbc, gi, bw, dcm, nss; +bool cck = false; +u32 v0, v2; +int i, idx; + +v0 =le32_to_cpu (rxv[0 ]); +v2 =le32_to_cpu (rxv[2 ]); + +idx =FIELD_GET (MT_PRXV_TX_RATE , v0); +i = idx; +nss =FIELD_GET (MT_PRXV_NSTS , v0) +1 ; + +stbc =FIELD_GET (MT_PRXV_HT_STBC , v2); +gi =FIELD_GET (MT_PRXV_HT_SHORT_GI , v2); +*mode =FIELD_GET (MT_PRXV_TX_MODE , v2); +dcm =FIELD_GET (MT_PRXV_DCM , v2); +bw =FIELD_GET (MT_PRXV_FRAME_MODE , v2); + +switch (*mode) { +case MT_PHY_TYPE_CCK : +cck = true; +fallthrough; +case MT_PHY_TYPE_OFDM : +i =mt76_get_rate (dev, sband, i, cck); +break ; +case MT_PHY_TYPE_HT_GF : +case MT_PHY_TYPE_HT : +status->encoding =RX_ENC_HT ; +if (gi) +status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >31 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_VHT : +status->nss = nss; +status->encoding =RX_ENC_VHT ; +if (gi) +status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; +if (i >11 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_HE_MU : +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : +status->nss = nss; +status->encoding =RX_ENC_HE ; +i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_HE_GI_3_2 ) +status->he_gi = gi; + +status->he_dcm = dcm; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : +status->nss = nss; +status->encoding =RX_ENC_EHT ; +i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_EHT_GI_3_2 ) +status->eht.gi = gi; +break ; +default : +return -EINVAL ; +} +status->rate_idx = i; + +switch (bw) { +case IEEE80211_STA_RX_BW_20 : +break ; +case IEEE80211_STA_RX_BW_40 : +if (*mode &MT_PHY_TYPE_HE_EXT_SU && + (idx &MT_PRXV_TX_ER_SU_106T )) { +status->bw =RATE_INFO_BW_HE_RU ; +status->he_ru = +NL80211_RATE_INFO_HE_RU_ALLOC_106 ; +}else { +status->bw =RATE_INFO_BW_40 ; +} +break ; +case IEEE80211_STA_RX_BW_80 : +status->bw =RATE_INFO_BW_80 ; +break ; +case IEEE80211_STA_RX_BW_160 : +status->bw =RATE_INFO_BW_160 ; +break ; +case IEEE80211_STA_RX_BW_320 : +status->bw =RATE_INFO_BW_320 ; +break ; +default : +return -EINVAL ; +} + +status->enc_flags |=RX_ENC_FLAG_STBC_MASK * stbc; +if (*mode <MT_PHY_TYPE_HE_SU && gi)Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +8
-0+status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; + +return 0 ; +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_fill_rx_rate); + +static void +mt76_connac3_mac_write_txwi_8023(__le32 *txwi, struct
sk_buffQuoted 33 lines
Quoted 33 lines
Quoted 33 lines
Quoted 33 lines
*skb,
+ structmt76_wcid*wcid)drivers/net/wireless/mediatek/mt76/mt76_connac.h +11
-0+{ +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +u8 fc_type, fc_stype; +u16 ethertype; +bool wmm = false; +u32 val; + +if (wcid->sta) { +struct ieee80211_sta *sta; + +sta = container_of((void *)wcid, struct ieee80211_sta,
drv_priv);drivers/net/wireless/mediatek/mt76/mt76_connac.h +4
-0+wmm = sta->wme; +} + +val = FIELD_PREP(MT_TXD1_HDR_FORMAT,
MT_HDR_FORMAT_802_3)Quoted 1 line
drivers/net/wireless/mediatek/mt76/mt76_connac.h +12
-0+FIELD_PREP (MT_TXD1_TID , tid); + +ethertype =get_unaligned_be16 (&skb->data[12 ]); +if (ethertype >=ETH_P_802_3_MIN ) +val |=MT_TXD1_ETH_802_3 ; + +txwi[1 ] |=cpu_to_le32 (val); + +fc_type =IEEE80211_FTYPE_DATA >>2 ; +fc_stype = wmm ?IEEE80211_STYPE_QOS_DATA >>4 :0 ; + +val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +7
-0+FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + +txwi[2 ] |=cpu_to_le32 (val); +} + +static void +mt76_connac3_mac_write_txwi_80211(struct mt76_dev*dev,
__le32Quoted 31 lines
Quoted 5 lines
Quoted 5 lines
Quoted 5 lines
*txwi,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+ struct sk_buff *skb, + struct ieee80211_key_conf *key) { +struct ieee80211_hdr *hdr = (struct ieee80211_hdr*)skb-
data;
Quoted 24 lines
Quoted 24 lines
Quoted 24 lines
+struct
ieee80211_mgmt*mgmt = (structieee80211_mgmt*)skb-Quoted 1 line
data;
+struct
ieee80211_tx_info*info =IEEE80211_SKB_CB(skb);drivers/net/wireless/mediatek/mt76/mt76_connac.h +9
-0+bool multicast =is_multicast_ether_addr (hdr->addr1); +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +__le16 fc = hdr->frame_control; +u8 fc_type, fc_stype; +u32 val; + +if (ieee80211_is_action (fc) && + mgmt->u.action.category ==WLAN_CATEGORY_BACK && + mgmt->u.action.u.addba_req.action_code ==
WLAN_ACTION_ADDBA_REQ)drivers/net/wireless/mediatek/mt76/mt76_connac.h +5
-0+tid =MT_TX_ADDBA ; +else if (ieee80211_is_mgmt(hdr->frame_control)) +tid =MT_TX_NORMAL ; + +val = FIELD_PREP(MT_TXD1_HDR_FORMAT,
MT_HDR_FORMAT_802_11)Quoted 1 line
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +9
-0+FIELD_PREP (MT_TXD1_HDR_INFO , +ieee80211_get_hdrlen_from_skb (skb) /2 ) | +FIELD_PREP (MT_TXD1_TID , tid); + +if (!ieee80211_is_data (fc) || multicast || + info->flags &IEEE80211_TX_CTL_USE_MINRATE ) +val |=MT_TXD1_FIXED_RATE ; + +if (key && multicast &&
ieee80211_is_robust_mgmt_frame(skb)&&
Quoted 35 lines
Quoted 35 lines
Quoted 35 lines
Quoted 35 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +8
-0+ key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { +val |=MT_TXD1_BIP ; +txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_PROTECT_FRAME ); +} + +txwi[1 ] |=cpu_to_le32 (val); + +fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >>2;
+fc_stype = (le16_to_cpu(fc)&IEEE80211_FCTL_STYPE) >> 4;drivers/net/wireless/mediatek/mt76/mt76_connac.h +7
-0+ +val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + +txwi[2 ] |=cpu_to_le32 (val); + +txwi[3] |= cpu_to_le32(FIELD_PREP(MT_TXD3_BCM,multicast));
drivers/net/wireless/mediatek/mt76/mt76_connac.h +16
-0+if (ieee80211_is_beacon (fc)) { +txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_SW_POWER_MGMT ); +txwi[3 ] |=cpu_to_le32 (MT_TXD3_REM_TX_COUNT ); +} + +if (info->flags &IEEE80211_TX_CTL_INJECTED ) { +u16 seqno =le16_to_cpu (hdr->seq_ctrl); + +if (ieee80211_is_back_req (hdr->frame_control)) { +struct ieee80211_bar *bar; + +bar = (struct ieee80211_bar *)skb->data; +seqno =le16_to_cpu (bar->start_seq_num); +} + +val = MT_TXD3_SN_VALID |Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h
Quoted 8 lines
+ FIELD_PREP(MT_TXD3_SEQ,
IEEE80211_SEQ_TO_SN(seqno));drivers/net/wireless/mediatek/mt76/mt76_connac.h +6
-0+txwi[3 ] |=cpu_to_le32 (val); +txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_HW_AMSDU ); +} +} + +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev,
__le32Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
*txwi,
+ structsk_buff*skb, structmt76_wcid
*wcid,
+ structieee80211_key_conf*key, int
pid,
+ enummt76_txq_idqid, u32 changed)drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+{ +u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE :Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h
Quoted 8 lines
MT_SDIO_TXD_SIZE;
+structieee80211_tx_info*info =IEEE80211_SKB_CB(skb);drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+struct ieee80211_vif *vif = info->control.vif; +u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >>2;
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+u8 p_fmt, q_idx, omac_idx =0 , wmm_idx =0 ; +bool is_8023 = info->flags &
IEEE80211_TX_CTL_HW_80211_ENCAP;Quoted 269 lines
Quoted 269 lines
Quoted 269 lines
Quoted 269 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +5
-0+struct mt76_vif *mvif; +u16 tx_count =15 ; +bool beacon = !!(changed & (BSS_CHANGED_BEACON | +BSS_CHANGED_BEACON_ENABLED )); +bool inband_disc = !!(changed &(
BSS_CHANGED_UNSOL_BCAST_PROBE_RESP|
+BSS_CHANGED_FILS_DISCOVERY));drivers/net/wireless/mediatek/mt76/mt76_connac.h +16
-0+ +mvif = vif ? (struct mt76_vif *)vif->drv_priv :NULL ; +if (mvif) { +omac_idx = mvif->omac_idx; +wmm_idx = mvif->wmm_idx; +band_idx = mvif->band_idx; +} + +if (inband_disc) { +p_fmt =MT_TX_TYPE_FW ; +q_idx =MT_LMAC_ALTX0 ; +}else if (beacon) { +p_fmt =MT_TX_TYPE_FW ; +q_idx =MT_LMAC_BCN0 ; +}else if (qid >=MT_TXQ_PSD ) { +p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+q_idx =MT_LMAC_ALTX0 ; +}else { +p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+q_idx = wmm_idx *MT76_CONNAC_MAX_WMM_SETS + +mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+} + +val =FIELD_PREP (MT_TXD0_TX_BYTES , skb->len + sz_txd)|
drivers/net/wireless/mediatek/mt76/mt76_connac.h +39
-0+FIELD_PREP (MT_TXD0_PKT_FMT , p_fmt) | +FIELD_PREP (MT_TXD0_Q_IDX , q_idx); +txwi[0 ] =cpu_to_le32 (val); + +val =FIELD_PREP (MT_TXD1_WLAN_IDX , wcid->idx) | +FIELD_PREP (MT_TXD1_OWN_MAC , omac_idx); + +if (band_idx) +val |=FIELD_PREP (MT_TXD1_TGID , band_idx); + +txwi[1 ] =cpu_to_le32 (val); +txwi[2 ] =0 ; + +val =MT_TXD3_SW_POWER_MGMT | +FIELD_PREP (MT_TXD3_REM_TX_COUNT , tx_count); +if (key) +val |=MT_TXD3_PROTECT_FRAME ; +if (info->flags &IEEE80211_TX_CTL_NO_ACK ) +val |=MT_TXD3_NO_ACK ; +if (wcid->amsdu) +val |=MT_TXD3_HW_AMSDU ; + +txwi[3 ] =cpu_to_le32 (val); +txwi[4 ] =0 ; + +val =FIELD_PREP (MT_TXD5_PID , pid); +if (pid >=MT_PACKET_ID_FIRST ) +val |=MT_TXD5_TX_STATUS_HOST ; +txwi[5 ] =cpu_to_le32 (val); + +val =MT_TXD6_DIS_MAT |MT_TXD6_DAS | +FIELD_PREP (MT_TXD6_MSDU_CNT ,1 ); +txwi[6 ] =cpu_to_le32 (val); +txwi[7 ] =0 ; + +if (is_8023) +mt76_connac3_mac_write_txwi_8023 (txwi, skb, wcid); +else +mt76_connac3_mac_write_txwi_80211(dev, txwi, skb,key);
drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+ +if (txwi[1 ] &cpu_to_le32 (MT_TXD1_FIXED_RATE )) { +struct ieee80211_hdr *hdr = (struct ieee80211_hdr*)skb->data;
drivers/net/wireless/mediatek/mt76/mt76_connac.h +14
-0+bool mcast =ieee80211_is_data (hdr->frame_control) && +is_multicast_ether_addr (hdr->addr1); +u8 idx =MT76_CONNAC3_BASIC_RATES_TBL ; + +if (mvif) { +if (mcast && mvif->mcast_rates_idx) +idx = mvif->mcast_rates_idx; +else if (beacon && mvif->beacon_rates_idx) +idx = mvif->beacon_rates_idx; +else +idx = mvif->basic_rates_idx; +} + +txwi[6] |= cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE,idx));
drivers/net/wireless/mediatek/mt76/mt76_connac.h +6
-0+txwi[3 ] |=cpu_to_le32 (MT_TXD3_BA_DISABLE ); +} +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_write_txwi); + +void mt76_connac3_txwi_free(struct mt76_dev *dev,struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac.h +13
-0+struct ieee80211_sta *sta, + struct list_head *free_list) +{ +__le32 *txwi; +u16 wcid_idx; + +mt76_connac_txp_skb_unmap (dev, t); +if (!t->skb) +goto out; + +txwi = (__le32 *)mt76_get_txwi_ptr (dev, t); +if (sta) { +struct mt76_wcid *wcid = (struct mt76_wcid *)sta-Quoted 1 line
drv_priv;drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+ +wcid_idx = wcid->idx; +if (likely(t->skb->protocol !=
cpu_to_be16(ETH_P_PAE)))drivers/net/wireless/mediatek/mt76/mt76_connac.h +6
-0+mt76_connac3_tx_check_aggr (sta, txwi); +}else { +wcid_idx =le32_get_bits (txwi[1 ],MT_TXD1_WLAN_IDX ); +} + +__mt76_tx_complete_skb(dev, wcid_idx, t->skb,
free_list);drivers/net/wireless/mediatek/mt76/mt76_connac.h +8
-0+out: +t->skb =NULL ; +mt76_put_txwi (dev, t); +} +EXPORT_SYMBOL_GPL (mt76_connac3_txwi_free); + +static bool +mt76_connac3_mac_add_txs_skb(struct mt76_dev *dev,struct
mt76_wcid
*wcid,drivers/net/wireless/mediatek/mt76/mt76_connac.h +53
-0+ int pid, __le32 *txs_data) +{ +struct mt76_sta_stats *stats = &wcid->stats; +struct ieee80211_supported_band *sband; +struct ieee80211_tx_info *info; +u32 txrate, txs, mode, stbc; +struct rate_info rate = {}; +struct sk_buff_head list; +struct mt76_phy *mphy; +struct sk_buff *skb; +bool cck = false; + +mt76_tx_status_lock (dev, &list); +skb =mt76_tx_status_skb_get (dev, wcid, pid, &list); +if (!skb) +goto out_no_skb; + +txs =le32_to_cpu (txs_data[0 ]); + +info =IEEE80211_SKB_CB (skb); +if (!(txs &MT_TXS0_ACK_ERROR_MASK )) +info->flags |=IEEE80211_TX_STAT_ACK ; + +info->status.ampdu_len =1 ; +info->status.ampdu_ack_len = !!(info->flags & +IEEE80211_TX_STAT_ACK ); +info->status.rates[0 ].idx =-1 ; + +txrate =FIELD_GET (MT_TXS0_TX_RATE , txs); + +rate.mcs =FIELD_GET (MT_TX_RATE_IDX , txrate); +rate.nss =FIELD_GET (MT_TX_RATE_NSS , txrate) +1 ; +stbc =le32_get_bits (txs_data[3 ],MT_TXS3_RATE_STBC ); + +if (stbc && rate.nss >1 ) +rate.nss >>=1 ; + +if (rate.nss -1 <ARRAY_SIZE (stats->tx_nss)) +stats->tx_nss[rate.nss -1 ]++; +if (rate.mcs <ARRAY_SIZE (stats->tx_mcs)) +stats->tx_mcs[rate.mcs]++; + +mode =FIELD_GET (MT_TX_RATE_MODE , txrate); +switch (mode) { +case MT_PHY_TYPE_CCK : +cck = true; +fallthrough; +case MT_PHY_TYPE_OFDM : +mphy =mt76_dev_phy (dev, wcid->phy_idx); + +if (mphy->chandef.chan->band ==NL80211_BAND_5GHZ ) +sband = &mphy->sband_5g.sband; +else if (mphy->chandef.chan->band ==
NL80211_BAND_6GHZ)drivers/net/wireless/mediatek/mt76/mt76_connac.h +5
-0+sband = &mphy->sband_6g.sband; +else +sband = &mphy->sband_2g.sband; + +rate.mcs = mt76_get_rate(mphy->dev, sband, rate.mcs,cck);
drivers/net/wireless/mediatek/mt76/mt76_connac.h +70
-0+rate.legacy = sband->bitrates[rate.mcs].bitrate; +break ; +case MT_PHY_TYPE_HT : +case MT_PHY_TYPE_HT_GF : +if (rate.mcs >31 ) +goto out; + +rate.flags =RATE_INFO_FLAGS_MCS ; +if (wcid->rate.flags &RATE_INFO_FLAGS_SHORT_GI ) +rate.flags |=RATE_INFO_FLAGS_SHORT_GI ; +break ; +case MT_PHY_TYPE_VHT : +if (rate.mcs >9 ) +goto out; + +rate.flags =RATE_INFO_FLAGS_VHT_MCS ; +break ; +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : +case MT_PHY_TYPE_HE_MU : +if (rate.mcs >11 ) +goto out; + +rate.he_gi = wcid->rate.he_gi; +rate.he_dcm =FIELD_GET (MT_TX_RATE_DCM , txrate); +rate.flags =RATE_INFO_FLAGS_HE_MCS ; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : +if (rate.mcs >13 ) +goto out; + +rate.eht_gi = wcid->rate.eht_gi; +rate.flags =RATE_INFO_FLAGS_EHT_MCS ; +break ; +default : +goto out; +} + +stats->tx_mode[mode]++; + +switch (FIELD_GET (MT_TXS0_BW , txs)) { +case IEEE80211_STA_RX_BW_320 : +rate.bw =RATE_INFO_BW_320 ; +stats->tx_bw[4 ]++; +break ; +case IEEE80211_STA_RX_BW_160 : +rate.bw =RATE_INFO_BW_160 ; +stats->tx_bw[3 ]++; +break ; +case IEEE80211_STA_RX_BW_80 : +rate.bw =RATE_INFO_BW_80 ; +stats->tx_bw[2 ]++; +break ; +case IEEE80211_STA_RX_BW_40 : +rate.bw =RATE_INFO_BW_40 ; +stats->tx_bw[1 ]++; +break ; +default : +rate.bw =RATE_INFO_BW_20 ; +stats->tx_bw[0 ]++; +break ; +} +wcid->rate = rate; + +out: +mt76_tx_status_skb_done (dev, skb, &list); +Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +7
-0+out_no_skb: +mt76_tx_status_unlock (dev, &list); + +return !!skb; +} + +void mt76_connac3_mac_add_txs(struct mt76_dev *dev,void
*data,
Quoted 77 lines
Quoted 77 lines
Quoted 76 lines
Quoted 72 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +8
-0+ u32 max_wtbl_size) +{ +struct mt76_wcid *wcid; +__le32 *txs_data = data; +u16 wcidx; +u8 pid; + +if (le32_get_bits(txs_data[0], MT_TXS0_TXS_FORMAT) >1)
drivers/net/wireless/mediatek/mt76/mt76_connac.h +18
-0+return ; + +wcidx =le32_get_bits (txs_data[2 ],MT_TXS2_WCID ); +pid =le32_get_bits (txs_data[3 ],MT_TXS3_PID ); + +if (pid <MT_PACKET_ID_FIRST ) +return ; + +if (wcidx >= max_wtbl_size) +return ; + +rcu_read_lock (); + +wcid =rcu_dereference (dev->wcid[wcidx]); +if (!wcid) +goto out; + +mt76_connac3_mac_add_txs_skb(dev, wcid, pid,
txs_data);drivers/net/wireless/mediatek/mt76/mt76_connac.h +27
-0+if (!wcid->sta) +goto out; + +spin_lock_bh (&dev->sta_poll_lock); +if (list_empty (&wcid->poll_list)) +list_add_tail (&wcid->poll_list, &dev->sta_poll_list); +spin_unlock_bh (&dev->sta_poll_lock); + +out: +rcu_read_unlock (); +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_add_txs); + +void mt76_connac3_tx_token_put (struct mt76_dev *dev) +{ +struct mt76_txwi_cache *txwi; +int id; + +spin_lock_bh (&dev->token_lock); +idr_for_each_entry(&dev->token, txwi, id) { +mt76_connac3_txwi_free (dev, txwi,NULL ,NULL ); +dev->token_count--; +} +spin_unlock_bh (&dev->token_lock); +idr_destroy (&dev->token); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_token_put);diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hindex6663a0b46541..bcc1d976b2b0100644
---a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h
+++b/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hdrivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0@@ -4,6 +4,24 @@#ifndef __MT76_CONNAC3_MAC_H#define __MT76_CONNAC3_MAC_H +/* NOTE: used to map mt76_rates. idx may change if firmware
expands
table */drivers/net/wireless/mediatek/mt76/mt76_connac.h
Quoted 2 lines
drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+#define MT76_CONNAC3_BASIC_RATES_TBL11 +#define MT76_CONNAC3_BEACON_RATES_TBL25 Different devices may have different defined value.
Quoted 2 lines
Quoted 2 lines
The other WiFi7 device I am working on relies on the values I
moved
Quoted 3 lines
Quoted 3 lines
in
mt76_connac3_mac.h(in common with mt7996). Moreover you canstill
Quoted 7 lines
Quoted 3 lines
have per-device values in
mt7996/mac.h(I have not removed it).Please double check with the mtk folk you work with. The 11 and
25is
Quoted 3 lines
the value I discussed with firmware folks to avoid overlapping
thetbl
Quoted 2 lines
mt7996 use (MU/other algo in fw), or it causes something hardly
solving
Quoted 1 line
issue
sure, thx for pointing this out.
@Deren: can you please double check?Regards,
LorenzoQuoted 4 lines
Quoted 4 lines
Quoted 4 lines
I'm thinking if it's too early to create this patch for just
moving
Quoted 4 lines
Quoted 4 lines
Quoted 1 line
mt7996 to
connac3_lib?The code I moved is used by the other device as well. This series
is
Quoted 9 lines
Quoted 9 lines
a
preliminary series to support it.Regards,
LorenzoQuoted 3 lines
Ryder
Ryder Lee
maintainerRe: [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library
Quoted 21 lines · Shayne Chen (陳軒丞)
Quoted 20 lines · On Sat, 2023-06-10 at 12:06 +0200, [email protected] wrote:
Quoted 20 lines · Shayne Chen
Quoted 19 lines
Quoted 19 lines
Quoted 2 lines
On Fri, 2023-06-09 at 18:34 +0200,
[email protected]Quoted 5 lines · wrote:
Quoted 5 lines · Ryder Lee
Quoted 4 lines
Quoted 2 lines · Lorenzo Bianconi
External email : Please do not click links or open
attachments
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
until you have verified the sender or the content.
Introduceconnac3_macinmt76_connaclibrary to
reuse
maccode
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
shared between WiFi7 chipsets.
Quoted 68 lines
Quoted 6 lines
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Signed-off-by Lorenzo Bianconi <[email protected]>Hi Lorenzo,
Hi Shayne,
Hi Lorenzo,
Quoted 59 lines
Quoted 12 lines
Quoted 12 lines
I don't think it's a good idea to start sharing mac or mcu functions
for all WiFi7 chipsets at such early stage.The driver is still under many processes of bug fixing, performance
tuning, and new features development.
Chipsets that mainly used for AP or STA segment have different designs
and should face different problems.Quoted 7 lines
Quoted 7 lines
Start sharing the code at early stage will break the independence,
make
it more hard to develop and do verifications, since many changes
will
affect chipsets of both segments.my goal is to share the code that hardly will be changed (or that will have
very few changes in the future, i.e. I have not changed mcu codebase).
If you consider for example the routines below:- mt76_connac*_mac_write_txwi_8023()
- mt76_connac*_mac_write_txwi_80211()
- mt76_connac*_mac_add_txs_skb()
- mt76_connac*_txwi_free()
- ...they are the same for mt7615/mt7663, mt7921/mt7915, mt7996/.. , what
is
changing is just register map between versions (e.g. mt7615/mt7663 and
mt7915/mt7921). I think it is not a good idea to copy-paste the code
because it will just make the code much harder to maintain, and this
will be
more difficult to address in the future.
If you consider the commit below:commit
ead449023d3acb1424886d7b8cc672ed69bdd27eAuthor: Lorenzo Bianconi <[email protected]> Date: Sun May 28 12:28:49 2023 +0200wifi: mt76: mt7996: fix possible NULL pointer dereference in
mt7996_mac_write_txwi()Fix possible NULL pointer dereference on mvif pointer in
mt7996_mac_write_txwiroutine.Deren will needs to monitor the ML and apply the same fix for the other WiFi7
chipset too.
This depends on viewpoint. For instance, I planed to add many changes for mt7986 but 7921 doesn't use (or even don't care), but I need to check other don't care devices without any help (because they don't care), so we maintain more an more patches in local branch rather than upstreming.
Other that that, I think it's ok in wifi6 but wifi7 is REALLY different. it's better to wait the major MLO development finished to have a whole picture to know what the best way to unify.
Quoted 5 lines
Quoted 4 lines
Moreover I kept mt7996/mac.{c,h} to put the per-chipset codebase. If you think
MT76_CONNAC3_BASIC_RATES_TBL11andMT76_CONNAC3_BEACON_RATES_TBL25
are sensible, we can put them inmt7996/mac.h
and this is just one anther example I can tell right now.
Quoted 28 lines
I understand your concern, but if the code starts to be shared at early
stage, we may need to add severalis_mt7996()to split different parts
temporarily or permanently, since we have different development procedure and focusing, on devices of different segements.Below are some examples I concern:
- We're doing some tests about switching all TXS to PPDU TXS, and the code inmac_add_txs_skb()needs to be changed. If devices of STA segement don't want to change or won't switch in short time, we may need to addis_mt7996()to split.- When adding MLO support, there will be many changes in
mac_write_txwi()andtxwi_free(), compared to previous chipsets. To prevent from adding side effects to other devices, we may also need to
addis_mt7996()to split code at least for temporary.I would like to know is it fine with you to add some
is_mt7996()to the
shared code for the above examples?
I think this could help to balance the trade off between sharing code and assuring the driver stability on different segements.Thanks,
ShayneQuoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Re: [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library
In reply to [email protected]Quoted 1,033 lines · On Fri, 2023-06-09 at 18:45 +0200, [email protected] wrote:
Quoted 1,025 lines
Quoted 1,015 lines · On Fri, 2023-06-09 at 18:34 +0200, [email protected] wrote:
Quoted 1,005 lines · Ryder Lee
Quoted 1,004 lines · Lorenzo Bianconi
External email : Please do not click links or open attachments
until
you have verified the sender or the content.
Introduceconnac3_macinmt76_connaclibrary to reuse mac
code
shared
between WiFi7 chipsets.Signed-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76_connac.h | 19 + .../wireless/mediatek/mt76/mt76_connac3_mac.c | 742 +++++++++++++++++ .../wireless/mediatek/mt76/mt76_connac3_mac.h | 18 + .../net/wireless/mediatek/mt76/mt7996/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 761 +------- ---- ---- -- .../net/wireless/mediatek/mt76/mt7996/main.c | 8 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +- .../wireless/mediatek/mt76/mt7996/mt7996.h | 28 +- 9 files changed, 807 insertions(+), 784 deletions(-) create mode 100644
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cdrivers/net/wireless/mediatek/mt76/Makefile +0
-0@@ -27,7 +27,7 @@ mt76x02-lib-y := mt76x02_util.omt76x02_mac.o
mt76x02_mcu.o \mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o
drivers/net/wireless/mediatek/mt76/Makefile +1
-1-mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o +mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.omt76_connac3_mac.o
obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
obj-$(CONFIG_MT76x2_COMMON) += mt76x2/drivers/net/wireless/mediatek/mt76/mt76_connac.h +0
-0@@ -415,4 +415,23 @@ void mt76_connac2_txwi_free(struct
mt76_dev
*dev, structmt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0struct list_head *free_list);void mt76_connac2_tx_token_put (struct mt76_dev *dev); +/* connac3 */ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
__le32
*txwi);
+void mt76_connac3_mac_decode_he_radiotap(structsk_buff*skb,__le32
*rxv,drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+ u8 mode); +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, + struct mt76_rx_status*status,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+ struct
ieee80211_supported_band
*sband,drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ __le32 *rxv, u8 *mode); +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev,
__le32
*txwi,drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+struct sk_buff *skb, struct
mt76_wcid
*wcid,drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+struct ieee80211_key_conf *key, int
pid,drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+enum mt76_txq_id qid, u32changed);
+void mt76_connac3_txwi_free(structmt76_dev*dev, structmt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+struct ieee80211_sta *sta, + struct list_head *free_list); +void mt76_connac3_mac_add_txs(struct mt76_dev *dev, void*data,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+ u32 max_wtbl_size); +void mt76_connac3_tx_token_put (struct mt76_dev *dev); +#endif /* __MT76_CONNAC_H */ diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cnew file mode 100644
index 000000000000..4b745bb74ca0drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0@@ -0,0 +1,742 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include "mt76_connac.h" +#include "mt76_connac3_mac.h" +#include "dma.h" + +#define HE_BITS (f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
+#defineHE_PREP(f, m, v)le16_encode_bits(le32_get_bits(
v,
MT_CRXV_HE_##m),\drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+IEEE80211_RADI
OTAP_HE_
##f)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
__le32
*txwi)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+{ + struct mt76_wcid *wcid; + u16 fc, tid; + u32 val; + + if (!sta || + !(sta->deflink.ht_cap.ht_supported || sta-Quoted 1 line
deflink.he_cap.has_he))
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + + tid =le32_get_bits (txwi[1 ],MT_TXD1_TID ); +if (tid >=6 )/* skip VO queue */ +return ; + + val =le32_to_cpu (txwi[2 ]); + fc =FIELD_GET (MT_TXD2_FRAME_TYPE , val) <<2 | +FIELD_GET (MT_TXD2_SUB_TYPE , val) <<4 ; + if (unlikely(fc != (IEEE80211_FTYPE_DATA |
IEEE80211_STYPE_QOS_DATA)))drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + + wcid = (struct mt76_wcid *)sta->drv_priv; +if (!test_and_set_bit (tid, &wcid->ampdu_state)) +ieee80211_start_tx_ba_session (sta, tid,0 ); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_check_aggr); + +static void +mt76_connac3_mac_decode_he_radiotap_ru(struct mt76_rx_status*status,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ struct
ieee80211_radiotap_he
*he,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ __le32 *rxv) +{ + u32 ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC),offs = 0;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ + status->bw =RATE_INFO_BW_HE_RU ; + +switch (ru) { + case 0 ... 36: + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_26;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ offs = ru; +break ; + case 37 ... 52: + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_52;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ offs = ru -37 ; +break ; + case 53 ... 60: + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_106;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ offs = ru -53 ; +break ; + case 61 ... 64: + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_242;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ offs = ru -61 ; +break ; + case 65 ... 66: + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_484;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ offs = ru -65 ; +break ; +case 67 : + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_996;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+break ; +case 68 : + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_2x996;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+break ; + } + + he->data1 |=HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + he->data2 |=HE_BITS (DATA2_RU_OFFSET_KNOWN ) | +le16_encode_bits (offs, + IEEE80211_RADIOTAP_HE_DAT
A2_RU_OF
FSET);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+} + +#define MU_PREP (f, v) le16_encode_bits(v,IEEE80211_RADIOTAP_HE_MU_##f)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+static void +mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff *skb,
__le32
*rxv)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ + struct mt76_rx_status *status = (struct mt76_rx_status*)skb-
Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ static const struct ieee80211_radiotap_he_mu mu_known ={
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) | +HE_BITS (MU_FLAGS1_SIG_B_DCM_KNOWN ) | +HE_BITS (MU_FLAGS1_CH1_RU_KNOWN ) | + HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN),
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ .flags2 =
HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN),drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+ }; +struct ieee80211_radiotap_he_mu *he_mu; + + status->flag |=RX_FLAG_RADIOTAP_HE_MU ; + + he_mu =skb_push (skb,sizeof (mu_known)); +memcpy (he_mu, &mu_known,sizeof (mu_known)); + + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status-Quoted 1 line
rate_idx);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+if (status->he_dcm) + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM,status-
Quoted 1 line
he_dcm);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW,
status->bw) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ MU_PREP(FLAGS2_SIG_B_SYMS_USERS, + le32_get_bits(rxv[4],
MT_CRXV_HE_NUM_USER));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + he_mu->ru_ch1[0] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU0) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ +if (status->bw >=RATE_INFO_BW_40 ) { + he_mu->flags1 |=
HE_BITS(MU_FLAGS1_CH2_RU_KNOWN);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ he_mu->ru_ch2[0] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU1) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ } + +if (status->bw >=RATE_INFO_BW_80 ) { +u32 ru_h, ru_l; + + he_mu->ru_ch1[1] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU2) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + ru_l = le32_get_bits(rxv[16],
MT_CRXV_HE_RU3_L);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ ru_h =le32_get_bits (rxv[17 ],MT_CRXV_HE_RU3_H )&
0x7;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+ he_mu->ru_ch2[1 ] = (u8)(ru_l | ru_h <<4 ); + } +} + +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff*skb,
__le32
*rxv,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ u8 mode) +{ + struct mt76_rx_status *status = (struct mt76_rx_status*)skb-
Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +15
-0+static const struct ieee80211_radiotap_he known = { + .data1 =HE_BITS (DATA1_DATA_MCS_KNOWN ) | +HE_BITS (DATA1_DATA_DCM_KNOWN ) | +HE_BITS (DATA1_STBC_KNOWN ) | +HE_BITS (DATA1_CODING_KNOWN ) | +HE_BITS (DATA1_LDPC_XSYMSEG_KNOWN ) | +HE_BITS (DATA1_DOPPLER_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE_KNOWN ) | +HE_BITS (DATA1_BSS_COLOR_KNOWN ), + .data2 =HE_BITS (DATA2_GI_KNOWN ) | +HE_BITS (DATA2_TXBF_KNOWN ) | +HE_BITS (DATA2_PE_DISAMBIG_KNOWN ) | +HE_BITS (DATA2_TXOP_KNOWN ), + }; + u32 ltf_size = le32_get_bits(rxv[4],
MT_CRXV_HE_LTF_SIZE) + 1;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+struct ieee80211_radiotap_he *he; + + status->flag |=RX_FLAG_RADIOTAP_HE ; + + he =skb_push (skb,sizeof (known)); +memcpy (he, &known,sizeof (known)); + + he->data3 =HE_PREP (DATA3_BSS_COLOR ,BSS_COLOR , rxv[9 ])|
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM,rxv[4]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK,rxv[13]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG,rxv[5]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+le16_encode_bits (ltf_size, + IEEE80211_RADIOTAP_HE_DATA5_LTF_SI
ZE);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+if (le32_to_cpu (rxv[0 ]) &MT_PRXV_TXBF ) + he->data5 |=HE_BITS (DATA5_TXBF ); + he->data6 =HE_PREP (DATA6_TXOP ,TXOP_DUR , rxv[9 ]) | +HE_PREP (DATA6_DOPPLER ,DOPPLER , rxv[9 ]); + +switch (mode) { +case MT_PHY_TYPE_HE_SU : + he->data1 |=HE_BITS (DATA1_FORMAT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BEAM_CHANGE_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + + he->data3 |= HE_PREP(DATA3_BEAM_CHANGE,
BEAM_CHNG,
rxv[8]) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA3_UL_DL, UPLINK,rxv[5]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+break ; +case MT_PHY_TYPE_HE_EXT_SU : + he->data1 |=HE_BITS (DATA1_FORMAT_EXT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + + he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK,rxv[5]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+break ; +case MT_PHY_TYPE_HE_MU : + he->data1 |=HE_BITS (DATA1_FORMAT_MU ) | +HE_BITS (DATA1_UL_DL_KNOWN ); + + he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK,rxv[5]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID,rxv[8]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + mt76_connac3_mac_decode_he_radiotap_ru(status,he,
rxv);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ mt76_connac3_mac_decode_he_mu_radiotap(skb,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+break ; +case MT_PHY_TYPE_HE_TB : + he->data1 |=HE_BITS (DATA1_FORMAT_TRIG ) | +HE_BITS (DATA1_SPTL_REUSE2_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE3_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE4_KNOWN ); + + he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1,
SR_MASK,
rxv[13]) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE2,
SR1_MASK,
rxv[13]) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE3,
SR2_MASK,
rxv[13]) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE4,
SR3_MASK,
rxv[13]);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + mt76_connac3_mac_decode_he_radiotap_ru(status,he,
rxv);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+break ; +default : +break ; + } +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_decode_he_radiotap); + +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, + struct mt76_rx_status*status,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ struct
ieee80211_supported_band
*sband,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +32
-0+ __le32 *rxv, u8 *mode) +{ +u8 stbc, gi, bw, dcm, nss; +bool cck = false; +u32 v0, v2; +int i, idx; + + v0 =le32_to_cpu (rxv[0 ]); + v2 =le32_to_cpu (rxv[2 ]); + + idx =FIELD_GET (MT_PRXV_TX_RATE , v0); + i = idx; + nss =FIELD_GET (MT_PRXV_NSTS , v0) +1 ; + + stbc =FIELD_GET (MT_PRXV_HT_STBC , v2); + gi =FIELD_GET (MT_PRXV_HT_SHORT_GI , v2); + *mode =FIELD_GET (MT_PRXV_TX_MODE , v2); + dcm =FIELD_GET (MT_PRXV_DCM , v2); + bw =FIELD_GET (MT_PRXV_FRAME_MODE , v2); + +switch (*mode) { +case MT_PHY_TYPE_CCK : + cck = true; + fallthrough; +case MT_PHY_TYPE_OFDM : + i =mt76_get_rate (dev, sband, i, cck); +break ; +case MT_PHY_TYPE_HT_GF : +case MT_PHY_TYPE_HT : + status->encoding =RX_ENC_HT ; +if (gi) + status->enc_flags |=
RX_ENC_FLAG_SHORT_GI;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+if (i >31 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_VHT : + status->nss = nss; + status->encoding =RX_ENC_VHT ; +if (gi) + status->enc_flags |=
RX_ENC_FLAG_SHORT_GI;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +40
-0+if (i >11 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_HE_MU : +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : + status->nss = nss; + status->encoding =RX_ENC_HE ; + i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_HE_GI_3_2 ) + status->he_gi = gi; + + status->he_dcm = dcm; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : + status->nss = nss; + status->encoding =RX_ENC_EHT ; + i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_EHT_GI_3_2 ) + status->eht.gi = gi; +break ; +default : +return -EINVAL ; + } + status->rate_idx = i; + +switch (bw) { +case IEEE80211_STA_RX_BW_20 : +break ; +case IEEE80211_STA_RX_BW_40 : +if (*mode &MT_PHY_TYPE_HE_EXT_SU && + (idx &MT_PRXV_TX_ER_SU_106T )) { + status->bw =RATE_INFO_BW_HE_RU ; + status->he_ru = +NL80211_RATE_INFO_HE_RU_ALLOC_1 06;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +27
-0+ }else { + status->bw =RATE_INFO_BW_40 ; + } +break ; +case IEEE80211_STA_RX_BW_80 : + status->bw =RATE_INFO_BW_80 ; +break ; +case IEEE80211_STA_RX_BW_160 : + status->bw =RATE_INFO_BW_160 ; +break ; +case IEEE80211_STA_RX_BW_320 : + status->bw =RATE_INFO_BW_320 ; +break ; +default : +return -EINVAL ; + } + + status->enc_flags |=RX_ENC_FLAG_STBC_MASK * stbc; +if (*mode <MT_PHY_TYPE_HE_SU && gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; + +return 0 ; +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_fill_rx_rate); + +static void +mt76_connac3_mac_write_txwi_8023(__le32 *txwi, struct
sk_buff
*skb,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +12
-0+ struct mt76_wcid *wcid) +{ +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +u8 fc_type, fc_stype; +u16 ethertype; +bool wmm = false; +u32 val; + +if (wcid->sta) { +struct ieee80211_sta *sta; + + sta = container_of((void *)wcid, struct
ieee80211_sta,drv_priv);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ wmm = sta->wme; + } + + val = FIELD_PREP(MT_TXD1_HDR_FORMAT,
MT_HDR_FORMAT_802_3) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +19
-0+FIELD_PREP (MT_TXD1_TID , tid); + + ethertype =get_unaligned_be16 (&skb->data[12 ]); +if (ethertype >=ETH_P_802_3_MIN ) + val |=MT_TXD1_ETH_802_3 ; + + txwi[1 ] |=cpu_to_le32 (val); + + fc_type =IEEE80211_FTYPE_DATA >>2 ; + fc_stype = wmm ?IEEE80211_STYPE_QOS_DATA >>4 :0 ; + + val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + + txwi[2 ] |=cpu_to_le32 (val); +} + +static void +mt76_connac3_mac_write_txwi_80211(struct mt76_dev *dev,
__le32
*txwi,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+struct sk_buff *skb, + struct ieee80211_key_conf*key)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr*)skb->data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt*)skb-
Quoted 1 line
data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +bool multicast =is_multicast_ether_addr (hdr->addr1); +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +__le16 fc = hdr->frame_control; +u8 fc_type, fc_stype; +u32 val; + +if (ieee80211_is_action (fc) && + mgmt->u.action.category ==WLAN_CATEGORY_BACK && + mgmt->u.action.u.addba_req.action_code ==
WLAN_ACTION_ADDBA_REQ)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+ tid =MT_TX_ADDBA ; + else if (ieee80211_is_mgmt(hdr->frame_control)) + tid =MT_TX_NORMAL ; + + val = FIELD_PREP(MT_TXD1_HDR_FORMAT,
MT_HDR_FORMAT_802_11) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ FIELD_PREP(MT_TXD1_HDR_INFO, + ieee80211_get_hdrlen_from_skb(skb) /2) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+FIELD_PREP (MT_TXD1_TID , tid); + +if (!ieee80211_is_data (fc) || multicast || + info->flags &IEEE80211_TX_CTL_USE_MINRATE ) + val |=MT_TXD1_FIXED_RATE ; + + if (key && multicast &&
ieee80211_is_robust_mgmt_frame(skb)&&drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+ key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { + val |=MT_TXD1_BIP ; + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_PROTECT_FRAME ); + } + + txwi[1 ] |=cpu_to_le32 (val); + + fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >>2;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >>4;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+ + val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + + txwi[2 ] |=cpu_to_le32 (val); + + txwi[3] |= cpu_to_le32(FIELD_PREP(MT_TXD3_BCM,multicast));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+if (ieee80211_is_beacon (fc)) { + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_SW_POWER_MGMT ); + txwi[3 ] |=cpu_to_le32 (MT_TXD3_REM_TX_COUNT ); + } + +if (info->flags &IEEE80211_TX_CTL_INJECTED ) { +u16 seqno =le16_to_cpu (hdr->seq_ctrl); + +if (ieee80211_is_back_req (hdr->frame_control)){
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+struct ieee80211_bar *bar; + + bar = (struct ieee80211_bar *)skb-Quoted 1 line
data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ seqno = le16_to_cpu(bar-Quoted 1 line
start_seq_num);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ } + + val =MT_TXD3_SN_VALID | + FIELD_PREP(MT_TXD3_SEQ,
IEEE80211_SEQ_TO_SN(seqno));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ txwi[3 ] |=cpu_to_le32 (val); + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_HW_AMSDU ); + } +} + +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev,
__le32
*txwi,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+struct sk_buff *skb, struct
mt76_wcid
*wcid,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+struct ieee80211_key_conf *key, int
pid,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+enum mt76_txq_id qid, u32changed)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ + u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE :
MT_SDIO_TXD_SIZE;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +struct ieee80211_vif *vif = info->control.vif; + u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >>2;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+u8 p_fmt, q_idx, omac_idx =0 , wmm_idx =0 ; + bool is_8023 = info->flags &
IEEE80211_TX_CTL_HW_80211_ENCAP;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+struct mt76_vif *mvif; +u16 tx_count =15 ; +bool beacon = !!(changed & (BSS_CHANGED_BEACON | + BSS_CHANGED_BEACON_ENABLED));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ bool inband_disc = !!(changed &(
BSS_CHANGED_UNSOL_BCAST_PROBE_RESP|drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+BSS_CHANGED_FILS_DISCO VERY));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +16
-0+ + mvif = vif ? (struct mt76_vif *)vif->drv_priv :NULL ; +if (mvif) { + omac_idx = mvif->omac_idx; + wmm_idx = mvif->wmm_idx; + band_idx = mvif->band_idx; + } + +if (inband_disc) { + p_fmt =MT_TX_TYPE_FW ; + q_idx =MT_LMAC_ALTX0 ; + }else if (beacon) { + p_fmt =MT_TX_TYPE_FW ; + q_idx =MT_LMAC_BCN0 ; + }else if (qid >=MT_TXQ_PSD ) { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ q_idx =MT_LMAC_ALTX0 ; + }else { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ q_idx = wmm_idx *MT76_CONNAC_MAX_WMM_SETS + + mt76_connac_lmac_mapping(skb_get_queue_mapping(
skb));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +40
-0+ } + + val =FIELD_PREP (MT_TXD0_TX_BYTES , skb->len + sz_txd) | +FIELD_PREP (MT_TXD0_PKT_FMT , p_fmt) | +FIELD_PREP (MT_TXD0_Q_IDX , q_idx); + txwi[0 ] =cpu_to_le32 (val); + + val =FIELD_PREP (MT_TXD1_WLAN_IDX , wcid->idx) | +FIELD_PREP (MT_TXD1_OWN_MAC , omac_idx); + +if (band_idx) + val |=FIELD_PREP (MT_TXD1_TGID , band_idx); + + txwi[1 ] =cpu_to_le32 (val); + txwi[2 ] =0 ; + + val =MT_TXD3_SW_POWER_MGMT | +FIELD_PREP (MT_TXD3_REM_TX_COUNT , tx_count); +if (key) + val |=MT_TXD3_PROTECT_FRAME ; +if (info->flags &IEEE80211_TX_CTL_NO_ACK ) + val |=MT_TXD3_NO_ACK ; +if (wcid->amsdu) + val |=MT_TXD3_HW_AMSDU ; + + txwi[3 ] =cpu_to_le32 (val); + txwi[4 ] =0 ; + + val =FIELD_PREP (MT_TXD5_PID , pid); +if (pid >=MT_PACKET_ID_FIRST ) + val |=MT_TXD5_TX_STATUS_HOST ; + txwi[5 ] =cpu_to_le32 (val); + + val =MT_TXD6_DIS_MAT |MT_TXD6_DAS | +FIELD_PREP (MT_TXD6_MSDU_CNT ,1 ); + txwi[6 ] =cpu_to_le32 (val); + txwi[7 ] =0 ; + +if (is_8023) + mt76_connac3_mac_write_txwi_8023(txwi, skb,wcid);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+else + mt76_connac3_mac_write_txwi_80211(dev, txwi,skb, key);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ +if (txwi[1 ] &cpu_to_le32 (MT_TXD1_FIXED_RATE )) { + struct ieee80211_hdr *hdr = (struct
ieee80211_hdr
*)skb->data;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ bool mcast = ieee80211_is_data(hdr-Quoted 1 line
frame_control) &&drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ is_multicast_ether_addr(hdr-Quoted 1 line
addr1);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+u8 idx =MT76_CONNAC3_BASIC_RATES_TBL ; + + if (mvif) { + if (mcast && mvif->mcast_rates_idx) + idx = mvif->mcast_rates_idx; + else if (beacon && mvif-Quoted 1 line
beacon_rates_idx)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ idx = mvif->beacon_rates_idx; + else + idx = mvif->basic_rates_idx; + } + + txwi[6] |=cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE,
idx));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ txwi[3 ] |=cpu_to_le32 (MT_TXD3_BA_DISABLE ); + } +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_write_txwi); + +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+struct ieee80211_sta *sta, + struct list_head *free_list) +{ + __le32 *txwi; +u16 wcid_idx; + +mt76_connac_txp_skb_unmap (dev, t); +if (!t->skb) + goto out; + + txwi = (__le32 *)mt76_get_txwi_ptr (dev, t); +if (sta) { + struct mt76_wcid *wcid = (struct mt76_wcid*)sta-
Quoted 1 line
drv_priv;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ + wcid_idx = wcid->idx; + if (likely(t->skb->protocol !=
cpu_to_be16(ETH_P_PAE)))drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+mt76_connac3_tx_check_aggr (sta, txwi); + }else { + wcid_idx = le32_get_bits(txwi[1],
MT_TXD1_WLAN_IDX);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ } + + __mt76_tx_complete_skb(dev, wcid_idx, t->skb,
free_list);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+out: + t->skb =NULL ; +mt76_put_txwi (dev, t); +} +EXPORT_SYMBOL_GPL (mt76_connac3_txwi_free); + +static bool +mt76_connac3_mac_add_txs_skb(struct mt76_dev *dev, struct
mt76_wcid
*wcid,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +51
-0+ int pid, __le32 *txs_data) +{ + struct mt76_sta_stats *stats = &wcid->stats; +struct ieee80211_supported_band *sband; +struct ieee80211_tx_info *info; +u32 txrate, txs, mode, stbc; +struct rate_info rate = {}; +struct sk_buff_head list; +struct mt76_phy *mphy; +struct sk_buff *skb; +bool cck = false; + +mt76_tx_status_lock (dev, &list); + skb =mt76_tx_status_skb_get (dev, wcid, pid, &list); +if (!skb) + goto out_no_skb; + + txs =le32_to_cpu (txs_data[0 ]); + + info =IEEE80211_SKB_CB (skb); +if (!(txs &MT_TXS0_ACK_ERROR_MASK )) + info->flags |=IEEE80211_TX_STAT_ACK ; + + info->status.ampdu_len =1 ; + info->status.ampdu_ack_len = !!(info->flags & +IEEE80211_TX_STAT_ACK ); + info->status.rates[0 ].idx =-1 ; + + txrate =FIELD_GET (MT_TXS0_TX_RATE , txs); + + rate.mcs =FIELD_GET (MT_TX_RATE_IDX , txrate); + rate.nss =FIELD_GET (MT_TX_RATE_NSS , txrate) +1 ; + stbc =le32_get_bits (txs_data[3 ],MT_TXS3_RATE_STBC ); + +if (stbc && rate.nss >1 ) + rate.nss >>=1 ; + +if (rate.nss -1 <ARRAY_SIZE (stats->tx_nss)) + stats->tx_nss[rate.nss -1 ]++; +if (rate.mcs <ARRAY_SIZE (stats->tx_mcs)) + stats->tx_mcs[rate.mcs]++; + + mode =FIELD_GET (MT_TX_RATE_MODE , txrate); +switch (mode) { +case MT_PHY_TYPE_CCK : + cck = true; + fallthrough; +case MT_PHY_TYPE_OFDM : + mphy =mt76_dev_phy (dev, wcid->phy_idx); + + if (mphy->chandef.chan->band ==
NL80211_BAND_5GHZ)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ sband = &mphy->sband_5g.sband; + else if (mphy->chandef.chan->band ==
NL80211_BAND_6GHZ)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+ sband = &mphy->sband_6g.sband; + else + sband = &mphy->sband_2g.sband; + + rate.mcs = mt76_get_rate(mphy->dev, sband,rate.mcs,
cck);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ rate.legacy = sband-Quoted 1 line
bitrates[rate.mcs].bitrate;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+break ; +case MT_PHY_TYPE_HT : +case MT_PHY_TYPE_HT_GF : +if (rate.mcs >31 ) + goto out; + + rate.flags =RATE_INFO_FLAGS_MCS ; + if (wcid->rate.flags &
RATE_INFO_FLAGS_SHORT_GI)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+ rate.flags |=RATE_INFO_FLAGS_SHORT_GI ; +break ; +case MT_PHY_TYPE_VHT : +if (rate.mcs >9 ) + goto out; + + rate.flags =RATE_INFO_FLAGS_VHT_MCS ; +break ; +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : +case MT_PHY_TYPE_HE_MU : +if (rate.mcs >11 ) + goto out; + + rate.he_gi = wcid->rate.he_gi; + rate.he_dcm = FIELD_GET(MT_TX_RATE_DCM,txrate);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +51
-0+ rate.flags =RATE_INFO_FLAGS_HE_MCS ; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : +if (rate.mcs >13 ) + goto out; + + rate.eht_gi = wcid->rate.eht_gi; + rate.flags =RATE_INFO_FLAGS_EHT_MCS ; +break ; +default : + goto out; + } + + stats->tx_mode[mode]++; + +switch (FIELD_GET (MT_TXS0_BW , txs)) { +case IEEE80211_STA_RX_BW_320 : + rate.bw =RATE_INFO_BW_320 ; + stats->tx_bw[4 ]++; +break ; +case IEEE80211_STA_RX_BW_160 : + rate.bw =RATE_INFO_BW_160 ; + stats->tx_bw[3 ]++; +break ; +case IEEE80211_STA_RX_BW_80 : + rate.bw =RATE_INFO_BW_80 ; + stats->tx_bw[2 ]++; +break ; +case IEEE80211_STA_RX_BW_40 : + rate.bw =RATE_INFO_BW_40 ; + stats->tx_bw[1 ]++; +break ; +default : + rate.bw =RATE_INFO_BW_20 ; + stats->tx_bw[0 ]++; +break ; + } + wcid->rate = rate; + +out: +mt76_tx_status_skb_done (dev, skb, &list); + +out_no_skb: +mt76_tx_status_unlock (dev, &list); + +return !!skb; +} + +void mt76_connac3_mac_add_txs(struct mt76_dev *dev, void*data,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +32
-0+ u32 max_wtbl_size) +{ +struct mt76_wcid *wcid; +__le32 *txs_data = data; +u16 wcidx; +u8 pid; + +if (le32_get_bits (txs_data[0 ],MT_TXS0_TXS_FORMAT ) >1 ) +return ; + + wcidx =le32_get_bits (txs_data[2 ],MT_TXS2_WCID ); + pid =le32_get_bits (txs_data[3 ],MT_TXS3_PID ); + +if (pid <MT_PACKET_ID_FIRST ) +return ; + +if (wcidx >= max_wtbl_size) +return ; + +rcu_read_lock (); + + wcid =rcu_dereference (dev->wcid[wcidx]); +if (!wcid) + goto out; + +mt76_connac3_mac_add_txs_skb (dev, wcid, pid, txs_data); +if (!wcid->sta) + goto out; + +spin_lock_bh (&dev->sta_poll_lock); +if (list_empty (&wcid->poll_list)) + list_add_tail(&wcid->poll_list, &dev-Quoted 1 line
sta_poll_list);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +21
-0+spin_unlock_bh (&dev->sta_poll_lock); + +out: +rcu_read_unlock (); +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_add_txs); + +void mt76_connac3_tx_token_put (struct mt76_dev *dev) +{ +struct mt76_txwi_cache *txwi; +int id; + +spin_lock_bh (&dev->token_lock); +idr_for_each_entry (&dev->token, txwi, id) { +mt76_connac3_txwi_free (dev, txwi,NULL ,NULL ); + dev->token_count--; + } +spin_unlock_bh (&dev->token_lock); +idr_destroy (&dev->token); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_token_put);diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hindex6663a0b46541..bcc1d976b2b0100644drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +0
-0@@ -4,6 +4,24 @@#ifndef __MT76_CONNAC3_MAC_H#define __MT76_CONNAC3_MAC_HQuoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h line 9
Quoted 6 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +1
-0+/* NOTE: used to map mt76_rates. idx may change if firmware expands
table */drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +2
-0+#define MT76_CONNAC3_BASIC_RATES_TBL 11 +#define MT76_CONNAC3_BEACON_RATES_TBL 25Different devices may have different defined value.
Quoted 7 lines
The other WiFi7 device I am working on relies on the values I moved
inmt76_connac3_mac.h(in common with mt7996). Moreover you can still
have per-device values inmt7996/mac.h(I have not removed it).Quoted 7 lines
Please double check with the mtk folk you work with. The 11 and 25 is
the value I discussed with firmware folks to avoid overlapping the tbl
mt7996 use (MU/other algo in fw), or it causes something hardly solving
issue
Quoted 6 lines
sure, thx for pointing this out.
@Deren: can you please double check?Regards,
Lorenzo
The idx is defined by different flow in fw and may be changed in next stage development. I think it's better to keep them in per-chip header.
Regards,
Deren
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 5 lines
I'm thinking if it's too early to create this patch for just moving
mt7996 toconnac3_lib?The code I moved is used by the other device as well. This series is
a
preliminary series to support it.Regards,
LorenzoQuoted 3 lines
Ryder
[email protected]
maintainerRe: [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library
Quoted 1,034 lines · Deren Wu
Quoted 1,033 lines · On Fri, 2023-06-09 at 18:45 +0200, [email protected] wrote:
Quoted 1,032 lines
Quoted 1,015 lines · On Fri, 2023-06-09 at 18:34 +0200, [email protected] wrote:
Quoted 1,005 lines · Ryder Lee
Quoted 1,004 lines · Lorenzo Bianconi
External email : Please do not click links or open attachments
until
you have verified the sender or the content.
Introduceconnac3_macinmt76_connaclibrary to reuse mac
code
shared
between WiFi7 chipsets.Signed-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/wireless/mediatek/mt76/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt76_connac.h | 19 + .../wireless/mediatek/mt76/mt76_connac3_mac.c | 742 +++++++++++++++++ .../wireless/mediatek/mt76/mt76_connac3_mac.h | 18 + .../net/wireless/mediatek/mt76/mt7996/init.c | 4 +- .../net/wireless/mediatek/mt76/mt7996/mac.c | 761 +------- ---- ---- -- .../net/wireless/mediatek/mt76/mt7996/main.c | 8 +- .../net/wireless/mediatek/mt76/mt7996/mcu.c | 9 +- .../wireless/mediatek/mt76/mt7996/mt7996.h | 28 +- 9 files changed, 807 insertions(+), 784 deletions(-) create mode 100644
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cdrivers/net/wireless/mediatek/mt76/Makefile +0
-0@@ -27,7 +27,7 @@ mt76x02-lib-y := mt76x02_util.omt76x02_mac.o
mt76x02_mcu.o \mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o
drivers/net/wireless/mediatek/mt76/Makefile +1
-1-mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o +mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.omt76_connac3_mac.o
obj-$(CONFIG_MT76x0_COMMON) += mt76x0/
obj-$(CONFIG_MT76x2_COMMON) += mt76x2/drivers/net/wireless/mediatek/mt76/mt76_connac.h +0
-0@@ -415,4 +415,23 @@ void mt76_connac2_txwi_free(struct
mt76_dev
*dev, structmt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0struct list_head *free_list);void mt76_connac2_tx_token_put (struct mt76_dev *dev); +/* connac3 */ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
__le32
*txwi);
+void mt76_connac3_mac_decode_he_radiotap(structsk_buff*skb,__le32
*rxv,drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+ u8 mode); +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, + struct mt76_rx_status*status,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+ struct
ieee80211_supported_band
*sband,drivers/net/wireless/mediatek/mt76/mt76_connac.h +2
-0+ __le32 *rxv, u8 *mode); +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev,
__le32
*txwi,drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+struct sk_buff *skb, struct
mt76_wcid
*wcid,drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+struct ieee80211_key_conf *key, int
pid,drivers/net/wireless/mediatek/mt76/mt76_connac.h +1
-0+enum mt76_txq_id qid, u32changed);
+void mt76_connac3_txwi_free(structmt76_dev*dev, structmt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+struct ieee80211_sta *sta, + struct list_head *free_list); +void mt76_connac3_mac_add_txs(struct mt76_dev *dev, void*data,
drivers/net/wireless/mediatek/mt76/mt76_connac.h +3
-0+ u32 max_wtbl_size); +void mt76_connac3_tx_token_put (struct mt76_dev *dev); +#endif /* __MT76_CONNAC_H */ diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.cnew file mode 100644
index 000000000000..4b745bb74ca0drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0@@ -0,0 +1,742 @@ +// SPDX-License-Identifier: ISC +/* Copyright (C) 2023 MediaTek Inc. */ + +#include "mt76_connac.h" +#include "mt76_connac3_mac.h" +#include "dma.h" + +#define HE_BITS (f) cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
+#defineHE_PREP(f, m, v)le16_encode_bits(le32_get_bits(
v,
MT_CRXV_HE_##m),\drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+IEEE80211_RADI
OTAP_HE_
##f)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ +void mt76_connac3_tx_check_aggr(struct ieee80211_sta *sta,
__le32
*txwi)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+{ + struct mt76_wcid *wcid; + u16 fc, tid; + u32 val; + + if (!sta || + !(sta->deflink.ht_cap.ht_supported || sta-Quoted 1 line
deflink.he_cap.has_he))
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + + tid =le32_get_bits (txwi[1 ],MT_TXD1_TID ); +if (tid >=6 )/* skip VO queue */ +return ; + + val =le32_to_cpu (txwi[2 ]); + fc =FIELD_GET (MT_TXD2_FRAME_TYPE , val) <<2 | +FIELD_GET (MT_TXD2_SUB_TYPE , val) <<4 ; + if (unlikely(fc != (IEEE80211_FTYPE_DATA |
IEEE80211_STYPE_QOS_DATA)))drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+return ; + + wcid = (struct mt76_wcid *)sta->drv_priv; +if (!test_and_set_bit (tid, &wcid->ampdu_state)) +ieee80211_start_tx_ba_session (sta, tid,0 ); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_check_aggr); + +static void +mt76_connac3_mac_decode_he_radiotap_ru(struct mt76_rx_status*status,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ struct
ieee80211_radiotap_he
*he,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ __le32 *rxv) +{ + u32 ru = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC),offs = 0;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ + status->bw =RATE_INFO_BW_HE_RU ; + +switch (ru) { + case 0 ... 36: + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_26;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ offs = ru; +break ; + case 37 ... 52: + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_52;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ offs = ru -37 ; +break ; + case 53 ... 60: + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_106;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ offs = ru -53 ; +break ; + case 61 ... 64: + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_242;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ offs = ru -61 ; +break ; + case 65 ... 66: + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_484;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ offs = ru -65 ; +break ; +case 67 : + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_996;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+break ; +case 68 : + status->he_ru =
NL80211_RATE_INFO_HE_RU_ALLOC_2x996;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+break ; + } + + he->data1 |=HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + he->data2 |=HE_BITS (DATA2_RU_OFFSET_KNOWN ) | +le16_encode_bits (offs, + IEEE80211_RADIOTAP_HE_DAT
A2_RU_OF
FSET);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+} + +#define MU_PREP (f, v) le16_encode_bits(v,IEEE80211_RADIOTAP_HE_MU_##f)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+static void +mt76_connac3_mac_decode_he_mu_radiotap(struct sk_buff *skb,
__le32
*rxv)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ + struct mt76_rx_status *status = (struct mt76_rx_status*)skb-
Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ static const struct ieee80211_radiotap_he_mu mu_known ={
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) | +HE_BITS (MU_FLAGS1_SIG_B_DCM_KNOWN ) | +HE_BITS (MU_FLAGS1_CH1_RU_KNOWN ) | + HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN),
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ .flags2 =
HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN),drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+ }; +struct ieee80211_radiotap_he_mu *he_mu; + + status->flag |=RX_FLAG_RADIOTAP_HE_MU ; + + he_mu =skb_push (skb,sizeof (mu_known)); +memcpy (he_mu, &mu_known,sizeof (mu_known)); + + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status-Quoted 1 line
rate_idx);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+if (status->he_dcm) + he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM,status-
Quoted 1 line
he_dcm);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW,
status->bw) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ MU_PREP(FLAGS2_SIG_B_SYMS_USERS, + le32_get_bits(rxv[4],
MT_CRXV_HE_NUM_USER));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + he_mu->ru_ch1[0] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU0) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ +if (status->bw >=RATE_INFO_BW_40 ) { + he_mu->flags1 |=
HE_BITS(MU_FLAGS1_CH2_RU_KNOWN);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ he_mu->ru_ch2[0] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU1) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ } + +if (status->bw >=RATE_INFO_BW_80 ) { +u32 ru_h, ru_l; + + he_mu->ru_ch1[1] = le32_get_bits(rxv[16],
MT_CRXV_HE_RU2) &0xff;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + ru_l = le32_get_bits(rxv[16],
MT_CRXV_HE_RU3_L);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ ru_h =le32_get_bits (rxv[17 ],MT_CRXV_HE_RU3_H )&
0x7;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+ he_mu->ru_ch2[1 ] = (u8)(ru_l | ru_h <<4 ); + } +} + +void mt76_connac3_mac_decode_he_radiotap(struct sk_buff*skb,
__le32
*rxv,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ u8 mode) +{ + struct mt76_rx_status *status = (struct mt76_rx_status*)skb-
Quoted 1 line
cb;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +15
-0+static const struct ieee80211_radiotap_he known = { + .data1 =HE_BITS (DATA1_DATA_MCS_KNOWN ) | +HE_BITS (DATA1_DATA_DCM_KNOWN ) | +HE_BITS (DATA1_STBC_KNOWN ) | +HE_BITS (DATA1_CODING_KNOWN ) | +HE_BITS (DATA1_LDPC_XSYMSEG_KNOWN ) | +HE_BITS (DATA1_DOPPLER_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE_KNOWN ) | +HE_BITS (DATA1_BSS_COLOR_KNOWN ), + .data2 =HE_BITS (DATA2_GI_KNOWN ) | +HE_BITS (DATA2_TXBF_KNOWN ) | +HE_BITS (DATA2_PE_DISAMBIG_KNOWN ) | +HE_BITS (DATA2_TXOP_KNOWN ), + }; + u32 ltf_size = le32_get_bits(rxv[4],
MT_CRXV_HE_LTF_SIZE) + 1;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+struct ieee80211_radiotap_he *he; + + status->flag |=RX_FLAG_RADIOTAP_HE ; + + he =skb_push (skb,sizeof (known)); +memcpy (he, &known,sizeof (known)); + + he->data3 =HE_PREP (DATA3_BSS_COLOR ,BSS_COLOR , rxv[9 ])|
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM,rxv[4]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK,rxv[13]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG,rxv[5]) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+le16_encode_bits (ltf_size, + IEEE80211_RADIOTAP_HE_DATA5_LTF_SI
ZE);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+if (le32_to_cpu (rxv[0 ]) &MT_PRXV_TXBF ) + he->data5 |=HE_BITS (DATA5_TXBF ); + he->data6 =HE_PREP (DATA6_TXOP ,TXOP_DUR , rxv[9 ]) | +HE_PREP (DATA6_DOPPLER ,DOPPLER , rxv[9 ]); + +switch (mode) { +case MT_PHY_TYPE_HE_SU : + he->data1 |=HE_BITS (DATA1_FORMAT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BEAM_CHANGE_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + + he->data3 |= HE_PREP(DATA3_BEAM_CHANGE,
BEAM_CHNG,
rxv[8]) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA3_UL_DL, UPLINK,rxv[5]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+break ; +case MT_PHY_TYPE_HE_EXT_SU : + he->data1 |=HE_BITS (DATA1_FORMAT_EXT_SU ) | +HE_BITS (DATA1_UL_DL_KNOWN ) | +HE_BITS (DATA1_BW_RU_ALLOC_KNOWN ); + + he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK,rxv[5]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+break ; +case MT_PHY_TYPE_HE_MU : + he->data1 |=HE_BITS (DATA1_FORMAT_MU ) | +HE_BITS (DATA1_UL_DL_KNOWN ); + + he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK,rxv[5]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID,rxv[8]);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + mt76_connac3_mac_decode_he_radiotap_ru(status,he,
rxv);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ mt76_connac3_mac_decode_he_mu_radiotap(skb,rxv);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+break ; +case MT_PHY_TYPE_HE_TB : + he->data1 |=HE_BITS (DATA1_FORMAT_TRIG ) | +HE_BITS (DATA1_SPTL_REUSE2_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE3_KNOWN ) | +HE_BITS (DATA1_SPTL_REUSE4_KNOWN ); + + he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1,
SR_MASK,
rxv[13]) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE2,
SR1_MASK,
rxv[13]) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE3,
SR2_MASK,
rxv[13]) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ HE_PREP(DATA4_TB_SPTL_REUSE4,
SR3_MASK,
rxv[13]);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ + mt76_connac3_mac_decode_he_radiotap_ru(status,he,
rxv);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+break ; +default : +break ; + } +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_decode_he_radiotap); + +int mt76_connac3_mac_fill_rx_rate (struct mt76_dev *dev, + struct mt76_rx_status*status,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ struct
ieee80211_supported_band
*sband,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +32
-0+ __le32 *rxv, u8 *mode) +{ +u8 stbc, gi, bw, dcm, nss; +bool cck = false; +u32 v0, v2; +int i, idx; + + v0 =le32_to_cpu (rxv[0 ]); + v2 =le32_to_cpu (rxv[2 ]); + + idx =FIELD_GET (MT_PRXV_TX_RATE , v0); + i = idx; + nss =FIELD_GET (MT_PRXV_NSTS , v0) +1 ; + + stbc =FIELD_GET (MT_PRXV_HT_STBC , v2); + gi =FIELD_GET (MT_PRXV_HT_SHORT_GI , v2); + *mode =FIELD_GET (MT_PRXV_TX_MODE , v2); + dcm =FIELD_GET (MT_PRXV_DCM , v2); + bw =FIELD_GET (MT_PRXV_FRAME_MODE , v2); + +switch (*mode) { +case MT_PHY_TYPE_CCK : + cck = true; + fallthrough; +case MT_PHY_TYPE_OFDM : + i =mt76_get_rate (dev, sband, i, cck); +break ; +case MT_PHY_TYPE_HT_GF : +case MT_PHY_TYPE_HT : + status->encoding =RX_ENC_HT ; +if (gi) + status->enc_flags |=
RX_ENC_FLAG_SHORT_GI;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+if (i >31 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_VHT : + status->nss = nss; + status->encoding =RX_ENC_VHT ; +if (gi) + status->enc_flags |=
RX_ENC_FLAG_SHORT_GI;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +40
-0+if (i >11 ) +return -EINVAL ; +break ; +case MT_PHY_TYPE_HE_MU : +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : + status->nss = nss; + status->encoding =RX_ENC_HE ; + i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_HE_GI_3_2 ) + status->he_gi = gi; + + status->he_dcm = dcm; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : + status->nss = nss; + status->encoding =RX_ENC_EHT ; + i &=GENMASK (3 ,0 ); + +if (gi <=NL80211_RATE_INFO_EHT_GI_3_2 ) + status->eht.gi = gi; +break ; +default : +return -EINVAL ; + } + status->rate_idx = i; + +switch (bw) { +case IEEE80211_STA_RX_BW_20 : +break ; +case IEEE80211_STA_RX_BW_40 : +if (*mode &MT_PHY_TYPE_HE_EXT_SU && + (idx &MT_PRXV_TX_ER_SU_106T )) { + status->bw =RATE_INFO_BW_HE_RU ; + status->he_ru = +NL80211_RATE_INFO_HE_RU_ALLOC_1 06;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +27
-0+ }else { + status->bw =RATE_INFO_BW_40 ; + } +break ; +case IEEE80211_STA_RX_BW_80 : + status->bw =RATE_INFO_BW_80 ; +break ; +case IEEE80211_STA_RX_BW_160 : + status->bw =RATE_INFO_BW_160 ; +break ; +case IEEE80211_STA_RX_BW_320 : + status->bw =RATE_INFO_BW_320 ; +break ; +default : +return -EINVAL ; + } + + status->enc_flags |=RX_ENC_FLAG_STBC_MASK * stbc; +if (*mode <MT_PHY_TYPE_HE_SU && gi) + status->enc_flags |=RX_ENC_FLAG_SHORT_GI ; + +return 0 ; +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_fill_rx_rate); + +static void +mt76_connac3_mac_write_txwi_8023(__le32 *txwi, struct
sk_buff
*skb,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +12
-0+ struct mt76_wcid *wcid) +{ +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +u8 fc_type, fc_stype; +u16 ethertype; +bool wmm = false; +u32 val; + +if (wcid->sta) { +struct ieee80211_sta *sta; + + sta = container_of((void *)wcid, struct
ieee80211_sta,drv_priv);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ wmm = sta->wme; + } + + val = FIELD_PREP(MT_TXD1_HDR_FORMAT,
MT_HDR_FORMAT_802_3) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +19
-0+FIELD_PREP (MT_TXD1_TID , tid); + + ethertype =get_unaligned_be16 (&skb->data[12 ]); +if (ethertype >=ETH_P_802_3_MIN ) + val |=MT_TXD1_ETH_802_3 ; + + txwi[1 ] |=cpu_to_le32 (val); + + fc_type =IEEE80211_FTYPE_DATA >>2 ; + fc_stype = wmm ?IEEE80211_STYPE_QOS_DATA >>4 :0 ; + + val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + + txwi[2 ] |=cpu_to_le32 (val); +} + +static void +mt76_connac3_mac_write_txwi_80211(struct mt76_dev *dev,
__le32
*txwi,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+struct sk_buff *skb, + struct ieee80211_key_conf*key)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ + struct ieee80211_hdr *hdr = (struct ieee80211_hdr*)skb->data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt*)skb-
Quoted 1 line
data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +10
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +bool multicast =is_multicast_ether_addr (hdr->addr1); +u8 tid = skb->priority &IEEE80211_QOS_CTL_TID_MASK ; +__le16 fc = hdr->frame_control; +u8 fc_type, fc_stype; +u32 val; + +if (ieee80211_is_action (fc) && + mgmt->u.action.category ==WLAN_CATEGORY_BACK && + mgmt->u.action.u.addba_req.action_code ==
WLAN_ACTION_ADDBA_REQ)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+ tid =MT_TX_ADDBA ; + else if (ieee80211_is_mgmt(hdr->frame_control)) + tid =MT_TX_NORMAL ; + + val = FIELD_PREP(MT_TXD1_HDR_FORMAT,
MT_HDR_FORMAT_802_11) |drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ FIELD_PREP(MT_TXD1_HDR_INFO, + ieee80211_get_hdrlen_from_skb(skb) /2) |
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+FIELD_PREP (MT_TXD1_TID , tid); + +if (!ieee80211_is_data (fc) || multicast || + info->flags &IEEE80211_TX_CTL_USE_MINRATE ) + val |=MT_TXD1_FIXED_RATE ; + + if (key && multicast &&
ieee80211_is_robust_mgmt_frame(skb)&&drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+ key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { + val |=MT_TXD1_BIP ; + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_PROTECT_FRAME ); + } + + txwi[1 ] |=cpu_to_le32 (val); + + fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >>2;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >>4;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +7
-0+ + val =FIELD_PREP (MT_TXD2_FRAME_TYPE , fc_type) | +FIELD_PREP (MT_TXD2_SUB_TYPE , fc_stype); + + txwi[2 ] |=cpu_to_le32 (val); + + txwi[3] |= cpu_to_le32(FIELD_PREP(MT_TXD3_BCM,multicast));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +9
-0+if (ieee80211_is_beacon (fc)) { + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_SW_POWER_MGMT ); + txwi[3 ] |=cpu_to_le32 (MT_TXD3_REM_TX_COUNT ); + } + +if (info->flags &IEEE80211_TX_CTL_INJECTED ) { +u16 seqno =le16_to_cpu (hdr->seq_ctrl); + +if (ieee80211_is_back_req (hdr->frame_control)){
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+struct ieee80211_bar *bar; + + bar = (struct ieee80211_bar *)skb-Quoted 1 line
data;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ seqno = le16_to_cpu(bar-Quoted 1 line
start_seq_num);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+ } + + val =MT_TXD3_SN_VALID | + FIELD_PREP(MT_TXD3_SEQ,
IEEE80211_SEQ_TO_SN(seqno));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ txwi[3 ] |=cpu_to_le32 (val); + txwi[3 ] &= ~cpu_to_le32 (MT_TXD3_HW_AMSDU ); + } +} + +void mt76_connac3_mac_write_txwi(struct mt76_dev *dev,
__le32
*txwi,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+struct sk_buff *skb, struct
mt76_wcid
*wcid,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+struct ieee80211_key_conf *key, int
pid,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+enum mt76_txq_id qid, u32changed)
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+{ + u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE :
MT_SDIO_TXD_SIZE;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb); +struct ieee80211_vif *vif = info->control.vif; + u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >>2;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+u8 p_fmt, q_idx, omac_idx =0 , wmm_idx =0 ; + bool is_8023 = info->flags &
IEEE80211_TX_CTL_HW_80211_ENCAP;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +4
-0+struct mt76_vif *mvif; +u16 tx_count =15 ; +bool beacon = !!(changed & (BSS_CHANGED_BEACON | + BSS_CHANGED_BEACON_ENABLED));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ bool inband_disc = !!(changed &(
BSS_CHANGED_UNSOL_BCAST_PROBE_RESP|drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+BSS_CHANGED_FILS_DISCO VERY));
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +16
-0+ + mvif = vif ? (struct mt76_vif *)vif->drv_priv :NULL ; +if (mvif) { + omac_idx = mvif->omac_idx; + wmm_idx = mvif->wmm_idx; + band_idx = mvif->band_idx; + } + +if (inband_disc) { + p_fmt =MT_TX_TYPE_FW ; + q_idx =MT_LMAC_ALTX0 ; + }else if (beacon) { + p_fmt =MT_TX_TYPE_FW ; + q_idx =MT_LMAC_BCN0 ; + }else if (qid >=MT_TXQ_PSD ) { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ q_idx =MT_LMAC_ALTX0 ; + }else { + p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT :
MT_TX_TYPE_SF;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ q_idx = wmm_idx *MT76_CONNAC_MAX_WMM_SETS + + mt76_connac_lmac_mapping(skb_get_queue_mapping(
skb));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +40
-0+ } + + val =FIELD_PREP (MT_TXD0_TX_BYTES , skb->len + sz_txd) | +FIELD_PREP (MT_TXD0_PKT_FMT , p_fmt) | +FIELD_PREP (MT_TXD0_Q_IDX , q_idx); + txwi[0 ] =cpu_to_le32 (val); + + val =FIELD_PREP (MT_TXD1_WLAN_IDX , wcid->idx) | +FIELD_PREP (MT_TXD1_OWN_MAC , omac_idx); + +if (band_idx) + val |=FIELD_PREP (MT_TXD1_TGID , band_idx); + + txwi[1 ] =cpu_to_le32 (val); + txwi[2 ] =0 ; + + val =MT_TXD3_SW_POWER_MGMT | +FIELD_PREP (MT_TXD3_REM_TX_COUNT , tx_count); +if (key) + val |=MT_TXD3_PROTECT_FRAME ; +if (info->flags &IEEE80211_TX_CTL_NO_ACK ) + val |=MT_TXD3_NO_ACK ; +if (wcid->amsdu) + val |=MT_TXD3_HW_AMSDU ; + + txwi[3 ] =cpu_to_le32 (val); + txwi[4 ] =0 ; + + val =FIELD_PREP (MT_TXD5_PID , pid); +if (pid >=MT_PACKET_ID_FIRST ) + val |=MT_TXD5_TX_STATUS_HOST ; + txwi[5 ] =cpu_to_le32 (val); + + val =MT_TXD6_DIS_MAT |MT_TXD6_DAS | +FIELD_PREP (MT_TXD6_MSDU_CNT ,1 ); + txwi[6 ] =cpu_to_le32 (val); + txwi[7 ] =0 ; + +if (is_8023) + mt76_connac3_mac_write_txwi_8023(txwi, skb,wcid);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+else + mt76_connac3_mac_write_txwi_80211(dev, txwi,skb, key);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ +if (txwi[1 ] &cpu_to_le32 (MT_TXD1_FIXED_RATE )) { + struct ieee80211_hdr *hdr = (struct
ieee80211_hdr
*)skb->data;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ bool mcast = ieee80211_is_data(hdr-Quoted 1 line
frame_control) &&drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ is_multicast_ether_addr(hdr-Quoted 1 line
addr1);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+u8 idx =MT76_CONNAC3_BASIC_RATES_TBL ; + + if (mvif) { + if (mcast && mvif->mcast_rates_idx) + idx = mvif->mcast_rates_idx; + else if (beacon && mvif-Quoted 1 line
beacon_rates_idx)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ idx = mvif->beacon_rates_idx; + else + idx = mvif->basic_rates_idx; + } + + txwi[6] |=cpu_to_le32(FIELD_PREP(MT_TXD6_TX_RATE,
idx));drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +6
-0+ txwi[3 ] |=cpu_to_le32 (MT_TXD3_BA_DISABLE ); + } +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_write_txwi); + +void mt76_connac3_txwi_free(struct mt76_dev *dev, struct
mt76_txwi_cache*t,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +13
-0+struct ieee80211_sta *sta, + struct list_head *free_list) +{ + __le32 *txwi; +u16 wcid_idx; + +mt76_connac_txp_skb_unmap (dev, t); +if (!t->skb) + goto out; + + txwi = (__le32 *)mt76_get_txwi_ptr (dev, t); +if (sta) { + struct mt76_wcid *wcid = (struct mt76_wcid*)sta-
Quoted 1 line
drv_priv;drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ + wcid_idx = wcid->idx; + if (likely(t->skb->protocol !=
cpu_to_be16(ETH_P_PAE)))drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+mt76_connac3_tx_check_aggr (sta, txwi); + }else { + wcid_idx = le32_get_bits(txwi[1],
MT_TXD1_WLAN_IDX);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +3
-0+ } + + __mt76_tx_complete_skb(dev, wcid_idx, t->skb,
free_list);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+out: + t->skb =NULL ; +mt76_put_txwi (dev, t); +} +EXPORT_SYMBOL_GPL (mt76_connac3_txwi_free); + +static bool +mt76_connac3_mac_add_txs_skb(struct mt76_dev *dev, struct
mt76_wcid
*wcid,drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +51
-0+ int pid, __le32 *txs_data) +{ + struct mt76_sta_stats *stats = &wcid->stats; +struct ieee80211_supported_band *sband; +struct ieee80211_tx_info *info; +u32 txrate, txs, mode, stbc; +struct rate_info rate = {}; +struct sk_buff_head list; +struct mt76_phy *mphy; +struct sk_buff *skb; +bool cck = false; + +mt76_tx_status_lock (dev, &list); + skb =mt76_tx_status_skb_get (dev, wcid, pid, &list); +if (!skb) + goto out_no_skb; + + txs =le32_to_cpu (txs_data[0 ]); + + info =IEEE80211_SKB_CB (skb); +if (!(txs &MT_TXS0_ACK_ERROR_MASK )) + info->flags |=IEEE80211_TX_STAT_ACK ; + + info->status.ampdu_len =1 ; + info->status.ampdu_ack_len = !!(info->flags & +IEEE80211_TX_STAT_ACK ); + info->status.rates[0 ].idx =-1 ; + + txrate =FIELD_GET (MT_TXS0_TX_RATE , txs); + + rate.mcs =FIELD_GET (MT_TX_RATE_IDX , txrate); + rate.nss =FIELD_GET (MT_TX_RATE_NSS , txrate) +1 ; + stbc =le32_get_bits (txs_data[3 ],MT_TXS3_RATE_STBC ); + +if (stbc && rate.nss >1 ) + rate.nss >>=1 ; + +if (rate.nss -1 <ARRAY_SIZE (stats->tx_nss)) + stats->tx_nss[rate.nss -1 ]++; +if (rate.mcs <ARRAY_SIZE (stats->tx_mcs)) + stats->tx_mcs[rate.mcs]++; + + mode =FIELD_GET (MT_TX_RATE_MODE , txrate); +switch (mode) { +case MT_PHY_TYPE_CCK : + cck = true; + fallthrough; +case MT_PHY_TYPE_OFDM : + mphy =mt76_dev_phy (dev, wcid->phy_idx); + + if (mphy->chandef.chan->band ==
NL80211_BAND_5GHZ)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +2
-0+ sband = &mphy->sband_5g.sband; + else if (mphy->chandef.chan->band ==
NL80211_BAND_6GHZ)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +5
-0+ sband = &mphy->sband_6g.sband; + else + sband = &mphy->sband_2g.sband; + + rate.mcs = mt76_get_rate(mphy->dev, sband,rate.mcs,
cck);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +1
-0+ rate.legacy = sband-Quoted 1 line
bitrates[rate.mcs].bitrate;
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +8
-0+break ; +case MT_PHY_TYPE_HT : +case MT_PHY_TYPE_HT_GF : +if (rate.mcs >31 ) + goto out; + + rate.flags =RATE_INFO_FLAGS_MCS ; + if (wcid->rate.flags &
RATE_INFO_FLAGS_SHORT_GI)drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +17
-0+ rate.flags |=RATE_INFO_FLAGS_SHORT_GI ; +break ; +case MT_PHY_TYPE_VHT : +if (rate.mcs >9 ) + goto out; + + rate.flags =RATE_INFO_FLAGS_VHT_MCS ; +break ; +case MT_PHY_TYPE_HE_SU : +case MT_PHY_TYPE_HE_EXT_SU : +case MT_PHY_TYPE_HE_TB : +case MT_PHY_TYPE_HE_MU : +if (rate.mcs >11 ) + goto out; + + rate.he_gi = wcid->rate.he_gi; + rate.he_dcm = FIELD_GET(MT_TX_RATE_DCM,txrate);
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +51
-0+ rate.flags =RATE_INFO_FLAGS_HE_MCS ; +break ; +case MT_PHY_TYPE_EHT_SU : +case MT_PHY_TYPE_EHT_TRIG : +case MT_PHY_TYPE_EHT_MU : +if (rate.mcs >13 ) + goto out; + + rate.eht_gi = wcid->rate.eht_gi; + rate.flags =RATE_INFO_FLAGS_EHT_MCS ; +break ; +default : + goto out; + } + + stats->tx_mode[mode]++; + +switch (FIELD_GET (MT_TXS0_BW , txs)) { +case IEEE80211_STA_RX_BW_320 : + rate.bw =RATE_INFO_BW_320 ; + stats->tx_bw[4 ]++; +break ; +case IEEE80211_STA_RX_BW_160 : + rate.bw =RATE_INFO_BW_160 ; + stats->tx_bw[3 ]++; +break ; +case IEEE80211_STA_RX_BW_80 : + rate.bw =RATE_INFO_BW_80 ; + stats->tx_bw[2 ]++; +break ; +case IEEE80211_STA_RX_BW_40 : + rate.bw =RATE_INFO_BW_40 ; + stats->tx_bw[1 ]++; +break ; +default : + rate.bw =RATE_INFO_BW_20 ; + stats->tx_bw[0 ]++; +break ; + } + wcid->rate = rate; + +out: +mt76_tx_status_skb_done (dev, skb, &list); + +out_no_skb: +mt76_tx_status_unlock (dev, &list); + +return !!skb; +} + +void mt76_connac3_mac_add_txs(struct mt76_dev *dev, void*data,
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +32
-0+ u32 max_wtbl_size) +{ +struct mt76_wcid *wcid; +__le32 *txs_data = data; +u16 wcidx; +u8 pid; + +if (le32_get_bits (txs_data[0 ],MT_TXS0_TXS_FORMAT ) >1 ) +return ; + + wcidx =le32_get_bits (txs_data[2 ],MT_TXS2_WCID ); + pid =le32_get_bits (txs_data[3 ],MT_TXS3_PID ); + +if (pid <MT_PACKET_ID_FIRST ) +return ; + +if (wcidx >= max_wtbl_size) +return ; + +rcu_read_lock (); + + wcid =rcu_dereference (dev->wcid[wcidx]); +if (!wcid) + goto out; + +mt76_connac3_mac_add_txs_skb (dev, wcid, pid, txs_data); +if (!wcid->sta) + goto out; + +spin_lock_bh (&dev->sta_poll_lock); +if (list_empty (&wcid->poll_list)) + list_add_tail(&wcid->poll_list, &dev-Quoted 1 line
sta_poll_list);drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.c new file +21
-0+spin_unlock_bh (&dev->sta_poll_lock); + +out: +rcu_read_unlock (); +} +EXPORT_SYMBOL_GPL (mt76_connac3_mac_add_txs); + +void mt76_connac3_tx_token_put (struct mt76_dev *dev) +{ +struct mt76_txwi_cache *txwi; +int id; + +spin_lock_bh (&dev->token_lock); +idr_for_each_entry (&dev->token, txwi, id) { +mt76_connac3_txwi_free (dev, txwi,NULL ,NULL ); + dev->token_count--; + } +spin_unlock_bh (&dev->token_lock); +idr_destroy (&dev->token); +} +EXPORT_SYMBOL_GPL (mt76_connac3_tx_token_put);diff --git
a/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hb/drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.hindex6663a0b46541..bcc1d976b2b0100644drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +0
-0@@ -4,6 +4,24 @@#ifndef __MT76_CONNAC3_MAC_H#define __MT76_CONNAC3_MAC_HQuoted 8 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h line 9
Quoted 6 lines
drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +1
-0+/* NOTE: used to map mt76_rates. idx may change if firmware expands
table */drivers/net/wireless/mediatek/mt76/mt76_connac3_mac.h +2
-0+#define MT76_CONNAC3_BASIC_RATES_TBL 11 +#define MT76_CONNAC3_BEACON_RATES_TBL 25Different devices may have different defined value.
Quoted 7 lines
The other WiFi7 device I am working on relies on the values I moved
inmt76_connac3_mac.h(in common with mt7996). Moreover you can still
have per-device values inmt7996/mac.h(I have not removed it).Please double check with the mtk folk you work with. The 11 and 25 is
the value I discussed with firmware folks to avoid overlapping the tbl
mt7996 use (MU/other algo in fw), or it causes something hardly solving
issue
Quoted 8 lines
Quoted 6 lines
sure, thx for pointing this out.
@Deren: can you please double check?Regards,
LorenzoThe idx is defined by different flow in fw and may be changed in next stage development. I think it's better to keep them in per-chip header.
ack, I will fix it.
Regards,
Lorenzo
Quoted 21 lines
Regards,
DerenQuoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 5 lines
I'm thinking if it's too early to create this patch for just moving
mt7996 toconnac3_lib?The code I moved is used by the other device as well. This series is
a
preliminary series to support it.Regards,
LorenzoQuoted 3 lines
Ryder
Re: [PATCH v2 15/15] wifi: mt76: connac: add connac3 mac library
Quoted 7 lines · "[email protected]" <[email protected]> writes:
Quoted 6 lines · Deren Wu
Quoted 5 lines · On Fri, 2023-06-09 at 18:45 +0200, [email protected] wrote:
Quoted 5 lines
Quoted 3 lines · On Fri, 2023-06-09 at 18:34 +0200, [email protected] wrote:
Quoted 2 lines · Ryder Lee
Quoted 1 line · Lorenzo Bianconi
Guys, please edit your quotes. You are now sending mails with 1000 lines and that makes it unreadable in patchwork:
Signature · 3 lines
https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches