From: Sean Wang <sean.wang@kernel.org>
To: nbd@nbd.name
Cc: linux-wireless@vger.kernel.org,
linux-mediatek@lists.infradead.org, yu-ching.liu@mediatek.com,
jenhao.yang@mediatek.com, posh.sun@mediatek.com,
Chengwei Yu <chengwei.yu@mediatek.com>,
Sean Wang <sean.wang@mediatek.com>
Subject: [PATCH 06/23] wifi: mt76: mt7925: implement NAN key management MCU command
Date: Sun, 27 Sep 2026 16:02:48 -0500 [thread overview]
Message-ID: <20260927210306.737669-7-sean.wang@kernel.org> (raw)
In-Reply-To: <20260927210306.737669-1-sean.wang@kernel.org>
From: Chengwei Yu <chengwei.yu@mediatek.com>
Add mt7925_nan_manage_key_cmd() and mt7925_nan_key_mgmt_tlv() to
install and remove NAN group and pairwise keys via
NAN_UNI_CMD_KEY_MANAGEMENT. The TLV builder covers all firmware key
types: NM-TK, ND-TK (unicast), TX/RX GTK (multicast data) and
TX/RX IGTK/BIGTK (multicast management).
Follows the same skb + mt76_connac_mcu_add_tlv() pattern as other NAN
commands (mt7925_nan_enable(), mt7925_nan_change_configure()) rather
than hand-assembling a packed struct, so it composes naturally with
the existing NAN command helpers.
Key material is grouped into struct mt7925_nan_key_info so callers
pass one pointer instead of five arguments; init/key_exist firmware
flags are hardcoded 1/0 since every real caller uses the same values.
Co-developed-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Chengwei Yu <chengwei.yu@mediatek.com>
---
.../net/wireless/mediatek/mt76/mt7925/nan.c | 122 ++++++++++++++++++
.../net/wireless/mediatek/mt76/mt7925/nan.h | 72 +++++++++++
2 files changed, 194 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/nan.c b/drivers/net/wireless/mediatek/mt76/mt7925/nan.c
index 73e45be8b40e..0579501207eb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/nan.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/nan.c
@@ -897,6 +897,128 @@ void mt7925_nan_stop_mac_randomization(struct ieee80211_vif *vif)
cancel_delayed_work_sync(&mvif->nan.mac_rand_work);
}
+static int
+mt7925_nan_key_mgmt_tlv(struct sk_buff *skb,
+ enum mt7925_nan_key_operation key_op,
+ enum mt7925_nan_key_type key_type,
+ u16 wtbl_entry,
+ const u8 *local_addr,
+ const u8 *peer_addr,
+ const struct mt7925_nan_key_info *key)
+{
+ struct mt7925_nan_key_mgmt_tlv *key_mgmt_tlv = NULL;
+ struct tlv *tlv = NULL;
+
+ if (!skb)
+ return -EINVAL;
+
+ tlv = mt76_connac_mcu_add_tlv(skb, NAN_UNI_CMD_KEY_MANAGEMENT,
+ sizeof(struct mt7925_nan_key_mgmt_tlv));
+ if (!tlv)
+ return -ENOMEM;
+
+ key_mgmt_tlv = (struct mt7925_nan_key_mgmt_tlv *)tlv;
+ key_mgmt_tlv->op = (u8)key_op;
+ key_mgmt_tlv->key_type = (u8)key_type;
+ key_mgmt_tlv->wtbl_idx = cpu_to_le16(wtbl_entry);
+ key_mgmt_tlv->init = 1;
+ key_mgmt_tlv->key_exist = 0;
+ key_mgmt_tlv->is_nmi_tk = 0;
+
+ memcpy(key_mgmt_tlv->local_addr, local_addr, ETH_ALEN);
+ memcpy(key_mgmt_tlv->peer_addr, peer_addr, ETH_ALEN);
+
+ switch (key_type) {
+ case NAN_KEY_TYPE_NMI_CXT_MGMT_KEY:
+ key_mgmt_tlv->nmi_key_idx = 0;
+ key_mgmt_tlv->is_nmi_tk = true;
+ break;
+ case NAN_KEY_TYPE_MC_TX_KEY:
+ case NAN_KEY_TYPE_MC_MGMT_TX_KEY:
+ /* TX GTK/IGTK/BIGTK: NDI-indexed slot; NDC ID not yet tracked */
+ key_mgmt_tlv->ndi_idx = 0;
+ break;
+ case NAN_KEY_TYPE_MC_RX_KEY:
+ case NAN_KEY_TYPE_MC_MGMT_RX_KEY:
+ key_mgmt_tlv->mc_rx_idx = (u8)wtbl_entry;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (key_op == NAN_KEY_OP_SET_KEY) {
+ key_mgmt_tlv->algorithm_id = key->algo_id;
+ key_mgmt_tlv->key_id = key->key_id;
+ key_mgmt_tlv->key_len = key->key_len;
+
+ if (key_type == NAN_KEY_TYPE_MC_MGMT_RX_KEY && key->pn) {
+ memcpy(key_mgmt_tlv->key_rsc, key->pn,
+ min_t(size_t, NAN_PACKET_NUMBER_LEN,
+ sizeof(key_mgmt_tlv->key_rsc)));
+ }
+
+ if (key->key_data) {
+ memcpy(key_mgmt_tlv->key_material, key->key_data,
+ min_t(size_t, key->key_len,
+ sizeof(key_mgmt_tlv->key_material)));
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * mt7925_nan_manage_key_cmd - Install/remove a NAN group or pairwise key
+ * @dev: mt792x device pointer
+ * @key_op: NAN_KEY_OP_SET_KEY or NAN_KEY_OP_CLS_KEY
+ * @key_type: which NAN key slot this targets (enum mt7925_nan_key_type)
+ * @wtbl_entry: WTBL index the key is bound to (WTBL_RESERVED_ENTRY invalid)
+ * @local_addr: local MAC address for this key context
+ * @peer_addr: peer MAC address for this key context
+ * @key: key material; key->key_data required for NAN_KEY_OP_SET_KEY
+ *
+ * There are no other callers yet; NAN group key installation added by a
+ * later change calls into this single command path.
+ */
+int
+mt7925_nan_manage_key_cmd(struct mt792x_dev *dev,
+ enum mt7925_nan_key_operation key_op,
+ enum mt7925_nan_key_type key_type,
+ u16 wtbl_entry,
+ const u8 *local_addr,
+ const u8 *peer_addr,
+ const struct mt7925_nan_key_info *key)
+{
+ struct mt76_dev *mdev = &dev->mt76;
+ struct mt7925_nan_common_hdr *hdr = NULL;
+ struct sk_buff *skb = NULL;
+ int ret;
+
+ if (!key || !local_addr || !peer_addr ||
+ key_type >= NAN_KEY_TYPE_NUM ||
+ wtbl_entry == WTBL_RESERVED_ENTRY ||
+ (key_op == NAN_KEY_OP_SET_KEY && !key->key_data))
+ return -EINVAL;
+
+ skb = mt76_mcu_msg_alloc(mdev, NULL,
+ sizeof(struct mt7925_nan_common_hdr) +
+ sizeof(struct mt7925_nan_key_mgmt_tlv));
+ if (!skb)
+ return -ENOMEM;
+
+ hdr = (struct mt7925_nan_common_hdr *)skb_put(skb, sizeof(*hdr));
+ memset(hdr, 0, sizeof(*hdr));
+
+ ret = mt7925_nan_key_mgmt_tlv(skb, key_op, key_type, wtbl_entry,
+ local_addr, peer_addr, key);
+ if (ret) {
+ dev_kfree_skb(skb);
+ return ret;
+ }
+
+ return mt76_mcu_skb_send_msg(mdev, skb, MCU_UNI_CMD(NAN), true);
+}
+
static int mt7925_nan_avail_ctrl_tlv(struct sk_buff *skb,
struct ieee80211_vif *vif)
{
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/nan.h b/drivers/net/wireless/mediatek/mt76/mt7925/nan.h
index 3a14ec384e4f..f15a16b773bb 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/nan.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/nan.h
@@ -109,6 +109,24 @@ enum nan_disc_event_type {
NAN_EVENT_ID_JOINED_CLUSTER = 2,
};
+enum mt7925_nan_key_operation {
+ NAN_KEY_OP_SET_KEY,
+ NAN_KEY_OP_CLS_KEY,
+};
+
+enum mt7925_nan_key_type {
+ NAN_KEY_TYPE_NMI_CXT_MGMT_KEY, /* NM-TK: NAN Management pairwise key */
+ NAN_KEY_TYPE_ND_TK, /* ND-TK: NAN Data pairwise key */
+ NAN_KEY_TYPE_MC_TX_KEY, /* TX GTK (multicast data) */
+ NAN_KEY_TYPE_MC_RX_KEY, /* RX GTK (multicast data) */
+ NAN_KEY_TYPE_MC_MGMT_TX_KEY, /* TX IGTK/BIGTK (multicast mgmt) */
+ NAN_KEY_TYPE_MC_MGMT_RX_KEY, /* RX IGTK/BIGTK (multicast mgmt) */
+ NAN_KEY_TYPE_NUM,
+};
+
+#define WTBL_RESERVED_ENTRY 0xFFFF
+#define NAN_PACKET_NUMBER_LEN 6
+
/* bit indices into mt792x_dev->nan_deferred_pending, set from the atomic
* MCU-event RX path and consumed by mt7925_nan_deferred_work()
*/
@@ -478,6 +496,35 @@ struct mt7925_nan_update_phy_setting_tlv {
struct mt7925_nan_phy_setting phy_5g;
} __packed __aligned(4);
+struct mt7925_nan_key_mgmt_tlv {
+ __le16 tag;
+ __le16 len;
+
+ u8 op; /* enum mt7925_nan_key_operation */
+ u8 key_type; /* enum mt7925_nan_key_type */
+ __le16 wtbl_idx;
+ u8 init;
+ u8 key_exist;
+ u8 is_nmi_tk;
+ u8 reserved0;
+
+ u8 local_addr[ETH_ALEN];
+ u8 peer_addr[ETH_ALEN];
+
+ union {
+ u8 nmi_key_idx;
+ u8 ndi_idx;
+ u8 mc_rx_idx;
+ };
+ u8 algorithm_id;
+ u8 key_id;
+ u8 key_len;
+
+ u8 key_rsc[NAN_PACKET_NUMBER_LEN];
+ u8 reserved1[2];
+ u8 key_material[32];
+} __packed __aligned(4);
+
/* NAN Low Power Control Command */
struct mt7925_nan_lowpower_ctrl_tlv {
__le16 tag;
@@ -528,6 +575,31 @@ void mt7925_nan_stop_mac_randomization(struct ieee80211_vif *vif);
int mt7925_nan_send_lowpower_ctrl_cmd(struct mt792x_dev *dev, bool enable);
+/**
+ * struct mt7925_nan_key_info - key material for mt7925_nan_manage_key_cmd
+ * @algo_id: firmware cipher algorithm ID (from mt7925_mcu_get_cipher())
+ * @key_id: key index (1-2 for GTK, 4-7 for IGTK/BIGTK)
+ * @key_len: key material length in bytes (16 or 32)
+ * @key_data: key bytes; must be non-NULL for SET_KEY operations
+ * @pn: 6-byte packet number / RSC; only used for MC_MGMT_RX_KEY,
+ * pass NULL for all other key types
+ */
+struct mt7925_nan_key_info {
+ u8 algo_id;
+ u8 key_id;
+ u8 key_len;
+ const u8 *key_data;
+ const u8 *pn;
+};
+
+int mt7925_nan_manage_key_cmd(struct mt792x_dev *dev,
+ enum mt7925_nan_key_operation key_op,
+ enum mt7925_nan_key_type key_type,
+ u16 wtbl_entry,
+ const u8 *local_addr,
+ const u8 *peer_addr,
+ const struct mt7925_nan_key_info *key);
+
void mt7925_nan_local_sched_changed(struct mt792x_dev *dev,
struct ieee80211_vif *vif);
--
2.43.0
next prev parent reply other threads:[~2026-09-27 21:09 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-27 21:02 [PATCH 00/23] wifi: mt76: mt7925: add NAN security and improve NDP reliability (part 2) Sean Wang
2026-09-27 21:02 ` [PATCH 01/23] wifi: mt76: mt7925: make NMI address TLV tail padding explicit Sean Wang
2026-09-27 21:02 ` [PATCH 02/23] wifi: mt76: mt7925: add NMI/NDI MAC address setter helpers Sean Wang
2026-10-06 9:25 ` Felix Fietkau
2026-09-27 21:02 ` [PATCH 03/23] wifi: mt76: mt7925: implement NAN MAC address randomization Sean Wang
2026-10-06 9:18 ` Felix Fietkau
2026-09-27 21:02 ` [PATCH 04/23] wifi: mt76: mt7925: wire up NAN MAC randomization lifecycle Sean Wang
2026-09-27 21:02 ` [PATCH 05/23] wifi: mt76: mt7925: add NAN low power event control on suspend/resume Sean Wang
2026-09-27 21:02 ` Sean Wang [this message]
2026-09-27 21:02 ` [PATCH 07/23] wifi: mt76: mt7925: add per-peer RX IGTK/BIGTK and RX GTK WTBLs Sean Wang
2026-09-27 21:02 ` [PATCH 08/23] wifi: mt76: mt7925: add NDC-aware TX GTK table for NAN_DATA Sean Wang
2026-10-06 9:20 ` Felix Fietkau
2026-09-27 21:02 ` [PATCH 09/23] wifi: mt76: mt7925: implement mt7925_nan_set_key for NAN security Sean Wang
2026-09-27 21:02 ` [PATCH 10/23] wifi: mt76: mt7925: install NAN BIP keys standalone in sta_key_tlv Sean Wang
2026-09-27 21:02 ` [PATCH 11/23] wifi: mt76: mt7925: do not disable RX NAPI twice on unload Sean Wang
2026-09-27 21:02 ` [PATCH 12/23] wifi: mt76: mt7925: assign the interface WTBL to the NAN management TXQ Sean Wang
2026-09-27 21:02 ` [PATCH 13/23] wifi: mt76: mt7925: do not deactivate shared NAN BSS on peer STA removal Sean Wang
2026-09-27 21:02 ` [PATCH 14/23] wifi: mt76: gate NAN unicast mgmt by peer availability via STA queues Sean Wang
2026-09-27 21:02 ` [PATCH 15/23] wifi: mt76: mt7925: hold NAN mgmt TX to the discovery window Sean Wang
2026-09-27 21:02 ` [PATCH 16/23] wifi: mt76: mt7925: double the retry budget for NAN unicast management Sean Wang
2026-09-27 21:02 ` [PATCH 17/23] wifi: mt76: mt7925: let TX status of DW-held NAN frames outlive the DW period Sean Wang
2026-09-27 21:03 ` [PATCH 18/23] wifi: mt76: mt7925: defer the NAN joined-cluster event out of NAN_START Sean Wang
2026-09-27 21:03 ` [PATCH 19/23] wifi: mt76: mt7925: steer NAN handshake frames by committed-bitmap state Sean Wang
2026-09-27 21:03 ` [PATCH 20/23] wifi: mt76: mt7925: disable only the RX NAPI instances that exist Sean Wang
2026-09-27 21:03 ` [PATCH 21/23] wifi: mt76: mt7925: stop queueing resets once the device is being removed Sean Wang
2026-09-27 21:03 ` [PATCH 22/23] wifi: mt76: mt7925: bound the lifetime of NAN unicast management frames Sean Wang
2026-09-27 21:03 ` [PATCH 23/23] wifi: mt76: mt7925: always deliver the joined-cluster event through the deferred work Sean Wang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260927210306.737669-7-sean.wang@kernel.org \
--to=sean.wang@kernel.org \
--cc=chengwei.yu@mediatek.com \
--cc=jenhao.yang@mediatek.com \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-wireless@vger.kernel.org \
--cc=nbd@nbd.name \
--cc=posh.sun@mediatek.com \
--cc=sean.wang@mediatek.com \
--cc=yu-ching.liu@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.