From: Chengwei Yu NAN RX group keys are per-peer: each NAN peer can carry an independent IGTK/BIGTK, and each NAN_DATA peer an independent GTK. Add nan_rx_igtk_wcid and nan_rx_gtk_wcid to mt792x_sta to hold dedicated WTBL entries for these keys. WTBLs are allocated lazily: mt7925_nan_sta_wcids_init() marks both fields MT792x_WCID_IDX_UNSET at peer-add time, and mt7925_nan_peer_wcids_free() releases whichever slots were actually allocated at peer-remove time. Peers that never install a NAN group key carry zero overhead. Co-developed-by: Sean Wang Signed-off-by: Sean Wang Signed-off-by: Chengwei Yu --- .../net/wireless/mediatek/mt76/mt7925/main.c | 47 +++++++++++++++++++ drivers/net/wireless/mediatek/mt76/mt792x.h | 11 +++++ 2 files changed, 58 insertions(+) diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c index 3e1c223e8da6..2d3bf7d806a7 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c @@ -923,6 +923,8 @@ mt7925_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return mvif->basic_rates_idx; } +static void mt7925_nan_sta_wcids_init(struct mt792x_sta *msta); + static int mt7925_mac_link_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_link_sta *link_sta, @@ -1060,6 +1062,9 @@ static int mt7925_mac_link_sta_add(struct mt76_dev *mdev, goto out_pm; } + if (vif->type == NL80211_IFTYPE_NAN || vif->type == NL80211_IFTYPE_NAN_DATA) + mt7925_nan_sta_wcids_init(msta); + mt76_connac_power_save_sched(&dev->mphy, &dev->pm); return 0; @@ -1306,6 +1311,45 @@ int mt7925_mac_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif, } EXPORT_SYMBOL_GPL(mt7925_mac_sta_event); +/* Mark per-peer NAN group key WTBLs as unallocated at station add time. + * Pairs with mt7925_nan_peer_wcids_free() at station remove time. + */ +static void mt7925_nan_sta_wcids_init(struct mt792x_sta *msta) +{ + msta->nan_rx_gtk_wcid.idx = MT792x_WCID_IDX_UNSET; + msta->nan_rx_igtk_wcid.idx = MT792x_WCID_IDX_UNSET; +} + +/* Free a lazily-allocated per-peer NAN group key WTBL and reset its sentinel. */ +static void mt7925_nan_wcid_free(struct mt76_dev *mdev, struct mt76_wcid *wcid) +{ + u16 idx = wcid->idx; + + rcu_assign_pointer(mdev->wcid[idx], NULL); + mt76_wcid_cleanup(mdev, wcid); + mt76_wcid_mask_clear(mdev->wcid_mask, idx); + wcid->idx = MT792x_WCID_IDX_UNSET; +} + +/* Release any lazily-allocated per-peer NAN group key WTBLs for a departing + * station. Called from mt7925_mac_link_sta_remove() after the primary WTBL + * is already freed, so the NAN-specific cleanup is clearly separated from the + * generic STA teardown path. + */ +static void mt7925_nan_peer_wcids_free(struct mt76_dev *mdev, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta) +{ + struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv; + + if (vif->type == NL80211_IFTYPE_NAN_DATA && + msta->nan_rx_gtk_wcid.idx != MT792x_WCID_IDX_UNSET) + mt7925_nan_wcid_free(mdev, &msta->nan_rx_gtk_wcid); + + if (msta->nan_rx_igtk_wcid.idx != MT792x_WCID_IDX_UNSET) + mt7925_nan_wcid_free(mdev, &msta->nan_rx_igtk_wcid); +} + static void mt7925_mac_link_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, struct ieee80211_link_sta *link_sta, @@ -1350,6 +1394,9 @@ static void mt7925_mac_link_sta_remove(struct mt76_dev *mdev, mt76_wcid_cleanup(mdev, wcid); mt76_wcid_mask_clear(mdev->wcid_mask, idx); + if (vif->type == NL80211_IFTYPE_NAN || vif->type == NL80211_IFTYPE_NAN_DATA) + mt7925_nan_peer_wcids_free(mdev, vif, link_sta->sta); + mt76_connac_power_save_sched(&dev->mphy, &dev->pm); } diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h index fa28a77d12bb..707ca24193f9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x.h +++ b/drivers/net/wireless/mediatek/mt76/mt792x.h @@ -18,6 +18,11 @@ #define MT792x_WTBL_SIZE 20 #define MT792x_WTBL_RESERVED (MT792x_WTBL_SIZE - 1) #define MT792x_WTBL_STA (MT792x_WTBL_RESERVED - MT792x_MAX_INTERFACES) +/* Sentinel for a lazily-allocated wcid that has not yet been assigned a slot. + * U16_MAX is outside every valid alloc range and matches the 0xffff value + * used in mt76 DMA ring entries to mark an unused wcid field. + */ +#define MT792x_WCID_IDX_UNSET U16_MAX #define MT792x_CFEND_RATE_DEFAULT 0x49 /* OFDM 24M */ #define MT792x_CFEND_RATE_11B 0x03 /* 11B LP, 11M */ @@ -148,6 +153,12 @@ struct mt792x_sta { /* NAN peer schedule */ struct mt792x_sta_nan_sched nan_sched; + + /* NAN per-peer group key WTBLs (allocated lazily when keys are installed) + * Note: TX GTK is interface-level, see mt792x_vif->nan_tx_gtk_table + */ + struct mt76_wcid nan_rx_gtk_wcid; /* NAN_DATA peer: RX GTK WTBL (per-peer) */ + struct mt76_wcid nan_rx_igtk_wcid; /* NAN peer: RX IGTK/BIGTK WTBL (per-peer) */ }; DECLARE_EWMA(rssi, 10, 8); -- 2.43.0