//
2.1. Kernel module for MT7165
Made with
Page icon

2.1. Kernel module for MT7165

MT7615 default EEPROM comes with a TX power limited at 6dbm. To remove this limit, you need to compile a custom kernel module that loads a different EEPROM when MT7615 is present.
This process is long and error prone. If you’re not in the mood to go through every step to build the custom kernel module, you can use this script from bin to automate the build.
Bash
Copy
screen curl -fsS https://properinter.net/bin/build_mt7615_kernel_module.sh | bash [...] Generating package index... Index has 979 packages (of which 979 are new) Index has 74 packages (of which 74 are new) make[1]: Leaving directory '/home/ubuntu/openwrt' build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/mt76-2024.10.28~c246fa54/.pkgdir/kmod-mt7615-common/lib/modules/6.6.63//mt7615-common.ko MT615 kernel module copied to ~/mt7615-common.ko

1. OpenWrt commit and kernel vermagic

You need the OpenWrt snapshot git commit and kernel version magic (vermagic). You will use them to build a kernel module with the exact same build configuration as the snapshot build that will be running on your router. Otherwise the custom kernel module won’t be loaded. If you already have an OpenWrt snapshot build up and running, ssh into the router and execute the following commands to get the kernel vermagic. Otherwise, read below.
root@openwrt:~#
Bash
Copy
ubus call system board { "kernel": "6.6.61", "hostname": "OpenWrt", "system": "ARMv8 Processor rev 0", "model": "Bananapi BPI-R4", "board_name": "bananapi,bpi-r4", "rootfs_type": "squashfs", "release": { "distribution": "OpenWrt", "version": "SNAPSHOT", "revision": "r28129-52b6c92479", "target": "mediatek/filogic", "description": "OpenWrt SNAPSHOT r28129-52b6c92479", "builddate": "1731967282" } } apk info kernel kernel-6.6.61~c61a5350068219c28273eb70e1086bd4-r1 description: Virtual kernel package kernel-6.6.61~c61a5350068219c28273eb70e1086bd4-r1 webpage: http://www.kernel.org/ kernel-6.6.61~c61a5350068219c28273eb70e1086bd4-r1 installed size: 24 KiB
Get the git commit hash and kernel vermagic from device running OpenWrt
ALT
If you’re building the custom module from scratch for the latest snapshot, you can get the commit hash from the snapshot build info and the kernel vermagic from the manifest.
Bash
Copy
curl -s https://downloads.openwrt.org/snapshots/targets/mediatek/filogic/version.buildinfo | grep -oP '\-\K[0-9a-f]+' 52b6c92479 curl -s https://downloads.openwrt.org/snapshots/targets/mediatek/filogic/openwrt-mediatek-filogic.manifest | grep -oP 'kernel.*~\K[0-9a-f]+' c61a5350068219c28273eb70e1086bd4
Get the git commit hash and kernel vermagic from the latest snapshot mirror
ALT

2. Prepare the OpenWrt build system

Bash
Copy
# install system dependencies sudo apt update sudo apt -y install build-essential clang flex bison g++ gawk \ gcc-multilib g++-multilib gettext git libncurses5-dev libssl-dev \ python3-setuptools rsync swig unzip zlib1g-dev file wget quilt # configure quilt to match openwrt's patch format cat << EOF > ~/.quiltrc QUILT_DIFF_ARGS="--no-timestamps --no-index -p ab --color=auto" QUILT_REFRESH_ARGS="--no-timestamps --no-index -p ab" QUILT_SERIES_ARGS="--color=auto" QUILT_PATCH_OPTS="--unified" QUILT_DIFF_OPTS="-p" EDITOR="vim" EOF # use screen or something similar in case you lose network connection screen # prepare the openwrt build system git clone https://git.openwrt.org/openwrt/openwrt.git cd openwrt # checkout the same revision as you're using in your openwrt build git checkout 52b6c92479 # ~ 1 minute ./scripts/feeds update -a # ~ 30 seconds ./scripts/feeds install -a # get the config build for the latest snapshot wget https://downloads.openwrt.org/snapshots/targets/mediatek/filogic/config.buildinfo -O .config make defconfig # prepare the toolchain # ~26 minutes make -j$(nproc) tools/install # ~13 minutes make -j$(nproc) toolchain/install

3. Patch and build mt7615-common kernel module

The patch we need to apply is taken from this post on the Banana Pi forum. It contains an hardcoded EEPROM for MT7615 that was retrieved from the Banana Pi R64 LEDE official image.
Diff
Copy
diff --git a/mt7615/eeprom.c b/mt7615/eeprom.c index ccedea7e8a..d95809c22c 100644 --- a/mt7615/eeprom.c +++ b/mt7615/eeprom.c @@ -332,6 +332,7 @@ static void mt7615_cal_free_data(struct mt7615_dev *dev) int mt7615_eeprom_init(struct mt7615_dev *dev, u32 addr) { + static const u8 eeprom_mt7615[] = {0x15, 0x76, 0xA0, 0x00, 0x00, 0x0C, 0x43, 0x26, 0x60, 0x00, 0x15, 0x76, 0xC3, 0x14, 0x00, 0x80, 0x02, 0x00, 0xC3, 0x14, 0x15, 0x76, 0x03, 0x22, 0xFF, 0xFF, 0x23, 0x04, 0x0D, 0x02, 0x8F, 0x02, 0x00, 0x80, 0x0A, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x60, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x01, 0x20, 0x20, 0x00, 0xB3, 0x40, 0xB6, 0x40, 0xC4, 0x24, 0x00, 0x00, 0x00, 0xC0, 0xC3, 0x24, 0x00, 0x00, 0x00, 0xC0, 0xC4, 0x14, 0x00, 0x00, 0x00, 0x40, 0xC4, 0x14, 0x00, 0x00, 0x00, 0x40, 0xC5, 0x14, 0x00, 0x00, 0xC0, 0xC4, 0x20, 0x00, 0x00, 0xC0, 0xC3, 0x14, 0x00, 0x00, 0x40, 0xC3, 0x14, 0x00, 0x00, 0x40, 0xC2, 0x22, 0x00, 0x00, 0x40, 0xC2, 0x14, 0x00, 0x00, 0x40, 0xC2, 0x22, 0x00, 0x00, 0xC0, 0xC2, 0x22, 0x00, 0x00, 0x40, 0xC3, 0x14, 0x00, 0x00, 0x40, 0xC3, 0x20, 0x00, 0x00, 0x40, 0xC3, 0x14, 0x00, 0x00, 0xC0, 0xC2, 0x14, 0x00, 0x00, 0x40, 0xC2, 0x22, 0x00, 0x00, 0xC0, 0xC1, 0x14, 0x00, 0x00, 0x40, 0xC1, 0x22, 0x00, 0x00, 0xC0, 0xC0, 0x22, 0x00, 0x00, 0xC6, 0xC6, 0xC4, 0xC4, 0xC4, 0x00, 0x00, 0xC2, 0x00, 0xC2, 0xC1, 0x81, 0x81, 0x81, 0x85, 0xC2, 0xC2, 0x00, 0x82, 0x82, 0x82, 0x81, 0x00, 0xC5, 0xC5, 0xC5, 0x00, 0x00, 0xC3, 0x00, 0xC3, 0xC3, 0x82, 0x82, 0x82, 0x83, 0x84, 0xC3, 0xC3, 0xC3, 0x82, 0x82, 0x82, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00, 0x00, 0x85, 0x01, 0x00, 0x00, 0x14, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xC1, 0x14, 0x00, 0x00, 0xC0, 0xC1, 0x14, 0x00, 0x00, 0x40, 0xC1, 0x14, 0x00, 0x00, 0x40, 0xC1, 0x14, 0x00, 0x00, 0x40, 0xC1, 0x14, 0x00, 0x00, 0xC0, 0xC0, 0x14, 0x00, 0x00, 0xC0, 0xC0, 0x14, 0x00, 0x00, 0xC0, 0xC0, 0x14, 0x00, 0x00, 0xC0, 0xC5, 0x14, 0x00, 0x00, 0x40, 0xC5, 0x14, 0x00, 0x00, 0x40, 0xC4, 0x14, 0x00, 0x00, 0xC0, 0xC3, 0x14, 0x00, 0x00, 0x40, 0xC3, 0x14, 0x00, 0x00, 0xC0, 0xC2, 0x14, 0x00, 0x00, 0xC0, 0xC2, 0x14, 0x00, 0x00, 0xC0, 0xC2, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; int ret; ret = mt7615_eeprom_load(dev, addr); @@ -340,8 +341,7 @@ int mt7615_eeprom_init(struct mt7615_dev *dev, u32 addr) ret = mt7615_check_eeprom(&dev->mt76); if (ret && dev->mt76.otp.data) { - memcpy(dev->mt76.eeprom.data, dev->mt76.otp.data, - dev->mt76.otp.size); + memcpy(dev->mt76.eeprom.data, eeprom_mt7615, 0x400); } else { dev->flash_eeprom = true; mt7615_cal_free_data(dev);
MT7615 kernel module patch
ALT
Bash
Copy
# make package/kernel/mt76/{clean,prepare,build} will not build modules, only # package them. if they weren't built previously then you'll only get empty # module packages. we need to build the kernel modules first. # ~7 minutes make -j$(nproc) target/linux/compile # verify that the build system kernel vermagic matches the one from OpenWrt # that is running on your device find build_dir/ -name .vermagic | xargs cat # c61a5350068219c28273eb70e1086bd4 # prepare the mt76 module with quilt so we can apply the patch before the build make -j$(nproc) package/mt76/{clean,prepare} V=s QUILT=1 cd $(ls -d build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/mt76-* | head -n 1) if [ -f patches/series ]; then quilt push -a fi wget https://raw.githubusercontent.com/proper-internet/patches/refs/heads/main/package/kernel/mt76/010-mt7615_txpower_fix.patch -P /tmp quilt import /tmp/010-mt7615_txpower_fix.patch quilt push cd - make -j$(nproc) package/kernel/mt76/update V=s # ~7 minutes make -j$(nproc) package/kernel/mt76/{clean,compile} package/index V=s # the built kernel module path is # ./build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/mt76-2024.10.28~c246fa54/.pkgdir/kmod-mt7615-common/lib/modules/6.6.61/mt7615-common.ko
Alternatively, and in case you don’t want to use quilt and patches in the step above, you can change the source file directly, make it immutable and compile the mt76 package.
Bash
Copy
# prepare the mt76 module so we can patch if before building it make -j$(nproc) package/kernel/mt76/prepare # patch mt7615/eeprom.c with the changes from the patch: # https://gist.github.com/pinge/0f43cddae8cd5fa52fbc5857e9f9d89b vim ./build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/mt76-2024.10.28~c246fa54/mt7615/eeprom.c # make the file immutable to avoid being overwritten with the source during build sudo chattr +i ./build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/mt76-2024.10.28~c246fa54/mt7615/eeprom.c # make will error when trying to overwrite the immutable mt7615/eeprom.c # ~7 minutes make --ignore-errors -j$(nproc) package/kernel/mt76/compile # the built kernel module path is # ./build_dir/target-aarch64_cortex-a53_musl/linux-mediatek_filogic/mt76-2024.10.28~c246fa54/.pkgdir/kmod-mt7615-common/lib/modules/6.6.61/mt7615-common.ko
Copy mt7615-common.ko to the instance home folder. It’s the only module you need to load the LEDE EEPROM and it’ll be part of the OpenWrt image.
Do not stop or destroy the instance. You will want to reuse it when building the OpenWrt image. You can continue to the ⚙️3. OpenWrt Config.

References