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

Nice to see you again…can you hrlp me getting the wifi-driver in better shape?

  • sort out necessary changes in mtk_wdt.c because they seems to break other devices like r64
  • drop wmt-tools

Nice to see you too :slight_smile: I’m currently working on upstreaming openwrt again (without wifi for now), would love to help with wifi after that.

  • What specifically do you try to change in mtk_wdt?
  • How are you going to get rid of ugly userspace helpers?

we have seen on porting that wifi does not work without use code in mtk_wdt.c

these are the changes in mtk_wdt.c (have simply copied the file from 4.14 to each kernel-version and did only compile fixes):

https://github.com/frank-w/BPI-R2-4.14/commit/f5ed1691c59096a4f8d15c45df718fc04bf18ac1#diff-a7c2e83ff71c648e58025d54ffb50e02

Here i tried to drop wmt-tools (first wmt_loader by initialize on bootup):

Have you ever send a Patch to mainline? What needs to be changed in pcie? Is it a dts or driver-patch? Afair i have no pcie-patch in 4.19+

I currently try to push poweroff-driver to mainline (and pcie/ahci to uboot)

@abbradar have you looked into it?

curently i try to port driver to 5.4, but again much have changed…one thing i don’t know to fix is build-errors (implicit-fallthrough). e.g. this one:

drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c: In function 'wlanCfgFindNextToken':
drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c:5834:8: error: this statement may fall through [-Werror=implicit-fallthrough=]
     if (x[1] != '\n') {
        ^
drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.c:5838:4: note: here
    case '\n':
    ^~~~
cc1: all warnings being treated as errors
make[6]: *** [drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_lib.o] Error 1
make[6]: *** Waiting for unfinished jobs....
In file included from ./include/linux/printk.h:332,
                 from ./include/linux/kernel.h:15,
                 from drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_os.h:534,
                 from drivers/misc/mediatek/connectivity/wlan/gen2/include/precomp.h:171,
                 from drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c:1061:
drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c: In function 'wlanoidSetAcpiDevicePowerState':
./include/linux/dynamic_debug.h:122:52: error: this statement may fall through [-Werror=implicit-fallthrough=]
 #define __dynamic_func_call(id, fmt, func, ...) do { \
                                                    ^
./include/linux/dynamic_debug.h:143:2: note: in expansion of macro '__dynamic_func_call'
  __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
  ^~~~~~~~~~~~~~~~~~~
./include/linux/dynamic_debug.h:153:2: note: in expansion of macro '_dynamic_func_call'
  _dynamic_func_call(fmt, __dynamic_pr_debug,  \
  ^~~~~~~~~~~~~~~~~~
./include/linux/printk.h:336:2: note: in expansion of macro 'dynamic_pr_debug'
  dynamic_pr_debug(fmt, ##__VA_ARGS__)
  ^~~~~~~~~~~~~~~~
drivers/misc/mediatek/connectivity/wlan/gen2/os/linux/include/gl_kal.h:947:53: note: in expansion of macro 'pr_debug'
 #define kalPrint                                    pr_debug
                                                     ^~~~~~~~
drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h:258:33: note: in expansion of macro 'kalPrint'
 #define LOG_FUNC                kalPrint
                                 ^~~~~~~~
drivers/misc/mediatek/connectivity/wlan/gen2/include/debug.h:265:3: note: in expansion of macro 'LOG_FUNC'
   LOG_FUNC("%s:(" #_Module " " #_Class ")"_Fmt, __func__, ##__VA_ARGS__); \
   ^~~~~~~~
drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c:6556:3: note: in expansion of macro 'DBGLOG'
   DBGLOG(OID, INFO, "Set Power State: D1\n");
   ^~~~~~
drivers/misc/mediatek/connectivity/wlan/gen2/common/wlan_oid.c:6558:2: note: here
  case ParamDeviceStateD2:
  ^~~~

anyone can help here?

imho it’s a false positive, because implicit-fallthrough is printed if break is missing in a switch’s case and here it is written as comment that break is not wanted (to print D1-D3 together if Powerstate=D1 and always set powerstate to D3)

 6549         switch (*prPowerState) {
 6550         case ParamDeviceStateD0:
 6551                 DBGLOG(OID, INFO, "Set Power State: D0\n");
 6552                 kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD0);
 6553                 fgRetValue = nicpmSetAcpiPowerD0(prAdapter);
 6554                 break;
 6555         case ParamDeviceStateD1:
 6556                 DBGLOG(OID, INFO, "Set Power State: D1\n");
 6557                 /* no break here */
 6558         case ParamDeviceStateD2:
 6559                 DBGLOG(OID, INFO, "Set Power State: D2\n");
 6560                 /* no break here */
 6561         case ParamDeviceStateD3:
 6562                 DBGLOG(OID, INFO, "Set Power State: D3\n");
 6563                 fgRetValue = nicpmSetAcpiPowerD3(prAdapter);
 6564                 kalDevSetPowerState(prAdapter->prGlueInfo, (UINT_32) ParamDeviceStateD3);
 6565                 break;
 6566         default:
 6567                 break;
 6568         }

please take also a look at the last commit (try to fix wakeup_source_prepare build-error), it compiles fine, but maybe it’s wrong (imho double memory-allocation)

@frank-w not yet, I won’t be near my R2 till mid-November :smiley: I think it’s false positive too but this is from 5-minute code reading.

thank you for first check…have marked the lines as wanted fallthroughs to get it compiled…any idea about the wakeup_source_prepare?

i tried to modify code to use wakeup_source_create directly, but can’t get it working till now

wake_lock_init called wakeup_source_init which is replaced by wakeup_source_create

 static inline void wake_lock_init(struct wake_lock *lock, int type,
                                  const char *name)
 {
        wakeup_source_init(&lock->ws, name);
 }

something like this (not working):

+++ b/drivers/misc/mediatek/connectivity/common/conn_soc/linux/pub/osal.c
@@ -984,12 +984,16 @@ INT32 osal_wake_lock_init(P_OSAL_WAKE_LOCK pLock)
 {
        if (!pLock)
                return -1;
-
+       struct wakeup_source *ws;//=pLock->wake_lock;
+/*
        #ifdef CONFIG_PM_WAKELOCKS
        wakeup_source_init(&pLock->wake_lock, pLock->name);
        #else
        wake_lock_init(&pLock->wake_lock, WAKE_LOCK_SUSPEND, pLock->name);
        #endif
+*/
+       ws=wakeup_source_create(pLock->name);
+       pLock->wake_lock->ws=ws;
        return 0;
 }

the wakeup-functions were dropped with this Patch: https://patchwork.kernel.org/patch/11080905/

maybe my current implementation is ok…because before prepare-function has allocated memory which is now done by create-function

--- a/include/linux/pm_wakeup.h
+++ b/include/linux/pm_wakeup.h
@@ -186,7 +186,7 @@ static inline void pm_wakeup_dev_event(struct device *dev, unsigned int msec,
 static inline void wakeup_source_init(struct wakeup_source *ws,
                                      const char *name)
 {
-       wakeup_source_prepare(ws, name);
+       ws=wakeup_source_create(name);
        wakeup_source_add(ws);
 }

seems it’s not right yet…

[  340.888358] Backtrace: 
[  340.890813] [<c01afa48>] (mod_timer) from [<c0660c24>] (pm_wakeup_ws_event.part.8+0x94/0xc4)
[  340.899260]  r10:c13c9020 r9:c1301e08 r8:00000000 r7:a00f0193 r6:e68d51f8 r5:00000fd4
[  340.907092]  r4:e68d51e8
[  340.909630] [<c0660b90>] (pm_wakeup_ws_event.part.8) from [<c0660c74>] (pm_wakeup_ws_event+0x20/0x24)
[  340.918857]  r9:c1301e08 r8:ea021000 r7:000000d7 r6:e68d54e0 r5:00000000 r4:e68d44e0
[  340.926611] [<c0660c54>] (pm_wakeup_ws_event) from [<c06e9754>] (kalHifAhbKalWakeLockTimeout+0x34/0x38)
[  340.936012] [<c06e9720>] (kalHifAhbKalWakeLockTimeout) from [<c0713d4c>] (HifAhbISR+0x78/0x1b4)
[  340.944714]  r5:00000000 r4:e68d44e0
[  340.948294] [<c0713cd4>] (HifAhbISR) from [<c018ddd0>] (__handle_irq_event_percpu+0xa8/0x27c)
[  340.956824]  r6:00000000 r5:ea2f2268 r4:e68dc940

i guess it’s because pointer to ws changes inside function and does not pushed back to caller (no reference-parameter)…and the crash is the first access to the wrong pointer…how can i fix this?

in testing code above i need to assign pointer to new created struct (ws) to pLock->wake_lock->ws

pLock->wake_lock->ws=ws;

0001-Drop-usage-of-wakelocks-Android-API-use-wake-sources.patch (12.6 KB)

Please try applying attached patch over 3061ab72e23bf4b077be3bf63faec28d13426d01 (it was the tip of 5.4-wifi at the moment of posting this message) and test if it works. Disclaimer: I hadn’t had a chance to boot-check this one, only did a compile-test. Changes in patch are to remove usage of Android specific wakelock API and switch into using wake sources API instead. Half of the driver had already been aware that wakesources exists but this support was disabled due to CONFIG_PM_WAKELOCKS being non-relevant for detecting if wake sources are available (and wake sources API is always safe to use no matter if wake sources are enabled/supported in current kernel). Instead all parts of the driver relied on the wakelock.h wrapper that was borrowed from the Android kernel sources and the only thing it did was to provide a fallback to wake sources API for wakelocks API calls.

IMO as you try to maintain driver specifically for linux kernel there’s no need to drag in Android compatibility bits - they only do increase maintenance burden for you. Thus I cleaned it up from parts that were relying on CONFIG_ANDROID and Android-only APIs.

1 Like

unfortunately same crash as before in pm_wakeup_ws_event, but in wifi-driver there is no call to this function…i guess it is called by kernel after a timeout reaches 0 and this is only initialized by wifi-driver with the wakeup_source_create (or similar) above

Well, looks like it’s time to sharpen my gdb skills :-). I will have to set up test image with this kernel though beforehand. I’d try to squeeze this into my evening schedule for today but no warranties :-).

@LeXa2 found the cause of the crash and give me a fix, ap0 is now created on 5.4

uploaded current codebase to my repo

in my quick test, i can create ap0, connect to it using my phone and establish a ssh connection to r2

Great. Does this mean that we can make use of the integrated wifi using 5.4-wifi Kernel? But next question is can we use this with OpenWrt by lexa2?

yes. wifi seems to work now in 5.4

basicly you need to extract the Patches from wifi-branch and merge them into lexas openwrt (maybe adding the Patch(es) to the Patch-dir in openwrt-source)

1 Like

This is some good news. Great work. As Long as we can have most of the hardware working on the device, It is all good for the device manufacturer.

Regarding merging it, I think @LeXa2 will be able to do this.

Thanks Again.

one caveat: i don’t know if wifi-driver is working with openwrt’s cfg80211-stack, but here maybe lexa2 knows more…afair anybody (@lexa2 or @abbradar) has got older wifi-driver working in openwrt and tried to push (which was declined because of code quality/size)

one question on this.

If I use your 5.4 branch with Arch Linux will it help with a working wifi as client and AP?

you have to use patches from wifi-branch, not -rc or any other

also you need wmt-tools and maybe my wifi-script for initialization

https://drive.google.com/open?id=15lHk7IEyVyQdYzVfvPvV-3jMhz7GSL7p

simply unpack this after installing dnsmasq and hostapd (any maybe uninstall wpasupplicant if installed)

wmt-tools+script+conf.zip

then adjust conf/script to your ip-configuration (change subnets for interface and dhcp-range)

ap-mode is done by writing A into control-device in script, change this to 1 to get client-mode

I was doing my debugging on OpenWRT so it is possible to have OpenWRT + krenel 5.4 + wifi. But it’s not that simple.

Firstly upstream OpenWRT sticks to using LTS kernels, so it is 4.14 for 18.06.x and 4.19 for 19.x releases. So using other kernel versions requires either a lot of changes/patches to OpenWRT that will be really hard to maintain or building kernel separately from OpenWRT and implanting it into the SD/eMMC. When I need to test new kernels with OpenWRT I stick to second approach.

Secondly, at was already written in this forum several times wifi driver for R2 is a big pile of smelly substance. It does not stick to using normal cfg80211 ways to do things and requires some additional non-standard configuration steps for wifi interfaces to appear. What it means is that we can’t simply use openwrt’s generic cfg80211 support, we will have to patch it somewhat to support R2 wifi driver specifics.

Thirdly, additional configuration steps I mention require using wifi driver specific tools. There’s source code avaialble for these tools so it is possible to compile them for OpenWRT but if we’re talking about “out of the box support” and “good user experience” we would also have to create an opkg package for these utilities.

Bottom line is that while it is certainly possible to implement (pt.2 and 3 are not that hard, pt.1 is but it is not required) I don’t see much profit from having it implemented. It is hard to expect stable wifi experience when we use driver of such quality. There are other more stable wifi hardware options available for R2. So spending time on implementing thing that won’t have much practical sense is something with really low priority on my list of things to do.

@spikerguy you can also extract wifi-patches from 4.14-main and 4.19-main (afair i had already removed feature-branches)

4.14-main:

frank@frank-G5:/media/data_fast/bpi/kernel/BPI-R2-4.14$ git log --oneline -- drivers/misc/mediatek/
4873a180960c (tag: CI-BUILD-20190112215322-4873a180960c) [BT] fix Bluetooth
7f7e9b3aa677 (tag: CI-BUILD-20181123125903-7f7e9b3aa677) mtk wifi: Ensure no NULL refs passed
ee7516478daf (tag: CI-BUILD-20181117140700-ee7516478daf) [wifi] disabled some debug-messages
33570b3aff16 [gcc] gcc8-patch by Dominik Koch
984d46ee9a87 fixed mt6625l using Major-Device-Number of SPI (153 => 155)
f5b5b7516d79 decreasing debug-level of Wifi-driver
124c82243f59 updated defconfig (issue #11), added option in build.sh for changing defconfig
c5b81e053998 changed defconfig (removed some defaults in wlan,added vlan-basics) fixed warning in mtk-combo-driver added branch to kernel-image-name
956607e2f2a2 patches for BT
e6b369a5ade1 merge mt6625l wifi driver

in 4.19 i had splitted driver-folder with changes outside

frank@frank-G5:/media/data_fast/bpi/kernel/BPI-R2-4.14$ git log --oneline -- drivers/misc/mediatek/
c0603006d7f0 (tag: CI-BUILD-20190112215205-c0603006d7f0) [BT] fix Bluetooth
203a5a7727a8 [gcc] gcc8-fixes by Dominik Koch + nic_rx-patch from https://bugs.linaro.org/show_bug.cgi?id=3823
ce8c582c6121 [wifi] adding driver-folder

frank@frank-G5:/media/data_fast/bpi/kernel/BPI-R2-4.14$ git log --oneline -- drivers/watchdog/mtk_wdt.c
0c22407b3b75 (tag: CI-BUILD-20190825_155925-0c22407b3) disable watchdog prints
83ffbaceffed [wifi] adding wifi-related changes outside driver-directory

Thank you for the detailed explanation. I agree with you that it is not feasible to maintain it separately.

Currently I was just following the pre-compiled kernel by you. I haven’t gotten time to update my PKGBUILD to build a kernel from your branch. I hope I can give it a try this weekend. As for Arch I try to make whole pkg including boot and kernel. Qemu is too slow thats why I try on the device itself. Ill try to see how i can arrange a fan over the cpu and compile with atleast ‘-j 3’.

Thanks for all the support.

Did you mean qemu-arm userspace + chroot here? If yes - I’m wondering why is it too slow for you. My experience using it - and I use it a lot for compiling stuff targeting Raspberry Pi 1/2/3 and Orance Pi PC - shows that with modern enough CPU (Ryzen 7 2700x for my case) and if you’ve got plenty of ram compiling speed is way faster (like, 3-4x times faster when compiling complex things like linux kernel) under qemu compared to what I got even on considered to be “powerful” ARM boards like RPi3/4.