As I keep seeing the same posts all the time and I don't think anyone has explained it yet, I will.
To anyone wondering why they are having either 30 dBm or 14 dBm / 16 dBm / 23 dBm TX-power values set on their wlX interfaces regardless of the country that they set - you can only blame the Xiaomi developers because of their laziness.
There is a script /lib/wifi/qcawificfg80211.sh that manages all the configurations for the wireless interfaces. Most of the code in the script was written by Qualcomm, but some parts were added by Xiaomi.
One of the parts, especially important in this case, is this one:
# for miwifi
if [ "$bdmode" = "24G" ]; then
max_power=30
wifitool "$ifname" setUnitTestCmd 67 3 16 1 1
iwpriv "$ifname" 11ngvhtintop 1
else
max_power=30
fi
if [ "$bd_country_code" = "EU" ]; then
if [ "$bdmode" = "24G" ]; then
max_power=14
else
if [ "$channel" -ge 100 ]; then
max_power=23
else
max_power=16
fi
fi
if [ $ifname = "wl2" ]; then
max_power=13
fi
fi
#miwifi: reduce 3db for Brazil band1
if [ "$nv_country_code" = "BR" ]; then
if [ "$bdmode" = "5G" -a "$channel" -le 48 ]; then
max_power=13
fi
fi
#miwifi: we use band1 txpower for wifi ap mode
netmode=`uci get xiaoqiang.common.NETMODE`
if [ -n "$netmode" -a "$netmode" = "wifiapmode" -a "$bdmode" = "5G" ]; then
max_power=16
if [ "$nv_country_code" = "BR" ]; then
max_power=13
fi
fi
config_get txpwr "$device" txpwr
if [ "$txpwr" = "mid" ]; then
txpower=`expr $max_power - 1`
elif [ "$txpwr" = "min" ]; then
txpower=`expr $max_power - 3`
else
txpower="$max_power"
fi
txpower="${txpower:-$vif_txpower}"
[ -z "$txpower" ] || iwconfig "$ifname" txpower "${txpower%%.*}"
$bd_country_code is a variable retrieved from bdata get CountryCode command
$nv_country_code from nvram get CountryCode
From reading the code, we can assume that there are only two valid values for bdata's CountryCode, which are either CN or EU. Setting it to CN will always result with TX-power set to 30 dBm for both 2.4 and 5 GHz (unless you set your nvram's CountryCode to Brazil or modify 'Signal Strength' value in Web GUI).
nvram's CountryCode is probably the value that we set in the Web GUI during our initial configuration of the router and in case of TX-power its value is not affecting us in most cases - unless you are from Brazil, where the power for 5 GHz would be set to 13 dBm.
So now we have few options:
- Modify the script and hard code your preferred values - but it cannot be done directly on the router because of the read-only SquashFS filesystem.
- Set the values manually every time your router is restarted.
- Create some script that will be executed at boot and will do that for you.
- Configure the interfaces according to the script above to get the most out of it, so if you are from Europe ($bd_country_code = "EU"):
- For 2.4 GHz (wl1) you cannot do much, it will be limited to 14 dBm.
- For 5 GHz (wl0), setting channel to 100 and below will result with TX-power 16 dBm and greater than 100 23 dBm.
- Keep the bdata's
CountryCodeset to CN and keep 30 dBm, which is most likely illegal in your country.
About the blocked channels, it is also hard coded in the script:
config wifi-iface
option device wifi$devidx
option ifname 'wl$radioidx'
option network '$network'
option mode '$mode'
option ssid '$ssid'
option encryption none
option wpsdevicename 'XiaoMiRouter'
EOF
if [ $devidx = 0 ]; then
cat <<EOF
option channel_block_list '52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,144,165'
option miwifi_mesh '1'
EOF
@perceival the performance issue with channel 165 may comes from the script setting htmode on channel 165 to HT20: it just hit me today that channel 165 has very narrow range, therefore only this mode is available and the performance won't be good https://en.wikipedia.org/wiki/List_of_WLAN_channels#5_GHz_or_5.9_GHz_(802.11a/h/j/n/ac/ax)
if [ "$channel" = 165 ]; then
htmode=HT20
fi