[BPI-R2] internal Wifi/BT (MT6625L) - Kernel

bpi-r2-gentoo ~ # tc qdisc show dev ap0    
qdisc mq 0: root
qdisc pfifo_fast 0: parent :4 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: parent :3 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: parent :2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: parent :1 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
bpi-r2-gentoo ~ # tc qdisc show dev lan0
qdisc noqueue 0: root refcnt 2
bpi-r2-gentoo ~ # tc qdisc show dev eth0
qdisc pfifo_fast 0: root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1

looks like there are some rules by defaul - the dump is after sch_fq module has removed.

Have not done much with tc,but imho there should be the qos classes and routing all to best-effort by default.

Regarding ap0,afair it was not suggested anywhere recreating the device or disable it…create it once and use…setting state multiple times by echo will lead to unstable/undefined behaviour. Why do you need it?

I don’t mean recreating device. In my case i can’t restart hostapd, it restarts but doesn’t work. In general i don’t need to restart it, but looks like it’s a driver issue, as other wifi devices lets to restart hostapd and continue to work. In case of new setup it can be very useful: change password or channel.

Afair this was happening also in earlier versions of driver. But none had an idea why this happen. We have no support for the code which is large and dirty. a few users like lexa2 helped me to get it working in newer kernelversions or in better shape.

BTW, did someone tried to compile ti as a module? in this case it may be possible to reload module as some type of workaround.

Imho lexa did with last version. He fixed module build (merged to 5.4)…before it can’t be compiled as module.

I had kind-a-fixed driver code to be able to build it as a module but if I recall correctly it wasn’t providing much in terms of stability or alike. Problem was that having driver loaded as a module was mostly a one way road: attempts to unload and reload it might end up in kernel panics or in kernel memory corruption manifesting in things like sudden in-memory file system structures corruption with a subsequent loss of the data on the drive as soon as kernel decides to write corrupted structures to the disk. I hadn’t had any chance to work on anything R2 related since Nov 2019 so can’t provide you with more info than this.

1 Like

hi,

i’ve started work on 5.8 and currently hanging on cfg80211-api-change

6cd536fe62ef (“cfg80211: change internal management frame registration API”)

i hang here on converting mgmt_frame_register to update_mgmt_frame_registrations callbacks

i had already replaced the struct-entry and the function-headers, but i do not know how to get missing frame_type and reg resolved. Can i get the fields back out of the update-param? other drivers callbacks got completely rewritten, so i have no clue what to change

i have uploaded current state here:

maybe anyone here can help??

found this in johannes’ commit:

- if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
- vif->probe_req_report = reg;
- }
+ vif->probe_req_report = upd->interface_stypes & BIT(IEEE80211_STYPE_PROBE_REQ >> 4);

This should be way to check frametype

It looks like frame_type can be extracted from upd->interface_stypes

This seems to be definition of bool reg:

struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
u32 preq_mask = BIT(IEEE80211_STYPE_PROBE_REQ >> 4);
bool global_change, intf_change;

intf_change = sdata->vif.probe_req_reg !=
			!!(upd->interface_stypes & preq_mask);

Bool Reg was true on register (cfg80211_mlme_register_mgmt) and false in unregister (cfg80211_process_mlme_unregistrations,removed)

Frametype was defined this way:

struct cfg80211_mgmt_registration *reg;
list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
u16 frame_type = le16_to_cpu(reg->frame_type);

Where upd.interface_stypes is defined as this (combined with or over all wdev->mgmt_registrations).

BIT(le16_to_cpu(reg->frame_type) >> 4);

Problem i see is that only stypes passed in upd-struct,but not the needed frametypes MAC_FRAME_PROBE_REQ and MAC_FRAME_ACTION which are defined in drivers/misc/mediatek/connectivity/wlan/gen2/include/nic/mac.h

#define MAC_FRAME_TYPE_MGT                      0
#define MAC_FRAME_PROBE_REQ                     (MAC_FRAME_TYPE_MGT | 0x0040)
#define MAC_FRAME_ACTION                        (MAC_FRAME_TYPE_MGT | 0x00D0)

So we are still in the bits 4-7 (lower 4 bits zero which are shifted away in new version)…4=0100,D=1101, so it looks like it is a redefinition of the stypes (with combination)…if we shift back the stypes it can work…but because of combination of multiple registrations this can be wrong

And the new update-callback is called once and not like the old callback for each wdev->mgmt_registrations

I guess we need to loop again through all devs and regs

struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
struct wireless_dev *tmp;
struct cfg80211_mgmt_registration *reg;

	rcu_read_lock();
	list_for_each_entry_rcu(tmp, &rdev->wiphy.wdev_list, list) {
		list_for_each_entry_rcu(reg, &tmp->mgmt_registrations, list) {
			u32 frame_type = le16_to_cpu(reg->frame_type);
			bool reg = !!(frame_type & IEEE80211_STYPE_PROBE_REQ);
//put switch here...
}}
rcu_read_unlock();

This part of code was changed due to a locking bug…i guess i need to change it too

Maybe this is enough:

	struct cfg80211_mgmt_registration *reg;
	spin_lock_bh(&wdev->mgmt_registrations_lock);

	list_for_each_entry(reg, &wdev->mgmt_registrations, list) {
    		u16 frame_type = le16_to_cpu(reg->frame_type);
    		bool reg = !!(frame_type & IEEE80211_STYPE_PROBE_REQ);
		//put switch here...
	}
	spin_unlock_bh(&wdev->mgmt_registrations_lock);

But i guess it will fail on unregister, because list is freed before

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/net/wireless/mlme.c?#n624

Maybe the MAC_* can be directly converted to the stype value…

MAC_FRAME_PROBE_REQ = IEEE80211_STYPE_PROBE_REQ = 0x40

MAC_FRAME_ACTION = IEEE80211_STYPE_ACTION = 0xd0

The flags set here are defined here:

Guarded by CFG_ENABLE_WIFI_DIRECT_CFG_80211 which is set here with interesting comment above

And i found another interesting detail: https://github.com/frank-w/BPI-R2-4.14/blob/9ac31137c6b49dbc12d80de16ef0f455ffd94a3d/drivers/misc/mediatek/connectivity/wlan/gen2/include/config.h#L893 would it be possible to drop wmt-utils so easily?? But this will require combo-driver to be built as module to load firmware and config (where all options currently rejected so i made it optional in 5.8-wifi branch).

I tried to change the callback as far as i understand…i guess upd->interface_stypes is 0 on unregister

i changed code as far as i understand, can compile, boot without errors, can start AP and connect to it

can please others test?

Sure, I will test it.

I’d have to collect a second board somewhere next week, so it can take some time.

If you got a spare board you can test 5.8-rc tree where all so far is merged

Ok this weekend I tested the 5.8-rc branch and have some preliminary results:

I am running ArchlinuxARM and I’ve built the kernel in qemu on the same filesystem as I am running on the board.

[root@alarm ~]# uname -a
Linux alarm 5.8.0-rc4-bpi-r2+ #1 SMP Sat Jul 18 01:46:19 CEST 2020 armv7l GNU/Linux

So I’ve managed to start the AP, connect and route my connection to the internet. Very nice! Stopping hostapd and restarting it is not enough to make the AP reappear, but I’ve read before this is a known issue. At least a reboot fixes it.

More worrying is that i get intermittent crashes on several systemd services with various stacktraces:

[  319.167468] systemd[1]: systemd-logind.service: Killing process 378 (systemd-logind) with signal SIGABRT.
[  319.204724] systemd[1]: systemd-networkd.service: Killing process 363 (systemd-network) with signal SIGABRT.
[  319.268033] systemd[1]: systemd-udevd.service: Killing process 356 (systemd-udevd) with signal SIGABRT.

and errors:

[   15.180655] systemd-coredump[240]: #0  0x00000000b6cd6254 epoll_wait (libc.so.6 + 0xdd254)
[  240.140213] systemd-coredump[322]: #0  0x00000000b6d4fa1c __pthread_clockjoin_ex (libpthread.so.0 + 0x8a1c)
[  319.652388] systemd-coredump[398]: #0  0x00000000b6cce684 tcgetattr (libc.so.6 + 0xd4684)
[ Jul 18 01:39:58 alarm systemd-coredump[591]: #0  0x00000000b6c43210 epoll_wait (libc.so.6 + 0xdd210)
[  375.759007] systemd-coredump[1112]: #0  0x00000000b6ce49bc getxattr (libc.so.6 + 0xdc9bc)
[  375.782972] systemd-coredump[1112]: #1  0x00000000b6eb8ed4 fgetxattrat_fake (libsystemd-shared-245.so + 0x135ed4)

I’d have to dive in further to get some more info on why this happens.

dmesg.tgz (17.2 KB)

Take a look at my wifi.sh. i make a “echo 0 >wmtdevice” to reset the combo-chip.

For the crashes i have no idea yet…i had not seen them before.did you modified the config? How long had you your device running? Was that after the hostapd restart?

[   63.281186] [WMT-DEV][E]wmt_dev_read_file(1456):error code:-2
[   63.287078] [WMT-DEV][E]wmt_dev_patch_get(1573):load file (/system/etc/firmware/WMT_SOC.cfg) fail, iRet(-2)
[   63.296894] [WMT-CONF][E]wmt_conf_read_file(516):read /system/etc/firmware/WMT_SOC.cfg file fails

it looks like you don’t have the config-file…i did a basic patch that the kernel crashes not if this is missing, but maybe there is another access anywhere which affects your systemd. could you try adding the file in this location? it should not return with -2…the last message is ok, but before it looks wrong

Yes that works, after this hostapd can be restarted:

echo 0 > /dev/wmtWifi
echo A > /dev/wmtWifi

I didn’t have that file, after I added it that particular error disappeared and some new ones appear:

[   37.094342] [WMT-CONF][E]wmt_conf_parse_pair(323):unknown field 'mt6620.defAnt'.
[   37.110249] [WMT-CONF][E]wmt_conf_parse_pair(323):unknown field 'mt6628.defAnt'.
[   37.117693] [WMT-CONF][E]wmt_conf_parse_pair(323):unknown field 'mt6630.defAnt'.

It doesn’t seem important as WiFi just works.

I didn’t have time yet to look into the systemd issues, however I am sure they are unrelated to WiFi. I frequently get crashes, for example after login, when running ip addr, doing CTRL+C, or just doing nothing. The system keeps running without further issues, but it doesn’t give a lot of confidence with important services are crashing all the time.

My kernel config is just your config: mt7623n_evb_fwu_defconfig, no changes. If you are interested you can try my built kernel + modules. I will investigate more myself later.

Ok,then it is not related to the config file…but strange anyway because i have not seen it in my test.

now with 5.8-rc yes…in earlier versions kernel crashes at this point :wink:

Can you try running system with that kernel without enabling the wifi or just drop the driver from config…just to test if this is the issue?

It crashes regardless of WiFi, I am quite sure that WiFi is not the issue.

If you want you can try the kernel on your filesystem if you see similar issues (see previous post for link).

To be clear: They are only systemd crashes, no kernel oops or panic.

have you tested if an older kernel (maybe also from my repo) has no systemd-crashes? this looks not like an kernel-issue

it can be kernel-related (like hostapd info-messages), but i had not seen them on my box…which armbian have you installed?

Yes, kernel 4.14 works fine.

Maybe related: https://bugzilla.redhat.com/show_bug.cgi?id=1660466 ?

Can you test lts kernel 5.4 (maybe 4.19) and 5.7?

Hi, all!

I’ve installed 5.8-rc, looks fine, at least no problems in 2 hourssince R2 have booted it :slight_smile:

5.8-startup.txt (97.0 КБ)

Internal wifi works, and speed is the same (or very similar) to my previous 5.5, no disconnects.

Since i use gentoo i have no systemd, everything else forks just fine.

I’ll update this post on any errors/changes.

P.S. i have monitorless setup right now, so no hdmi/lima tests for a while.