The branch stable/15 has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=3a2aabbab109c5430e2513e6c91ac66eba457255
commit 3a2aabbab109c5430e2513e6c91ac66eba457255 Author: Bjoern A. Zeeb <[email protected]> AuthorDate: 2026-01-23 13:52:47 +0000 Commit: Bjoern A. Zeeb <[email protected]> CommitDate: 2026-02-26 22:59:04 +0000 mt76: update Mediatek's mt76 driver This version is based on git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 24d479d26b25bce5faea3ddd9fa8f3a6c3129ea7 ( tag: v6.19-rc6 ). Notable change: license got switched from ISC to BSD-3-Clause-Clear. util.h is now imported from upstream given it is no longer GPL-only. See the upstream repository 909675fd4344f73aad5f75f123bd271ada2ab9fb and a96fed2825d8dfb068bf640419c619b5f2df4218. For us the new version should also help with page pools and DMA32. Sponsored by: The FreeBSD Foundation (cherry picked from commit b1bebaaba9b9c0ddfe503c43ca8e9e3917ee2c57) --- .../include/linux/soc/airoha/airoha_offload.h | 48 ++ .../common/include/linux/soc/mediatek/mtk_wed.h | 14 +- sys/contrib/dev/mediatek/mt76/Kconfig | 51 ++ sys/contrib/dev/mediatek/mt76/Makefile | 48 ++ sys/contrib/dev/mediatek/mt76/agg-rx.c | 4 +- sys/contrib/dev/mediatek/mt76/channel.c | 15 +- sys/contrib/dev/mediatek/mt76/debugfs.c | 6 +- sys/contrib/dev/mediatek/mt76/dma.c | 302 ++++++-- sys/contrib/dev/mediatek/mt76/dma.h | 98 ++- sys/contrib/dev/mediatek/mt76/eeprom.c | 87 ++- sys/contrib/dev/mediatek/mt76/mac80211.c | 65 +- sys/contrib/dev/mediatek/mt76/mcu.c | 2 +- sys/contrib/dev/mediatek/mt76/mmio.c | 20 +- sys/contrib/dev/mediatek/mt76/mt76.h | 232 +++++- sys/contrib/dev/mediatek/mt76/mt7603/Kconfig | 12 + sys/contrib/dev/mediatek/mt76/mt7603/Makefile | 7 + sys/contrib/dev/mediatek/mt76/mt7603/beacon.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/core.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/debugfs.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/dma.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/eeprom.c | 5 +- sys/contrib/dev/mediatek/mt76/mt7603/eeprom.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/init.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/mac.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/mac.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/main.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/mcu.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/mcu.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/mt7603.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/pci.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/regs.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7603/soc.c | 4 +- sys/contrib/dev/mediatek/mt76/mt7615/Kconfig | 56 ++ sys/contrib/dev/mediatek/mt76/mt7615/Makefile | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/debugfs.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/dma.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/eeprom.c | 6 +- sys/contrib/dev/mediatek/mt76/mt7615/eeprom.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/init.c | 7 +- sys/contrib/dev/mediatek/mt76/mt7615/mac.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/mac.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/main.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/mcu.c | 6 +- sys/contrib/dev/mediatek/mt76/mt7615/mcu.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/mmio.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/mt7615.h | 2 +- .../dev/mediatek/mt76/mt7615/mt7615_trace.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/pci.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/pci_init.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/pci_mac.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/regs.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/sdio.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/soc.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/testmode.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/trace.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/usb.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7615/usb_sdio.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76_connac.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76_connac2_mac.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76_connac3_mac.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76_connac3_mac.h | 9 +- sys/contrib/dev/mediatek/mt76/mt76_connac_mac.c | 21 +- sys/contrib/dev/mediatek/mt76/mt76_connac_mcu.c | 39 +- sys/contrib/dev/mediatek/mt76/mt76_connac_mcu.h | 4 +- sys/contrib/dev/mediatek/mt76/mt76x0/pci.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x0/pci_mcu.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x0/usb_mcu.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_beacon.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_debugfs.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_dfs.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_dfs.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_dma.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_eeprom.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_eeprom.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_mac.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_mac.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_mcu.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_mcu.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_mmio.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_phy.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_phy.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_regs.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_trace.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_trace.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_txrx.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_usb.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_usb_core.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_usb_mcu.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x02_util.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/Kconfig | 29 + sys/contrib/dev/mediatek/mt76/mt76x2/Makefile | 15 + sys/contrib/dev/mediatek/mt76/mt76x2/eeprom.c | 6 +- sys/contrib/dev/mediatek/mt76/mt76x2/eeprom.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/init.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/mac.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/mac.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/mcu.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/mcu.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/mt76x2.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/mt76x2u.h | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/pci.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/pci_init.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/pci_main.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/pci_mcu.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/pci_phy.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/phy.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/usb.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/usb_init.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/usb_mac.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/usb_main.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/usb_mcu.c | 2 +- sys/contrib/dev/mediatek/mt76/mt76x2/usb_phy.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7915/Kconfig | 2 +- sys/contrib/dev/mediatek/mt76/mt7915/Makefile | 2 +- sys/contrib/dev/mediatek/mt76/mt7915/coredump.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7915/coredump.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7915/debugfs.c | 76 +- sys/contrib/dev/mediatek/mt76/mt7915/dma.c | 6 +- sys/contrib/dev/mediatek/mt76/mt7915/eeprom.c | 6 +- sys/contrib/dev/mediatek/mt76/mt7915/eeprom.h | 8 +- sys/contrib/dev/mediatek/mt76/mt7915/init.c | 13 +- sys/contrib/dev/mediatek/mt76/mt7915/mac.c | 4 +- sys/contrib/dev/mediatek/mt76/mt7915/mac.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7915/main.c | 4 +- sys/contrib/dev/mediatek/mt76/mt7915/mcu.c | 203 +++-- sys/contrib/dev/mediatek/mt76/mt7915/mcu.h | 8 +- sys/contrib/dev/mediatek/mt76/mt7915/mmio.c | 8 +- sys/contrib/dev/mediatek/mt76/mt7915/mt7915.h | 11 +- sys/contrib/dev/mediatek/mt76/mt7915/pci.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7915/regs.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7915/soc.c | 23 +- sys/contrib/dev/mediatek/mt76/mt7915/testmode.c | 4 +- sys/contrib/dev/mediatek/mt76/mt7915/testmode.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/Kconfig | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/Makefile | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/debugfs.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/init.c | 8 +- sys/contrib/dev/mediatek/mt76/mt7921/mac.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/main.c | 4 +- sys/contrib/dev/mediatek/mt76/mt7921/mcu.c | 4 +- sys/contrib/dev/mediatek/mt76/mt7921/mcu.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/mt7921.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/pci.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/pci_mac.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/pci_mcu.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/regs.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/sdio.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/sdio_mac.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/sdio_mcu.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/testmode.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7921/usb.c | 5 +- sys/contrib/dev/mediatek/mt76/mt7925/Kconfig | 2 +- sys/contrib/dev/mediatek/mt76/mt7925/Makefile | 4 +- sys/contrib/dev/mediatek/mt76/mt7925/debugfs.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7925/init.c | 156 +--- sys/contrib/dev/mediatek/mt76/mt7925/mac.c | 6 +- sys/contrib/dev/mediatek/mt76/mt7925/mac.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7925/main.c | 107 +-- sys/contrib/dev/mediatek/mt76/mt7925/mcu.c | 127 +++- sys/contrib/dev/mediatek/mt76/mt7925/mcu.h | 10 +- sys/contrib/dev/mediatek/mt76/mt7925/mt7925.h | 11 +- sys/contrib/dev/mediatek/mt76/mt7925/pci.c | 41 +- sys/contrib/dev/mediatek/mt76/mt7925/pci_mac.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7925/pci_mcu.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7925/regd.c | 265 +++++++ sys/contrib/dev/mediatek/mt76/mt7925/regd.h | 19 + sys/contrib/dev/mediatek/mt76/mt7925/regs.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7925/testmode.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7925/usb.c | 5 +- sys/contrib/dev/mediatek/mt76/mt792x.h | 5 +- sys/contrib/dev/mediatek/mt76/mt792x_acpi_sar.c | 2 +- sys/contrib/dev/mediatek/mt76/mt792x_acpi_sar.h | 2 +- sys/contrib/dev/mediatek/mt76/mt792x_core.c | 9 +- sys/contrib/dev/mediatek/mt76/mt792x_debugfs.c | 2 +- sys/contrib/dev/mediatek/mt76/mt792x_dma.c | 8 +- sys/contrib/dev/mediatek/mt76/mt792x_mac.c | 2 +- sys/contrib/dev/mediatek/mt76/mt792x_regs.h | 2 +- sys/contrib/dev/mediatek/mt76/mt792x_trace.c | 2 +- sys/contrib/dev/mediatek/mt76/mt792x_trace.h | 2 +- sys/contrib/dev/mediatek/mt76/mt792x_usb.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7996/Kconfig | 9 +- sys/contrib/dev/mediatek/mt76/mt7996/Makefile | 3 +- sys/contrib/dev/mediatek/mt76/mt7996/coredump.c | 2 +- sys/contrib/dev/mediatek/mt76/mt7996/coredump.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7996/debugfs.c | 74 +- sys/contrib/dev/mediatek/mt76/mt7996/dma.c | 343 +++++++-- sys/contrib/dev/mediatek/mt76/mt7996/eeprom.c | 5 +- sys/contrib/dev/mediatek/mt76/mt7996/eeprom.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7996/init.c | 390 +++++++--- sys/contrib/dev/mediatek/mt76/mt7996/mac.c | 836 +++++++++++++++++---- sys/contrib/dev/mediatek/mt76/mt7996/mac.h | 2 +- sys/contrib/dev/mediatek/mt76/mt7996/main.c | 614 +++++++++------ sys/contrib/dev/mediatek/mt76/mt7996/mcu.c | 378 +++++----- sys/contrib/dev/mediatek/mt76/mt7996/mcu.h | 19 +- sys/contrib/dev/mediatek/mt76/mt7996/mmio.c | 113 ++- sys/contrib/dev/mediatek/mt76/mt7996/mt7996.h | 144 +++- sys/contrib/dev/mediatek/mt76/mt7996/pci.c | 10 +- sys/contrib/dev/mediatek/mt76/mt7996/regs.h | 34 +- sys/contrib/dev/mediatek/mt76/pci.c | 2 +- sys/contrib/dev/mediatek/mt76/scan.c | 15 +- sys/contrib/dev/mediatek/mt76/sdio.c | 2 +- sys/contrib/dev/mediatek/mt76/sdio.h | 2 +- sys/contrib/dev/mediatek/mt76/sdio_txrx.c | 2 +- sys/contrib/dev/mediatek/mt76/testmode.c | 2 +- sys/contrib/dev/mediatek/mt76/testmode.h | 2 +- sys/contrib/dev/mediatek/mt76/trace.c | 2 +- sys/contrib/dev/mediatek/mt76/trace.h | 2 +- sys/contrib/dev/mediatek/mt76/tx.c | 11 +- sys/contrib/dev/mediatek/mt76/usb.c | 2 +- sys/contrib/dev/mediatek/mt76/usb_trace.c | 2 +- sys/contrib/dev/mediatek/mt76/usb_trace.h | 2 +- sys/contrib/dev/mediatek/mt76/util.c | 2 +- sys/contrib/dev/mediatek/mt76/util.h | 132 ++-- sys/contrib/dev/mediatek/mt76/wed.c | 20 +- sys/modules/mt76/Makefile.inc | 3 +- sys/modules/mt76/mt7925/Makefile | 2 +- 217 files changed, 4191 insertions(+), 1624 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/soc/airoha/airoha_offload.h b/sys/compat/linuxkpi/common/include/linux/soc/airoha/airoha_offload.h new file mode 100644 index 000000000000..ade0b06d839f --- /dev/null +++ b/sys/compat/linuxkpi/common/include/linux/soc/airoha/airoha_offload.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2026 Bjoern A. Zeeb + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#ifndef _LINUXKPI_LINUX_SOC_AIROHA_AIROHA_OFFLOAD_H +#define _LINUXKPI_LINUX_SOC_AIROHA_AIROHA_OFFLOAD_H + +#include <linux/kernel.h> /* pr_debug */ + +enum airoha_npu_wlan_get_cmd { + __dummy_airoha_npu_wlan_get_cmd, +}; +enum airoha_npu_wlan_set_cmd { + __dummy_airoha_npu_wlan_set_cmd, +}; + +struct airoha_npu { +}; +struct airoha_npu_rx_dma_desc { +}; +struct airoha_npu_tx_dma_desc { +}; + +static __inline int +airoha_npu_wlan_send_msg(void *npu, int ifindex, + enum airoha_npu_wlan_set_cmd cmd, void *val, size_t len, gfp_t gfp) +{ + pr_debug("%s: TODO\n", __func__); + return (-EOPNOTSUPP); +} + +static __inline int +airoha_npu_wlan_get_msg(void *npu, int ifindex, + enum airoha_npu_wlan_get_cmd cmd, void *val, size_t len, gfp_t gfp) +{ + pr_debug("%s: TODO\n", __func__); + return (-EOPNOTSUPP); +} + +static __inline void +airoha_npu_wlan_enable_irq(struct airoha_npu *npu, int q) +{ + pr_debug("%s: TODO\n", __func__); +} + +#endif /* _LINUXKPI_LINUX_SOC_AIROHA_AIROHA_OFFLOAD_H */ diff --git a/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h b/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h index 2b9c6ae4911e..64daa8c78c9d 100644 --- a/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h +++ b/sys/compat/linuxkpi/common/include/linux/soc/mediatek/mtk_wed.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2022-2025 Bjoern A. Zeeb + * Copyright (c) 2022-2026 Bjoern A. Zeeb * * SPDX-License-Identifier: BSD-2-Clause */ @@ -37,7 +37,13 @@ mtk_wed_device_active(struct mtk_wed_device *dev __unused) static inline bool mtk_wed_get_rx_capa(struct mtk_wed_device *dev __unused) { + pr_debug("%s: TODO\n", __func__); + return (false); +} +static inline bool +mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev __unused) +{ pr_debug("%s: TODO\n", __func__); return (false); } @@ -66,6 +72,12 @@ mtk_wed_get_rx_capa(struct mtk_wed_device *dev __unused) { return (false); } + +static inline bool +mtk_wed_is_amsdu_supported(struct mtk_wed_device *dev __unused) +{ + return (false); +} #endif /* CONFIG_NET_MEDIATEK_SOC_WED */ #endif /* _LINUXKPI_LINUX_SOC_MEDIATEK_MTK_WED_H */ diff --git a/sys/contrib/dev/mediatek/mt76/Kconfig b/sys/contrib/dev/mediatek/mt76/Kconfig new file mode 100644 index 000000000000..502303622a53 --- /dev/null +++ b/sys/contrib/dev/mediatek/mt76/Kconfig @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: BSD-3-Clause-Clear +config MT76_CORE + tristate + select PAGE_POOL + +config MT76_LEDS + bool + depends on MT76_CORE + depends on LEDS_CLASS=y || MT76_CORE=LEDS_CLASS + default y + +config MT76_USB + tristate + depends on MT76_CORE + +config MT76_SDIO + tristate + depends on MT76_CORE + +config MT76x02_LIB + tristate + select MT76_CORE + +config MT76x02_USB + tristate + select MT76_USB + +config MT76_CONNAC_LIB + tristate + select MT76_CORE + +config MT792x_LIB + tristate + select MT76_CONNAC_LIB + +config MT792x_USB + tristate + select MT76_USB + +config MT76_NPU + bool + depends on MT76_CORE + +source "drivers/net/wireless/mediatek/mt76/mt76x0/Kconfig" +source "drivers/net/wireless/mediatek/mt76/mt76x2/Kconfig" +source "drivers/net/wireless/mediatek/mt76/mt7603/Kconfig" +source "drivers/net/wireless/mediatek/mt76/mt7615/Kconfig" +source "drivers/net/wireless/mediatek/mt76/mt7915/Kconfig" +source "drivers/net/wireless/mediatek/mt76/mt7921/Kconfig" +source "drivers/net/wireless/mediatek/mt76/mt7996/Kconfig" +source "drivers/net/wireless/mediatek/mt76/mt7925/Kconfig" diff --git a/sys/contrib/dev/mediatek/mt76/Makefile b/sys/contrib/dev/mediatek/mt76/Makefile new file mode 100644 index 000000000000..1d42adfe8030 --- /dev/null +++ b/sys/contrib/dev/mediatek/mt76/Makefile @@ -0,0 +1,48 @@ +# SPDX-License-Identifier: BSD-3-Clause-Clear +obj-$(CONFIG_MT76_CORE) += mt76.o +obj-$(CONFIG_MT76_USB) += mt76-usb.o +obj-$(CONFIG_MT76_SDIO) += mt76-sdio.o +obj-$(CONFIG_MT76x02_LIB) += mt76x02-lib.o +obj-$(CONFIG_MT76x02_USB) += mt76x02-usb.o +obj-$(CONFIG_MT76_CONNAC_LIB) += mt76-connac-lib.o +obj-$(CONFIG_MT792x_LIB) += mt792x-lib.o +obj-$(CONFIG_MT792x_USB) += mt792x-usb.o + +mt76-y := \ + mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o \ + tx.o agg-rx.o mcu.o wed.o scan.o channel.o + +mt76-$(CONFIG_MT76_NPU) += npu.o +mt76-$(CONFIG_PCI) += pci.o +mt76-$(CONFIG_NL80211_TESTMODE) += testmode.o + +mt76-usb-y := usb.o usb_trace.o +mt76-sdio-y := sdio.o sdio_txrx.o + +CFLAGS_trace.o := -I$(src) +CFLAGS_usb_trace.o := -I$(src) +CFLAGS_mt76x02_trace.o := -I$(src) +CFLAGS_mt792x_trace.o := -I$(src) + +mt76x02-lib-y := mt76x02_util.o mt76x02_mac.o mt76x02_mcu.o \ + mt76x02_eeprom.o mt76x02_phy.o mt76x02_mmio.o \ + mt76x02_txrx.o mt76x02_trace.o mt76x02_debugfs.o \ + mt76x02_dfs.o mt76x02_beacon.o + +mt76x02-usb-y := mt76x02_usb_mcu.o mt76x02_usb_core.o + +mt76-connac-lib-y := mt76_connac_mcu.o mt76_connac_mac.o mt76_connac3_mac.o + +mt792x-lib-y := mt792x_core.o mt792x_mac.o mt792x_trace.o \ + mt792x_debugfs.o mt792x_dma.o +mt792x-lib-$(CONFIG_ACPI) += mt792x_acpi_sar.o +mt792x-usb-y := mt792x_usb.o + +obj-$(CONFIG_MT76x0_COMMON) += mt76x0/ +obj-$(CONFIG_MT76x2_COMMON) += mt76x2/ +obj-$(CONFIG_MT7603E) += mt7603/ +obj-$(CONFIG_MT7615_COMMON) += mt7615/ +obj-$(CONFIG_MT7915E) += mt7915/ +obj-$(CONFIG_MT7921_COMMON) += mt7921/ +obj-$(CONFIG_MT7996E) += mt7996/ +obj-$(CONFIG_MT7925_COMMON) += mt7925/ diff --git a/sys/contrib/dev/mediatek/mt76/agg-rx.c b/sys/contrib/dev/mediatek/mt76/agg-rx.c index 07c386c7b4d0..3d34caf7e4f7 100644 --- a/sys/contrib/dev/mediatek/mt76/agg-rx.c +++ b/sys/contrib/dev/mediatek/mt76/agg-rx.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: ISC +// SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (C) 2018 Felix Fietkau <[email protected]> */ @@ -173,6 +173,8 @@ void mt76_rx_aggr_reorder(struct sk_buff *skb, struct sk_buff_head *frames) if (ackp == IEEE80211_QOS_CTL_ACK_POLICY_NOACK) return; + if (wcid->def_wcid) + wcid = wcid->def_wcid; tid = rcu_dereference(wcid->aggr[tidno]); if (!tid) return; diff --git a/sys/contrib/dev/mediatek/mt76/channel.c b/sys/contrib/dev/mediatek/mt76/channel.c index 77b75792eb48..2b705bdb7993 100644 --- a/sys/contrib/dev/mediatek/mt76/channel.c +++ b/sys/contrib/dev/mediatek/mt76/channel.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: ISC +// SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (C) 2024 Felix Fietkau <[email protected]> */ @@ -314,21 +314,24 @@ void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif, kfree(mlink); } -static void mt76_roc_complete(struct mt76_phy *phy) +void mt76_roc_complete(struct mt76_phy *phy) { struct mt76_vif_link *mlink = phy->roc_link; + struct mt76_dev *dev = phy->dev; if (!phy->roc_vif) return; if (mlink) mlink->mvif->roc_phy = NULL; - if (phy->main_chandef.chan) + if (phy->main_chandef.chan && + !test_bit(MT76_MCU_RESET, &dev->phy.state)) mt76_set_channel(phy, &phy->main_chandef, false); mt76_put_vif_phy_link(phy, phy->roc_vif, phy->roc_link); phy->roc_vif = NULL; phy->roc_link = NULL; - ieee80211_remain_on_channel_expired(phy->hw); + if (!test_bit(MT76_MCU_RESET, &dev->phy.state)) + ieee80211_remain_on_channel_expired(phy->hw); } void mt76_roc_complete_work(struct work_struct *work) @@ -351,6 +354,7 @@ void mt76_abort_roc(struct mt76_phy *phy) mt76_roc_complete(phy); mutex_unlock(&dev->mutex); } +EXPORT_SYMBOL_GPL(mt76_abort_roc); int mt76_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_channel *chan, int duration, @@ -368,7 +372,8 @@ int mt76_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, mutex_lock(&dev->mutex); - if (phy->roc_vif || dev->scan.phy == phy) { + if (phy->roc_vif || dev->scan.phy == phy || + test_bit(MT76_MCU_RESET, &dev->phy.state)) { ret = -EBUSY; goto out; } diff --git a/sys/contrib/dev/mediatek/mt76/debugfs.c b/sys/contrib/dev/mediatek/mt76/debugfs.c index b6a2746c187d..a5ac6ca86735 100644 --- a/sys/contrib/dev/mediatek/mt76/debugfs.c +++ b/sys/contrib/dev/mediatek/mt76/debugfs.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: ISC +// SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (C) 2016 Felix Fietkau <[email protected]> */ @@ -93,9 +93,9 @@ void mt76_seq_puts_array(struct seq_file *file, const char *str, { int i; - seq_printf(file, "%10s:", str); + seq_printf(file, "%16s:", str); for (i = 0; i < len; i++) - seq_printf(file, " %2d", val[i]); + seq_printf(file, " %4d", val[i]); seq_puts(file, "\n"); } EXPORT_SYMBOL_GPL(mt76_seq_puts_array); diff --git a/sys/contrib/dev/mediatek/mt76/dma.c b/sys/contrib/dev/mediatek/mt76/dma.c index af902a761e42..5c04a0dce1fa 100644 --- a/sys/contrib/dev/mediatek/mt76/dma.c +++ b/sys/contrib/dev/mediatek/mt76/dma.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: ISC +// SPDX-License-Identifier: BSD-3-Clause-Clear /* * Copyright (C) 2016 Felix Fietkau <[email protected]> */ @@ -11,37 +11,6 @@ #include "mt76.h" #include "dma.h" -#if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_WED) - -#define Q_READ(_q, _field) ({ \ - u32 _offset = offsetof(struct mt76_queue_regs, _field); \ - u32 _val; \ - if ((_q)->flags & MT_QFLAG_WED) \ - _val = mtk_wed_device_reg_read((_q)->wed, \ - ((_q)->wed_regs + \ - _offset)); \ - else \ - _val = readl(&(_q)->regs->_field); \ - _val; \ -}) - -#define Q_WRITE(_q, _field, _val) do { \ - u32 _offset = offsetof(struct mt76_queue_regs, _field); \ - if ((_q)->flags & MT_QFLAG_WED) \ - mtk_wed_device_reg_write((_q)->wed, \ - ((_q)->wed_regs + _offset), \ - _val); \ - else \ - writel(_val, &(_q)->regs->_field); \ -} while (0) - -#else - -#define Q_READ(_q, _field) readl(&(_q)->regs->_field) -#define Q_WRITE(_q, _field, _val) writel(_val, &(_q)->regs->_field) - -#endif - static struct mt76_txwi_cache * mt76_alloc_txwi(struct mt76_dev *dev) { @@ -189,25 +158,62 @@ mt76_free_pending_rxwi(struct mt76_dev *dev) } EXPORT_SYMBOL_GPL(mt76_free_pending_rxwi); +static void +mt76_dma_queue_magic_cnt_init(struct mt76_dev *dev, struct mt76_queue *q) +{ + if (!mt76_queue_is_wed_rro(q)) + return; + + q->magic_cnt = 0; + if (mt76_queue_is_wed_rro_ind(q)) { + struct mt76_wed_rro_desc *rro_desc; + u32 data1 = FIELD_PREP(RRO_IND_DATA1_MAGIC_CNT_MASK, + MT_DMA_WED_IND_CMD_CNT - 1); + int i; + + rro_desc = (struct mt76_wed_rro_desc *)q->desc; + for (i = 0; i < q->ndesc; i++) { + struct mt76_wed_rro_ind *cmd; + + cmd = (struct mt76_wed_rro_ind *)&rro_desc[i]; + cmd->data1 = cpu_to_le32(data1); + } + } else if (mt76_queue_is_wed_rro_rxdmad_c(q)) { + struct mt76_rro_rxdmad_c *dmad = (void *)q->desc; + u32 data3 = FIELD_PREP(RRO_RXDMAD_DATA3_MAGIC_CNT_MASK, + MT_DMA_MAGIC_CNT - 1); + int i; + + for (i = 0; i < q->ndesc; i++) + dmad[i].data3 = cpu_to_le32(data3); + } +} + static void mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q) { Q_WRITE(q, desc_base, q->desc_dma); - if (q->flags & MT_QFLAG_WED_RRO_EN) + if ((q->flags & MT_QFLAG_WED_RRO_EN) && !mt76_npu_device_active(dev)) Q_WRITE(q, ring_size, MT_DMA_RRO_EN | q->ndesc); else Q_WRITE(q, ring_size, q->ndesc); + + if (mt76_queue_is_npu_tx(q)) { + writel(q->desc_dma, &q->regs->desc_base); + writel(q->ndesc, &q->regs->ring_size); + } q->head = Q_READ(q, dma_idx); q->tail = q->head; } -void __mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q, - bool reset_idx) +void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q, + bool reset_idx) { if (!q || !q->ndesc) return; - if (!mt76_queue_is_wed_rro_ind(q)) { + if (!mt76_queue_is_wed_rro_ind(q) && + !mt76_queue_is_wed_rro_rxdmad_c(q) && !mt76_queue_is_npu(q)) { int i; /* clear descriptors */ @@ -215,27 +221,26 @@ void __mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q, q->desc[i].ctrl = cpu_to_le32(MT_DMA_CTL_DMA_DONE); } + mt76_dma_queue_magic_cnt_init(dev, q); if (reset_idx) { - Q_WRITE(q, cpu_idx, 0); + if (mt76_queue_is_emi(q)) + *q->emi_cpu_idx = 0; + else + Q_WRITE(q, cpu_idx, 0); Q_WRITE(q, dma_idx, 0); } mt76_dma_sync_idx(dev, q); } -void mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q) -{ - __mt76_dma_queue_reset(dev, q, true); -} - static int mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q, struct mt76_queue_buf *buf, void *data) { struct mt76_queue_entry *entry = &q->entry[q->head]; struct mt76_txwi_cache *txwi = NULL; + u32 buf1 = 0, ctrl, info = 0; struct mt76_desc *desc; int idx = q->head; - u32 buf1 = 0, ctrl; int rx_token; if (mt76_queue_is_wed_rro_ind(q)) { @@ -244,6 +249,9 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q, rro_desc = (struct mt76_wed_rro_desc *)q->desc; data = &rro_desc[q->head]; goto done; + } else if (mt76_queue_is_wed_rro_rxdmad_c(q)) { + data = &q->desc[q->head]; + goto done; } desc = &q->desc[q->head]; @@ -252,7 +260,7 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q, buf1 = FIELD_PREP(MT_DMA_CTL_SDP0_H, buf->addr >> 32); #endif - if (mt76_queue_is_wed_rx(q)) { + if (mt76_queue_is_wed_rx(q) || mt76_queue_is_wed_rro_data(q)) { txwi = mt76_get_rxwi(dev); if (!txwi) return -ENOMEM; @@ -265,12 +273,26 @@ mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q, buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token); ctrl |= MT_DMA_CTL_TO_HOST; + + txwi->qid = q - dev->q_rx; + } + + if (mt76_queue_is_wed_rro_msdu_pg(q) && + dev->drv->rx_rro_add_msdu_page) { + if (dev->drv->rx_rro_add_msdu_page(dev, q, buf->addr, data)) + return -ENOMEM; + } + + if (q->flags & MT_QFLAG_WED_RRO_EN) { + info |= FIELD_PREP(MT_DMA_MAGIC_MASK, q->magic_cnt); + if ((q->head + 1) == q->ndesc) + q->magic_cnt = (q->magic_cnt + 1) % MT_DMA_MAGIC_CNT; } WRITE_ONCE(desc->buf0, cpu_to_le32(buf->addr)); WRITE_ONCE(desc->buf1, cpu_to_le32(buf1)); WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); - WRITE_ONCE(desc->info, 0); + WRITE_ONCE(desc->info, cpu_to_le32(info)); done: entry->dma_addr[0] = buf->addr; @@ -379,7 +401,10 @@ static void mt76_dma_kick_queue(struct mt76_dev *dev, struct mt76_queue *q) { wmb(); - Q_WRITE(q, cpu_idx, q->head); + if (mt76_queue_is_emi(q)) + *q->emi_cpu_idx = cpu_to_le16(q->head); + else + Q_WRITE(q, cpu_idx, q->head); } static void @@ -399,6 +424,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush) while (q->queued > 0 && q->tail != last) { mt76_dma_tx_cleanup_idx(dev, q, q->tail, &entry); + mt76_npu_txdesc_cleanup(q, q->tail); mt76_queue_tx_complete(dev, q, &entry); if (entry.txwi) { @@ -422,16 +448,62 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush) wake_up(&dev->tx_wait); } +static void * +mt76_dma_get_rxdmad_c_buf(struct mt76_dev *dev, struct mt76_queue *q, + int idx, int *len, bool *more) +{ + struct mt76_queue_entry *e = &q->entry[idx]; + struct mt76_rro_rxdmad_c *dmad = e->buf; + u32 data1 = le32_to_cpu(dmad->data1); + u32 data2 = le32_to_cpu(dmad->data2); + struct mt76_txwi_cache *t; + u16 rx_token_id; + u8 ind_reason; + void *buf; + + rx_token_id = FIELD_GET(RRO_RXDMAD_DATA2_RX_TOKEN_ID_MASK, data2); + t = mt76_rx_token_release(dev, rx_token_id); + if (!t) + return ERR_PTR(-EAGAIN); + + q = &dev->q_rx[t->qid]; + dma_sync_single_for_cpu(dev->dma_dev, t->dma_addr, + SKB_WITH_OVERHEAD(q->buf_size), + page_pool_get_dma_dir(q->page_pool)); + + if (len) + *len = FIELD_GET(RRO_RXDMAD_DATA1_SDL0_MASK, data1); + if (more) + *more = !FIELD_GET(RRO_RXDMAD_DATA1_LS_MASK, data1); + + buf = t->ptr; + ind_reason = FIELD_GET(RRO_RXDMAD_DATA2_IND_REASON_MASK, data2); + if (ind_reason == MT_DMA_WED_IND_REASON_REPEAT || + ind_reason == MT_DMA_WED_IND_REASON_OLDPKT) { + mt76_put_page_pool_buf(buf, false); + buf = ERR_PTR(-EAGAIN); + } + t->ptr = NULL; + t->dma_addr = 0; + + mt76_put_rxwi(dev, t); + + return buf; +} + static void * mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx, - int *len, u32 *info, bool *more, bool *drop) + int *len, u32 *info, bool *more, bool *drop, bool flush) { struct mt76_queue_entry *e = &q->entry[idx]; struct mt76_desc *desc = &q->desc[idx]; u32 ctrl, desc_info, buf1; void *buf = e->buf; - if (mt76_queue_is_wed_rro_ind(q)) + if (mt76_queue_is_wed_rro_rxdmad_c(q) && !flush) + buf = mt76_dma_get_rxdmad_c_buf(dev, q, idx, len, more); + + if (mt76_queue_is_wed_rro(q)) goto done; ctrl = le32_to_cpu(READ_ONCE(desc->ctrl)); @@ -486,20 +558,50 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush, if (!q->queued) return NULL; - if (mt76_queue_is_wed_rro_data(q)) - return NULL; + if (mt76_queue_is_wed_rro_data(q) || mt76_queue_is_wed_rro_msdu_pg(q)) + goto done; + + if (mt76_queue_is_wed_rro_ind(q)) { + struct mt76_wed_rro_ind *cmd; + u8 magic_cnt; - if (!mt76_queue_is_wed_rro_ind(q)) { + if (flush) + goto done; + + cmd = q->entry[idx].buf; + magic_cnt = FIELD_GET(RRO_IND_DATA1_MAGIC_CNT_MASK, + le32_to_cpu(cmd->data1)); + if (magic_cnt != q->magic_cnt) + return NULL; + + if (q->tail == q->ndesc - 1) + q->magic_cnt = (q->magic_cnt + 1) % MT_DMA_WED_IND_CMD_CNT; + } else if (mt76_queue_is_wed_rro_rxdmad_c(q)) { + struct mt76_rro_rxdmad_c *dmad; + u16 magic_cnt; + + if (flush) + goto done; + + dmad = q->entry[idx].buf; + magic_cnt = FIELD_GET(RRO_RXDMAD_DATA3_MAGIC_CNT_MASK, + le32_to_cpu(dmad->data3)); + if (magic_cnt != q->magic_cnt) + return NULL; + + if (q->tail == q->ndesc - 1) + q->magic_cnt = (q->magic_cnt + 1) % MT_DMA_MAGIC_CNT; + } else { if (flush) q->desc[idx].ctrl |= cpu_to_le32(MT_DMA_CTL_DMA_DONE); else if (!(q->desc[idx].ctrl & cpu_to_le32(MT_DMA_CTL_DMA_DONE))) return NULL; } - +done: q->tail = (q->tail + 1) % q->ndesc; q->queued--; - return mt76_dma_get_buf(dev, q, idx, len, info, more, drop); + return mt76_dma_get_buf(dev, q, idx, len, info, more, drop, flush); } static int @@ -557,6 +659,10 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q, if (test_bit(MT76_RESET, &phy->state)) goto free_skb; + /* TODO: Take into account unlinear skbs */ + if (mt76_npu_device_active(dev) && skb_linearize(skb)) + goto free_skb; + t = mt76_get_txwi(dev); if (!t) goto free_skb; @@ -604,6 +710,9 @@ mt76_dma_tx_queue_skb(struct mt76_phy *phy, struct mt76_queue *q, if (ret < 0) goto unmap; + if (mt76_npu_device_active(dev)) + return mt76_npu_dma_add_buf(phy, q, skb, &tx_info.buf[1], txwi); + return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf, tx_info.info, tx_info.skb, t); @@ -650,7 +759,8 @@ mt76_dma_rx_fill_buf(struct mt76_dev *dev, struct mt76_queue *q, void *buf = NULL; int offset; - if (mt76_queue_is_wed_rro_ind(q)) + if (mt76_queue_is_wed_rro_ind(q) || + mt76_queue_is_wed_rro_rxdmad_c(q)) goto done; buf = mt76_get_page_pool_buf(q, &offset, q->buf_size); @@ -680,9 +790,6 @@ int mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q, { int frames; - if (!q->ndesc) - return 0; - spin_lock_bh(&q->lock); frames = mt76_dma_rx_fill_buf(dev, q, allow_direct); spin_unlock_bh(&q->lock); @@ -708,27 +815,23 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q, q->ndesc = n_desc; q->buf_size = bufsize; q->hw_idx = idx; + q->dev = dev; + + if (mt76_queue_is_wed_rro_ind(q)) + size = sizeof(struct mt76_wed_rro_desc); + else if (mt76_queue_is_npu_tx(q)) + size = sizeof(struct airoha_npu_tx_dma_desc); + else if (mt76_queue_is_npu_rx(q)) + size = sizeof(struct airoha_npu_rx_dma_desc); + else + size = sizeof(struct mt76_desc); - size = mt76_queue_is_wed_rro_ind(q) ? sizeof(struct mt76_wed_rro_desc) - : sizeof(struct mt76_desc); q->desc = dmam_alloc_coherent(dev->dma_dev, q->ndesc * size, &q->desc_dma, GFP_KERNEL); if (!q->desc) return -ENOMEM; - if (mt76_queue_is_wed_rro_ind(q)) { - struct mt76_wed_rro_desc *rro_desc; - int i; - - rro_desc = (struct mt76_wed_rro_desc *)q->desc; - for (i = 0; i < q->ndesc; i++) { - struct mt76_wed_rro_ind *cmd; - - cmd = (struct mt76_wed_rro_ind *)&rro_desc[i]; - cmd->magic_cnt = MT_DMA_WED_IND_CMD_CNT - 1; - } - } - + mt76_dma_queue_magic_cnt_init(dev, q); size = q->ndesc * sizeof(*q->entry); q->entry = devm_kzalloc(dev->dev, size, GFP_KERNEL); if (!q->entry) @@ -738,6 +841,7 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q, if (ret) return ret; + mt76_npu_queue_setup(dev, q); ret = mt76_wed_dma_setup(dev, q, false); if (ret) return ret; @@ -748,7 +852,10 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q, return 0; } - mt76_dma_queue_reset(dev, q); + /* HW specific driver is supposed to reset brand-new EMI queues since + * it needs to set cpu index pointer. + */ + mt76_dma_queue_reset(dev, q, !mt76_queue_is_emi(q)); return 0; } @@ -762,6 +869,11 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q) if (!q->ndesc) return; *** 10208 LINES SKIPPED ***
