[BPI-R64] mt7622 mac80211 WiFi driver

i see no mt7622 driver in master/mt7622-branch

It looks like it’s part of 7615…

Is it compatible with my current dts-node? still wondering why root and some others (mt76x0,76x2,7603) do not have a Kconfig file…and still the problem with trace.o (trace.h not found)

after fixing this, i get this on 5.4 with this driver:

drivers/net/wireless/mediatek/mt76_new/mac80211.c: In function 'mt76_phy_init':
drivers/net/wireless/mediatek/mt76_new/mac80211.c:286:31: error: 'NL80211_EXT_FEATURE_AQL' undeclared (first use in this function); did you mean 'NL80211_EXT_FEATURE_TXQS'?
  wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_AQL);
                               ^~~~~~~~~~~~~~~~~~~~~~~
                               NL80211_EXT_FEATURE_TXQS
drivers/net/wireless/mediatek/mt76_new/mac80211.c:286:31: note: each undeclared identifier is reported only once for each function it appears in
drivers/net/wireless/mediatek/mt76_new/mac80211.c: In function 'mt76_airtime_report':
drivers/net/wireless/mediatek/mt76_new/mac80211.c:760:12: error: implicit declaration of function 'ieee80211_calc_rx_airtime'; did you mean 'ieee80211_check_tim'? [-Werror=implicit-function-declaration]
  airtime = ieee80211_calc_rx_airtime(dev->hw, &info, len);
            ^~~~~~~~~~~~~~~~~~~~~~~~~
            ieee80211_check_tim

for first i need this commit: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/include/uapi/linux/nl80211.h?id=911bde0fe5ccd7e55760be9d6dcc67a8850fcc12 => i cannot apply without conflicts in 5/6 files (include/uapi/linux/nl80211.h,net/mac80211/debugfs_sta.c,net/mac80211/main.c,net/mac80211/sta_info.c,net/mac80211/tx.c). except the debugfs-file i have solved them…but this one is tricky (and many changes overlapping)

for second https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/include/net/mac80211.h?id=db3e1c40cf2f973fbdd52ae0b59a9472b1c04f4a

after fixing them…there are many new errors…so new driver not usable for me (at least in 5.4)

net/mac80211/main.c: In function 'ieee80211_alloc_hw_nm':
net/mac80211/main.c:673:7: error: 'struct ieee80211_local' has no member named 'aql_threshold'
  local->aql_threshold = IEEE80211_AQL_THRESHOLD;
       ^~
net/mac80211/main.c:673:25: error: 'IEEE80211_AQL_THRESHOLD' undeclared (first use in this function); did you mean 'IEEE80211_MAX_RTS_THRESHOLD'?
  local->aql_threshold = IEEE80211_AQL_THRESHOLD;
                         ^~~~~~~~~~~~~~~~~~~~~~~
                         IEEE80211_MAX_RTS_THRESHOLD
net/mac80211/main.c:673:25: note: each undeclared identifier is reported only once for each function it appears in
net/mac80211/main.c:674:19: error: 'struct ieee80211_local' has no member named 'aql_total_pending_airtime'
  atomic_set(&local->aql_total_pending_airtime, 0);
                   ^~
scripts/Makefile.build:265: recipe for target 'net/mac80211/main.o' failed
make[2]: *** [net/mac80211/main.o] Error 1
make[2]: *** Waiting for unfinished jobs....
  CC [M]  net/wireless/sysfs.o
net/mac80211/sta_info.c: In function 'ieee80211_sta_update_pending_airtime':
net/mac80211/sta_info.c:1908:25: error: 'struct airtime_info' has no member named 'aql_tx_pending'
        &sta->airtime[ac].aql_tx_pending);
                         ^
net/mac80211/sta_info.c:1910:32: error: 'struct ieee80211_local' has no member named 'aql_total_pending_airtime'
   atomic_add(tx_airtime, &local->aql_total_pending_airtime);
                                ^~
net/mac80211/sta_info.c:1916:30: error: 'struct airtime_info' has no member named 'aql_tx_pending'
             &sta->airtime[ac].aql_tx_pending);
                              ^
net/mac80211/sta_info.c:1920:36: error: 'struct airtime_info' has no member named 'aql_tx_pending'
    atomic_cmpxchg(&sta->airtime[ac].aql_tx_pending,
                                    ^
net/mac80211/sta_info.c:1925:18: error: 'struct ieee80211_local' has no member named 'aql_total_pending_airtime'
            &local->aql_total_pending_airtime);
                  ^~
net/mac80211/sta_info.c:1930:24: error: 'struct ieee80211_local' has no member named 'aql_total_pending_airtime'
   atomic_cmpxchg(&local->aql_total_pending_airtime,
                        ^~
scripts/Makefile.build:265: recipe for target 'net/mac80211/sta_info.o' failed

any chance to fix only the mt7622 semaphore issue? as far as i see it checks status and this failes…maybe a sleep/delay may help?

For kernel 5.5

I’m not sure what’s going on in kernel 5.5, but I’ve got the same error at getting patch semaphore before, which is due to power-domain not enabled.

This may need to be verified, have you noticed any change on this part?

For kernel 5.4 and latest mt76

  1. For the AQL flag, you can try some of these patches, which backport the AQL support to 5.4

  2. For the latest mt7622_wmac dts node, please refer this patch. Also, mt7622/mt7615e share the same module mt7615e.ko

  3. For the problem you need to “unload and load” the module once, does it happen only on using wpa_supplicant or also on hostapd?

I’ve cherry-picked your patches from my older 5.4 branch (where i do not get this error). I guess some recent changes in 5.4 breaking it…

My node contains power-domain

I’m still on 5.4, Or do you mean it is switched on anywhere else/later? Where is powerdomain switched on? It is working on unload/load,so i guess it’s a timing issue.

Currently i do not want to use backport patches because it makes it difficulter applying updates. I only wanted to try newer driver version to compare.

unload/load is independ from hostapd/wpa-supplicant (which depends on wlan-device exists). It is needed to get drivers probe working (patch semaphore) to create the wlan-device.

I’m not familiar with the power domain part, may need some time to dig it out.

For the patches, please apply this series and this patch you applied before, to see if it works on your kernel 5.4.

[v11,0/4] Add Airtime Queue Limits (AQL) to mac80211
[v11,1/4] mac80211: Add new sta_info getter by sta/vif addrs
[v11,2/4] mac80211: Import airtime calculation code from mt76
[v11,3/4] mac80211: Implement Airtime-based Queue Limit (AQL)
[v11,4/4] mac80211: Use Airtime-based Queue Limits (AQL) on packet dequeue

it’s not enough…

./include/net/mac80211.h:1067:6: error: 'struct ieee80211_tx_info' has no member named 'tx_time_est'
  info->tx_time_est = min_t(u16, tx_time_est, 4095) >> 2;

but i want to know why your current version is failing some times on the Patch semaphore…was working on 5.4-r64-rc (5.4.0-rc1), but not on 5.4.12

I has same problem with semaphore, and found out after some time that modules conflict - if rfkill module is loaded earlier than mt7622 then error arise. So I made softdep and the error has gone:

sa@bpi-r64:~$ cat /etc/modprobe.d/wifi.conf 
#blacklist rfkill
softdep rfkill pre: mt7622
sa@bpi-r64:~$ cat /etc/modprobe.d/wifi.conf 
#blacklist rfkill
softdep rfkill pre: mt7622
sa@bpi-r64:~$ dmesg | grep mt7622
[    0.000000] Kernel command line: board=bpi-r64 console=ttyS0,115200n1 earlyprintk root=/dev/mmcblk1p2 rootfstype=ext4 rootwait service=linux debug=7 initcall_debug=0 androidboot.hardware=mt7622 swiotlb=512
[    1.232638] rtc_mt7622 10212800.rtc: registered as rtc0
[    6.134757] rtc_mt7622 10212800.rtc: setting system clock to 2020-02-09T21:51:14 UTC (1581285074)
[   11.082558] mt7622_wmac 18000000.wmac: ASIC revision: 76220010
[   11.089035] mt7622_wmac 18000000.wmac: Invalid MAC address, using random address 7a:d8:70:2d:ea:3d
[   11.098779] mt7622_wmac 18000000.wmac: MAC addr = 7a:d8:70:2d:ea:3d
[   11.121530] mt7622_wmac 18000000.wmac: HW/SW Version: 0x8a108a10, Build Time: 20190801210006a
[   11.159501] mt7622_wmac 18000000.wmac: N9 Firmware Version: _reserved_, Build Time: 20190801210351
[   11.216096] mt7622_wmac 18000000.wmac: Firmware init done
[   11.238435] mt7622_wmac 18000000.wmac: Driver own success
1 Like

thank you, works for me too

softdep rfkill pre: mt7622

sorry for delay…made some tests with uboot and ethernet-driver on this board so tested this too

Hi, I would like to bridge wlan0 (wifi) and lanX but fail, kernel 5.4. Why it is not possible?

Here is my try:

$ ip link add name br1 type bridge
$ ip link set br1 up

$ ip link set lan0 master br1

$ bridge link
6: lan0@eth0: <BROADCAST,MULTICAST> mtu 1500 master br1 state disabled priority 32 cost 100 

$ ip link set wlan0 master br1
Error: Device does not allow enslaving to a bridge.

or with ifup

Mar 08 10:27:20 bananapir64 ifup[11273]: can't add wlan0 to bridge br0: Operation not supported

I’ve seen in the forum that it is not possible, e.g. [Bpi and gateway with wire](this one), but what is the reason?

you could try this: https://serverfault.com/a/554663

but i would suggest using routing to get packets between interfaces

1 Like

I am testing wifi now and found out that ping from bpi-r64 to connected device (my phone) is too long - several times > 1 second:

    sa@bananapir64:~$ ping 172.30.1.143
    PING 172.30.1.143 (172.30.1.143) 56(84) bytes of data.
    64 bytes from 172.30.1.143: icmp_seq=1 ttl=64 time=1210 ms
    64 bytes from 172.30.1.143: icmp_seq=2 ttl=64 time=201 ms
    64 bytes from 172.30.1.143: icmp_seq=3 ttl=64 time=1356 ms
    64 bytes from 172.30.1.143: icmp_seq=4 ttl=64 time=341 ms
    64 bytes from 172.30.1.143: icmp_seq=5 ttl=64 time=774 ms
    64 bytes from 172.30.1.143: icmp_seq=6 ttl=64 time=6.10 ms
    64 bytes from 172.30.1.143: icmp_seq=7 ttl=64 time=193 ms
    64 bytes from 172.30.1.143: icmp_seq=8 ttl=64 time=1354 ms
    64 bytes from 172.30.1.143: icmp_seq=9 ttl=64 time=335 ms
    64 bytes from 172.30.1.143: icmp_seq=10 ttl=64 time=769 ms
    64 bytes from 172.30.1.143: icmp_seq=11 ttl=64 time=6.46 ms
    64 bytes from 172.30.1.143: icmp_seq=12 ttl=64 time=199 ms
    64 bytes from 172.30.1.143: icmp_seq=13 ttl=64 time=1349 ms
    64 bytes from 172.30.1.143: icmp_seq=14 ttl=64 time=329 ms
    64 bytes from 172.30.1.143: icmp_seq=15 ttl=64 time=763 ms
    64 bytes from 172.30.1.143: icmp_seq=16 ttl=64 time=73.6 ms
    ^C
    --- 172.30.1.143 ping statistics ---
    16 packets transmitted, 16 received, 0% packet loss, time 91ms
    rtt min/avg/max/mdev = 6.096/578.547/1355.555/489.164 ms, pipe 2

My hostapd.conf:

sa@bananapir64:~$ sed -E 's/^(wpa_passphrase|ssid)=(.*)/\1=***/g' /etc/hostapd/hostapd.conf
ctrl_interface=/var/run/hostapd
#ctrl_interface_group=0 # These 2 are just parameters so that the hostap daemon runs.

interface=wlan0
#interface=ap0
driver=nl80211

ssid=***

#2.4G
hw_mode=g
channel=1
#wmm_enabled=1

#5G-Support
#country_code=DE
#ieee80211n=1
#ieee80211d=1
#hw_mode=a
#channel=48

#security
#wpa=2
#wpa_passphrase=12345678
#wpa_key_mgmt=WPA-PSK
#wpa_pairwise=TKIP CCMP
#ignore_broadcast_ssid=0
auth_algs=1
#rsn_pairwise=CCMP

#macaddr_acl=0
#accept_mac_file=/etc/hostapd/acl_accept
#deny_mac_file=/etc/hostapd/acl_deny

# https://wiki.gentoo.org/wiki/Hostapd
wpa=2
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
wpa_passphrase=***

It seems not fine. I have antenna connected to WF0 and phone 1 meter away.

Wifi analyzer shows -59dbm

Is it possible to reduce e.g. to 0.3 sec?

do you running with bridge or standalone/routing? can you test ping-time in standalone-mode (pinging wlan0-ip from client)?

-59dBm sounds like bad quality for 1m distance, have you checked all connections?

Yes, I run it standalone, without bridge:

$ ip addr show wlan0
10: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 7a:9b:e6:8b:bf:08 brd ff:ff:ff:ff:ff:ff
    inet 172.30.1.129/25 brd 172.30.1.255 scope global wlan0
       valid_lft forever preferred_lft forever

Hmm, from my notebook to wlan0 address ping is ok:

$ ping 172.30.1.129
PING 172.30.1.129 (172.30.1.129) 56(84) bytes of data.
64 bytes from 172.30.1.129: icmp_seq=1 ttl=64 time=2.59 ms
64 bytes from 172.30.1.129: icmp_seq=2 ttl=64 time=3.39 ms
64 bytes from 172.30.1.129: icmp_seq=3 ttl=64 time=4.22 ms
64 bytes from 172.30.1.129: icmp_seq=4 ttl=64 time=21.3 ms
64 bytes from 172.30.1.129: icmp_seq=5 ttl=64 time=3.39 ms
64 bytes from 172.30.1.129: icmp_seq=6 ttl=64 time=6.27 ms
64 bytes from 172.30.1.129: icmp_seq=7 ttl=64 time=3.50 ms

But backward, from wlan0 address to wifi-client, e.g. my notebook, is not good:

sa@bananapir64:~$ ping 172.30.1.144
PING 172.30.1.144 (172.30.1.144) 56(84) bytes of data.
64 bytes from 172.30.1.144: icmp_seq=1 ttl=64 time=3.08 ms
64 bytes from 172.30.1.144: icmp_seq=2 ttl=64 time=169 ms
64 bytes from 172.30.1.144: icmp_seq=3 ttl=64 time=622 ms
64 bytes from 172.30.1.144: icmp_seq=4 ttl=64 time=3.10 ms
64 bytes from 172.30.1.144: icmp_seq=5 ttl=64 time=623 ms
64 bytes from 172.30.1.144: icmp_seq=6 ttl=64 time=6.68 ms
64 bytes from 172.30.1.144: icmp_seq=7 ttl=64 time=106 ms
64 bytes from 172.30.1.144: icmp_seq=8 ttl=64 time=1076 ms
64 bytes from 172.30.1.144: icmp_seq=9 ttl=64 time=72.7 ms
64 bytes from 172.30.1.144: icmp_seq=10 ttl=64 time=606 ms
64 bytes from 172.30.1.144: icmp_seq=11 ttl=64 time=200 ms
64 bytes from 172.30.1.144: icmp_seq=12 ttl=64 time=393 ms

Btw, iperf is showing max 30 Mbits/sec.

iperf -s -u -i 1
iperf -c 172.30.1.129 -u -b 1m -l 1300 -t 100

# 1mbit/s
[  3] local 172.30.1.129 port 5001 connected with 172.30.1.144 port 46101
[ ID] Interval       Transfer     Bandwidth        Jitter   Lost/Total Datagrams
[  3]  0.0- 1.0 sec   123 KBytes  1.01 Mbits/sec   0.078 ms    0/   97 (0%)
[  3]  1.0- 2.0 sec   123 KBytes  1.01 Mbits/sec   0.253 ms    0/   97 (0%)
[  3]  2.0- 3.0 sec   122 KBytes   998 Kbits/sec   0.096 ms    0/   96 (0%)
[  3]  3.0- 4.0 sec   122 KBytes   998 Kbits/sec   0.134 ms    0/   96 (0%)
[  3]  4.0- 5.0 sec   122 KBytes   998 Kbits/sec   0.303 ms    0/   96 (0%)
[  3]  5.0- 6.0 sec   122 KBytes   998 Kbits/sec   0.182 ms    0/   96 (0%)
[  3]  6.0- 7.0 sec   122 KBytes   998 Kbits/sec   0.044 ms    0/   96 (0%)

# 10mbit/s
[  4] local 172.30.1.129 port 5001 connected with 172.30.1.144 port 56346
[  4]  0.0- 1.0 sec  1.20 MBytes  10.1 Mbits/sec   0.308 ms    0/  971 (0%)
[  4]  1.0- 2.0 sec  1.19 MBytes  10.0 Mbits/sec   0.038 ms    0/  962 (0%)
[  4]  2.0- 3.0 sec  1.19 MBytes  9.99 Mbits/sec   0.058 ms    0/  961 (0%)
[  4]  3.0- 4.0 sec  1.19 MBytes  10.0 Mbits/sec   0.052 ms    0/  962 (0%)
[  4]  4.0- 5.0 sec  1.19 MBytes  9.99 Mbits/sec   0.210 ms    0/  961 (0%)
[  4]  5.0- 6.0 sec  1.19 MBytes  10.0 Mbits/sec   0.033 ms    0/  962 (0%)
[  4]  6.0- 7.0 sec  1.19 MBytes  9.99 Mbits/sec   0.050 ms    0/  961 (0%)
[  4]  7.0- 8.0 sec  1.19 MBytes  10.0 Mbits/sec   0.045 ms    0/  962 (0%)
[  4]  8.0- 9.0 sec  1.19 MBytes  9.99 Mbits/sec   0.180 ms    0/  961 (0%)

# 30mbit/s
[  3] local 172.30.1.129 port 5001 connected with 172.30.1.144 port 33150
[ ID] Interval       Transfer     Bandwidth        Jitter   Lost/Total Datagrams
[  3]  0.0- 1.0 sec  3.61 MBytes  30.3 Mbits/sec   0.075 ms    0/ 2909 (0%)
[  3]  1.0- 2.0 sec  3.57 MBytes  29.9 Mbits/sec   0.053 ms    0/ 2879 (0%)
[  3]  2.0- 3.0 sec  3.58 MBytes  30.0 Mbits/sec   0.106 ms    0/ 2887 (0%)
[  3]  3.0- 4.0 sec  3.48 MBytes  29.2 Mbits/sec   0.504 ms    0/ 2803 (0%)
[  3]  4.0- 5.0 sec  3.50 MBytes  29.4 Mbits/sec   0.704 ms    0/ 2826 (0%)
[  3]  5.0- 6.0 sec  3.56 MBytes  29.9 Mbits/sec   0.825 ms    0/ 2871 (0%)
[  3]  6.0- 7.0 sec  3.48 MBytes  29.2 Mbits/sec   0.564 ms    0/ 2809 (0%)
[  3]  7.0- 8.0 sec  3.61 MBytes  30.3 Mbits/sec   0.709 ms    0/ 2911 (0%)
[  3]  8.0- 9.0 sec  3.58 MBytes  30.0 Mbits/sec   0.371 ms    0/ 2887 (0%)
[  3]  0.0- 9.8 sec  34.9 MBytes  29.8 Mbits/sec   1.221 ms    0/28159 (0%)

About connections, I just do it this way:

Pingtime is time for both directions (round trip time). Initial send of icmp echo request and receive of corresponding echo reply.

Are you sure you have no disturbing effects (walls between r64 and client,overlapping wifi,…)?

I understand it. Nevertheless, there is quite a difference if I ping from r64 and to r64 o_O

Are you sure you have no disturbing effects (walls between r64 and client,overlapping wifi,…)?

Nope, you can see at the picture the antenna itself and the part of my notebook.

Did you update WiFi RF calibration data into flash?(dd if=MT7622_EEPROM.bin of=/dev/mtd3)

Can i use calibrationdata if i have no mtd (debian/ubuntu)?

Can i use calibrationdata if i have no mtd (debian/ubuntu)?

This mt76 driver loads eeprom kinda tricky (look at eeprom.c). First, there is parameter in wmac node:

mediatek,mtd-eeprom = <(reference) (offset)>;

where (reference) - reference to partition definiton, (offset) - offset in it.

Driver looks for mtd-eeprom parameter, follow to partition reference, take label of it and then uses mtd subsystem to load content by partiton label. So, actually, only label is needed from device tree.

Next, you can simulate mtd by using block2mtd driver, which makes mtd devices from common block devices (like emmc/sd). Also there is cmdline parser which can make mtd partitioning. You can enable both driver and parser:

CONFIG_MTD_BLOCK2MTD=y
CONFIG_MTD_CMDLINE_PARTS=y

Next, we need to create virtual mtd device and made fake partition for mt76 in dts, example from OpenWRT build for eMMC:

bootargs = "earlycon=uart8250,mmio32,0x11002000 console=ttyS0,115200n1 swiotlb=512 block2mtd.block2mtd=/dev/mmcblk0,65536,eMMC,5 mtdparts=eMMC:768k(mbr),512k(uboot),512k(uboot-env),256k(factory),-(firmware)"
&mmc0 {
        ....
        /* Fake card and partition, just for taking name "factory" */
	emmc@0 {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "mmc-card";
		reg = <0>;

		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			factory: partition@1c0000 {
				label = "factory";
				/* no need actually, just for sure */
				reg = <0x01c0000 0x00040000>;
			};
		};
	};
};
/* EEPROM location */
&wmac {
	mediatek,mtd-eeprom = <&factory 0x0000>;
	status = "okay";
};

For debian, you can create GPT partition somewhere on SD/eMMC card, flash EEPROM to it. For example, 256k EEPROM partition at 204800 sector (100MiB), then dts will looks like

bootargs = "... block2mtd.block2mtd=/dev/mmcblk1,65536,SD,5 mtdparts=SD:100M(boot),256k(factory),-(root)"
&mmc1 {
        ....
        /* Fake card and partition, just for taking name "factory" */
	sd@0 {
		#address-cells = <1>;
		#size-cells = <1>;
		compatible = "mmc-card";
		reg = <0>;

		partitions {
			compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			factory: partition@6400000 {
				label = "factory";
				/* no need actually, just for sure */
				reg = <0x06400000 0x00040000>;
			};
		};
	};
};
&wmac {
	mediatek,mtd-eeprom = <&factory 0x0000>;
	status = "okay";
};

However, you should use block2mtd driver (drivers/mtd/devices/block2mtd.c) from OpenWRT tree, because vanilla driver uses auto-generated mtd names with colon, which breaks mtdparts

2 Likes

I had the same problem so hardcoded it into mt76 driver from OpenWRTMT7615e_7622_eeprom_hardcoded.patch (7.9 KB) TX power is working correct now. I did not trace if driver is using it as a real EEPROM but for read only calibration works ok.

I’ve connected 4 antennas to the board, how does the board decides which device uses which antenna?

Doing a speed test gives about 100mbps for each device if ran separately. If I run a speed test on 2 devices at the same time one device gets 40, another one gets 20, which looks like both devices use the same antenna.

Shouldn’t they bot get 100mbps and both use different antennas?

I’m running master openwrt.

[   21.396876] mt7622-wmac 18000000.wmac: HW/SW Version: 0x8a108a10, Build Time: 20190801210006a
[   21.427145] mt7622-wmac 18000000.wmac: N9 Firmware Version: 2.0, Build Time: 20200131180931

i guess currently only one antenna is used…i see a Patch on patchwork which seems to be related to this (but only pinctl), there should be also a driver+dts-change to use these pinctl to use multiple antennas

https://patchwork.kernel.org/patch/11792841/