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