Replace tarball with un-tarred ImmortalWrt patch tree (package/feeds/files overrides)
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
# v33 完美固件源码包
|
||||||
|
|
||||||
|
对应 sysupgrade-v33.bin(md5 57d43f1a56c66fafd5c62e8846641232)。
|
||||||
|
|
||||||
|
## 包含文件(相对 ImmortalWrt 源码树根)
|
||||||
|
|
||||||
|
### package/mtk/ — MTK 闭源驱动层补丁
|
||||||
|
- `applications/mtwifi-cfg/files/mtwifi-cfg/mtwifi_cfg` — 5G/HE160 双分支写 VHT_Sec80_Channel=155
|
||||||
|
- `applications/mtwifi-cfg/files/mtwifi.sh` — detect_mtwifi 诚实 UCI(idx=1=5g/HE160, idx=2=2g/HE40)
|
||||||
|
- `applications/mtwifi-cfg/files/netifd/mtwifi.sh` — v33 关键补丁:setup 完成后 deferred 后台检测 dat MacAddress 与物理 netdev MAC,重发 wireless_add_vif 上报物理 ifname
|
||||||
|
- `applications/luci-app-mtk/luasrc/controller/mtkwifi.lua` — 顶部空 index() 禁用 MTK 私有面板
|
||||||
|
|
||||||
|
### package/mtk/drivers/wifi-profile/
|
||||||
|
- `files/mt7981/l1profile.dat` — 主次顺序 b0;b1(出厂值,未改动)
|
||||||
|
|
||||||
|
### feeds/luci/
|
||||||
|
- `modules/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js` — Overview/Modal SSID 读 iwinfo、reload-block 补丁、freqlist/txpowerlist 改传物理 ifname
|
||||||
|
|
||||||
|
### files/ — 烤入 squashfs 的配置与脚本
|
||||||
|
- `etc/uci-defaults/99-custom-config` — 首启 UCI 默认值(诚实标签 + turboacc tcpcca=bbr)
|
||||||
|
- `etc/wifi-band-verify.sh` — log-only 验证脚本
|
||||||
|
- `etc/rc.local` — 开机兜底(检测 vxlan0,缺失重触发)
|
||||||
|
- `etc/hotplug.d/iface/30-mss-clamp` — MSS clamp 持久化
|
||||||
|
- `etc/hotplug.d/iface/40-wg-track` — WG 隧道状态跟踪
|
||||||
|
- `etc/sysctl.d/99-bridge-nf.conf` — bridge-nf-call-{ip,ip6,ar}tables=1
|
||||||
|
- `etc/config/{wireless,firewall,dhcp,turboacc,dropbear,network}` — 7 个核心 UCI 配置全部烤入(**network 已脱敏:private_key 与 preshared_key 替换为占位符,使用前必须重新生成 WG 密钥对**)
|
||||||
|
|
||||||
|
### 顶层
|
||||||
|
- `netifd-wireless.sh` — `/lib/netifd/netifd-wireless.sh` (wifi-scripts 包)
|
||||||
|
|
||||||
|
## 刷入流程
|
||||||
|
1. 克隆 padavanonly fork 的 ImmortalWrt-Actions 源码树到 build server
|
||||||
|
2. 用本包覆盖对应路径
|
||||||
|
3. `make -j4` → `bin/targets/mediatek/filogic/immortalwrt-mediatek-filogic-cudy_tr3000-v1-ubootmod-squashfs-sysupgrade.bin`
|
||||||
|
4. FIT 镜像雕刻验证:`OFF=$(grep -abo "hsqs" image.bin | head -1 | cut -d: -f1); dd if=image.bin of=root.sqfs bs=1 skip=$OFF; unsquashfs -d sq root.sqfs`
|
||||||
|
5. U-Boot TFTP/网页刷入(**绝不用 sysupgrade**)
|
||||||
+2468
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,35 @@
|
|||||||
|
config dnsmasq
|
||||||
|
option domainneeded '1'
|
||||||
|
option boguspriv '1'
|
||||||
|
option filterwin2k '0'
|
||||||
|
option localise_queries '1'
|
||||||
|
option rebind_protection '1'
|
||||||
|
option rebind_localhost '1'
|
||||||
|
option local '/lan/'
|
||||||
|
option domain 'lan'
|
||||||
|
option expandhosts '1'
|
||||||
|
option nonegcache '0'
|
||||||
|
option cachesize '1000'
|
||||||
|
option authoritative '1'
|
||||||
|
option readethers '1'
|
||||||
|
option leasefile '/tmp/dhcp.leases'
|
||||||
|
option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
|
||||||
|
option nonwildcard '1'
|
||||||
|
option localservice '1'
|
||||||
|
option ednspacket_max '1232'
|
||||||
|
option filter_aaaa '0'
|
||||||
|
option filter_a '0'
|
||||||
|
|
||||||
|
config dhcp 'lan'
|
||||||
|
option interface 'lan'
|
||||||
|
option ignore '1'
|
||||||
|
|
||||||
|
config dhcp 'wan'
|
||||||
|
option interface 'wan'
|
||||||
|
option ignore '1'
|
||||||
|
|
||||||
|
config odhcpd 'odhcpd'
|
||||||
|
option maindhcp '0'
|
||||||
|
option leasefile '/tmp/hosts/odhcpd'
|
||||||
|
option leasetrigger '/usr/sbin/odhcpd-update'
|
||||||
|
option loglevel '4'
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
config dropbear
|
||||||
|
option PasswordAuth 'on'
|
||||||
|
option RootPasswordAuth 'on'
|
||||||
|
option Port '22'
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
config defaults
|
||||||
|
option input 'REJECT'
|
||||||
|
option output 'ACCEPT'
|
||||||
|
option forward 'REJECT'
|
||||||
|
option synflood_protect '1'
|
||||||
|
option fullcone '1'
|
||||||
|
option flow_offloading '0'
|
||||||
|
|
||||||
|
config zone
|
||||||
|
option name 'lan'
|
||||||
|
option input 'ACCEPT'
|
||||||
|
option output 'ACCEPT'
|
||||||
|
option forward 'ACCEPT'
|
||||||
|
list network 'lan'
|
||||||
|
list network 'wg0'
|
||||||
|
|
||||||
|
config zone
|
||||||
|
option name 'wan'
|
||||||
|
option input 'REJECT'
|
||||||
|
option output 'ACCEPT'
|
||||||
|
option forward 'REJECT'
|
||||||
|
option masq '1'
|
||||||
|
option mtu_fix '1'
|
||||||
|
list network 'wan'
|
||||||
|
list network 'wan6'
|
||||||
|
|
||||||
|
config forwarding
|
||||||
|
option src 'lan'
|
||||||
|
option dest 'wan'
|
||||||
|
|
||||||
|
config rule
|
||||||
|
option name 'Allow-DHCP-Renew'
|
||||||
|
option src 'wan'
|
||||||
|
option proto 'udp'
|
||||||
|
option dest_port '68'
|
||||||
|
option target 'ACCEPT'
|
||||||
|
option family 'ipv4'
|
||||||
|
|
||||||
|
config rule
|
||||||
|
option name 'Allow-Ping'
|
||||||
|
option src 'wan'
|
||||||
|
option proto 'icmp'
|
||||||
|
option icmp_type 'echo-request'
|
||||||
|
option family 'ipv4'
|
||||||
|
option target 'ACCEPT'
|
||||||
|
|
||||||
|
config rule
|
||||||
|
option name 'Allow-IGMP'
|
||||||
|
option src 'wan'
|
||||||
|
option proto 'igmp'
|
||||||
|
option family 'ipv4'
|
||||||
|
option target 'ACCEPT'
|
||||||
|
|
||||||
|
config rule
|
||||||
|
option name 'Allow-DHCPv6'
|
||||||
|
option src 'wan'
|
||||||
|
option proto 'udp'
|
||||||
|
option dest_port '546'
|
||||||
|
option family 'ipv6'
|
||||||
|
option target 'ACCEPT'
|
||||||
|
|
||||||
|
config rule
|
||||||
|
option name 'Allow-MLD'
|
||||||
|
option src 'wan'
|
||||||
|
option proto 'icmp'
|
||||||
|
option src_ip 'fe80::/10'
|
||||||
|
list icmp_type '130/0'
|
||||||
|
list icmp_type '131/0'
|
||||||
|
list icmp_type '132/0'
|
||||||
|
list icmp_type '143/0'
|
||||||
|
option family 'ipv6'
|
||||||
|
option target 'ACCEPT'
|
||||||
|
|
||||||
|
config rule
|
||||||
|
option name 'Allow-ICMPv6-Input'
|
||||||
|
option src 'wan'
|
||||||
|
option proto 'icmp'
|
||||||
|
list icmp_type 'echo-request'
|
||||||
|
list icmp_type 'echo-reply'
|
||||||
|
list icmp_type 'destination-unreachable'
|
||||||
|
list icmp_type 'packet-too-big'
|
||||||
|
list icmp_type 'time-exceeded'
|
||||||
|
list icmp_type 'bad-header'
|
||||||
|
list icmp_type 'unknown-header-type'
|
||||||
|
list icmp_type 'router-solicitation'
|
||||||
|
list icmp_type 'neighbour-solicitation'
|
||||||
|
list icmp_type 'router-advertisement'
|
||||||
|
list icmp_type 'neighbour-advertisement'
|
||||||
|
option limit '1000/sec'
|
||||||
|
option family 'ipv6'
|
||||||
|
option target 'ACCEPT'
|
||||||
|
|
||||||
|
config rule
|
||||||
|
option name 'Allow-ICMPv6-Forward'
|
||||||
|
option src 'wan'
|
||||||
|
option dest '*'
|
||||||
|
option proto 'icmp'
|
||||||
|
list icmp_type 'echo-request'
|
||||||
|
list icmp_type 'echo-reply'
|
||||||
|
list icmp_type 'destination-unreachable'
|
||||||
|
list icmp_type 'packet-too-big'
|
||||||
|
list icmp_type 'time-exceeded'
|
||||||
|
list icmp_type 'bad-header'
|
||||||
|
list icmp_type 'unknown-header-type'
|
||||||
|
option limit '1000/sec'
|
||||||
|
option family 'ipv6'
|
||||||
|
option target 'ACCEPT'
|
||||||
|
|
||||||
|
config rule
|
||||||
|
option name 'Allow-IPSec-ESP'
|
||||||
|
option src 'wan'
|
||||||
|
option dest 'lan'
|
||||||
|
option proto 'esp'
|
||||||
|
option target 'ACCEPT'
|
||||||
|
|
||||||
|
config rule
|
||||||
|
option name 'Allow-ISAKMP'
|
||||||
|
option src 'wan'
|
||||||
|
option dest 'lan'
|
||||||
|
option dest_port '500'
|
||||||
|
option proto 'udp'
|
||||||
|
option target 'ACCEPT'
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
config interface 'loopback'
|
||||||
|
option device 'lo'
|
||||||
|
option proto 'static'
|
||||||
|
option ipaddr '127.0.0.1'
|
||||||
|
option netmask '255.0.0.0'
|
||||||
|
|
||||||
|
config globals 'globals'
|
||||||
|
option ula_prefix 'fdab:c3fc:a55d::/48'
|
||||||
|
|
||||||
|
config device
|
||||||
|
option name 'br-lan'
|
||||||
|
option type 'bridge'
|
||||||
|
list ports 'eth1'
|
||||||
|
|
||||||
|
config interface 'lan'
|
||||||
|
option device 'br-lan'
|
||||||
|
option proto 'static'
|
||||||
|
option ipaddr '192.168.1.2'
|
||||||
|
option netmask '255.255.255.0'
|
||||||
|
option ip6assign '60'
|
||||||
|
|
||||||
|
config interface 'wan'
|
||||||
|
option device 'eth0'
|
||||||
|
option proto 'dhcp'
|
||||||
|
|
||||||
|
config interface 'wan6'
|
||||||
|
option device 'eth0'
|
||||||
|
option proto 'dhcpv6'
|
||||||
|
|
||||||
|
config interface 'wg0'
|
||||||
|
option proto 'wireguard'
|
||||||
|
option private_key '<REDACTED-YOUR-WG-PRIVATE-KEY'
|
||||||
|
option listen_port '51820'
|
||||||
|
list addresses '10.99.0.2/32'
|
||||||
|
option mtu '1420'
|
||||||
|
option route_allowed_ips '1'
|
||||||
|
|
||||||
|
config wireguard_wg0 'wgpeer'
|
||||||
|
option public_key 'GPrZqc8t7F3DG/D0ks+GcZQeUYy+3ClFnbSftSqiygQ='
|
||||||
|
option preshared_key '<REDACTED-YOUR-WG-PSK'
|
||||||
|
option endpoint_host '10.200.80.93'
|
||||||
|
option endpoint_port '51820'
|
||||||
|
option persistent_keepalive '25'
|
||||||
|
list allowed_ips '10.99.0.1/32'
|
||||||
|
|
||||||
|
config route
|
||||||
|
option interface 'wg0'
|
||||||
|
option target '10.99.0.1'
|
||||||
|
option netmask '255.255.255.255'
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
config turboacc 'config'
|
||||||
|
option fastpath 'mediatek_hnat'
|
||||||
|
option fastpath_mh_eth_hnat '1'
|
||||||
|
option fastpath_mh_eth_hnat_v6 '1'
|
||||||
|
option fastpath_mh_eth_hnat_bind_rate '30'
|
||||||
|
option fastpath_mh_eth_hnat_bind_trap '0'
|
||||||
|
option fullcone_nat '2'
|
||||||
|
option hal 'none'
|
||||||
|
option sw_flow '0'
|
||||||
|
option hw_flow '0'
|
||||||
|
option sfe_bridge '0'
|
||||||
|
option bbr_cca '1'
|
||||||
|
option dns_caching '0'
|
||||||
|
option dns_caching_dns '223.5.5.5,223.6.6.6'
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
config wifi-device 'MT7981_1_1'
|
||||||
|
option type 'mtwifi'
|
||||||
|
option phy 'ra0'
|
||||||
|
option hwmode '11a'
|
||||||
|
option band '5g'
|
||||||
|
option dbdc_main '1'
|
||||||
|
option channel '36'
|
||||||
|
option txpower '100'
|
||||||
|
option htmode 'HE160'
|
||||||
|
option country 'CN'
|
||||||
|
option mu_beamformer '1'
|
||||||
|
option noscan '0'
|
||||||
|
option serialize '1'
|
||||||
|
|
||||||
|
config wifi-iface 'default_MT7981_1_1'
|
||||||
|
option device 'MT7981_1_1'
|
||||||
|
option network 'lan'
|
||||||
|
option mode 'ap'
|
||||||
|
option ssid 'ImmortalWrt-5G'
|
||||||
|
option encryption 'none'
|
||||||
|
option uapsd '0'
|
||||||
|
|
||||||
|
config wifi-device 'MT7981_1_2'
|
||||||
|
option type 'mtwifi'
|
||||||
|
option phy 'rax0'
|
||||||
|
option hwmode '11g'
|
||||||
|
option band '2g'
|
||||||
|
option dbdc_main '0'
|
||||||
|
option channel 'auto'
|
||||||
|
option txpower '100'
|
||||||
|
option htmode 'HE40'
|
||||||
|
option country 'CN'
|
||||||
|
option mu_beamformer '1'
|
||||||
|
option noscan '1'
|
||||||
|
option serialize '1'
|
||||||
|
|
||||||
|
config wifi-iface 'default_MT7981_1_2'
|
||||||
|
option device 'MT7981_1_2'
|
||||||
|
option network 'lan'
|
||||||
|
option mode 'ap'
|
||||||
|
option ssid 'ImmortalWrt-2.4G'
|
||||||
|
option encryption 'none'
|
||||||
|
option uapsd '0'
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# === MSS clamp persistence (坑 #12 part 3) ===
|
||||||
|
# fw4 reload (triggered by any ifup) wipes the nft rule added by 20-vxlan hotplug.
|
||||||
|
# This iface hotplug re-adds the rule after every interface ifup event,
|
||||||
|
# but only if the rule is missing (idempotent).
|
||||||
|
# Idempotency: grep for the unique "set 1360" string before adding.
|
||||||
|
[ "$ACTION" = "ifup" ] || exit 0
|
||||||
|
sleep 2 # wait for fw4 reload to complete
|
||||||
|
nft list chain inet fw4 mangle_forward 2>/dev/null | grep -q 'set 1360' || \
|
||||||
|
nft add rule inet fw4 mangle_forward 'iifname "br-lan" tcp flags syn tcp option maxseg size set 1360' 2>/dev/null
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# /etc/hotplug.d/iface/40-wg-track
|
||||||
|
# 触发: 小路由 WAN iface 起来时 (boot / DHCP renew / link bounce)
|
||||||
|
# 目的: 跟踪 WG 隧道自动恢复状态,验证坑 #15 是否真根除
|
||||||
|
# 安装: scp 到 /etc/hotplug.d/iface/40-wg-track + chmod +x
|
||||||
|
|
||||||
|
[ "$ACTION" = "ifup" ] || exit 0
|
||||||
|
case "$INTERFACE" in
|
||||||
|
wan) ;;
|
||||||
|
*) exit 0 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
WAN_IP=$(ip -4 addr show eth0 2>/dev/null | awk '/inet / {print $2; exit}' | cut -d/ -f1)
|
||||||
|
[ -z "$WAN_IP" ] && exit 0
|
||||||
|
|
||||||
|
LOGFILE=/tmp/wg-tunnel-track.log
|
||||||
|
|
||||||
|
# 等 30s 让 tunnel 稳定 (handshake init + keepalive 至少跑两轮)
|
||||||
|
sleep 30
|
||||||
|
|
||||||
|
TS=$(date '+%Y-%m-%d %H:%M:%S')
|
||||||
|
ENDPOINT=$(wg show wg0 2>/dev/null | awk '/endpoint:/ {print $2; exit}')
|
||||||
|
HANDSHAKE=$(wg show wg0 2>/dev/null | awk -F': ' '/latest handshake/ {print $2}')
|
||||||
|
TRANSFER=$(wg show wg0 2>/dev/null | awk '/transfer:/ {print $2, $3, $4, $5}')
|
||||||
|
PING_LOSS=$(ping -c 3 -W 2 10.99.0.1 2>&1 | awk '/packets transmitted/ {print $6}')
|
||||||
|
|
||||||
|
STATUS="OK"
|
||||||
|
[ "$PING_LOSS" != "0%" ] && STATUS="FAIL"
|
||||||
|
|
||||||
|
echo "$TS | status=$STATUS | WAN=$WAN_IP | endpoint=$ENDPOINT | handshake=$HANDSHAKE | loss=$PING_LOSS | xfer=$TRANSFER" >> "$LOGFILE"
|
||||||
|
|
||||||
|
# Rotate: 只保留最后 200 行
|
||||||
|
tail -200 "$LOGFILE" > "$LOGFILE.tmp" 2>/dev/null && mv "$LOGFILE.tmp" "$LOGFILE"
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# RPS/RFS tuning for single-RX-queue devices (mtk_soc_eth)
|
||||||
|
# Distributes softirq across all CPUs; without this, all eth RX runs on CPU0 only.
|
||||||
|
# Pairs with sysctl tuning in /etc/sysctl.conf (BBR + buffer sizes).
|
||||||
|
|
||||||
|
[ -d /sys/class/net/eth1/queues ] && echo 3 > /sys/class/net/eth1/queues/rx-0/rps_cpus
|
||||||
|
[ -d /sys/class/net/eth0/queues ] && echo 3 > /sys/class/net/eth0/queues/rx-0/rps_cpus
|
||||||
|
[ -d /sys/class/net/br-lan/queues ] && echo 3 > /sys/class/net/br-lan/queues/rx-0/rps_cpus
|
||||||
|
[ -d /sys/class/net/ra0/queues ] && echo 3 > /sys/class/net/ra0/queues/rx-0/rps_cpus
|
||||||
|
[ -d /sys/class/net/rax0/queues ] && echo 3 > /sys/class/net/rax0/queues/rx-0/rps_cpus
|
||||||
|
|
||||||
|
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries 2>/dev/null
|
||||||
|
[ -f /sys/class/net/eth1/queues/rx-0/rps_flow_cnt ] && echo 32768 > /sys/class/net/eth1/queues/rx-0/rps_flow_cnt
|
||||||
|
[ -f /sys/class/net/br-lan/queues/rx-0/rps_flow_cnt ] && echo 32768 > /sys/class/net/br-lan/queues/rx-0/rps_flow_cnt
|
||||||
|
|
||||||
|
# === VXLAN boot fallback (keng #12 part 2) ===
|
||||||
|
# Hotplug 20-vxlan sometimes misses wg0 ifup at boot (no 10.99 route, no log entry).
|
||||||
|
# If we got here without vxlan0, manually re-trigger the same script.
|
||||||
|
[ -e /sys/class/net/vxlan0 ] || ACTION=ifup INTERFACE=wg0 /etc/hotplug.d/net/20-vxlan
|
||||||
|
|
||||||
|
# === WiFi band label verifier (v28, log-only) ===
|
||||||
|
# Aligns UCI wifi labels with physical broadcast once driver is stable.
|
||||||
|
# Log-only (no uci mutation); see /etc/wifi-band-verify.sh for rationale.
|
||||||
|
( /etc/wifi-band-verify.sh >/dev/null 2>&1 & )
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
net.bridge.bridge-nf-call-ip6tables=1
|
||||||
|
net.bridge.bridge-nf-call-iptables=1
|
||||||
|
net.bridge.bridge-nf-call-arptables=1
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# 99-custom-config - Apply TR3000-specific defaults on first boot
|
||||||
|
# Sets LAN IP, WiFi SSID/htmode/uapsd, dnsmasq, IPv6 RA, turboacc BBR
|
||||||
|
# Runs once (uci-defaults scripts auto-delete after running)
|
||||||
|
#
|
||||||
|
# v29 2026-07-22: HONEST labels. UCI idx=1=5g config (driver maps
|
||||||
|
# band=5g content to the 5G PHY whatever netdev it is this boot).
|
||||||
|
# idx=2=2g config (maps to 2.4G PHY). ra0/rax0 netdev binding is
|
||||||
|
# random per boot but physical broadcast always correct (band-content
|
||||||
|
# invariant). LuCI Overview shows iwinfo truth. Edit forms show UCI
|
||||||
|
# config. Do NOT use LuCI Save and Apply (triggers wifi reload);
|
||||||
|
# reboot to apply wireless changes.
|
||||||
|
|
||||||
|
. /lib/functions.sh
|
||||||
|
|
||||||
|
# ===== LAN IP =====
|
||||||
|
uci set network.lan.ipaddr="192.168.1.2"
|
||||||
|
uci set network.lan.netmask="255.255.255.0"
|
||||||
|
uci commit network
|
||||||
|
|
||||||
|
# ===== WiFi SSID + htmode + uapsd (honest labels) =====
|
||||||
|
uci set wireless.MT7981_1_1.phy="ra0"
|
||||||
|
uci set wireless.MT7981_1_1.band="5g"
|
||||||
|
uci set wireless.MT7981_1_1.hwmode="11a"
|
||||||
|
uci set wireless.MT7981_1_1.htmode="HE160"
|
||||||
|
uci set wireless.MT7981_1_1.country="CN"
|
||||||
|
uci set wireless.MT7981_1_1.channel="36"
|
||||||
|
uci set wireless.MT7981_1_1.dbdc_main="1"
|
||||||
|
uci set wireless.default_MT7981_1_1.ssid="ImmortalWrt-5G"
|
||||||
|
uci set wireless.default_MT7981_1_1.uapsd="0"
|
||||||
|
uci set wireless.default_MT7981_1_1.encryption="none"
|
||||||
|
|
||||||
|
uci set wireless.MT7981_1_2.phy="rax0"
|
||||||
|
uci set wireless.MT7981_1_2.band="2g"
|
||||||
|
uci set wireless.MT7981_1_2.hwmode="11g"
|
||||||
|
uci set wireless.MT7981_1_2.htmode="HE40"
|
||||||
|
uci set wireless.MT7981_1_2.country="CN"
|
||||||
|
uci set wireless.MT7981_1_2.channel="auto"
|
||||||
|
uci set wireless.MT7981_1_2.dbdc_main="0"
|
||||||
|
uci set wireless.default_MT7981_1_2.ssid="ImmortalWrt-2.4G"
|
||||||
|
uci set wireless.default_MT7981_1_2.uapsd="0"
|
||||||
|
uci set wireless.default_MT7981_1_2.encryption="none"
|
||||||
|
|
||||||
|
uci commit wireless
|
||||||
|
|
||||||
|
# ===== dnsmasq enable =====
|
||||||
|
/etc/init.d/dnsmasq enable
|
||||||
|
|
||||||
|
# ===== IPv6 RA disabled =====
|
||||||
|
uci set dhcp.lan.ra="disabled"
|
||||||
|
uci set dhcp.lan.dhcpv6="disabled"
|
||||||
|
uci commit dhcp
|
||||||
|
|
||||||
|
# ===== turboacc: BBR as default TCP CCA =====
|
||||||
|
# /etc/init.d/turboacc force-sets tcp_congestion_control from
|
||||||
|
# turboacc.config.tcpcca at every boot (S90, after sysctl.d), defaulting
|
||||||
|
# to cubic and clobbering sysctl.d/12-tcp-bbr.conf. Pin bbr here so the
|
||||||
|
# 网络加速 page shows BBR active out of the box.
|
||||||
|
uci set turboacc.config.tcpcca="bbr"
|
||||||
|
uci commit turboacc
|
||||||
|
|
||||||
|
# ===== Firewall: prepare for MSS clamp via hotplug =====
|
||||||
|
# fw4 reload wipes hotplug MSS clamp rules; the 30-mss-clamp hotplug
|
||||||
|
# re-adds them on every iface ifup. No static config needed here.
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# wifi-band-verify.sh — LOG-ONLY diagnostic. Compares UCI labels against the
|
||||||
|
# PHYSICAL band each netdev is on and records the verdict to logread.
|
||||||
|
# NEVER writes UCI: with ra0/rax0 ↔ dat binding random per boot (and band-content
|
||||||
|
# invariant keeping physical always correct), mutating UCI oscillates across
|
||||||
|
# wifi reloads. Logging the mismatch is enough — LuCI display patch (wireless.js
|
||||||
|
# getActiveSSID) makes the UI match iwinfo truth regardless of UCI labels.
|
||||||
|
# Triggered by rc.local at boot and mtwifi_cfg dispatcher tail.
|
||||||
|
# Commit-only would still be loop-safe, but useless: detection is non-deterministic
|
||||||
|
# across reloads, so any commit causes oscillation. Log-only is structurally stable.
|
||||||
|
|
||||||
|
LOCK=/tmp/wifi-band-verify.lock
|
||||||
|
NOW=$(date +%s)
|
||||||
|
if [ -f "$LOCK" ]; then
|
||||||
|
LAST=$(cat "$LOCK" 2>/dev/null)
|
||||||
|
[ -n "$LAST" ] && [ $((NOW - LAST)) -lt 120 ] && exit 0
|
||||||
|
fi
|
||||||
|
echo "$NOW" > "$LOCK"
|
||||||
|
|
||||||
|
log() { logger -t wifi-band-verify -- "$*"; }
|
||||||
|
|
||||||
|
get_ch() { iwinfo "$1" info 2>/dev/null | awk '/Channel:/ {print $4}'; }
|
||||||
|
get_essid(){ iwinfo "$1" info 2>/dev/null | awk -F"\x22" '/ESSID:/ {print $2}'; }
|
||||||
|
|
||||||
|
# Phase 1: wait until both radios report identical channels on two consecutive
|
||||||
|
# 10s probes (guards against mid-init transient reads; max 18 rounds = 3min).
|
||||||
|
ra0ch=""; rax0ch=""; stable=0; i=0
|
||||||
|
while [ $i -lt 18 ]; do
|
||||||
|
c1=$(get_ch ra0); c2=$(get_ch rax0)
|
||||||
|
case "$c1" in ""|*[!0-9]*) c1="" ;; esac
|
||||||
|
case "$c2" in ""|*[!0-9]*) c2="" ;; esac
|
||||||
|
if [ -n "$c1" ] && [ -n "$c2" ] && [ "$c1" = "$ra0ch" ] && [ "$c2" = "$rax0ch" ]; then
|
||||||
|
stable=1; break
|
||||||
|
fi
|
||||||
|
ra0ch=$c1; rax0ch=$c2
|
||||||
|
i=$((i+1)); sleep 10
|
||||||
|
done
|
||||||
|
[ $stable -eq 1 ] || { log "radios not stable after 3min; skipped"; exit 0; }
|
||||||
|
|
||||||
|
# Phase 2: physical band from channel (2g ≤14, 5g ≥36)
|
||||||
|
band_of() { [ "$1" -le 14 ] && echo 2g || echo 5g; }
|
||||||
|
ra0band=$(band_of "$ra0ch"); rax0band=$(band_of "$rax0ch")
|
||||||
|
[ "$ra0band" = "$rax0band" ] && { log "both radios on $ra0band ch$ra0ch/$rax0ch; abnormal"; exit 0; }
|
||||||
|
|
||||||
|
# Phase 3: read UCI labels and live ESSIDs, log verdict — NO mutation.
|
||||||
|
uci -q get wireless.MT7981_1_1 >/dev/null || exit 0
|
||||||
|
uci -q get wireless.MT7981_1_2 >/dev/null || exit 0
|
||||||
|
u1=$(uci -q get wireless.MT7981_1_1.band)
|
||||||
|
u2=$(uci -q get wireless.MT7981_1_2.band)
|
||||||
|
s1=$(uci -q get wireless.default_MT7981_1_1.ssid)
|
||||||
|
s2=$(uci -q get wireless.default_MT7981_1_2.ssid)
|
||||||
|
e1=$(get_essid ra0); e2=$(get_essid rax0)
|
||||||
|
|
||||||
|
if [ "$u1" = "$ra0band" ] && [ "$u2" = "$rax0band" ] && [ "$s1" = "$e1" ] && [ "$s2" = "$e2" ]; then
|
||||||
|
log "consistent: ra0=$ra0band ch$ra0ch [$e1], rax0=$rax0band ch$rax0ch [$e2]; uci=$u1/$u2"
|
||||||
|
else
|
||||||
|
log "MISMATCH (no-op): ra0=$ra0band ch$ra0ch [$e1], rax0=$rax0band ch$rax0ch [$e2]; uci=$u1/$u2 ssid=$s1/$s2"
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,440 @@
|
|||||||
|
NETIFD_MAIN_DIR="${NETIFD_MAIN_DIR:-/lib/netifd}"
|
||||||
|
|
||||||
|
. /usr/share/libubox/jshn.sh
|
||||||
|
. $NETIFD_MAIN_DIR/utils.sh
|
||||||
|
|
||||||
|
CMD_UP=0
|
||||||
|
CMD_SET_DATA=1
|
||||||
|
CMD_PROCESS_ADD=2
|
||||||
|
CMD_PROCESS_KILL_ALL=3
|
||||||
|
CMD_SET_RETRY=4
|
||||||
|
|
||||||
|
add_driver() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
wireless_setup_vif_failed() {
|
||||||
|
local error="$1"
|
||||||
|
echo "Interface $_w_iface setup failed: $error"
|
||||||
|
}
|
||||||
|
|
||||||
|
wireless_setup_failed() {
|
||||||
|
local error="$1"
|
||||||
|
|
||||||
|
echo "Device setup failed: $error"
|
||||||
|
wireless_set_retry 0
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare_key_wep() {
|
||||||
|
local key="$1"
|
||||||
|
local hex=1
|
||||||
|
|
||||||
|
echo -n "$key" | grep -qE "[^a-fA-F0-9]" && hex=0
|
||||||
|
[ "${#key}" -eq 10 -a $hex -eq 1 ] || \
|
||||||
|
[ "${#key}" -eq 26 -a $hex -eq 1 ] || {
|
||||||
|
[ "${key:0:2}" = "s:" ] && key="${key#s:}"
|
||||||
|
key="$(echo -n "$key" | hexdump -ve '1/1 "%02x" ""')"
|
||||||
|
}
|
||||||
|
echo "$key"
|
||||||
|
}
|
||||||
|
|
||||||
|
_wdev_prepare_channel() {
|
||||||
|
json_get_vars channel band hwmode
|
||||||
|
|
||||||
|
auto_channel=0
|
||||||
|
enable_ht=0
|
||||||
|
htmode=
|
||||||
|
hwmode="${hwmode##11}"
|
||||||
|
|
||||||
|
case "$channel" in
|
||||||
|
""|0|auto)
|
||||||
|
channel=0
|
||||||
|
auto_channel=1
|
||||||
|
;;
|
||||||
|
[0-9]*) ;;
|
||||||
|
*)
|
||||||
|
wireless_setup_failed "INVALID_CHANNEL"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$hwmode" in
|
||||||
|
a|b|g|ad) ;;
|
||||||
|
*)
|
||||||
|
if [ "$channel" -gt 14 ]; then
|
||||||
|
hwmode=a
|
||||||
|
else
|
||||||
|
hwmode=g
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$band" in
|
||||||
|
2g) hwmode=g;;
|
||||||
|
5g|6g) hwmode=a;;
|
||||||
|
60g) hwmode=ad;;
|
||||||
|
*)
|
||||||
|
case "$hwmode" in
|
||||||
|
*a) band=5g;;
|
||||||
|
*ad) band=60g;;
|
||||||
|
*b|*g) band=2g;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
_wdev_handler() {
|
||||||
|
json_load "$data"
|
||||||
|
|
||||||
|
json_select config
|
||||||
|
_wdev_prepare_channel
|
||||||
|
json_select ..
|
||||||
|
|
||||||
|
eval "drv_$1_$2 \"$interface\""
|
||||||
|
}
|
||||||
|
|
||||||
|
_wdev_msg_call() {
|
||||||
|
local old_cb
|
||||||
|
|
||||||
|
json_set_namespace wdev old_cb
|
||||||
|
"$@"
|
||||||
|
json_set_namespace $old_cb
|
||||||
|
}
|
||||||
|
|
||||||
|
_wdev_wrapper() {
|
||||||
|
while [ -n "$1" ]; do
|
||||||
|
eval "$1() { _wdev_msg_call _$1 \"\$@\"; }"
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_wdev_notify_init() {
|
||||||
|
local command="$1"; shift;
|
||||||
|
|
||||||
|
json_init
|
||||||
|
json_add_int "command" "$command"
|
||||||
|
json_add_string "device" "$__netifd_device"
|
||||||
|
while [ -n "$1" ]; do
|
||||||
|
local name="$1"; shift
|
||||||
|
local value="$1"; shift
|
||||||
|
json_add_string "$name" "$value"
|
||||||
|
done
|
||||||
|
json_add_object "data"
|
||||||
|
}
|
||||||
|
|
||||||
|
_wdev_notify() {
|
||||||
|
local options="$1"
|
||||||
|
|
||||||
|
json_close_object
|
||||||
|
ubus $options call network.wireless notify "$(json_dump)"
|
||||||
|
}
|
||||||
|
|
||||||
|
_wdev_add_variables() {
|
||||||
|
while [ -n "$1" ]; do
|
||||||
|
local var="${1%%=*}"
|
||||||
|
local val="$1"
|
||||||
|
shift
|
||||||
|
[[ "$var" = "$val" ]] && continue
|
||||||
|
val="${val#*=}"
|
||||||
|
json_add_string "$var" "$val"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_wireless_add_vif() {
|
||||||
|
local name="$1"; shift
|
||||||
|
local ifname="$1"; shift
|
||||||
|
|
||||||
|
_wdev_notify_init $CMD_SET_DATA "interface" "$name"
|
||||||
|
json_add_string "ifname" "$ifname"
|
||||||
|
_wdev_add_variables "$@"
|
||||||
|
_wdev_notify
|
||||||
|
}
|
||||||
|
|
||||||
|
_wireless_add_vlan() {
|
||||||
|
local name="$1"; shift
|
||||||
|
local ifname="$1"; shift
|
||||||
|
|
||||||
|
_wdev_notify_init $CMD_SET_DATA interface "$__cur_interface" "vlan" "$name"
|
||||||
|
json_add_string "ifname" "$ifname"
|
||||||
|
_wdev_add_variables "$@"
|
||||||
|
_wdev_notify
|
||||||
|
}
|
||||||
|
|
||||||
|
_wireless_set_up() {
|
||||||
|
_wdev_notify_init $CMD_UP
|
||||||
|
_wdev_notify
|
||||||
|
}
|
||||||
|
|
||||||
|
_wireless_set_data() {
|
||||||
|
_wdev_notify_init $CMD_SET_DATA
|
||||||
|
_wdev_add_variables "$@"
|
||||||
|
_wdev_notify
|
||||||
|
}
|
||||||
|
|
||||||
|
_wireless_add_process() {
|
||||||
|
_wdev_notify_init $CMD_PROCESS_ADD
|
||||||
|
local exe="$2"
|
||||||
|
[ -L "$exe" ] && exe="$(readlink -f "$exe")"
|
||||||
|
json_add_int pid "$1"
|
||||||
|
json_add_string exe "$exe"
|
||||||
|
[ -n "$3" ] && json_add_boolean required 1
|
||||||
|
[ -n "$4" ] && json_add_boolean keep 1
|
||||||
|
exe2="$(readlink -f /proc/$1/exe)"
|
||||||
|
[ "$exe" != "$exe2" ] && echo "WARNING (wireless_add_process): executable path $exe does not match process $1 path ($exe2)"
|
||||||
|
_wdev_notify
|
||||||
|
}
|
||||||
|
|
||||||
|
_wireless_process_kill_all() {
|
||||||
|
_wdev_notify_init $CMD_PROCESS_KILL_ALL
|
||||||
|
[ -n "$1" ] && json_add_int signal "$1"
|
||||||
|
_wdev_notify
|
||||||
|
}
|
||||||
|
|
||||||
|
_wireless_set_retry() {
|
||||||
|
_wdev_notify_init $CMD_SET_RETRY
|
||||||
|
json_add_int retry "$1"
|
||||||
|
_wdev_notify
|
||||||
|
}
|
||||||
|
|
||||||
|
_wdev_wrapper \
|
||||||
|
wireless_add_vif \
|
||||||
|
wireless_add_vlan \
|
||||||
|
wireless_set_up \
|
||||||
|
wireless_set_data \
|
||||||
|
wireless_add_process \
|
||||||
|
wireless_process_kill_all \
|
||||||
|
wireless_set_retry \
|
||||||
|
|
||||||
|
wireless_vif_parse_encryption() {
|
||||||
|
json_get_vars encryption
|
||||||
|
set_default encryption none
|
||||||
|
|
||||||
|
auth_mode_open=1
|
||||||
|
auth_mode_shared=0
|
||||||
|
auth_type=none
|
||||||
|
|
||||||
|
if [ "$hwmode" = "ad" ]; then
|
||||||
|
wpa_cipher="GCMP"
|
||||||
|
else
|
||||||
|
wpa_cipher="CCMP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$encryption" in
|
||||||
|
*tkip+aes|*tkip+ccmp|*aes+tkip|*ccmp+tkip) wpa_cipher="CCMP TKIP";;
|
||||||
|
*ccmp256) wpa_cipher="CCMP-256";;
|
||||||
|
*aes|*ccmp) wpa_cipher="CCMP";;
|
||||||
|
*tkip) wpa_cipher="TKIP";;
|
||||||
|
*gcmp256) wpa_cipher="GCMP-256";;
|
||||||
|
*gcmp) wpa_cipher="GCMP";;
|
||||||
|
wpa3-192*) wpa_cipher="GCMP-256";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# 802.11n requires CCMP for WPA
|
||||||
|
[ "$enable_ht:$wpa_cipher" = "1:TKIP" ] && wpa_cipher="CCMP TKIP"
|
||||||
|
|
||||||
|
# Examples:
|
||||||
|
# psk-mixed/tkip => WPA1+2 PSK, TKIP
|
||||||
|
# wpa-psk2/tkip+aes => WPA2 PSK, CCMP+TKIP
|
||||||
|
# wpa2/tkip+aes => WPA2 RADIUS, CCMP+TKIP
|
||||||
|
|
||||||
|
case "$encryption" in
|
||||||
|
wpa2*|wpa3*|*psk2*|psk3*|sae*|owe*)
|
||||||
|
wpa=2
|
||||||
|
;;
|
||||||
|
wpa*mixed*|*psk*mixed*)
|
||||||
|
wpa=3
|
||||||
|
;;
|
||||||
|
wpa*|*psk*)
|
||||||
|
wpa=1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
wpa=0
|
||||||
|
wpa_cipher=
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
wpa_pairwise="$wpa_cipher"
|
||||||
|
|
||||||
|
case "$encryption" in
|
||||||
|
owe*)
|
||||||
|
auth_type=owe
|
||||||
|
;;
|
||||||
|
wpa3-192*)
|
||||||
|
auth_type=eap192
|
||||||
|
;;
|
||||||
|
wpa3-mixed*)
|
||||||
|
auth_type=eap-eap2
|
||||||
|
;;
|
||||||
|
wpa3*)
|
||||||
|
auth_type=eap2
|
||||||
|
;;
|
||||||
|
psk3-mixed*|sae-mixed*)
|
||||||
|
auth_type=psk-sae
|
||||||
|
;;
|
||||||
|
psk3*|sae*)
|
||||||
|
auth_type=sae
|
||||||
|
;;
|
||||||
|
*psk*)
|
||||||
|
auth_type=psk
|
||||||
|
;;
|
||||||
|
*wpa*|*8021x*)
|
||||||
|
auth_type=eap
|
||||||
|
;;
|
||||||
|
*wep*)
|
||||||
|
auth_type=wep
|
||||||
|
case "$encryption" in
|
||||||
|
*shared*)
|
||||||
|
auth_mode_open=0
|
||||||
|
auth_mode_shared=1
|
||||||
|
;;
|
||||||
|
*mixed*)
|
||||||
|
auth_mode_shared=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$encryption" in
|
||||||
|
*osen*)
|
||||||
|
auth_osen=1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
_wireless_set_brsnoop_isolation() {
|
||||||
|
local multicast_to_unicast="$1"
|
||||||
|
local isolate
|
||||||
|
|
||||||
|
json_get_vars isolate proxy_arp
|
||||||
|
|
||||||
|
[ ${isolate:-0} -gt 0 -o -z "$network_bridge" ] && return
|
||||||
|
[ ${multicast_to_unicast:-1} -gt 0 -o ${proxy_arp:-0} -gt 0 ] && json_add_boolean isolate 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each_interface() {
|
||||||
|
local _w_types="$1"; shift
|
||||||
|
local _w_ifaces _w_iface
|
||||||
|
local _w_type
|
||||||
|
local _w_found
|
||||||
|
|
||||||
|
local multicast_to_unicast
|
||||||
|
|
||||||
|
json_get_keys _w_ifaces interfaces
|
||||||
|
json_select interfaces
|
||||||
|
for _w_iface in $_w_ifaces; do
|
||||||
|
json_select "$_w_iface"
|
||||||
|
if [ -n "$_w_types" ]; then
|
||||||
|
json_get_var network_bridge bridge
|
||||||
|
json_get_var network_ifname bridge-ifname
|
||||||
|
json_get_var multicast_to_unicast multicast_to_unicast
|
||||||
|
json_select config
|
||||||
|
_wireless_set_brsnoop_isolation "$multicast_to_unicast"
|
||||||
|
json_get_var _w_type mode
|
||||||
|
json_select ..
|
||||||
|
_w_types=" $_w_types "
|
||||||
|
[[ "${_w_types%$_w_type*}" = "$_w_types" ]] && {
|
||||||
|
json_select ..
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
__cur_interface="$_w_iface"
|
||||||
|
"$@" "$_w_iface"
|
||||||
|
json_select ..
|
||||||
|
done
|
||||||
|
json_select ..
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each_vlan() {
|
||||||
|
local _w_vlans _w_vlan
|
||||||
|
|
||||||
|
json_get_keys _w_vlans vlans
|
||||||
|
json_select vlans
|
||||||
|
for _w_vlan in $_w_vlans; do
|
||||||
|
json_select "$_w_vlan"
|
||||||
|
json_select config
|
||||||
|
"$@" "$_w_vlan"
|
||||||
|
json_select ..
|
||||||
|
json_select ..
|
||||||
|
done
|
||||||
|
json_select ..
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each_station() {
|
||||||
|
local _w_stas _w_sta
|
||||||
|
|
||||||
|
json_get_keys _w_stas stas
|
||||||
|
json_select stas
|
||||||
|
for _w_sta in $_w_stas; do
|
||||||
|
json_select "$_w_sta"
|
||||||
|
json_select config
|
||||||
|
"$@" "$_w_sta"
|
||||||
|
json_select ..
|
||||||
|
json_select ..
|
||||||
|
done
|
||||||
|
json_select ..
|
||||||
|
}
|
||||||
|
|
||||||
|
_wdev_common_device_config() {
|
||||||
|
config_add_string channel hwmode band htmode noscan
|
||||||
|
}
|
||||||
|
|
||||||
|
_wdev_common_iface_config() {
|
||||||
|
config_add_string mode ssid encryption 'key:wpakey'
|
||||||
|
config_add_boolean bridge_isolate
|
||||||
|
config_add_array tags
|
||||||
|
}
|
||||||
|
|
||||||
|
_wdev_common_vlan_config() {
|
||||||
|
config_add_string name vid iface
|
||||||
|
config_add_boolean bridge_isolate
|
||||||
|
}
|
||||||
|
|
||||||
|
_wdev_common_station_config() {
|
||||||
|
config_add_string mac key vid iface
|
||||||
|
}
|
||||||
|
|
||||||
|
init_wireless_driver() {
|
||||||
|
name="$1"; shift
|
||||||
|
cmd="$1"; shift
|
||||||
|
|
||||||
|
case "$cmd" in
|
||||||
|
dump)
|
||||||
|
add_driver() {
|
||||||
|
eval "drv_$1_cleanup"
|
||||||
|
|
||||||
|
json_init
|
||||||
|
json_add_string name "$1"
|
||||||
|
|
||||||
|
json_add_array device
|
||||||
|
_wdev_common_device_config
|
||||||
|
eval "drv_$1_init_device_config"
|
||||||
|
json_close_array
|
||||||
|
|
||||||
|
json_add_array iface
|
||||||
|
_wdev_common_iface_config
|
||||||
|
eval "drv_$1_init_iface_config"
|
||||||
|
json_close_array
|
||||||
|
|
||||||
|
json_add_array vlan
|
||||||
|
_wdev_common_vlan_config
|
||||||
|
eval "drv_$1_init_vlan_config"
|
||||||
|
json_close_array
|
||||||
|
|
||||||
|
json_add_array station
|
||||||
|
_wdev_common_station_config
|
||||||
|
eval "drv_$1_init_station_config"
|
||||||
|
json_close_array
|
||||||
|
|
||||||
|
json_dump
|
||||||
|
}
|
||||||
|
;;
|
||||||
|
setup|teardown)
|
||||||
|
interface="$1"; shift
|
||||||
|
data="$1"; shift
|
||||||
|
export __netifd_device="$interface"
|
||||||
|
|
||||||
|
add_driver() {
|
||||||
|
[[ "$name" == "$1" ]] || return 0
|
||||||
|
_wdev_handler "$1" "$cmd"
|
||||||
|
}
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
+1380
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,698 @@
|
|||||||
|
#!/usr/bin/lua
|
||||||
|
--[[
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023 hanwckf <hanwckf@vip.qq.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* The Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
]]
|
||||||
|
|
||||||
|
local cjson = require "cjson"
|
||||||
|
local inspect = require "inspect"
|
||||||
|
local nixio = require "nixio"
|
||||||
|
local l1parser = require "l1dat_parser"
|
||||||
|
local datconf = require "datconf"
|
||||||
|
local utils = require "mtwifi_utils"
|
||||||
|
local defs = require "mtwifi_defs"
|
||||||
|
|
||||||
|
local l1dat = l1parser.load_l1_profile(l1parser.L1_DAT_PATH)
|
||||||
|
|
||||||
|
function string:split(sep)
|
||||||
|
local sep, fields = sep or ":", {}
|
||||||
|
local pattern = string.format("([^%s]+)", sep)
|
||||||
|
self:gsub(pattern, function(c) fields[#fields+1] = c end)
|
||||||
|
return fields
|
||||||
|
end
|
||||||
|
|
||||||
|
function load_profile(path)
|
||||||
|
local cfgs = {}
|
||||||
|
|
||||||
|
cfgobj = datconf.openfile(path)
|
||||||
|
if cfgobj then
|
||||||
|
cfgs = cfgobj:getall()
|
||||||
|
cfgobj:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
return cfgs
|
||||||
|
end
|
||||||
|
|
||||||
|
function save_profile(cfgs, path)
|
||||||
|
if not cfgs then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local datobj = datconf.openfile(path)
|
||||||
|
datobj:merge(cfgs)
|
||||||
|
datobj:close(true)
|
||||||
|
|
||||||
|
os.execute("sync")
|
||||||
|
end
|
||||||
|
|
||||||
|
function diff_cfg(cfg1, cfg2)
|
||||||
|
local diff = {}
|
||||||
|
|
||||||
|
for k,v in pairs(cfg1) do
|
||||||
|
if tostring(cfg2[k]) ~= tostring(cfg1[k]) then
|
||||||
|
diff[k] = {cfg1[k] or "", cfg2[k] or ""}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for k,v in pairs(cfg2) do
|
||||||
|
if tostring(cfg2[k]) ~= tostring(cfg1[k]) then
|
||||||
|
diff[k] = {cfg1[k] or "", cfg2[k] or ""}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return diff
|
||||||
|
end
|
||||||
|
|
||||||
|
function vif_status(ifname)
|
||||||
|
local flags = tonumber(utils.read_pipe("cat /sys/class/net/"..ifname.."/flags 2>/dev/null")) or 0
|
||||||
|
if flags%2 == 1 then
|
||||||
|
return "up"
|
||||||
|
end
|
||||||
|
return "down"
|
||||||
|
end
|
||||||
|
|
||||||
|
function is_dbdc_inited(ifname)
|
||||||
|
local mac = utils.trim(utils.read_pipe("cat /sys/class/net/"..ifname.."/address 2>/dev/null"))
|
||||||
|
if mac and mac ~= "00:00:00:00:00:00" then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function ifup(ifname)
|
||||||
|
if ifname and #ifname > 0 then
|
||||||
|
os.execute("ifconfig "..ifname.." up")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ifdown(ifname)
|
||||||
|
if ifname and #ifname > 0 then
|
||||||
|
os.execute("ifconfig "..ifname.." down")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function cfg2dat(cfg)
|
||||||
|
if type(cfg) == type(true) then
|
||||||
|
if cfg then return 1 else return 0 end
|
||||||
|
elseif type(cfg) == type(0) or type(cfg) == type("") then
|
||||||
|
return cfg
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function set_dev_dat(dats, dat, cfg)
|
||||||
|
if cfg ~= nil then
|
||||||
|
dats[dat] = cfg2dat(cfg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function set_dat(dats, apidx, dat, cfg)
|
||||||
|
if cfg ~= nil then
|
||||||
|
dats[dat] = utils.token_set(dats[dat], apidx, cfg2dat(cfg))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function set_idx_dat(dats, apidx, dat, cfg)
|
||||||
|
if cfg ~= nil then
|
||||||
|
dats[dat..tostring(apidx)] = cfg
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function vif_in_dev(vif, dev)
|
||||||
|
if (vif == dev.main_ifname
|
||||||
|
or string.match(vif, utils.esc(dev.ext_ifname).."[0-9]+")
|
||||||
|
or string.match(vif, utils.esc(dev.apcli_ifname).."[0-9]+")
|
||||||
|
or string.match(vif, utils.esc(dev.wds_ifname).."[0-9]+")
|
||||||
|
or string.match(vif, utils.esc(dev.mesh_ifname).."[0-9]+")) then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function vif_is_apcli(vif, dev)
|
||||||
|
if (string.match(vif, utils.esc(dev.apcli_ifname).."[0-9]+")) then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function vif_count(cfg)
|
||||||
|
local vif_num = 0
|
||||||
|
local ap_num = 0
|
||||||
|
local apcli_num = 0
|
||||||
|
|
||||||
|
for k,v in pairs(cfg.interfaces) do
|
||||||
|
vif_num = vif_num + 1
|
||||||
|
if v.config.mode == "ap" then
|
||||||
|
ap_num = ap_num + 1
|
||||||
|
elseif v.config.mode == "sta" then
|
||||||
|
apcli_num = apcli_num +1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return vif_num, ap_num, apcli_num
|
||||||
|
end
|
||||||
|
|
||||||
|
function mtwifi_cfg_foreach_vif(cfg, mode, func)
|
||||||
|
if cfg == nil or func == nil then return end
|
||||||
|
|
||||||
|
local vif_num,_,_ = vif_count(cfg)
|
||||||
|
for idx=0,vif_num-1 do
|
||||||
|
local v = cfg.interfaces[tostring(idx)]
|
||||||
|
if v.config.mode and v.config.mode == mode then
|
||||||
|
func(v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function __apcli_auto_connect(ifname)
|
||||||
|
__exec_iwpriv_cmd(ifname, "ApCliEnable", "1")
|
||||||
|
__exec_iwpriv_cmd(ifname, "ApCliAutoConnect", "3")
|
||||||
|
end
|
||||||
|
|
||||||
|
function mtwifi_up(devname, cfg, restore_vifs, is_dbdc)
|
||||||
|
nixio.syslog("info", "mtwifi-cfg: start "..devname)
|
||||||
|
local dev = l1dat.devname_ridx[devname]
|
||||||
|
local dbdc_main_ifname = defs.dbdc_init_ifname
|
||||||
|
|
||||||
|
if not dev then return end
|
||||||
|
|
||||||
|
if is_dbdc then
|
||||||
|
if not is_dbdc_inited(dbdc_main_ifname) then
|
||||||
|
nixio.syslog("info", "mtwifi-cfg: dbdc card init...")
|
||||||
|
ifup(dbdc_main_ifname)
|
||||||
|
utils.sleep(1)
|
||||||
|
ifdown(dbdc_main_ifname)
|
||||||
|
end
|
||||||
|
|
||||||
|
if restore_vifs and devname ~= cfg.device then
|
||||||
|
-- restart ap vif
|
||||||
|
for _,vif in ipairs(restore_vifs) do
|
||||||
|
if vif_in_dev(vif, dev) and (not vif_is_apcli(vif, dev)) then
|
||||||
|
nixio.syslog("info", "mtwifi-cfg: restore ap vif: "..vif)
|
||||||
|
ifup(vif)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- restart apcli vif
|
||||||
|
for _,vif in ipairs(restore_vifs) do
|
||||||
|
if vif_is_apcli(vif, dev) then
|
||||||
|
nixio.syslog("info", "mtwifi-cfg: restore apcli vif: "..vif)
|
||||||
|
ifup(vif)
|
||||||
|
__apcli_auto_connect(vif)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local start_vif = function(v)
|
||||||
|
if (not v.config.disabled) and v.mtwifi_ifname then
|
||||||
|
local vif = v.mtwifi_ifname
|
||||||
|
nixio.syslog("info", "mtwifi-cfg: up vif: "..vif)
|
||||||
|
ifup(vif)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
mtwifi_cfg_foreach_vif(cfg, "ap", start_vif)
|
||||||
|
mtwifi_cfg_foreach_vif(cfg, "sta", start_vif)
|
||||||
|
os.execute("startwapp.sh")
|
||||||
|
end
|
||||||
|
|
||||||
|
function mtwifi_down(devname, cfg)
|
||||||
|
nixio.syslog("info", "mtwifi-cfg: stop "..devname)
|
||||||
|
local dev = l1dat.devname_ridx[devname]
|
||||||
|
local reset_vifs = {}
|
||||||
|
|
||||||
|
if not dev then return end
|
||||||
|
|
||||||
|
for _,vif in ipairs(string.split(utils.read_pipe("ls /sys/class/net"), "\n")) do
|
||||||
|
if (vif_status(vif) == "up" and vif_in_dev(vif, dev)) then
|
||||||
|
nixio.syslog("info", "mtwifi-cfg: down vif: "..vif)
|
||||||
|
ifdown(vif)
|
||||||
|
if cfg and devname ~= cfg.device then
|
||||||
|
reset_vifs[#reset_vifs+1] = vif
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
os.execute("startwapp.sh")
|
||||||
|
return reset_vifs
|
||||||
|
end
|
||||||
|
|
||||||
|
function mtwifi_reinstall()
|
||||||
|
nixio.syslog("info", "mtwifi-cfg: unload mtwifi module...")
|
||||||
|
|
||||||
|
--os.execute("rmmod mt_whnat")
|
||||||
|
--os.execute("rmmod mtfwd")
|
||||||
|
os.execute("rmmod mtk_warp_proxy")
|
||||||
|
os.execute("rmmod mtk_warp")
|
||||||
|
--os.execute("rmmod mt7915_mt_wifi")
|
||||||
|
os.execute("rmmod mt_wifi")
|
||||||
|
|
||||||
|
utils.sleep(2)
|
||||||
|
|
||||||
|
nixio.syslog("info", "mtwifi-cfg: reload mtwifi module...")
|
||||||
|
|
||||||
|
os.execute("modprobe mt_wifi")
|
||||||
|
--os.execute("modprobe mt7915_mt_wifi")
|
||||||
|
os.execute("modprobe mtk_warp")
|
||||||
|
os.execute("modprobe mtk_warp_proxy")
|
||||||
|
--os.execute("modprobe mtfwd")
|
||||||
|
--os.execute("modprobe mt_whnat")
|
||||||
|
end
|
||||||
|
|
||||||
|
function __exec_iwpriv_cmd(ifname, key, val)
|
||||||
|
local cmd = string.format("iwpriv %s set %s=%s", ifname, key, tostring(val))
|
||||||
|
nixio.syslog("info", "mtwifi-cfg: iwpriv cmd: "..cmd)
|
||||||
|
os.execute(cmd)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mtwifi_cfg_iwpriv_hook(cfg)
|
||||||
|
local ap_hook = function(v)
|
||||||
|
if (not v.config.disabled) and v.mtwifi_ifname then
|
||||||
|
local vif = v.mtwifi_ifname
|
||||||
|
for k, j in pairs(defs.iwpriv_ap_cfgs) do
|
||||||
|
__exec_iwpriv_cmd(vif, j[1], v.config[k] or j[2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local apcli_hook = function(v)
|
||||||
|
if (not v.config.disabled) and v.mtwifi_ifname then
|
||||||
|
local vif = v.mtwifi_ifname
|
||||||
|
__apcli_auto_connect(vif)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
mtwifi_cfg_foreach_vif(cfg, "ap", ap_hook)
|
||||||
|
mtwifi_cfg_foreach_vif(cfg, "sta", apcli_hook)
|
||||||
|
end
|
||||||
|
|
||||||
|
function set_chip_cfg(cfg, dats)
|
||||||
|
local dev_dats
|
||||||
|
local uci
|
||||||
|
local dat_key
|
||||||
|
|
||||||
|
if not cfg.config.dbdc_main then return end
|
||||||
|
|
||||||
|
for k,v in pairs(defs.chip_cfgs) do
|
||||||
|
uci = k
|
||||||
|
dat_key = v[1]
|
||||||
|
|
||||||
|
-- reset chip cfgs to default
|
||||||
|
dats[dat_key] = v[2]
|
||||||
|
|
||||||
|
-- setup current dev cfg
|
||||||
|
set_dev_dat(dats, dat_key, cfg.config[uci])
|
||||||
|
end
|
||||||
|
|
||||||
|
-- setup other dev cfg
|
||||||
|
for k,v in pairs(l1dat.devname_ridx) do
|
||||||
|
if k ~= cfg.device then
|
||||||
|
dev_dats = load_profile(v.profile_path)
|
||||||
|
if dev_dats then
|
||||||
|
for _,j in pairs(defs.chip_cfgs) do
|
||||||
|
dat_key = j[1]
|
||||||
|
set_dev_dat(dev_dats, dat_key, dats[dat_key])
|
||||||
|
end
|
||||||
|
save_profile(dev_dats, v.profile_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function mtwifi_cfg_setup(argv)
|
||||||
|
local cfg = cjson.decode(argv)
|
||||||
|
|
||||||
|
utils.log2file("input = " .. inspect(cfg))
|
||||||
|
|
||||||
|
local devname = cfg.device
|
||||||
|
local dev = l1dat.devname_ridx[devname]
|
||||||
|
|
||||||
|
if not dev then return end
|
||||||
|
|
||||||
|
local profile = dev.profile_path
|
||||||
|
|
||||||
|
local dats = load_profile(profile)
|
||||||
|
if not dats then
|
||||||
|
nixio.syslog("err", "mtwifi-cfg: profile ".. profile .. "open failed")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local dats_orig = load_profile(profile)
|
||||||
|
|
||||||
|
local vif_num, bssid_num, apcli_num = vif_count(cfg)
|
||||||
|
|
||||||
|
if vif_num == 0 then
|
||||||
|
nixio.syslog("err", "mtwifi-cfg: not valid vif found!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if bssid_num > defs.max_mbssid then
|
||||||
|
nixio.syslog("err", "mtwifi-cfg: too many vifs!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if apcli_num > 1 then
|
||||||
|
nixio.syslog("err", "mtwifi-cfg: only support one apcli vif!")
|
||||||
|
end
|
||||||
|
|
||||||
|
if bssid_num > 0 then
|
||||||
|
dats.BssidNum = bssid_num
|
||||||
|
else
|
||||||
|
dats.BssidNum = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- setup apcli
|
||||||
|
dats.ApCliEnable = 0
|
||||||
|
dats.ApCliSsid = ""
|
||||||
|
dats.ApCliBssid = ""
|
||||||
|
dats.ApCliAuthMode = ""
|
||||||
|
dats.ApCliEncrypType = ""
|
||||||
|
dats.ApCliWPAPSK = ""
|
||||||
|
dats.ApCliPMFMFPC = 0
|
||||||
|
dats.ApCliPMFMFPR = 0
|
||||||
|
dats.ApCliPMFSHA256 = 0
|
||||||
|
|
||||||
|
for _,v in pairs(cfg.interfaces) do
|
||||||
|
if v.config.mode == "sta" then
|
||||||
|
if not v.config.disabled then
|
||||||
|
dats.ApCliEnable = 1
|
||||||
|
end
|
||||||
|
dats.ApCliSsid = v.config.ssid or ""
|
||||||
|
dats.ApCliBssid = v.config.bssid or ""
|
||||||
|
dats.ApCliAuthMode = defs.enc2dat[v.config.encryption][1]
|
||||||
|
dats.ApCliEncrypType = defs.enc2dat[v.config.encryption][2]
|
||||||
|
dats.ApCliWPAPSK = v.config.key or ""
|
||||||
|
|
||||||
|
if dats.ApCliAuthMode == "OWE" or dats.ApCliAuthMode == "WPA3PSK" then
|
||||||
|
dats.ApCliPMFMFPC = 1
|
||||||
|
dats.ApCliPMFMFPR = 1
|
||||||
|
dats.ApCliPMFSHA256 = 0
|
||||||
|
end
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- setup chip cfgs
|
||||||
|
set_chip_cfg(cfg, dats)
|
||||||
|
|
||||||
|
-- setup dev cfgs
|
||||||
|
if cfg.config.twt then
|
||||||
|
dats.TWTSupport = cfg.config.twt
|
||||||
|
else
|
||||||
|
dats.TWTSupport = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(cfg.config.country) == type("") and #cfg.config.country == 2 then
|
||||||
|
dats.CountryCode = cfg.config.country
|
||||||
|
if cfg.config.band == "2g" then
|
||||||
|
dats.CountryRegion = defs.countryRegions[cfg.config.country][1]
|
||||||
|
elseif cfg.config.band == "5g" then
|
||||||
|
dats.CountryRegionABand = defs.countryRegions[cfg.config.country][2]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if cfg.config.channel == "auto" then
|
||||||
|
dats.AutoChannelSelect = 3
|
||||||
|
dats.Channel = 0
|
||||||
|
else
|
||||||
|
dats.AutoChannelSelect = 0
|
||||||
|
dats.Channel = cfg.config.channel
|
||||||
|
end
|
||||||
|
|
||||||
|
if cfg.config.htmode == "HT20" or cfg.config.htmode == "VHT20" or cfg.config.htmode == "HE20" then
|
||||||
|
dats.HT_BW = 0
|
||||||
|
dats.VHT_BW = 0
|
||||||
|
elseif cfg.config.htmode == "HT40" or cfg.config.htmode == "VHT40" or cfg.config.htmode == "HE40" then
|
||||||
|
dats.HT_BW = 1
|
||||||
|
dats.VHT_BW = 0
|
||||||
|
if cfg.config.noscan ~= nil and cfg.config.noscan == "1" then
|
||||||
|
dats.HT_BSSCoexistence = 0
|
||||||
|
else
|
||||||
|
dats.HT_BSSCoexistence = 1
|
||||||
|
end
|
||||||
|
elseif cfg.config.htmode == "VHT80" or cfg.config.htmode == "HE80" then
|
||||||
|
dats.HT_BW = 1
|
||||||
|
dats.VHT_BW = 1
|
||||||
|
elseif cfg.config.htmode == "VHT160" or cfg.config.htmode == "HE160" then
|
||||||
|
dats.HT_BW = 1
|
||||||
|
dats.VHT_BW = 2
|
||||||
|
end
|
||||||
|
-- DBDC merge quirk workaround (Cudy TR3000 / MT7981B):
|
||||||
|
-- ra0/rax0 <-> dat binding is RANDOM per boot (dat.MacAddress
|
||||||
|
-- writes flip across reboots). The driver applies PHY-correct
|
||||||
|
-- band/channel/htmode/SSID per netdev regardless of which dat it
|
||||||
|
-- bound (band-content invariant), so physical broadcast is always
|
||||||
|
-- correct: ra0 broadcasts 2.4G HE40, rax0 broadcasts 5G HE160 ch36.
|
||||||
|
-- Only UCI labels vs iwinfo can disagree. mtwifi_cfg writes
|
||||||
|
-- VHT_Sec80_Channel based on cfg.config.band (not idx), so the 5g
|
||||||
|
-- profile carries Sec80=155 whether it lands in b0.dat or b1.dat;
|
||||||
|
-- the 2g profile harmlessly carries VHT_BW=2 + Sec80=155 (Sec80
|
||||||
|
-- ignored on 2.4G).
|
||||||
|
if cfg.config.band == "2g" then
|
||||||
|
dats.HT_BW = 1
|
||||||
|
dats.VHT_BW = 2
|
||||||
|
dats.VHT_Sec80_Channel = 155
|
||||||
|
elseif cfg.config.band == "5g" and (cfg.config.htmode == "HE160" or cfg.config.htmode == "VHT160") then
|
||||||
|
dats.VHT_Sec80_Channel = 155
|
||||||
|
end
|
||||||
|
|
||||||
|
if cfg.config.txpower and cfg.config.txpower < 100 then
|
||||||
|
dats.PERCENTAGEenable = 1
|
||||||
|
dats.TxPower = cfg.config.txpower
|
||||||
|
else
|
||||||
|
dats.PERCENTAGEenable = 0
|
||||||
|
dats.TxPower = 100
|
||||||
|
end
|
||||||
|
|
||||||
|
if cfg.config.mu_beamformer then
|
||||||
|
dats.ETxBfEnCond = 1
|
||||||
|
if dats.ApCliEnable == 1 then
|
||||||
|
dats.MUTxRxEnable = 3
|
||||||
|
else
|
||||||
|
dats.MUTxRxEnable = 3
|
||||||
|
end
|
||||||
|
dats.ITxBfEn = 1
|
||||||
|
else
|
||||||
|
dats.ETxBfEnCond = 0
|
||||||
|
dats.MUTxRxEnable = 0
|
||||||
|
dats.ITxBfEn = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
local WirelessMode
|
||||||
|
if cfg.config.band == "2g" then
|
||||||
|
if string.sub(cfg.config.htmode,1,2) == "HE" then
|
||||||
|
WirelessMode = 16 -- PHY_11AX_24G
|
||||||
|
else
|
||||||
|
WirelessMode = 9 -- PHY_11BGN_MIXED
|
||||||
|
end
|
||||||
|
elseif cfg.config.band == "5g" then
|
||||||
|
if string.sub(cfg.config.htmode,1,2) == "HE" then
|
||||||
|
WirelessMode = 17 -- PHY_11AX_5G
|
||||||
|
else
|
||||||
|
WirelessMode = 15 -- PHY_11VHT_N_MIXED
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- reset vif cfgs to default
|
||||||
|
for k,v in pairs(defs.vif_cfgs) do
|
||||||
|
dats[k] = ""
|
||||||
|
for i = 1, bssid_num do
|
||||||
|
dats[k] = utils.token_set(dats[k], i, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for k,v in pairs(defs.vif_cfgs_idx) do
|
||||||
|
for i = 1, defs.max_mbssid do
|
||||||
|
dats[k..tostring(i)] = ""
|
||||||
|
end
|
||||||
|
for i = 1, bssid_num do
|
||||||
|
dats[k..tostring(i)] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for k,v in pairs(defs.vif_acl) do
|
||||||
|
for i = 0, defs.max_mbssid-1 do
|
||||||
|
dats[k..tostring(i)] = ""
|
||||||
|
end
|
||||||
|
for i = 0, bssid_num-1 do
|
||||||
|
dats[k..tostring(i)] = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- setup vif cfgs
|
||||||
|
local apidx = 1
|
||||||
|
for idx = 0,vif_num-1 do
|
||||||
|
v = cfg.interfaces[tostring(idx)]
|
||||||
|
if v.config.mode == "ap" then
|
||||||
|
set_idx_dat(dats, apidx, "SSID", v.config.ssid)
|
||||||
|
set_idx_dat(dats, apidx, "WPAPSK", v.config.key or "")
|
||||||
|
set_dat(dats, apidx, "NoForwarding", 0)
|
||||||
|
set_dat(dats, apidx, "HideSSID", v.config.hidden)
|
||||||
|
set_dat(dats, apidx, "WmmCapable", v.config.wmm)
|
||||||
|
set_dat(dats, apidx, "RRMEnable", v.config.ieee80211k)
|
||||||
|
set_dat(dats, apidx, "FtSupport", v.config.ieee80211r)
|
||||||
|
set_dat(dats, apidx, "RekeyInterval", v.config.wpa_group_rekey)
|
||||||
|
set_dat(dats, apidx, "MuMimoDlEnable",0)
|
||||||
|
set_dat(dats, apidx, "MuMimoUlEnable",0)
|
||||||
|
set_dat(dats, apidx, "MuOfdmaDlEnable",v.config.ofdma_dl)
|
||||||
|
set_dat(dats, apidx, "MuOfdmaUlEnable",v.config.ofdma_ul)
|
||||||
|
set_dat(dats, apidx, "HT_AMSDU",v.config.amsdu)
|
||||||
|
set_dat(dats, apidx, "HT_AutoBA",v.config.autoba)
|
||||||
|
set_dat(dats, apidx, "APSDCapable",v.config.uapsd)
|
||||||
|
set_dat(dats, apidx, "RTSThreshold", v.config.rts)
|
||||||
|
set_dat(dats, apidx, "FragThreshold",v.config.frag)
|
||||||
|
set_dat(dats, apidx, "WirelessMode", WirelessMode)
|
||||||
|
|
||||||
|
if v.config.macfilter then
|
||||||
|
if v.config.macfilter == "allow" then
|
||||||
|
set_idx_dat(dats, apidx-1, "AccessPolicy", 1)
|
||||||
|
elseif v.config.macfilter == "deny" then
|
||||||
|
set_idx_dat(dats, apidx-1, "AccessPolicy", 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if v.config.maclist then
|
||||||
|
local maclist = ""
|
||||||
|
for i, v in ipairs(v.config.maclist) do
|
||||||
|
if i > defs.max_acl_entry then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
if #maclist > 0 then
|
||||||
|
maclist = maclist .. ";" .. v
|
||||||
|
else
|
||||||
|
maclist = v
|
||||||
|
end
|
||||||
|
end
|
||||||
|
set_idx_dat(dats, apidx-1, "AccessControlList", maclist)
|
||||||
|
end
|
||||||
|
|
||||||
|
local authmode = defs.enc2dat[v.config.encryption][1]
|
||||||
|
set_dat(dats, apidx, "AuthMode", authmode)
|
||||||
|
set_dat(dats, apidx, "EncrypType", defs.enc2dat[v.config.encryption][2])
|
||||||
|
|
||||||
|
if authmode == "OWE" or authmode == "WPA3PSK" then
|
||||||
|
set_dat(dats, apidx, "PMFMFPC", 1)
|
||||||
|
set_dat(dats, apidx, "PMFMFPR", 1)
|
||||||
|
set_dat(dats, apidx, "PMFSHA256", 0)
|
||||||
|
elseif authmode == "WPA2PSKWPA3PSK" then
|
||||||
|
set_dat(dats, apidx, "PMFMFPC", 1)
|
||||||
|
set_dat(dats, apidx, "PMFMFPR", 0)
|
||||||
|
set_dat(dats, apidx, "PMFSHA256", 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not (authmode == "OPEN" or authmode == "OWE") then
|
||||||
|
set_dat(dats, apidx, "RekeyMethod", "TIME")
|
||||||
|
end
|
||||||
|
|
||||||
|
apidx = apidx + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local reinstall_wifidrv = false
|
||||||
|
local cfg_diff = diff_cfg(dats_orig, dats)
|
||||||
|
utils.log2file("diff = " .. inspect(cfg_diff))
|
||||||
|
|
||||||
|
save_profile(dats, profile)
|
||||||
|
|
||||||
|
for _,v in pairs(defs.reinstall_cfgs) do
|
||||||
|
if cfg_diff[v] ~= nil then
|
||||||
|
if utils.exists("/sys/module/mt_wifi") == false then
|
||||||
|
nixio.syslog("err", "mtwifi-cfg: mtwifi module is build-in, please reboot the device!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
reinstall_wifidrv = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if string.find(profile, "dbdc") then
|
||||||
|
if reinstall_wifidrv then
|
||||||
|
for k, _ in pairs(l1dat.devname_ridx) do
|
||||||
|
mtwifi_down(k)
|
||||||
|
end
|
||||||
|
|
||||||
|
mtwifi_reinstall()
|
||||||
|
|
||||||
|
for k, _ in pairs(l1dat.devname_ridx) do
|
||||||
|
if k == devname then
|
||||||
|
mtwifi_up(k, cfg, nil, true)
|
||||||
|
else
|
||||||
|
os.execute("/sbin/wifi up " .. k) -- TODO: may cause deadlock
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local restore_vifs = {}
|
||||||
|
local restart_other_dbdc_dev = false
|
||||||
|
if next(cfg_diff) ~= nil then
|
||||||
|
restart_other_dbdc_dev = true
|
||||||
|
end
|
||||||
|
|
||||||
|
if restart_other_dbdc_dev then
|
||||||
|
for k, _ in pairs(l1dat.devname_ridx) do
|
||||||
|
local ret = mtwifi_down(k, cfg)
|
||||||
|
for _, v in ipairs(ret) do
|
||||||
|
table.insert(restore_vifs, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if #restore_vifs > 0 then
|
||||||
|
nixio.syslog("info", "mtwifi-cfg: dbdc restore_vifs: "..inspect.inspect(restore_vifs))
|
||||||
|
end
|
||||||
|
|
||||||
|
for k, _ in pairs(l1dat.devname_ridx) do
|
||||||
|
mtwifi_up(k, cfg, restore_vifs, true)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
mtwifi_down(devname)
|
||||||
|
mtwifi_up(devname, cfg, nil, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
mtwifi_down(devname)
|
||||||
|
|
||||||
|
if reinstall_wifidrv then
|
||||||
|
mtwifi_reinstall()
|
||||||
|
end
|
||||||
|
|
||||||
|
mtwifi_up(devname, cfg)
|
||||||
|
end
|
||||||
|
|
||||||
|
mtwifi_cfg_iwpriv_hook(cfg)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mtwifi_cfg_down(devname)
|
||||||
|
if devname then
|
||||||
|
mtwifi_down(devname)
|
||||||
|
else
|
||||||
|
for k, _ in pairs(l1dat.devname_ridx) do
|
||||||
|
mtwifi_down(k)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local action = {
|
||||||
|
["down"] = function(devname)
|
||||||
|
mtwifi_cfg_down(devname)
|
||||||
|
end,
|
||||||
|
|
||||||
|
["setup"] = function()
|
||||||
|
local argv = io.read()
|
||||||
|
if #argv > 0 then
|
||||||
|
mtwifi_cfg_setup(argv)
|
||||||
|
os.execute("( /etc/wifi-band-verify.sh >/dev/null 2>&1 & )")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
if #arg == 1 then
|
||||||
|
action[arg[1]]()
|
||||||
|
elseif #arg == 2 then
|
||||||
|
action[arg[1]](arg[2])
|
||||||
|
end
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (C) 2023, hanwckf <hanwckf@vip.qq.com>
|
||||||
|
#
|
||||||
|
# v21 2026-07-21: HONEST labels (UCI now matches physical reality).
|
||||||
|
# Driver binds profiles by MacAddress match, NOT by l1profile order:
|
||||||
|
# b0.dat (MacAddress=2.4G eeprom MAC) -> rax0 netdev (2.4G HW)
|
||||||
|
# b1.dat (MacAddress=5G eeprom MAC) -> ra0 netdev (5G HW)
|
||||||
|
# v21 additionally swaps INDEX0_profile_path in l1profile.dat to
|
||||||
|
# "b1.dat;b0.dat", so l1dat_parser maps: idx=1 (ra0) -> b1.dat,
|
||||||
|
# idx=2 (rax0) -> b0.dat. Result: each UCI section writes the DAT that
|
||||||
|
# the driver actually binds to its phy, so UCI band/ssid can be honest:
|
||||||
|
# idx=1 (ra0, 5G HW): band=5g HE160 ch 36 ssid=ImmortalWrt-5G
|
||||||
|
# idx=2 (rax0, 2.4G HW): band=2g HE40 ch auto ssid=ImmortalWrt-2.4G
|
||||||
|
# Kernel DBDC merge quirk (unchanged): VHT_BW / VHT_Sec80_Channel for
|
||||||
|
# ra0's slot are taken from b0.dat, so mtwifi_cfg still forces
|
||||||
|
# VHT_BW=2 + VHT_Sec80_Channel=155 into the band==2g profile.
|
||||||
|
# Validated live on v20 2026-07-21: ra0 2401Mbps HE160 ch36,
|
||||||
|
# rax0 HE40, DBDC_card0.dat identical to v20 working state.
|
||||||
|
|
||||||
|
append DRIVERS "mtwifi"
|
||||||
|
|
||||||
|
detect_mtwifi() {
|
||||||
|
local idx ifname
|
||||||
|
local band hwmode htmode htbsscoex ssid dbdc_main channel
|
||||||
|
if [ -d "/sys/module/mt_wifi" ]; then
|
||||||
|
dev_list="$(l1util list)"
|
||||||
|
for dev in $dev_list; do
|
||||||
|
ifname="$(l1util get ${dev} main_ifname)"
|
||||||
|
idx="$(l1util get ${dev} subidx)"
|
||||||
|
if [ $idx -eq 1 ]; then
|
||||||
|
# v29: UCI idx=1 is the 5G config. Driver maps band=5g content
|
||||||
|
# to the 5G PHY (whichever netdev it is this boot).
|
||||||
|
dbdc_main="1"
|
||||||
|
band="5g"
|
||||||
|
hwmode="11a"
|
||||||
|
htmode="HE160"
|
||||||
|
htbsscoex="0"
|
||||||
|
ssid="ImmortalWrt-5G"
|
||||||
|
txpower="100"
|
||||||
|
channel="36"
|
||||||
|
else
|
||||||
|
# v29: UCI idx=2 is the 2.4G config.
|
||||||
|
dbdc_main="0"
|
||||||
|
band="2g"
|
||||||
|
hwmode="11g"
|
||||||
|
htmode="HE40"
|
||||||
|
htbsscoex="1"
|
||||||
|
ssid="ImmortalWrt-2.4G"
|
||||||
|
txpower="100"
|
||||||
|
channel="auto"
|
||||||
|
fi
|
||||||
|
config_get type ${dev//./_} type
|
||||||
|
if [ "$type" != "mtwifi" ]; then
|
||||||
|
uci -q batch <<-EOF
|
||||||
|
set wireless.${dev//./_}=wifi-device
|
||||||
|
set wireless.${dev//./_}.type=mtwifi
|
||||||
|
set wireless.${dev//./_}.phy=${ifname}
|
||||||
|
set wireless.${dev//./_}.hwmode=${hwmode}
|
||||||
|
set wireless.${dev//./_}.band=${band}
|
||||||
|
set wireless.${dev//./_}.dbdc_main=${dbdc_main}
|
||||||
|
set wireless.${dev//./_}.channel=${channel}
|
||||||
|
set wireless.${dev//./_}.txpower=${txpower}
|
||||||
|
set wireless.${dev//./_}.htmode=${htmode}
|
||||||
|
set wireless.${dev//./_}.country=CN
|
||||||
|
set wireless.${dev//./_}.mu_beamformer=1
|
||||||
|
set wireless.${dev//./_}.noscan=${htbsscoex}
|
||||||
|
set wireless.${dev//./_}.serialize=1
|
||||||
|
|
||||||
|
set wireless.default_${dev//./_}=wifi-iface
|
||||||
|
set wireless.default_${dev//./_}.device=${dev//./_}
|
||||||
|
set wireless.default_${dev//./_}.network=lan
|
||||||
|
set wireless.default_${dev//./_}.mode=ap
|
||||||
|
set wireless.default_${dev//./_}.ssid=${ssid}
|
||||||
|
set wireless.default_${dev//./_}.encryption=none
|
||||||
|
set wireless.default_${dev//./_}.uapsd=0
|
||||||
|
EOF
|
||||||
|
else
|
||||||
|
uci -q batch <<-EOF
|
||||||
|
set wireless.${dev//./_}.phy=${ifname}
|
||||||
|
set wireless.${dev//./_}.hwmode=${hwmode}
|
||||||
|
set wireless.${dev//./_}.band=${band}
|
||||||
|
set wireless.${dev//./_}.dbdc_main=${dbdc_main}
|
||||||
|
set wireless.${dev//./_}.channel=${channel}
|
||||||
|
set wireless.${dev//./_}.htmode=${htmode}
|
||||||
|
set wireless.${dev//./_}.country=CN
|
||||||
|
set wireless.${dev//./_}.mu_beamformer=1
|
||||||
|
set wireless.${dev//./_}.noscan=${htbsscoex}
|
||||||
|
set wireless.${dev//./_}.serialize=1
|
||||||
|
set wireless.default_${dev//./_}.device=${dev//./_}
|
||||||
|
set wireless.default_${dev//./_}.network=lan
|
||||||
|
set wireless.default_${dev//./_}.mode=ap
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
uci -q commit wireless
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
@@ -0,0 +1,194 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023, hanwckf <hanwckf@vip.qq.com>
|
||||||
|
#
|
||||||
|
|
||||||
|
. /lib/netifd/netifd-wireless.sh
|
||||||
|
|
||||||
|
init_wireless_driver "$@"
|
||||||
|
|
||||||
|
LOCK_FILE="/tmp/mtwifi.lock"
|
||||||
|
|
||||||
|
MTWIFI_MAX_AP_IDX=15
|
||||||
|
MTWIFI_MAX_APCLI_IDX=0
|
||||||
|
MTWIFI_CFG_IFNAME_KEY="mtwifi_ifname"
|
||||||
|
|
||||||
|
drv_mtwifi_init_device_config() {
|
||||||
|
config_add_int txpower beacon_int dtim_period
|
||||||
|
config_add_boolean mu_beamformer dbdc_main whnat bandsteering
|
||||||
|
config_add_string country twt
|
||||||
|
}
|
||||||
|
|
||||||
|
drv_mtwifi_init_iface_config() {
|
||||||
|
config_add_string 'ssid:string' macfilter bssid kicklow assocthres steeringthresold
|
||||||
|
config_add_boolean wmm hidden isolate ieee80211k ieee80211r
|
||||||
|
config_add_int wpa_group_rekey frag rts
|
||||||
|
config_add_array 'maclist:list(macaddr)' 'steeringbssid:list(macaddr)'
|
||||||
|
config_add_boolean mumimo_dl mumimo_ul ofdma_dl ofdma_ul amsdu autoba uapsd
|
||||||
|
}
|
||||||
|
|
||||||
|
drv_mtwifi_cleanup() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mtwifi_vif_ap_config() {
|
||||||
|
local name="$1"
|
||||||
|
local ifname=""
|
||||||
|
local disabled=""
|
||||||
|
|
||||||
|
json_select config
|
||||||
|
json_get_var disabled disabled
|
||||||
|
json_select ..
|
||||||
|
|
||||||
|
[ "$disabled" = "1" ] && return
|
||||||
|
|
||||||
|
json_get_var ifname $MTWIFI_CFG_IFNAME_KEY
|
||||||
|
[ -z "$ifname" ] && return
|
||||||
|
|
||||||
|
# v33: record vif for the deferred physical remap (see
|
||||||
|
# mtwifi_deferred_phys_remap). The ra*/rax* <-> PHY binding is random
|
||||||
|
# per boot and the second netdev may not exist yet at this point, so
|
||||||
|
# the remap runs after setup completes.
|
||||||
|
echo "$name $ifname" >> "/tmp/mtwifi_vifs.$MTWIFI_CUR_DEV"
|
||||||
|
|
||||||
|
logger -t "netifd-mtwifi" "add $ifname to vifidx $name"
|
||||||
|
wireless_add_vif "$name" "$ifname"
|
||||||
|
}
|
||||||
|
|
||||||
|
mtwifi_phys_ifname() {
|
||||||
|
# Echo the netdev that PHYSICALLY carries the given device's content.
|
||||||
|
# The section's dat (l1profile profile_path) always programs its own
|
||||||
|
# PHY, and the dat's MacAddress equals the MAC of whichever netdev
|
||||||
|
# physically carries it this boot.
|
||||||
|
local dat mac n
|
||||||
|
dat=$(l1util get "${1//_/.}" profile_path 2>/dev/null)
|
||||||
|
[ -f "$dat" ] || return
|
||||||
|
mac=$(sed -n 's/^MacAddress=//p' "$dat" | head -1)
|
||||||
|
[ -n "$mac" ] || return
|
||||||
|
for n in /sys/class/net/ra* /sys/class/net/rax*; do
|
||||||
|
[ -f "$n/address" ] || continue
|
||||||
|
if [ "$(cat "$n/address")" = "$mac" ]; then
|
||||||
|
basename "$n"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
mtwifi_deferred_phys_remap() {
|
||||||
|
# Re-notify netifd with the physical ifname for each vif of device $1
|
||||||
|
# once the netdev shows up, so ubus status (and everything derived
|
||||||
|
# from it: LuCI title, freqlist, channel dropdown, bridge membership)
|
||||||
|
# matches reality. UCI writes stay section-based and unaffected.
|
||||||
|
local dev="$1" vifs="/tmp/mtwifi_vifs.$1"
|
||||||
|
local name static_if phys tries=0
|
||||||
|
[ -s "$vifs" ] || return
|
||||||
|
while [ $tries -lt 45 ]; do
|
||||||
|
phys=$(mtwifi_phys_ifname "$dev")
|
||||||
|
[ -n "$phys" ] && break
|
||||||
|
sleep 1
|
||||||
|
tries=$((tries+1))
|
||||||
|
done
|
||||||
|
[ -n "$phys" ] || return
|
||||||
|
while read -r name static_if; do
|
||||||
|
[ -n "$name" ] || continue
|
||||||
|
[ "$phys" = "$static_if" ] && continue
|
||||||
|
logger -t "netifd-mtwifi" "deferred physical remap: $dev $static_if -> $phys"
|
||||||
|
__netifd_device="$dev"
|
||||||
|
wireless_add_vif "$name" "$phys"
|
||||||
|
done < "$vifs"
|
||||||
|
rm -f "$vifs"
|
||||||
|
}
|
||||||
|
|
||||||
|
mtwifi_vif_sta_config() {
|
||||||
|
local name="$1"
|
||||||
|
local ifname=""
|
||||||
|
local disabled=""
|
||||||
|
|
||||||
|
json_select config
|
||||||
|
json_get_var disabled disabled
|
||||||
|
json_select ..
|
||||||
|
|
||||||
|
[ "$disabled" = "1" ] && return
|
||||||
|
|
||||||
|
json_get_var ifname $MTWIFI_CFG_IFNAME_KEY
|
||||||
|
|
||||||
|
if [ -n "$ifname" ]; then
|
||||||
|
logger -t "netifd-mtwifi" "add $ifname to vifidx $name"
|
||||||
|
wireless_add_vif "$name" "$ifname"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
mtwifi_vif_ap_set_data() {
|
||||||
|
local ifname=""
|
||||||
|
|
||||||
|
if [ ! $AP_IDX -gt $MTWIFI_MAX_AP_IDX ]; then
|
||||||
|
ifname="${MTWIFI_AP_IF_PREFIX}${AP_IDX}"
|
||||||
|
AP_IDX=$((AP_IDX+1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
json_add_string "$MTWIFI_CFG_IFNAME_KEY" "$ifname"
|
||||||
|
}
|
||||||
|
|
||||||
|
mtwifi_vif_sta_set_data() {
|
||||||
|
local ifname=""
|
||||||
|
|
||||||
|
if [ ! $APCLI_IDX -gt $MTWIFI_MAX_APCLI_IDX ]; then
|
||||||
|
ifname="${MTWIFI_APCLI_IF_PREFIX}${APCLI_IDX}"
|
||||||
|
APCLI_IDX=$((APCLI_IDX+1))
|
||||||
|
fi
|
||||||
|
|
||||||
|
json_add_string "$MTWIFI_CFG_IFNAME_KEY" "$ifname"
|
||||||
|
}
|
||||||
|
|
||||||
|
drv_mtwifi_setup() {
|
||||||
|
ubus -t 120 wait_for network.interface.lan
|
||||||
|
|
||||||
|
local dev="$1"
|
||||||
|
# UCI section names use underscores (e.g., MT7981_1_1) but l1util/l1dat
|
||||||
|
# expect dotted names (e.g., MT7981.1.1). Convert before any lookup.
|
||||||
|
local dev_dot="${dev//_/.}"
|
||||||
|
|
||||||
|
json_add_string device "$dev_dot"
|
||||||
|
MTWIFI_CUR_DEV="$dev"
|
||||||
|
rm -f "/tmp/mtwifi_vifs.$dev"
|
||||||
|
|
||||||
|
lock $LOCK_FILE
|
||||||
|
|
||||||
|
logger -t "netifd-mtwifi" "up: $dev ($dev_dot)"
|
||||||
|
|
||||||
|
MTWIFI_AP_IF_PREFIX="$(l1util get $dev_dot ext_ifname)"
|
||||||
|
MTWIFI_APCLI_IF_PREFIX="$(l1util get $dev_dot apcli_ifname)"
|
||||||
|
|
||||||
|
AP_IDX=0
|
||||||
|
for_each_interface ap mtwifi_vif_ap_set_data
|
||||||
|
|
||||||
|
APCLI_IDX=0
|
||||||
|
for_each_interface sta mtwifi_vif_sta_set_data
|
||||||
|
|
||||||
|
json_dump | /sbin/mtwifi_cfg setup
|
||||||
|
|
||||||
|
for_each_interface ap mtwifi_vif_ap_config
|
||||||
|
for_each_interface sta mtwifi_vif_sta_config
|
||||||
|
|
||||||
|
wireless_set_up
|
||||||
|
|
||||||
|
lock -u $LOCK_FILE
|
||||||
|
|
||||||
|
( mtwifi_deferred_phys_remap "$dev" ) >/dev/null 2>&1 </dev/null &
|
||||||
|
}
|
||||||
|
|
||||||
|
drv_mtwifi_teardown() {
|
||||||
|
local dev="$1"
|
||||||
|
local dev_dot="${dev//_/.}"
|
||||||
|
|
||||||
|
lock $LOCK_FILE
|
||||||
|
|
||||||
|
logger -t "netifd-mtwifi" "down: $dev ($dev_dot)"
|
||||||
|
|
||||||
|
rm -f "/tmp/mtwifi_vifs.$dev"
|
||||||
|
/sbin/mtwifi_cfg down "$dev_dot"
|
||||||
|
|
||||||
|
lock -u $LOCK_FILE
|
||||||
|
}
|
||||||
|
|
||||||
|
add_driver mtwifi
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
Default
|
||||||
|
INDEX0=MT7981
|
||||||
|
INDEX0_profile_path=/etc/wireless/mediatek/mt7981.dbdc.b0.dat;/etc/wireless/mediatek/mt7981.dbdc.b1.dat
|
||||||
|
INDEX0_init_script=/lib/wifi/mtwifi.lua;/lib/wifi/mtwifi.lua
|
||||||
|
INDEX0_init_compatible=mtwifi;mtwifi
|
||||||
|
INDEX0_EEPROM_offset=0x0
|
||||||
|
INDEX0_EEPROM_size=0x5000
|
||||||
|
INDEX0_EEPROM_name=e2p
|
||||||
|
INDEX0_main_ifname=ra0;rax0
|
||||||
|
INDEX0_ext_ifname=ra;rax
|
||||||
|
INDEX0_wds_ifname=wds;wdsx
|
||||||
|
INDEX0_apcli_ifname=apcli;apclix
|
||||||
|
INDEX0_mesh_ifname=mesh;meshx
|
||||||
|
INDEX0_nvram_zone=dev1;dev2
|
||||||
|
INDEX0_single_sku_path=/etc/wireless/mediatek/mt7981-sku.dat
|
||||||
|
INDEX0_bf_sku_path=/etc/wireless/mediatek/mt7981-sku-bf.dat
|
||||||
Binary file not shown.
Reference in New Issue
Block a user