blob: 746cedc3b49ae49cfe05cd0d7776601f3a2a76dd [file] [log] [blame]
developer05f3b2b2024-08-19 19:17:34 +08001From 17651c073f135c837ca0b8d0b3e9ab8c4beef67f Mon Sep 17 00:00:00 2001
2From: Shayne Chen <shayne.chen@mediatek.com>
3Date: Wed, 15 May 2024 17:47:33 +0800
4Subject: [PATCH 134/199] mtk: mt76: mt7996: do software link addr translation
5 for EAPOL
6
7Previously, we do HW link address translation for EAPOL addr1 and addr2,
8but SW link address translation for EAPOL addr3 due to incompatibility
9between HW converting rules and 802.11 EAPOL frames.
10
11This patch adds support for doing pure SW link address translation for
12EAPOL, to get rid of ambiguity and could also help on debugging EAPOL
13timeout issues.
14
15Note that dma_sync_single_for_cpu/dma_sync_single_for_device is
16necessary to sync the changes of address to DMA.
17
18Assign EAPOL's SA/DA to MLD address.
19
20Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com>
21Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
22Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
23---
24 mt7996/mac.c | 46 +++++++++++++++++++++++++++++++---------------
25 1 file changed, 31 insertions(+), 15 deletions(-)
26
27diff --git a/mt7996/mac.c b/mt7996/mac.c
28index bba16975..020203ec 100644
29--- a/mt7996/mac.c
30+++ b/mt7996/mac.c
31@@ -831,7 +831,8 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
32 txwi[5] = cpu_to_le32(val);
33
34 val = MT_TXD6_DAS;
35- if ((q_idx >= MT_LMAC_ALTX0 && q_idx <= MT_LMAC_BCN0))
36+ if ((q_idx >= MT_LMAC_ALTX0 && q_idx <= MT_LMAC_BCN0) ||
37+ unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE)))
38 val |= MT_TXD6_DIS_MAT;
39
40 if (is_mt7996(&dev->mt76))
41@@ -939,23 +940,38 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
42 mt7996_mac_write_txwi(dev, txwi_ptr, tx_info->skb, wcid, key,
43 pid, qid, 0);
44
45- /* translate addr3 of EAPOL by driver */
46+ /* Since the rules of HW MLD address translation are not fully compatible
47+ * with 802.11 EAPOL frame, we do the translation by software
48+ */
49 if (unlikely(tx_info->skb->protocol == cpu_to_be16(ETH_P_PAE)) && sta->mlo) {
50- if (ether_addr_equal(vif->addr, hdr->addr3)) {
51- struct ieee80211_bss_conf *conf;
52-
53- conf = rcu_dereference(vif->link_conf[wcid->link_id]);
54- if (unlikely(!conf))
55- return -ENOLINK;
56-
57- memcpy(hdr->addr3, conf->addr, ETH_ALEN);
58- } else if (ether_addr_equal(sta->addr, hdr->addr3)) {
59- struct ieee80211_link_sta *link_sta;
60-
61- link_sta = rcu_dereference(sta->link[wcid->link_id]);
62- memcpy(hdr->addr3, link_sta->addr, ETH_ALEN);
63+ struct ieee80211_bss_conf *conf;
64+ struct ieee80211_link_sta *link_sta;
65+ __le16 fc = hdr->frame_control;
66+
67+ conf = rcu_dereference(vif->link_conf[wcid->link_id]);
68+ link_sta = rcu_dereference(sta->link[wcid->link_id]);
69+ if (!conf || !link_sta)
70+ return -ENOLINK;
71+
72+ dma_sync_single_for_cpu(mdev->dma_dev, tx_info->buf[1].addr,
73+ tx_info->buf[1].len, DMA_TO_DEVICE);
74+
75+ memcpy(hdr->addr1, link_sta->addr, ETH_ALEN);
76+ memcpy(hdr->addr2, conf->addr, ETH_ALEN);
77+
78+ /* EAPOL's SA/DA need to be MLD address in MLO */
79+ if (ieee80211_has_a4(fc)) {
80+ memcpy(hdr->addr3, sta->addr, ETH_ALEN);
81+ memcpy(hdr->addr4, vif->addr, ETH_ALEN);
82+ } else if (ieee80211_has_tods(fc)) {
83+ memcpy(hdr->addr3, sta->addr, ETH_ALEN);
84+ } else if (ieee80211_has_fromds(fc)) {
85+ memcpy(hdr->addr3, vif->addr, ETH_ALEN);
86 }
87
88+ dma_sync_single_for_device(mdev->dma_dev, tx_info->buf[1].addr,
89+ tx_info->buf[1].len, DMA_TO_DEVICE);
90+
91 pr_info("EAPOL: a1=%pM, a2=%pM, a3=%pM\n", hdr->addr1, hdr->addr2, hdr->addr3);
92 }
93
94--
952.18.0
96