wifi: mt76: mt7996: Implement MLD address translation for EAPOL

Do the MLD to link address translation for EAPOL frames in driver.

Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20250904-mt7996-mlo-more-fixes-v1-3-89d8fed67f20@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
Shayne Chen 2025-09-04 09:56:41 +02:00 committed by Felix Fietkau
parent 9aa03d1823
commit 7ef0c7ad73

View File

@ -966,7 +966,8 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
txwi[5] = cpu_to_le32(val);
val = MT_TXD6_DAS;
if (q_idx >= MT_LMAC_ALTX0 && q_idx <= MT_LMAC_BCN0)
if ((q_idx >= MT_LMAC_ALTX0 && q_idx <= MT_LMAC_BCN0) ||
skb->protocol == cpu_to_be16(ETH_P_PAE))
val |= MT_TXD6_DIS_MAT;
if (is_mt7996(&dev->mt76))
@ -1053,6 +1054,41 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
if (id < 0)
return id;
/* Since the rules of HW MLD address translation are not fully
* compatible with 802.11 EAPOL frame, we do the translation by
* software
*/
if (tx_info->skb->protocol == cpu_to_be16(ETH_P_PAE) && sta->mlo) {
struct ieee80211_hdr *hdr = (void *)tx_info->skb->data;
struct ieee80211_bss_conf *link_conf;
struct ieee80211_link_sta *link_sta;
link_conf = rcu_dereference(vif->link_conf[wcid->link_id]);
if (!link_conf)
return -EINVAL;
link_sta = rcu_dereference(sta->link[wcid->link_id]);
if (!link_sta)
return -EINVAL;
dma_sync_single_for_cpu(mdev->dma_dev, tx_info->buf[1].addr,
tx_info->buf[1].len, DMA_TO_DEVICE);
memcpy(hdr->addr1, link_sta->addr, ETH_ALEN);
memcpy(hdr->addr2, link_conf->addr, ETH_ALEN);
if (ieee80211_has_a4(hdr->frame_control)) {
memcpy(hdr->addr3, sta->addr, ETH_ALEN);
memcpy(hdr->addr4, vif->addr, ETH_ALEN);
} else if (ieee80211_has_tods(hdr->frame_control)) {
memcpy(hdr->addr3, sta->addr, ETH_ALEN);
} else if (ieee80211_has_fromds(hdr->frame_control)) {
memcpy(hdr->addr3, vif->addr, ETH_ALEN);
}
dma_sync_single_for_device(mdev->dma_dev, tx_info->buf[1].addr,
tx_info->buf[1].len, DMA_TO_DEVICE);
}
pid = mt76_tx_status_skb_add(mdev, wcid, tx_info->skb);
memset(txwi_ptr, 0, MT_TXD_SIZE);
/* Transmit non qos data by 802.11 header and need to fill txd by host*/