Skip to content

wifi: ath9k: Add PTP patch from wifi-ptp project #6882

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 3 commits into
base: rpi-6.12.y
Choose a base branch
from

Conversation

6by9
Copy link
Contributor

@6by9 6by9 commented Jun 4, 2025

@6by9
Copy link
Contributor Author

6by9 commented Jun 4, 2025

I am NOT proposing that this gets merged here, but created it for #4358

Copy link
Contributor

@jacob-keller jacob-keller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's what I think you want to implement, assuming sc->cc_mult is the base multiplier. I also suggested converting the ath_warn to ath_dbg so that its not spammy unless enabled as frequency can be adjusted multiple times per second depending on the synchronization rate. Hope this helps!

mult = sc->cc_mult;
adj = mult;
adj *= scaled_ppm;
diff = div_u64(adj, 1000000000ULL);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mistake here is still using 1,000,000,000 (1 billion). You need to use 1million * 2^16, but you can actually just replace this all with adjust_by_scaled_ppm.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you!

Comment on lines 8 to 18
#if 0
struct ath_softc *sc = container_of(ptp, struct ath_softc, ptp_clock_info);
unsigned long flags;
int neg_adj = 0;
u32 mult, diff;
u64 adj;

if (scaled_ppm < 0) {
neg_adj = -1;
scaled_ppm = -scaled_ppm;
}
mult = sc->cc_mult;
adj = mult;
adj *= scaled_ppm;
diff = div_u64(adj, 1000000000ULL);

spin_lock_irqsave(&sc->systim_lock, flags);
timecounter_read(&sc->tc);
sc->cc.mult = neg_adj ? mult - diff : mult + diff;
spin_unlock_irqrestore(&sc->systim_lock, flags);

ath_warn(ath9k_hw_common(sc->sc_ah), "phc adjust adj=%llu freq=%u\n", adj, diff);
#endif

return 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#if 0
struct ath_softc *sc = container_of(ptp, struct ath_softc, ptp_clock_info);
unsigned long flags;
int neg_adj = 0;
u32 mult, diff;
u64 adj;
if (scaled_ppm < 0) {
neg_adj = -1;
scaled_ppm = -scaled_ppm;
}
mult = sc->cc_mult;
adj = mult;
adj *= scaled_ppm;
diff = div_u64(adj, 1000000000ULL);
spin_lock_irqsave(&sc->systim_lock, flags);
timecounter_read(&sc->tc);
sc->cc.mult = neg_adj ? mult - diff : mult + diff;
spin_unlock_irqrestore(&sc->systim_lock, flags);
ath_warn(ath9k_hw_common(sc->sc_ah), "phc adjust adj=%llu freq=%u\n", adj, diff);
#endif
return 0;
struct ath_softc *sc = container_of(ptp, struct ath_softc, ptp_clock_info);
unsigned long flags;
spin_lock_irqsave(&sc->systim_lock, flags);
timecounter_read(&sc->tc);
sc->cc.mult = adjust_by_scaled_ppm(sc->cc_mult, scaled_ppm);
spin_unlock_irqrestore(&sc->systim_lock, flags);
ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG, "phc adjust adj=%llu freq=%u\n", adj, diff);
return 0;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whitespace is probably not correct here for kernel style, but you should get the idea. You could also pull adjust_by_scaled_ppm to outside the lock, but I don't think its necessary, since its really just a few multiplications and division.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace and coding style are a bit of a mess generally with these changes, but that can be a task for others to fix up if they were ever to think of upstreaming them (I have no idea if it would even be considered upstream).
I did try a checkpatch --fix-inplace, but it only addressed a small fraction of the issues.

@6by9 6by9 force-pushed the rpi-6.12.y-ath9k-ptp branch from 3b8126e to 8b8afcd Compare June 12, 2025 16:35
@wirelessOJ
Copy link

@jacob-keller @6by9 @CALMorACT When I ransudo./ptp4l -I wlan0 -p /dev/pptp0 -mthere was an error that suggested a driver issue. I wondered if this was due to how the ath9k.diff was forward ported. Looking at the logs using sudo dmesg | grep ath9k

[ 4.181657] ath9k 0000:01:00.0: enabling device (0000 -> 0002)
[ 4.360628] ath9k 0000:01:00.0: Failed to initialize device
[ 4.360662] ath9k 0000:01:00.0: probe with driver ath9k failed with error -12

It looks like the device (PCI 0000:01:00.0) tried to load with ath9k but failed.

I am wondering if I could have assistance troubleshooting this.

Thank you!

@pelwell
Copy link
Contributor

pelwell commented Jul 3, 2025

Error 12 is ENOMEM, a pretty fundamental failure while probing. I don't believe it's actually run out of memory, but perhaps it's because of the PCIe space exposed by the card. What does lspci -v report?

@jacob-keller
Copy link
Contributor

Ya. That looks like a pretty fundamental issue with loading the wireless driver.

@wirelessOJ
Copy link

lspci -v reports:

00:00.0 PCI bridge: Broadcom Inc. and subsidiaries BCM2711 PCIe Bridge (rev 20) (prog-if 00 [Normal decode])
      Device tree node: /sys/firmware/devicetree/base/scb/pcie@7d500000/pci@0,0
      Flags: bus master, fast devsel, latency 0, IRQ 27
      Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
      Memory behind bridge: 00000000-000fffff [size=1M] [32-bit]
      Prefetchable memory behind bridge: [disabled] [64-bit]
      Capabilities: <access denied>
      Kernel driver in use: pcieport

01:00.0 Network controller: Qualcomm Atheros AR93xx Wireless Network Adapter (rev 01)
      Subsystem: Qualcomm Atheros AR93xx Wireless Network Adapter
      Flags: fast devsel, IRQ 27
      Memory at 600000000 (64-bit, non-prefetchable) [size=128K]
      Expansion ROM at 600020000 [virtual] [disabled] [size=64K]
      Capabilities: <access denied>
      Kernel modules: ath9k

@wirelessOJ
Copy link

so isn't this a problem with how the ath9k driver was forward ported?

@wirelessOJ
Copy link

@6by9 @pelwell @jacob-keller @CALMorACT If anyone has any advice, I believe something is wrong with the kernel and I am uncertain how to move forward

@jacob-keller
Copy link
Contributor

Unfortunately I don't have much experience with wireless drivers :(

@wirelessOJ
Copy link

wirelessOJ commented Jul 14, 2025

I ended up adding cma=256M and dtoverlay=pcie-32bit-dma to the config.txt file and that has resolved the ath9k initialization errors I was seeing. When I run lscpi -v I can now see too that the kernel driver ath9k is being used.

@jacob-keller
Copy link
Contributor

Try increasing the tx_timestamp_timeout config value for ptp4l. The timestamps may not be returned within the default time, depending on driver/hardware implementation. If a value of 100 or 200 milliseconds still fails then it's likely a bug with the driver never reporting a timestamp for one of the packets.

@wirelessOJ
Copy link

wirelessOJ commented Jul 15, 2025

100 and 200 result in the same error. I am wondering...

when I run ls /sys/class/ptp there is a ptp0 and when I then run readlink /sys/class/ptp/ptp0/device

it points to:

../../../unimac-mdio--19:00

but then when I run ls -l /sys/class/net/*/device

lrwxrwxrwx 1 root root 0 Jul 14 10:39 /sys/class/net/eth0/device -> ../../../fd580000.ethernet

lrwxrwxrwx 1 root root 0 Jul 14 10:39 /sys/class/net/wlan0/device -> ../../../0000:01:00.0

lrwxrwxrwx 1 root root 0 Jul 14 10:39 /sys/class/net/wlan1/device -> ../../../mmc1:0001:1

It shows that the ptp0 devices is the onboard ethernet MDIO interface.

IF the ath9k driver patch was applied correctly, shouldn't there be a wlan0 ptp0 device present? Likewise, I am wondering if the driver is imported correctly, if the error I first see after running./ptp4lthat says interface 'wlan0' does not support requested timestamping mode would still show up as an error no matter what?

I am looking at this issue: zlab-pub/wifi-ptp#8

"Please ensure the "ls /sys/class/net/${WLAN_DEV}/device/ptp" has the right output, it means there is a available PHC/PTP clock for you and the driver patch successfully. You can read the 'dmesg' output for more info if this step is error for you"

I currently do not have a device under wlan0 that is a ptp device. I am thinking that this might indicate a problem with the way the driver patch was applied to this kernel.

@jacob-keller
Copy link
Contributor

Does your ptp4l command hardcode the ptp device? If so, you should stop doing that and rely on the ethtool -T autodetection. What does ethtool -T show for the wlan0 device?

@jacob-keller
Copy link
Contributor

If you use the wrong ptp device for a given network interface things will not work. Maybe the ath9k driver didn't implement the get_ts_info appropriately?

@wirelessOJ
Copy link

wirelessOJ commented Jul 16, 2025

Yes, I don't believe it is implementing as it should. There is no phc_device associated with wlan0.

This is what it shows for the wlan0 interface

ethtool -T wlan0
Time stamping parameters for wlan0:
Capabilities:
      software-receive
      software-system-clock
PTP Hardware Clock: none
Hardware Transmit Timestamp Modes: none
Hardware Receive Filter Modes: none

@jacob-keller
Copy link
Contributor

jacob-keller commented Jul 16, 2025 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants