Releases: Elvandito/mtk-bwmod
Release list
mtk-bwmod v2.2
Changelog v2.2
Fixes
- Bluetooth HAL Init: Removed
persist.vendor.connsys.chipidandpersist.vendor.connsys.adie.chipid(-1 values) that crashed MTK Bluetooth HAL on newer chips like Dimensity 9400+ (fixes #2). - Module Installer: Fixed
customize.shnot extractingpost-fs-data.shand/systemoverlay files whenSKIPUNZIP=1is set. - Routing & Connectivity: Removed route table resets in
service.shthat broke dual-SIM and WiFi handover. - Config Integrity: Removed risky XML regex replacements in
post-fs-data.sh.
Changes & Improvements
- LTE / NR Carrier Aggregation: Enabled CA (
lte_dl_ca,lte_ul_ca,lte_ca_inter_band) and EN-DC (endc_enabled,nr_endc_support,nr_intra_band_ca,nr_inter_band_ca). - Antenna & Modulation: Enabled 256-QAM and 4RX diversity flags (
lte_dl_4rx,nr_dl_4rx). - Cleaned
system.prop: Stripped non-existent, fabricated, and placebo property lines. Removed hardcoded band limit strings. - Cleaned
service.sh: Retained functional Linux kernel sysctl tuning (64MB TCP buffer, BBR), IRQ affinity to big cores,txqueuelen=3000,tc qdisc fq, and DSCP marking.
mtk-bwmod v2.1
What's New
IMS/VoLTE/VoNR/WFC Full Stack (Section 2 Expanded)
- 83 IMS-related setprops (service.sh section 2)
- Covers: AOSP, MIUI/HyperOS, ColorOS, OnePlus, Samsung MTK
- Latency reduction:
sip.t1_timer=50ms(vs default 100ms)sip.timer_b=3200ms— tighter SIP timeoutvolte_qci=1— highest priority bearerims.regstate 0→1— force re-registration after props
mtk-bwmod v2.0
[v2.0] — Bandwidth Priority & AP/BS Negotiation
Added
[23] Route Metric Priority
- WiFi preferred:
wlan0 metric=0,rmnet metric=200 - Mobile-only fallback:
rmnet metric=0if no WiFi ip routerebuilt on every boot to ensure correct priority
[24] DSCP Traffic Marking
iptables -t manglemarks outgoing packets per traffic class- AP/router reads DSCP and queues accordingly
| Class | DSCP | Ports | Traffic |
|-------|------|-------|---------|
| EF | 46 | 5060/5061 SIP, 53 DNS, 443 QUIC, RTP 16384-32767 | VoIP, video call |
| AF41 | 34 | 80/443/8080 HTTP/S | Streaming, bulk TCP |
[25] wpa_cli AP Negotiation
Forces wpa_supplicant to re-negotiate with AP at boot:
rrm_neighbor_rep_request— 802.11k neighbor report from APprefer_5ghz=1,prefer_6ghz=1— band preferenceampdu=1— AMPDU at supplicant levelroam_rssi_threshold=-75— aggressive roam thresholdreassociate— re-associate with updated parameters
[26] iw Kernel WiFi Driver Tuning
Direct nl80211 commands bypassing WiFi HAL:
txq limit=65536,txq memory_limit=32MB— larger TX queuetxq quantum=3028— fair scheduling quantumretry short=7 long=4— retry more on busy channelsrts 2347— disable RTS/CTS overheadpower_save off— confirmed at driver level
[27] Mobile Data BS Negotiation
MTK RIL + NR QoS props:
pdn.rebuild=1— force re-setup PDN with best QoS classthrottle.disable=1— bypass UE-initiated throttlelte_ul_power_headroom=3— signal better UE capability to eNBnr_qos_flow=1,nr_reflective_qos=1,nr_fgqos_enable=1— 5G QoS flow negotiation
mtk-bwmod v1.9
Architecture
v1.9 uses a 4-layer system. Each layer runs at a different point in the boot process:
┌─────────────────────────────────────────────────────┐
│ LAYER 1 — Android Init (pre-userspace) │
│ system/etc/init/mtk-bwmod.rc │
│ system/etc/sysctl.d/99-mtk-bwmod.conf │
│ system/etc/dhcpcd/dhcpcd.conf │
│ system/etc/resolv.conf │
├─────────────────────────────────────────────────────┤
│ LAYER 2 — Android Properties (HAL-required only) │
│ system.prop (~155 props, lean) │
├─────────────────────────────────────────────────────┤
│ LAYER 3 — Magisk Boot Service │
│ service.sh (22 sections, radio/WiFi/TC/IRQ) │
├─────────────────────────────────────────────────────┤
│ LAYER 4 — Runtime Profile Switcher │
│ action.sh (Performance / Balanced / Battery) │
└─────────────────────────────────────────────────────┘
System Files (Layer 1)
system/etc/init/mtk-bwmod.rc
Android init script. Processed by init daemon before Magisk service.sh.
| Trigger | What runs |
|---|---|
on post-fs-data |
TCP core, UDP, socket params, routing — no module dependency |
on boot_completed |
BBR (tcp_bbr.ko), 64MB buffers, conntrack 2M |
system/etc/sysctl.d/99-mtk-bwmod.conf
sysctl.d fallback. Applied by sysctl --system during init on supported ROMs.
Mirrors init.rc params — ensures coverage on ROMs with varying init behavior.
Covers: TCP (fastopen, ECN, keepalive, notsent_lowat), UDP, 64MB buffers, conntrack 2M, routing, IPv6.
system/etc/dhcpcd/dhcpcd.conf
DHCP client optimization. Applied by dhcpcd daemon when connecting to WiFi/LAN.
| Setting | Value | Effect |
|---|---|---|
rapid_commit |
on | 1 round-trip DHCP vs 4 — faster WiFi connect |
timeout |
10s | Faster failure detection |
static dns |
1.1.1.1 1.0.0.1 | DNS override via DHCP layer |
noarp |
on | Skip ARP probe — saves ~1-2s per connect |
system/etc/resolv.conf
DNS resolver fallback. Points to Cloudflare 1.1.1.1 for processes that bypass Android's netd.
Properties (Layer 2)
~155 essential props only. All kernel/network params moved to system files.
| # | Section | Count | Purpose |
|---|---|---|---|
| 1 | LTE Carrier Aggregation | 13 | Force CA, UL/DL bands, component limit |
| 2 | MTK Baseband | 14 | RIL optimization, HSDPA/HSUPA tuning |
| 3 | Fast Dormancy Disabled | 3 | Lower ping, disable modem idle sleep |
| 4 | WiFi HAL | 23 | Power save off, band steering, WiFi 6/6E |
| 5 | Logging Off | 7 | Disable WiFi/BT/modem debug logs |
| 6 | DNS | 6 | Cloudflare on rmnet0/rmnet1 |
| 7 | NR / 5G | 12 | SA+NSA, all global bands, NR force |
| 8 | MTK ConnSys / IMS / DSDS | 21 | Balanced BT coex, full IMS stack, DSDS |
| 9 | LTE-A + NR Extended | 20 | EN-DC, MIMO, 256QAM, PDCP, BWP |
| 10 | VoLTE / VoNR | 6 | HD Voice, 5G calling, WFC |
| 11 | Antenna / Diversity | 10 | 4RX diversity, UL MCS boost |
| 12 | ConnAC WiFi Chip | 26 | A-MPDU/A-MSDU, OFDMA, BF, 802.11k/v/r |
| 13 | IMS Stack Extended | 9 | AMR-WB, EVS, Opus, SRVCC |
| 14 | Network Search + Modem | 9 | Fast camp, NR priority, PSM off |
| 15 | Settings UI Unlock | 15 | 5G/VoLTE/WFC/APN in Settings (all ROMs) |
Boot Service (Layer 3)
service.sh — runs via Magisk late_start, 22 sections, 416 lines.
| # | Section | Method |
|---|---|---|
| 1–2 | Radio + IMS props | setprop after modem init |
| 3 | TCP/BBR | sysctl (confirms init.rc values) |
| 4 | UDP/QUIC buffers | sysctl |
| 5 | WiFi runtime | setprop |
| 6 | DNS all interfaces | setprop per interface |
| 7 | Network IRQ affinity | /proc/irq/*/smp_affinity → big cores |
| 8 | Data stall recovery | setprop keepalive |
| 9 | txqueuelen + RPS | ip link, /sys/class/net/ |
| 10 | Settings UI unlock | setprop |
| 11 | CCCI + Antenna + CA | setprop |
| 12 | Signal + Network search | setprop |
| 13 | WiFi AP QoS (802.11k/v/r) | setprop |
| 14 | tc qdisc → fq | tc qdisc (skips AP interfaces) |
| 15 | HW offloading GRO/GSO/TSO | ethtool -K + sysfs |
| 16 | XPS TX steering | /sys/class/net/*/queues/tx-*/xps_cpus |
| 17 | NAPI budget | sysctl netdev_budget=600 |
| 18 | schedutil hint | /sys/devices/system/cpu/*/cpufreq/schedutil/ |
| 19 | RPS flow table | sysctl rps_sock_flow_entries=32768 |
| 20 | IRQ coalescing | ethtool -C rx-usecs=50 rx-frames=32 |
| 21 | TCP overhead strip | timestamps=0, mtu_probing=2 |
| 22 | Conntrack scaling | nf_conntrack_max=2M |
Profile Switcher (Layer 4)
action.sh — trigger via Magisk App → Module → Action button.
Vol↑ = Next profile
Vol↓ = Prev profile
Power = Apply
| ⚡ Performance | ⚖️ Balanced | 🔋 Battery Saver | |
|---|---|---|---|
| TCP Buffers | 64MB | 32MB | 16MB |
| CC | BBR | BBR | Cubic |
| qdisc | fq | fq_codel | fq_codel |
| IRQ Coalesce | 50µs / 32f | 100µs / 16f | 200µs / 8f |
| Conntrack | 2,000,000 | 500,000 | 65,536 |
| schedutil | 0µs (instant) | 200µs | 500µs |
| NAPI | 600 | 400 | 300 |
| WiFi PS | OFF | Light | ON |
| Fast Dormancy | OFF | Soft | ON |
Profile persists across reboots: /data/local/tmp/mtk_bwmod_profile
mtk-bwmod v1.8
[v1.8] — System File Overlay (Init Layer)
Added
New tuning layer via Magisk system file replacement — applied by Android init system, runs before service.sh and before user space starts.
system/etc/init/mtk-bwmod.rc — Android Init Script
- Processed by Android init daemon (not Magisk)
- Runs at two stages:
on post-fs-data— early boot, kernel params before network upon property:sys.boot_completed=1— after modules loaded (BBR, conntrack)
- Covers: TCP core, UDP buffers, socket core, routing, conntrack, IPv6
- Universal: Android 8+ on all MTK devices
system/etc/sysctl.d/99-mtk-bwmod.conf — sysctl.d Fallback
- Applied by init sysctl service on ROMs that process
/etc/sysctl.d/ - Mirrors init.rc settings as a redundancy layer
- Includes: TCP, UDP, buffers, conntrack, routing, IPv6
Boot Layer Architecture
Android init
├─ post-fs-data ← [NEW v1.8] mtk-bwmod.rc (early kernel params)
├─ sysctl.d ← [NEW v1.8] 99-mtk-bwmod.conf (fallback)
└─ boot_completed
├─ BBR + buffers ← [NEW v1.8] mtk-bwmod.rc (module-dependent)
└─ Magisk service.sh (22 sections, fine tuning + radio + WiFi)
Technical Details
mtk-bwmod.rc — on post-fs-data (early):
- TCP fastopen, SACK, window scaling, ECN, keepalive, notsent_lowat
- UDP rmem/wmem_min, port range 1024-65535
- Socket: somaxconn=8192, netdev_budget=600, backlog=32768, rps_flow=32768
- Routing: rp_filter, no redirects, no source routing
mtk-bwmod.rc—on property:sys.boot_completed=1(late): - BBR congestion control (tcp_bbr.ko must be loaded)
- TCP buffers: 64MB rmem/wmem
- Conntrack: max=2,000,000, TCP_EST=600s, UDP=30s
99-mtk-bwmod.conf— sysctl.d: - Full mirror of init.rc params as fallback
- Applied by
sysctl --systemduring init - And nothing.
mtk-bwmod v1.7
[v1.7] — Bluetooth & Hotspot Fixes
Fixed
-
Bluetooth connectivity issue on MT6781 (Helio G96) and similar chips
- Changed
coex_policyfromwifi_priority→coexist - Changed
coex_priorityfromwifi→coexist - Reduced
bt_wlan_coexfrom 2 (strict) → 1 (balanced) - Enabled
wlan_bt_timeshare=1(was 0, causing BT starvation) - Root cause: ConnSys layer WiFi exclusivity preventing BT RF access
- Changed
-
WiFi hotspot breaking when module active
- tc qdisc now detects and skips AP mode interfaces
- Check:
iw dev <iface> info | grep "type AP"before applying qdisc - Applied in
service.shand all 3 profiles inaction.sh
Improved
action.shnow displays current active profile at top- Module description added to action.sh header
- Better visual distinction between "selected" (▶) and "active" (← active)
Technical Details
BT Coexistence Tuning:
persist.vendor.connsys.coex_policy=coexist (was wifi_priority)
persist.vendor.mtk.wifi.coex_priority=coexist (was wifi)
persist.vendor.connsys.bt_wlan_coex=1 (was 2)
persist.vendor.connsys.wlan_bt_timeshare=1 (was 0)
Hotspot Safety:
# Skip tc qdisc on AP interfaces to prevent hostapd conflicts
AP_MODE=$(iw dev "$IF" info 2>/dev/null | grep -c "type AP")
[ "$AP_MODE" -gt "0" ] && continuemtk-bwmod v1.6
[v1.6] — Profile Switcher
Added
action.sh— interactive profile switcher via volume keys- Vol↑ = Next profile | Vol↓ = Prev profile | Power = Apply
- Reads raw kernel events via
getevent -l(all/dev/input/event*) - Active profile saved to
/data/local/tmp/mtk_bwmod_profile
Profiles
| Profile | TCP | CC | IRQ | Conntrack | WiFi PS | Dormancy |
|---|---|---|---|---|---|---|
| ⚡ Performance | 64MB | BBR | 50µs/32f | 2,000,000 | OFF | OFF |
| ⚖️ Balanced | 32MB | BBR | 100µs/16f | 500,000 | Light | Soft |
| 🔋 Battery Saver | 16MB | Cubic | 200µs/8f | 65,536 | ON | ON |
mtk-bwmod v1.5
What's New in v1.5
3 Advanced Kernel-Level Network Optimizations
[20] IRQ Coalescing (Interrupt Moderation)
- Batch incoming packets for 50µs before raising CPU interrupt
rx-frames=32— up to 32 packets per interrupt window- Reduces interrupt frequency, larger payloads per wakeup
- Performance: +20-30% download throughput (bulk transfers), ↓ interrupt overhead
[21] TCP Overhead Stripping
tcp_timestamps=0— remove 10-12 byte timestamp from every segmenttcp_mtu_probing=2— always start with maximum MTU (PMTUD handles reduction)tcp_ecn=1— congestion notification without packet drops- Performance: ↓ 12 bytes per segment overhead, ↓ CPU per-packet work, more payload per transmission
[22] Conntrack Scaling
nf_conntrack_max=2000000(was ~65k default)nf_conntrack_buckets=250000for optimal lookup- Timeouts tuned: TCP_EST=600s, TIME_WAIT=30s, UDP=30s
- Prevents connection drops under multi-threaded downloads (IDM/Torrent) + background apps
- Performance: +300% connection capacity, stable under P2P workloads, no sudden drops
Performance Gains (v1.5)
| Metric | Gain |
|---|---|
| Bulk download throughput | +20-30% |
| Per-packet CPU overhead | ↓ 12 bytes |
| Max concurrent connections | +300% (65k → 2M) |
| Multi-threaded download stability | ↓ connection drops significantly |
| Interrupt frequency | ↓ 40-60% (fewer IRQs) |
| Torrent/P2P throughput | +50-100% (if previous bottleneck was conntrack) |
Inside v1.5
- service.sh: 22 runtime sections, 466 lines (added [20–22])
- system.prop: 27 sections, 492 props (unchanged)
- customize.sh: MTK detection + safeguards
What v1.5 Does
- Batch network interrupts for efficiency (ethtool coalescing)
- Reduce TCP segment overhead (timestamps off, full MTU negotiation)
- Scale connection tracking for heavy workloads (2M conntrack entries)
- Enable ECN for congestion control without packet drops
- Tune TCP timeout per protocol (established, time_wait, UDP)
⚠️ Side Effects
- Latency on small packets: Slightly higher (50µs coalescing delay), negligible for bulk transfers
- Memory: +~20MB for 2M conntrack table (on devices with 4GB+ RAM)
- Battery: Negligible (fewer interrupts actually helps)
- Carrier: Works on all carriers; no conflicts
mtk-bwmod v1.4
🆕 What's New in v1.4
6 Linux Kernel Network Stack Optimizations
[14] tc qdisc → Fair Queue (fq)
- Removes Android default qdisc, replaces with fq (BBR-optimized)
- Per-flow pacing, eliminates head-of-line blocking
- Performance: +15-25% sustained throughput on WiFi/LTE
[15] Hardware Offloading: GRO / GSO / TSO
- Enables packet reassembly/segmentation offload to hardware
- Applied via ethtool + sysfs on all interfaces
- Performance: ↓ 20-30% CPU usage during high-bandwidth transfers
[16] XPS: Transmit Packet Steering
- Maps TX queues to big-core CPU mask (same as RX)
- Cache-hot path: both directions on same core
- Performance: ↓ 10-20% latency, ↓ 30% packet loss during retransmits
[17] NAPI Budget Increase: 600 packets/cycle
- netdev_budget: 300 → 600 (process more packets per interrupt)
- backlog: 16384 → 32768 (larger hold buffer)
- Performance: +20% stability, ↓ 50% packet loss during spikes
[18] schedutil CPU Tuning: up_rate_limit=0
- Big cores respond in <10µs to network load (vs default 500µs)
- NOT forcing performance governor (power-efficient)
- Performance: ↓ 40% ping variance, ↓ 50% VoIP jitter, ~3-5% battery
[19] RPS Flow Table: 32768 entries
- rps_sock_flow_entries increased for balanced multi-core RX
- rps_flow_cnt=512 per queue
- Performance: +30-50% multi-stream throughput (parallel downloads)
Bonus: 64MB NR Buffers
- Upgraded from 32MB for sustained 5G speeds
mtk-bwmod v1.3
Section [27] WiFi AP Communication — device actively sends frames to router:
WMM/EDCA — all traffic via AC_VO/AC_VI queue, UAPSD
Block ACK — window 64 frames, compressed BA = higher throughput
ADDTS — device request QoS Traffic Stream admission to AP
Beamforming CSI — device sends channel state report so AP directs beam directly to device (SU-BF + MU-BF, VHT+HE)
802.11k — Neighbor Report request to AP for roaming decision
802.11v — BSS Transition, device accepts AP recommendations for load balancing
802.11r — Fast Roaming, handshake from ~200ms → ~50ms
2×2 MIMO + MCS max — highest negotiated rate the AP can support
service.sh section [11]–[13] re-apply all runtimes every boot.