@airtower option a) is probably not possible as the driver was 'found' in a github repo with a questionable origin and license so it would most probably not be acceptable for upstreaming.
No new #rtw8723cs commits today, but instead two #pmbootstrap MRs because I finally tried out envkernel.sh, mostly because I got too annoyed about #clangd not working on the kernel sources. The kernel has a helpful scripts/clang-tools/gen_compile_commands.py script to generate the compile_commands.json file, but it requires build output, which I don't get from pmbootstrap build --src
. With envkernel.sh and a little extra tweaking it works now.
If you're curious about those MRs: https://gitlab.com/postmarketOS/pmbootstrap/-/merge_requests/2229 and https://gitlab.com/postmarketOS/pmbootstrap/-/merge_requests/2230 #MobileLinux
And now there's a third #pmbootstrap MR from this, which fixing building a pmOS kernel package from the kernel built using envkernel: https://gitlab.com/postmarketOS/pmbootstrap/-/merge_requests/2231 So now I have a full working envkernel workflow. Would anyone be interested in a little writeup about the clangd part?
Also, I have first scan results from #rtw8723cs! Only from the default channel (no channel switching yet), and signal strength isn't processed, but it's a very clear "it's working" sign.
And pushed: https://github.com/airtower-luna/linux/commit/82b9450af17ca1e241b3f44b444f43f9c22b70c8 #rtw8723cs
Maybe someone wants to implement channel switching while I take care of the phy_status?
The old 8723cs vendor driver is all the "specification" I have for #rtw8723cs, and then I find something like this in RSSI calculation:
case 0xb:
rx_pwr_all = -42 - (2 * vga_idx); /*TBD*/
Just great! At least the author(s) seem to have been confident about the other cases?
Register address definitions like #define R_0x950 0x950
are… not very helpful to figure out what the register is for. What I know so far is that bit 11 says whether some LNA (low noise amplifier) status uses 3 or 4 bits (and the expected value is 1 for RTL8703B), and in some other chips other bits seem to have things to do with driving different antennas. Now what do I call my own macro for that register? #rtw8723cs
And it gets even weirder… No matter the value of that bit, only 3 bits are actually read. The 4 bit value is just a bitwise OR with (1 << 3). And the result only ever gets used in a switch with hardcoded numbered cases! I think I get what's going on though: Depending on that bit the 3 bits of rx power information received from the chip need to be interpreted differently, and they chose about the most convoluted way possible to do it. #rtw8723cs
And sometimes things are simpler than they seem. I was looking for clues how to calculate the channel bandwidth of a received packet from an rxsc
field in the phy status like the other rtw88 drivers do, but the rxsc
field in the 8723cs phy status is a) half as wide as that used by the later models (2 instead of 4 bit), and b) entirely unused in the vendor driver. Turns out it just uses a field from the RX descriptor instead. #rtw8723cs
And RX PHY status parsing is working, I'm getting reasonable signal information! Monitor mode works as long as you only care about the default channel. One issue is that the driver gets (and then needs to drop) packets with length zero, based on timing my guess is that it's Bluetooth interference: BT coex isn't implemented yet, and they always appear/disappear with state changes there. Channel switching is my next target. #rtw8723cs #MobileLinux #Pinephone
If anyone wants to help and pick a component I'm unlikely to get to very soon, BT coex would be a great candidate. Just saying.
Latest commit: https://github.com/airtower-luna/linux/commit/9035ed34783a89d80db0c75b007fbd5bcfcbe5ec
@airtower writeup about clangd sounds really good - yespls
There's a scary amount of #if 0
and if (0)
blocks in the old driver source.
Oh great, this comment looks like a software workaround for an RTL8703B hardware issue, the function is part of the channel switch procedure in 8723cs. I guess I'll have to replicate it in #rtw8723cs, wish I had a spectrum analyzer to verify that (and RF power in general). https://xff.cz/git/linux/tree/drivers/staging/rtl8723cs/hal/rtl8703b/rtl8703b_phycfg.c?h=orange-pi-6.7#n801
Interesting, the mainline rtw8723d driver has a similar workaround, but for significantly fewer channels: only 13 and 14, as opposed to 5 through 8 and 13 and 14. I guess they improved the hardware in between?
And I have channel switching working, scan finds my home wifi now! Code needs some cleanup before I commit, but it's working, and in some parts simplified compared to the old driver! #rtw8723cs
Full success! I'm sending this post from my #Pinephone, over wifi with #rtw8723cs! I have a working connection with WPA3. #MobileLinux https://github.com/airtower-luna/linux/commits/rtw88_8723cs/
@airtower Wow I'm amazed by how quickly you got that working, congratulation! 🎉
@airtower wow, thank you so much for your work! Upstreaming this driver is a very important piece of the puzzle for a true mainline Linux phone battling against the paperweight dilemma https://blog.mobian.org/posts/2023/09/30/paperweight-dilemma/ .
@darkdragon Thanks, that's exactly the main motivation, plus that 8723cs can't do WPA3 with iwd (iwd requires the driver to do the SAE handshake, wpa_supplicant can do it from userspace if needed). To be precise I'm not upstreaming the old driver, just using it for the information needed to write a new chip driver that lets the mainline rtw88 driver support the rtl8723cs.
@aren Thank you! The step from "channel switch working" to "TX working" was fairly small because the necessary fill_txdesc_checksum
function is exactly the same as for the 8723d chip, I could just reuse the function after comparing. One of the cleanup tasks I'll need to do before sending the driver to linux-wireless is moving all the functions that can be shared between 8723d and 8703b/8723cs into a support module.
Why do all these Realtek drivers (both old 8723cs and other rtw88 drivers) use "IQK" as acronym for "IQ Calibration"? Still need to figure out what that is and what exactly "IQ" means in the wifi context, but it's something about signal quality, and apparently temperature matters. #rtw8723cs
This is getting pretty deep into analog radio tech: https://www.analog.com/media/en/technical-documentation/application-notes/AN-1039.pdf Haven't read the full thing yet, not sure if I will, but reading the intro and skimming the rest tells me it's calibration of the "in-phase and quadrature modulator (IQ modulator)". #rtw8723cs
Hm. Missing signal quality calibration could explain why the signal currently gets bad really quickly with distance and walls in between. My phone connects to wifi just fine across the room from the router, but walking two rooms over it can't connect any more. Now the question is, do I switch focus from BT coex to IQK? I'm pretty sure lack of BT coex is leading to dropped packets and WPA handshake often needing a few tries. #rtw8723cs
@airtower Trying to summarize the essentials about IQ modulation necessary to using it: Signals are transmitted using radio waves, on top of a carrier wave a data signal is modulated, the data signal does carry information by variation in amplitude and phase, amplitude and phase can be expressed as complex numbers or plotted in the IQ plane.
@airtower You receive an analog signal and need to convert it into a digital one by discretization. For the simple 2 value amplitude modulation (2AM) you can say all negative amplitudes are digital 0 and all positive ones are digital 1. For calibration, you need to find out where the barrier between negative and positive amplitudes are by adding some constant offset to the signal. Modern signal processing is way more advanced like 64QAM where one needs to differentiate 64 points in the IQ plane.
@darkdragon The first half is about what I remember from the "Signals and Systems" lecture in university, but I didn't remember the terminology enough to connect with the "IQK" thing, the calibration part is new. Thanks! The driver application seems to be mostly "apply settings from data tables depending on various conditions", but understanding the context helps finding the right things.
@airtower I guess that a well-defined pattern is sent (e.g. all possible values in binary ascending order) and then the chip/firmware/driver needs to add offsets / factors which detect the correct numbers best. Haven't read the document or done any network drivers, I just remember the theory from university.
@darkdragon Would make sense, I've already seen code that makes sure other RF operations don't overlap with IQK.
@airtower the second part is basically the following lecture about communications systems (Nachrichtentechnik) 😉 It becomes quite interesting when you reach MIMO with multiple antennas where you basically rely on enough different reflections in natural settings which can act as independent channels and then do the calibration as part of every transmission burst just by calculating eigenvalues in the measured channel matrix.
@darkdragon I must've passed that at some point, but evidently don't remember much of the details… My focus was much more on the digital side.
@airtower this is amazing, do you by any chance have an idea how close the 8723bs is to the cs? It's quite annoying that these have two completely different drivers
@martijnbraam Very vaguely. I haven't really looked at the driver, but they often occur together in checks for hardware generations in the rtl8723cs code. So I'd guess that 8723b is similarly close to the 8703b (confusingly that's the wifi part of 8723cs) as 8703b is to 8723d. Which is a lot, I'm directly calling some functions from rtw8723d in the new rtw8703b driver.
If someone wants to write a 8723bs driver, I'd say checking if they can build on rtw88 would be a good start. Might even be they could reuse some of the code I'm adding, for example the PHY status layout for RX seems to have changed right after the 8703b (before 8723d).
Random find from the 8723cs source code: The thermal change threshold to trigger LCK (a kind of calibration) is 8, and a comment says that's 20°C. So the sensor measures (or transmits, at least) in steps of 2.5°C. I pushed some BT coex stuff for #rtw8723cs last night, but switched focus to calibration for now because the short range bothers me more. The BT coex stuff as far as I got seems to reduce wifi issues during connection, but BT still isn't usable with wifi on.
Took a deep dive into the rtl8723cs code TX power track code, and compared with rtw8723d code. Looks like I can reuse a lot for #rtw8723cs again, but not all, the main difference is how settings are written to registers (and of course data tables with settings for different rates, modulations, etc.). Another nice thing is that I can start using only those tables and implement calibration later. Maybe the defaults will be enough to connect from two rooms away from my AP?
Nope, power path without actual calibration doesn't help, but at least it was a good split of tasks. And a little test with ping from phone to AP, with tcpdump running on the router indicates TX is indeed where the problem is. For all packets that showed up on the router the phone also received the response. So IQK has to be next. #rtw8723cs
Finally got the range issue fixed (implementing IQK didn't), and I'll probably never trust an EFUSE without verifying again. Turns out the one in the RTL8723CS chip in my #Pinephone doesn't contain valid TX power data (like the general rtw88 infrastructure expects). Upon closer inspection the old driver detects that case and uses a built-in array instead. #rtw8723cs
And pushed the code. Not extensively tested yet of course, but should be usable as long as you don't need BT coex. https://github.com/airtower-luna/linux/commit/4e9144773d349afee446b8b02247286fe0faade5 #rtw8723cs #Pinephone
If you try #rtw8723cs, please enable CONFIG_RTW88_DEBUG
in the kernel build, and enable as many of the rtw88 debug flags as possible without flooding your log too much when loading the rtw88_core
module. I currently have this in a modprobe.d config for general use:
options rtw88_core debug_mask=0x000200a0
The value is a bitwise OR of the flags, so 0xffffffff enables everything (especially RTW_DBG_FW
and RTW_DBG_COEX
produce a lot of messages). You can change the value at runtime by writing to /sys/module/rtw88_core/parameters/debug_mask
. If anything goes wrong, the debug messages might provide hints what it was.
I'm writing this from my #pinephone connected to WLAN using @airtower's #rtw8723cs module. Impressive work, Fiona! 🙇
Still trying to figure out BT coex. The annoying thing is that while the general logic is pretty much the same between rtl8723cs and rtw88, and both use tables in the same format to configure BT coex, they use the tables in different ways. This includes rtw88 using indices that simply aren't defined in rtl8723cs, and rtl8723cs modifying some TDMA table entries under certain conditions (e.g. a device with A2DP profile being connected). Not having documentation on what each index is supposed to mean on either side makes it hard to make adjustments, I might have to create some based on under exactly which conditions which driver uses which index. #rtw8723cs
Oh, and to make it even weirder I found a few cases where rtl8723cs applies a modification that never changes anything. For example, a bitwise OR 0x11 | modify
, where modify
is guaranteed to be 0x01 or 0x00. The result is always 0x11 anyway. #rtw8723cs
Finding some weird stuff in #rtw88, too. For example in this function: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/wireless/realtek/rtw88/coex.c?h=v6.7#n2190 wl_cpt_test
and bt_cpt_test
are used in if
s, but never set to anything but false
. Bug? #rtw8723cs
So, got BT coex working. Turns out there were two invalid EFUSE bytes affecting it, of which I had found and fixed only one before. The nice part is that the coex tables are the same format between devices, so I can just reuse the rtw8723d tables to adjust for the different indices rtw88 uses.
I also added very detailed EFUSE parse logging, and I'll go through all those 0xff values and see if they might cause trouble elsewhere. Rtw88 does some validation, but the fallback usually isn't what's needed for 8703B. I'm really curious if other people's RTL8723CS chips (#Pinephone or otherwise) also have almost entirely invalid EFUSE data. If you want to check: Load the module with RTW_DBG_EFUSE
enabled in rtw88_core debug_mask
(scroll up the thread a little for details), and look for "EFUSE raw logical map" and the about 70 lines after in the kernel log. If your EFUSE is also mostly 0xff the last relevant line will be mac_addr=ff:ff:ff:ff:ff:ff
.
Anyway, this means #rtw8723cs now does all I need in daily operation, which is a huge step! #LinuxMobile
@pavel Thank you! And kinda? There's a bit of tidying up to do, but I have a working driver. Kinda scary, especially because it's such a big patch. Right now I'm also confused if I need to add a DT binding because the driver tries to get the MAC from DT. Other than that… I guess improvements (esp. RX speed and BT coex need work) can happen later.
Fixing EVM for RX improved the RX rate quite a bit for me, I guess now it's time to prepare the patches for linux-wireless. https://github.com/airtower-luna/linux/commit/651bfee08705c426db45a4288789238ea1d7d56f #rtw8723cs
For anyone who's using #rtw8723cs from my Git repo, I've rebased the rtw88_8723cs
branch on top of megi's 6.7.2 tag (orange-pi-6.7-20240127-1717
), plus the patches in the pmOS 6.7.2 package, plus rtw88 changes in 6.8-rc2. Of course I want 6.7.2 in general, but I also want to minimize the diff for sending patches. The pre-rebase version is still available at rtw88_8723cs-6.7
for now, but I'm not going to work on that any more.
Why is scripts/checkpatch.pl
complaining if you have the SPDX-License-Identifier in a //
comment (not /* ... */
) in a header, but also complaining if you don't use //
for the same thing in a .c file? Can't you just pick one style and stick with it? #Linux
@airtower tried cleanpatch/file today. Did not figure out how it’s supposed to work, so had to manually clean (tabs vs spaces). It just complained about something and did nothing
@kloenk Complaining and then you manually fix it is fortunately all checkpatch.pl needs to do. You give it a diff/patch file/git commit(s) and then it tells you if anything about them is wrong or at least questionable.
@pavel So basically "If I can't have them in headers, I'll have them in C?"
Is there a guideline for how long I should wait for a response when asking people if they want a Suggested-by
line? Obviously (and documented) I can't just add it without asking, so I'm wondering how long I should wait before sending the patch without, without that being rude. #rtw8723cs #Linux
Sent patches to linux-wireless, we'll see how review goes. https://lore.kernel.org/linux-wireless/20240202121050.977223-1-fiona.klute@gmx.de/T/ #rtw8723cs #LinuxMobile
I've added CFO (carrier frequency offset) tracking to #rtw8723cs, it makes RX a lot more stable for me. This was fairly quick because the relevant parts of the rtl8723cs code are comparatively easy to read, and very similar to the code rtw88 already has for 8822c CFO tracking. I mostly had to be careful about different bitmasks and registers, the general process is the same. I guess it's best to send that to linux-wireless after the main driver has been reviewed and merged, not try to push it into the first patch set, so I have it on a separate branch for now (which I might rebase as I make changes based on review).
If you want to try: https://github.com/airtower-luna/linux/commits/rtw88_8723cs-optimize
@airtower FYI, I've been trying this optimized version for a while and it seems that the version without CFO works better for me. The problem is that downloads almost grind to a halt. E.g. I had to switch to the staging module to downgrade back to the kernel without CFO because the upload to the phone just didn't finish with the CFO rtw88 module. If you need more details, please let me know how I can help.
@fraolt Hmm, that's odd. I've had RX slow down occasionally, but it's not a regular thing, so I assumed interference. And scanning in the background makes it worse (channel switching is slow, unfortunately). If you have logs with debug output enabled I'd like to take a look.
@airtower Sure! I'll set debug_mask=0x000200a0 or do you need sth else. Do you have any wishes wrt iperf settings to match your setup?
@fraolt I'm using debug_mask=0xfffb7fa7
now, that's all enabled except PHY, FW, COEX, SDIO, ADAPTIVITY. If you can enable more (ideally 0xffffffff) without flooding your logs that'd be even better. I don't have anything specific that I'm after yet, just trying to get as much info as possible to hopefully spot something odd.
My iperf setup isn't anything special, just server on the phone and client somewhere else (in my case with a wired connection to the AP), in (default) TCP mode.