Avoids expensive 64-bit atomic access in the data path

Signed-off-by: Felix Fietkau <[email protected]>
---
 drivers/net/wireless/mediatek/mt76/mt76.h         | 2 ++
 drivers/net/wireless/mediatek/mt76/mt7603/mac.c   | 6 +++++-
 drivers/net/wireless/mediatek/mt76/mt7603/main.c  | 1 +
 drivers/net/wireless/mediatek/mt76/mt76x02_mac.c  | 7 ++++++-
 drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 7 +++++--
 drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 1 +
 6 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h 
b/drivers/net/wireless/mediatek/mt76/mt76.h
index 40b3ce01e74d..6bee65edb26a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -220,6 +220,8 @@ struct mt76_wcid {
        u8 rx_key_pn[IEEE80211_NUM_TIDS][6];
 
        u32 tx_info;
+
+       u64 tx_pn;
        bool sw_iv;
 
        u8 packet_id;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c 
b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index d6e260ca1423..fb1961ac9dc6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -924,7 +924,11 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
        txwi[3] = cpu_to_le32(val);
 
        if (key) {
-               u64 pn = atomic64_inc_return(&key->tx_pn);
+               u64 pn;
+
+               spin_lock(&dev->mt76.lock);
+               pn = ++wcid->tx_pn;
+               spin_unlock(&dev->mt76.lock);
 
                txwi[3] |= cpu_to_le32(MT_TXD3_PN_VALID);
                txwi[4] = cpu_to_le32(pn & GENMASK(31, 0));
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c 
b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index 7849528db134..3754723190d5 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -472,6 +472,7 @@ mt7603_set_key(struct ieee80211_hw *hw, enum set_key_cmd 
cmd,
        if (cmd == SET_KEY) {
                key->hw_key_idx = wcid->idx;
                wcid->hw_key_idx = idx;
+               wcid->tx_pn = atomic64_read(&key->tx_pn);
        } else {
                if (idx == wcid->hw_key_idx)
                        wcid->hw_key_idx = -1;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index 29dbe18abbc9..8e5f920deef1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -352,7 +352,12 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, 
struct mt76x02_txwi *txwi,
                txwi->wcid = 0xff;
 
        if (wcid && wcid->sw_iv && key) {
-               u64 pn = atomic64_inc_return(&key->tx_pn);
+               u64 pn;
+
+               spin_lock(&dev->mt76.lock);
+               pn = ++wcid->tx_pn;
+               spin_unlock(&dev->mt76.lock);
+
                ccmp_pn[0] = pn;
                ccmp_pn[1] = pn >> 8;
                ccmp_pn[2] = 0;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index ec94d612f53c..736a77936249 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -420,10 +420,13 @@ static void mt76x02_key_sync(struct ieee80211_hw *hw, 
struct ieee80211_vif *vif,
 
        wcid = (struct mt76_wcid *) sta->drv_priv;
 
-       if (wcid->hw_key_idx != key->keyidx || wcid->sw_iv)
+       if (wcid->hw_key_idx != key->keyidx)
            return;
 
-       mt76x02_mac_wcid_sync_pn(dev, wcid->idx, key);
+       if (wcid->sw_iv)
+               atomic64_set(&key->tx_pn, wcid->tx_pn);
+       else
+               mt76x02_mac_wcid_sync_pn(dev, wcid->idx, key);
 }
 
 static void mt76x02_reset_state(struct mt76x02_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c 
b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index a6bb71a6ed0d..079ac265ef26 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -433,6 +433,7 @@ int mt76x02_set_key(struct ieee80211_hw *hw, enum 
set_key_cmd cmd,
                if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) {
                        key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
                        wcid->sw_iv = true;
+                       wcid->tx_pn = atomic64_read(&key->tx_pn);
                }
        } else {
                if (idx == wcid->hw_key_idx) {
-- 
2.17.0

Reply via email to