diff mbox series

[03/18] wifi: iwlwifi: mvm: report hardware timestamps in RX/TX status

Message ID 20230320122330.e0392d498101.I9bf12c8ecfb3f17253a13dc48a48647ddd6e7855@changeid
State New
Headers show
Series wifi: iwlwifi: updates intended for v6.4 2023-03-24 | expand

Commit Message

Greenman, Gregory March 20, 2023, 10:33 a.m. UTC
From: Avraham Stern <avraham.stern@intel.com>

For TM/FTM frames, report the hardware timestamps reported by the
fw as part of the RX/TX status. Since the fw reports the timestamps
in a dedicated notification (and not as part of the RX/TX status),
hold the frame until the fw timestamps notification is received.
Timestamping is enabled when a station is connected and disabled
when disconnected. For AP interface, only the first station will
have timestamping enabled since the fw only supports timestamping
for one peer.

Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
 .../wireless/intel/iwlwifi/fw/api/commands.h  |  18 ++
 .../wireless/intel/iwlwifi/fw/api/datapath.h  | 135 ++++++++++++++
 drivers/net/wireless/intel/iwlwifi/fw/file.h  |   1 +
 .../net/wireless/intel/iwlwifi/mvm/Makefile   |   1 +
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |   8 +
 drivers/net/wireless/intel/iwlwifi/mvm/ops.c  |  14 ++
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c |   7 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  |   8 +
 .../wireless/intel/iwlwifi/mvm/time-sync.c    | 174 ++++++++++++++++++
 .../wireless/intel/iwlwifi/mvm/time-sync.h    |  30 +++
 drivers/net/wireless/intel/iwlwifi/mvm/tx.c   |   4 +-
 11 files changed, 396 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/wireless/intel/iwlwifi/mvm/time-sync.c
 create mode 100644 drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h

Comments

Nathan Chancellor March 31, 2023, 5:51 p.m. UTC | #1
Hi all,

On Mon, Mar 20, 2023 at 12:33:04PM +0200, gregory.greenman@intel.com wrote:
> From: Avraham Stern <avraham.stern@intel.com>
> 
> For TM/FTM frames, report the hardware timestamps reported by the
> fw as part of the RX/TX status. Since the fw reports the timestamps
> in a dedicated notification (and not as part of the RX/TX status),
> hold the frame until the fw timestamps notification is received.
> Timestamping is enabled when a station is connected and disabled
> when disconnected. For AP interface, only the first station will
> have timestamping enabled since the fw only supports timestamping
> for one peer.
> 
> Signed-off-by: Avraham Stern <avraham.stern@intel.com>
> Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>

My apologies if this has been reported and/or fixed already, I did a
search of lore but did not see much that appeared relevant. I bisected
the following warning to this change as commit c7eca79def44 ("wifi:
iwlwifi: mvm: report hardware timestamps in RX/TX status") in -next:

[    4.843020] ------------[ cut here ]------------
[    4.843025] WARNING: CPU: 0 PID: 325 at drivers/net/wireless/intel/iwlwifi/mvm/../iwl-trans.h:1083 iwl_op_mode_mvm_start+0x9aa/0x9c0 [iwlmvm]
[    4.843080] Modules linked in: asix(+) spi_nor uvcvideo(+) polyval_clmulni iwlmvm(+) btbcm(+) mdio_devres i915(+) videobuf2_vmalloc snd_hda_codec_realtek btintel polyval_generic mtd phylink joydev mac80211 btmtk snd_hda_codec_generic asus_nb_wmi videobuf2_memops i2c_algo_bit gf128mul drm_buddy intel_gtt uvc selftests libarc4 ghash_clmulni_intel videobuf2_v4l2 snd_hda_intel iTCO_wdt processor_thermal_device_pci_legacy asus_wmi snd_intel_dspcfg sha512_ssse3 bluetooth at24 hid_multitouch intel_soc_dts_iosf mousedev drm_display_helper videodev usbnet aesni_intel ledtrig_audio intel_pmc_bxt snd_hda_codec iwlwifi ak8975 spi_intel_platform processor_thermal_device mei_hdcp crypto_simd spi_intel sparse_keymap mei_pxp processor_thermal_rfim mii snd_hwdep videobuf2_common drm_kms_helper intel_rapl_msr iTCO_vendor_support cryptd rapl syscopyarea platform_profile intel_cstate snd_hda_core libphy processor_thermal_mbox vfat fat mc intel_uncore crc16 sysfillrect snd_pcm processor_thermal_rapl ecdh_generic pcspkr i2c_i801 snd_timer
[    4.843176]  usbhid sysimgblt cfg80211 snd psmouse intel_rapl_common cec lpc_ich mei_me inv_mpu6050_i2c int340x_thermal_zone soundcore mei i2c_smbus rfkill ttm video i2c_mux dell_smo8800 inv_mpu6050 acpi_als wmi industrialio_triggered_buffer kfifo_buf int3400_thermal industrialio soc_button_array acpi_thermal_rel asus_wireless mac_hid lzo_rle pkcs8_key_parser dm_mod drm crypto_user loop fuse zram bpf_preload ip_tables x_tables serio_raw atkbd libps2 vivaldi_fmap xhci_pci xhci_pci_renesas i8042 serio btrfs blake2b_generic xor raid6_pq libcrc32c crc32c_generic crc32c_intel
[    4.843240] CPU: 0 PID: 325 Comm: modprobe Not tainted 6.3.0-rc1-debug-00495-gc7eca79def44 #1 a4d5f87d096a215486e36913932219012550f685
[    4.843244] Hardware name: ASUSTeK COMPUTER INC. Q302LA/Q302LA, BIOS Q302LA.203 05/15/2014
[    4.843246] RIP: 0010:iwl_op_mode_mvm_start+0x9aa/0x9c0 [iwlmvm]
[    4.843290] Code: 49 c7 c0 c8 fa c1 c1 31 d2 be 40 00 00 00 48 c7 c1 30 63 c1 c1 48 8b 78 40 e8 c2 1b 20 ff e9 1c fd ff ff 0f 0b e9 3a fe ff ff <0f> 0b e9 0e fc ff ff 0f 0b e9 2c fe ff ff e8 43 9c 6e c6 0f 1f 00
[    4.843293] RSP: 0018:ffffb72e805afc58 EFLAGS: 00010286
[    4.843296] RAX: 00000000ffffffff RBX: ffff99bc92c2a080 RCX: ffffffffc1c16b80
[    4.843299] RDX: 0000000000000260 RSI: 0000000000000068 RDI: ffffffffc1c16920
[    4.843302] RBP: ffff99bc94d2c028 R08: 0000000000000059 R09: ffffffffc1c16480
[    4.843304] R10: ffffffffc1c16550 R11: 0000000000000001 R12: ffff99bc92c2a088
[    4.843306] R13: 0000000fffffffe0 R14: ffff99bc83c7e010 R15: ffffb72e805afc60
[    4.843309] FS:  00007f05697f2740(0000) GS:ffff99bd96e00000(0000) knlGS:0000000000000000
[    4.843312] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    4.843315] CR2: 00007fba940d0c3e CR3: 0000000101da8006 CR4: 00000000001706f0
[    4.843318] Call Trace:
[    4.843321]  <TASK>
[    4.843328]  _iwl_op_mode_start+0x9b/0xc0 [iwlwifi 816e2f3ee29c5271f5f7be3fda523a489541761f]
[    4.843368]  iwl_opmode_register+0x6c/0xe0 [iwlwifi 816e2f3ee29c5271f5f7be3fda523a489541761f]
[    4.843400]  ? __pfx_init_module+0x10/0x10 [iwlmvm b9e7319e6775482213302e32712682db1169b8ac]
[    4.843440]  iwl_mvm_init+0x26/0xff0 [iwlmvm b9e7319e6775482213302e32712682db1169b8ac]
[    4.843480]  ? __pfx_init_module+0x10/0x10 [iwlmvm b9e7319e6775482213302e32712682db1169b8ac]
[    4.843517]  do_one_initcall+0x5d/0x240
[    4.843525]  do_init_module+0x4a/0x200
[    4.843532]  __do_sys_init_module+0x17f/0x1b0
[    4.843540]  do_syscall_64+0x5f/0x90
[    4.843545]  ? ksys_read+0x6f/0xf0
[    4.843551]  ? syscall_exit_to_user_mode+0x1b/0x40
[    4.843556]  ? do_syscall_64+0x6b/0x90
[    4.843560]  entry_SYSCALL_64_after_hwframe+0x72/0xdc
[    4.843566] RIP: 0033:0x7f0569121eee
[    4.843584] Code: 48 8b 0d 85 ee 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 af 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 52 ee 0c 00 f7 d8 64 89 01 48
[    4.843587] RSP: 002b:00007fff32834278 EFLAGS: 00000246 ORIG_RAX: 00000000000000af
[    4.843591] RAX: ffffffffffffffda RBX: 000055de38cbbba0 RCX: 00007f0569121eee
[    4.843593] RDX: 000055de379efcb2 RSI: 0000000000195667 RDI: 000055de38ec0d00
[    4.843595] RBP: 000055de379efcb2 R08: 27d4eb2f165667c5 R09: 0000000000000000
[    4.843598] R10: 00000000001fd711 R11: 0000000000000246 R12: 0000000000040000
[    4.843600] R13: 000055de38cbbcd0 R14: 0000000000000000 R15: 000055de38cbdec0
[    4.843605]  </TASK>
[    4.843606] ---[ end trace 0000000000000000 ]---

The output of 'sudo lspci -vvv -s 02:00.0', in case it is helpful:

02:00.0 Network controller: Intel Corporation Wireless 7260 (rev cb)
	Subsystem: Intel Corporation Dual Band Wireless-AC 7260
	Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0, Cache Line Size: 64 bytes
	Interrupt: pin A routed to IRQ 49
	Region 0: Memory at f7c00000 (64-bit, non-prefetchable) [size=8K]
	Capabilities: [c8] Power Management version 3
		Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
		Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
	Capabilities: [d0] MSI: Enable+ Count=1/1 Maskable- 64bit+
		Address: 00000000fee04004  Data: 0024
	Capabilities: [40] Express (v2) Endpoint, MSI 00
		DevCap:	MaxPayload 128 bytes, PhantFunc 0, Latency L0s <512ns, L1 unlimited
			ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset+ SlotPowerLimit 0W
		DevCtl:	CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
			RlxdOrd- ExtTag- PhantFunc- AuxPwr+ NoSnoop+ FLReset-
			MaxPayload 128 bytes, MaxReadReq 128 bytes
		DevSta:	CorrErr+ NonFatalErr- FatalErr- UnsupReq+ AuxPwr+ TransPend-
		LnkCap:	Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <4us, L1 <32us
			ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp-
		LnkCtl:	ASPM L1 Enabled; RCB 64 bytes, Disabled- CommClk+
			ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
		LnkSta:	Speed 2.5GT/s, Width x1
			TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
		DevCap2: Completion Timeout: Range B, TimeoutDis+ NROPrPrP- LTR+
			 10BitTagComp- 10BitTagReq- OBFF Via WAKE#, ExtFmt- EETLPPrefix-
			 EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
			 FRS- TPHComp- ExtTPHComp-
			 AtomicOpsCap: 32bit- 64bit- 128bitCAS-
		DevCtl2: Completion Timeout: 16ms to 55ms, TimeoutDis- LTR+ 10BitTagReq- OBFF Disabled,
			 AtomicOpsCtl: ReqEn-
		LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-
			 Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
			 Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
		LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete- EqualizationPhase1-
			 EqualizationPhase2- EqualizationPhase3- LinkEqualizationRequest-
			 Retimer- 2Retimers- CrosslinkRes: unsupported
	Capabilities: [100 v1] Advanced Error Reporting
		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
		UESvrt:	DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr-
		CEMsk:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
		AERCap:	First Error Pointer: 00, ECRCGenCap- ECRCGenEn- ECRCChkCap- ECRCChkEn-
			MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
		HeaderLog: 00000000 00000000 00000000 00000000
	Capabilities: [140 v1] Device Serial Number a0-a8-cd-ff-ff-7a-2c-81
	Capabilities: [14c v1] Latency Tolerance Reporting
		Max snoop latency: 3145728ns
		Max no snoop latency: 3145728ns
	Capabilities: [154 v1] Vendor Specific Information: ID=cafe Rev=1 Len=014 <?>
	Kernel driver in use: iwlwifi
	Kernel modules: iwlwifi

If there is any additional information that I can provide or patches I
can test, I am more than happy to do so.

Cheers,
Nathan

# bad: [4b0f4525dc4fe8af17b3daefe585f0c2eb0fe0a5] Add linux-next specific files for 20230331
# good: [b2bc47e9b2011a183f9d3d3454a294a938082fb9] Merge tag 'net-6.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
git bisect start '4b0f4525dc4fe8af17b3daefe585f0c2eb0fe0a5' 'b2bc47e9b2011a183f9d3d3454a294a938082fb9'
# bad: [ed5f95f3349003d74a4a11b27b0f05d6794c382a] Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
git bisect bad ed5f95f3349003d74a4a11b27b0f05d6794c382a
# good: [a9b4a69e674abf5612e9201c0092f3be4ea47202] Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6.git
git bisect good a9b4a69e674abf5612e9201c0092f3be4ea47202
# good: [79548b7984e4c606c6caaad72a0864a83855ebc9] Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
git bisect good 79548b7984e4c606c6caaad72a0864a83855ebc9
# good: [bafe06064a0979c2955902038c7bcde9a642c919] Merge branch 'thermal/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux.git
git bisect good bafe06064a0979c2955902038c7bcde9a642c919
# good: [a725238d9bbcc774b0561b6d10657dcee22a95c3] Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git
git bisect good a725238d9bbcc774b0561b6d10657dcee22a95c3
# bad: [b7e39d565fe1d32c6d8253340d577cc53fad03d8] wifi: iwlwifi: mvm: use STA link address
git bisect bad b7e39d565fe1d32c6d8253340d577cc53fad03d8
# good: [1595ecce1cf32688760281f40b58b7a1d4a69aa9] wifi: iwlwifi: mvm: add support for PTP HW clock (PHC)
git bisect good 1595ecce1cf32688760281f40b58b7a1d4a69aa9
# bad: [6cf882d9aa9e8f1f2d63182e179ac4b2e59c00db] wifi: iwlwifi: mvm: Use 64-bit division helper in iwl_mvm_get_crosstimestamp_fw()
git bisect bad 6cf882d9aa9e8f1f2d63182e179ac4b2e59c00db
# bad: [e626dad92383ca16d1d71e66124a272a0cbfe7bd] wifi: mac80211: fix race in mesh sequence number assignment
git bisect bad e626dad92383ca16d1d71e66124a272a0cbfe7bd
# bad: [f5034bcf6868bf5c2de272819aa6de23f5d588f7] wifi: iwlwifi: mvm: Don't send MAC CTXT cmd after deauthorization
git bisect bad f5034bcf6868bf5c2de272819aa6de23f5d588f7
# bad: [a5de7de7e78eddd3ae16aec01c5601ae36c1c2e8] wifi: iwlwifi: mvm: enable TX beacon protection
git bisect bad a5de7de7e78eddd3ae16aec01c5601ae36c1c2e8
# bad: [c7eca79def44f1faf024d8442044287bef749818] wifi: iwlwifi: mvm: report hardware timestamps in RX/TX status
git bisect bad c7eca79def44f1faf024d8442044287bef749818
# good: [21fb8da6ebe40ce83468d6198143b4b583b967f9] wifi: iwlwifi: mvm: read synced time from firmware if supported
git bisect good 21fb8da6ebe40ce83468d6198143b4b583b967f9
# first bad commit: [c7eca79def44f1faf024d8442044287bef749818] wifi: iwlwifi: mvm: report hardware timestamps in RX/TX status
Greenman, Gregory April 10, 2023, 2:12 p.m. UTC | #2
On Fri, 2023-03-31 at 10:51 -0700, Nathan Chancellor wrote:
> Hi all,
> 
> On Mon, Mar 20, 2023 at 12:33:04PM +0200, gregory.greenman@intel.com wrote:
> > From: Avraham Stern <avraham.stern@intel.com>
> > 
> > For TM/FTM frames, report the hardware timestamps reported by the
> > fw as part of the RX/TX status. Since the fw reports the timestamps
> > in a dedicated notification (and not as part of the RX/TX status),
> > hold the frame until the fw timestamps notification is received.
> > Timestamping is enabled when a station is connected and disabled
> > when disconnected. For AP interface, only the first station will
> > have timestamping enabled since the fw only supports timestamping
> > for one peer.
> > 
> > Signed-off-by: Avraham Stern <avraham.stern@intel.com>
> > Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
> 
> My apologies if this has been reported and/or fixed already, I did a
> search of lore but did not see much that appeared relevant. I bisected
> the following warning to this change as commit c7eca79def44 ("wifi:
> iwlwifi: mvm: report hardware timestamps in RX/TX status") in -next:
> 
> [    4.843020] ------------[ cut here ]------------
> [    4.843025] WARNING: CPU: 0 PID: 325 at drivers/net/wireless/intel/iwlwifi/mvm/../iwl-trans.h:1083 iwl_op_mode_mvm_start+0x9aa/0x9c0 [iwlmvm]
> [    4.843080] Modules linked in: asix(+) spi_nor uvcvideo(+) polyval_clmulni iwlmvm(+) btbcm(+) mdio_devres i915(+) videobuf2_vmalloc snd_hda_codec_realtek btintel polyval_generic mtd phylink
> joydev mac80211 btmtk snd_hda_codec_generic asus_nb_wmi videobuf2_memops i2c_algo_bit gf128mul drm_buddy intel_gtt uvc selftests libarc4 ghash_clmulni_intel videobuf2_v4l2 snd_hda_intel iTCO_wdt
> processor_thermal_device_pci_legacy asus_wmi snd_intel_dspcfg sha512_ssse3 bluetooth at24 hid_multitouch intel_soc_dts_iosf mousedev drm_display_helper videodev usbnet aesni_intel ledtrig_audio
> intel_pmc_bxt snd_hda_codec iwlwifi ak8975 spi_intel_platform processor_thermal_device mei_hdcp crypto_simd spi_intel sparse_keymap mei_pxp processor_thermal_rfim mii snd_hwdep videobuf2_common
> drm_kms_helper intel_rapl_msr iTCO_vendor_support cryptd rapl syscopyarea platform_profile intel_cstate snd_hda_core libphy processor_thermal_mbox vfat fat mc intel_uncore crc16 sysfillrect snd_pcm
> processor_thermal_rapl ecdh_generic pcspkr i2c_i801 snd_timer
> [    4.843176]  usbhid sysimgblt cfg80211 snd psmouse intel_rapl_common cec lpc_ich mei_me inv_mpu6050_i2c int340x_thermal_zone soundcore mei i2c_smbus rfkill ttm video i2c_mux dell_smo8800
> inv_mpu6050 acpi_als wmi industrialio_triggered_buffer kfifo_buf int3400_thermal industrialio soc_button_array acpi_thermal_rel asus_wireless mac_hid lzo_rle pkcs8_key_parser dm_mod drm crypto_user
> loop fuse zram bpf_preload ip_tables x_tables serio_raw atkbd libps2 vivaldi_fmap xhci_pci xhci_pci_renesas i8042 serio btrfs blake2b_generic xor raid6_pq libcrc32c crc32c_generic crc32c_intel
> [    4.843240] CPU: 0 PID: 325 Comm: modprobe Not tainted 6.3.0-rc1-debug-00495-gc7eca79def44 #1 a4d5f87d096a215486e36913932219012550f685
> [    4.843244] Hardware name: ASUSTeK COMPUTER INC. Q302LA/Q302LA, BIOS Q302LA.203 05/15/2014
> [    4.843246] RIP: 0010:iwl_op_mode_mvm_start+0x9aa/0x9c0 [iwlmvm]
> [    4.843290] Code: 49 c7 c0 c8 fa c1 c1 31 d2 be 40 00 00 00 48 c7 c1 30 63 c1 c1 48 8b 78 40 e8 c2 1b 20 ff e9 1c fd ff ff 0f 0b e9 3a fe ff ff <0f> 0b e9 0e fc ff ff 0f 0b e9 2c fe ff ff e8 43
> 9c 6e c6 0f 1f 00
> [    4.843293] RSP: 0018:ffffb72e805afc58 EFLAGS: 00010286
> [    4.843296] RAX: 00000000ffffffff RBX: ffff99bc92c2a080 RCX: ffffffffc1c16b80
> [    4.843299] RDX: 0000000000000260 RSI: 0000000000000068 RDI: ffffffffc1c16920
> [    4.843302] RBP: ffff99bc94d2c028 R08: 0000000000000059 R09: ffffffffc1c16480
> [    4.843304] R10: ffffffffc1c16550 R11: 0000000000000001 R12: ffff99bc92c2a088
> [    4.843306] R13: 0000000fffffffe0 R14: ffff99bc83c7e010 R15: ffffb72e805afc60
> [    4.843309] FS:  00007f05697f2740(0000) GS:ffff99bd96e00000(0000) knlGS:0000000000000000
> [    4.843312] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [    4.843315] CR2: 00007fba940d0c3e CR3: 0000000101da8006 CR4: 00000000001706f0
> [    4.843318] Call Trace:
> [    4.843321]  <TASK>
> [    4.843328]  _iwl_op_mode_start+0x9b/0xc0 [iwlwifi 816e2f3ee29c5271f5f7be3fda523a489541761f]
> [    4.843368]  iwl_opmode_register+0x6c/0xe0 [iwlwifi 816e2f3ee29c5271f5f7be3fda523a489541761f]
> [    4.843400]  ? __pfx_init_module+0x10/0x10 [iwlmvm b9e7319e6775482213302e32712682db1169b8ac]
> [    4.843440]  iwl_mvm_init+0x26/0xff0 [iwlmvm b9e7319e6775482213302e32712682db1169b8ac]
> [    4.843480]  ? __pfx_init_module+0x10/0x10 [iwlmvm b9e7319e6775482213302e32712682db1169b8ac]
> [    4.843517]  do_one_initcall+0x5d/0x240
> [    4.843525]  do_init_module+0x4a/0x200
> [    4.843532]  __do_sys_init_module+0x17f/0x1b0
> [    4.843540]  do_syscall_64+0x5f/0x90
> [    4.843545]  ? ksys_read+0x6f/0xf0
> [    4.843551]  ? syscall_exit_to_user_mode+0x1b/0x40
> [    4.843556]  ? do_syscall_64+0x6b/0x90
> [    4.843560]  entry_SYSCALL_64_after_hwframe+0x72/0xdc
> [    4.843566] RIP: 0033:0x7f0569121eee
> [    4.843584] Code: 48 8b 0d 85 ee 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 af 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 52 ee 0c 00
> f7 d8 64 89 01 48
> [    4.843587] RSP: 002b:00007fff32834278 EFLAGS: 00000246 ORIG_RAX: 00000000000000af
> [    4.843591] RAX: ffffffffffffffda RBX: 000055de38cbbba0 RCX: 00007f0569121eee
> [    4.843593] RDX: 000055de379efcb2 RSI: 0000000000195667 RDI: 000055de38ec0d00
> [    4.843595] RBP: 000055de379efcb2 R08: 27d4eb2f165667c5 R09: 0000000000000000
> [    4.843598] R10: 00000000001fd711 R11: 0000000000000246 R12: 0000000000040000
> [    4.843600] R13: 000055de38cbbcd0 R14: 0000000000000000 R15: 000055de38cbdec0
> [    4.843605]  </TASK>
> [    4.843606] ---[ end trace 0000000000000000 ]---
> 
> The output of 'sudo lspci -vvv -s 02:00.0', in case it is helpful:
> 
> 02:00.0 Network controller: Intel Corporation Wireless 7260 (rev cb)
>         Subsystem: Intel Corporation Dual Band Wireless-AC 7260
>         Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
>         Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
>         Latency: 0, Cache Line Size: 64 bytes
>         Interrupt: pin A routed to IRQ 49
>         Region 0: Memory at f7c00000 (64-bit, non-prefetchable) [size=8K]
>         Capabilities: [c8] Power Management version 3
>                 Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
>                 Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
>         Capabilities: [d0] MSI: Enable+ Count=1/1 Maskable- 64bit+
>                 Address: 00000000fee04004  Data: 0024
>         Capabilities: [40] Express (v2) Endpoint, MSI 00
>                 DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <512ns, L1 unlimited
>                         ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset+ SlotPowerLimit 0W
>                 DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
>                         RlxdOrd- ExtTag- PhantFunc- AuxPwr+ NoSnoop+ FLReset-
>                         MaxPayload 128 bytes, MaxReadReq 128 bytes
>                 DevSta: CorrErr+ NonFatalErr- FatalErr- UnsupReq+ AuxPwr+ TransPend-
>                 LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Exit Latency L0s <4us, L1 <32us
>                         ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp-
>                 LnkCtl: ASPM L1 Enabled; RCB 64 bytes, Disabled- CommClk+
>                         ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
>                 LnkSta: Speed 2.5GT/s, Width x1
>                         TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
>                 DevCap2: Completion Timeout: Range B, TimeoutDis+ NROPrPrP- LTR+
>                          10BitTagComp- 10BitTagReq- OBFF Via WAKE#, ExtFmt- EETLPPrefix-
>                          EmergencyPowerReduction Not Supported, EmergencyPowerReductionInit-
>                          FRS- TPHComp- ExtTPHComp-
>                          AtomicOpsCap: 32bit- 64bit- 128bitCAS-
>                 DevCtl2: Completion Timeout: 16ms to 55ms, TimeoutDis- LTR+ 10BitTagReq- OBFF Disabled,
>                          AtomicOpsCtl: ReqEn-
>                 LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-
>                          Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
>                          Compliance Preset/De-emphasis: -6dB de-emphasis, 0dB preshoot
>                 LnkSta2: Current De-emphasis Level: -3.5dB, EqualizationComplete- EqualizationPhase1-
>                          EqualizationPhase2- EqualizationPhase3- LinkEqualizationRequest-
>                          Retimer- 2Retimers- CrosslinkRes: unsupported
>         Capabilities: [100 v1] Advanced Error Reporting
>                 UESta:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
>                 UEMsk:  DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
>                 UESvrt: DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
>                 CESta:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr-
>                 CEMsk:  RxErr- BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr+
>                 AERCap: First Error Pointer: 00, ECRCGenCap- ECRCGenEn- ECRCChkCap- ECRCChkEn-
>                         MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
>                 HeaderLog: 00000000 00000000 00000000 00000000
>         Capabilities: [140 v1] Device Serial Number a0-a8-cd-ff-ff-7a-2c-81
>         Capabilities: [14c v1] Latency Tolerance Reporting
>                 Max snoop latency: 3145728ns
>                 Max no snoop latency: 3145728ns
>         Capabilities: [154 v1] Vendor Specific Information: ID=cafe Rev=1 Len=014 <?>
>         Kernel driver in use: iwlwifi
>         Kernel modules: iwlwifi
> 
> If there is any additional information that I can provide or patches I
> can test, I am more than happy to do so.
> 
> Cheers,
> Nathan
> 
> # bad: [4b0f4525dc4fe8af17b3daefe585f0c2eb0fe0a5] Add linux-next specific files for 20230331
> # good: [b2bc47e9b2011a183f9d3d3454a294a938082fb9] Merge tag 'net-6.3-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
> git bisect start '4b0f4525dc4fe8af17b3daefe585f0c2eb0fe0a5' 'b2bc47e9b2011a183f9d3d3454a294a938082fb9'
> # bad: [ed5f95f3349003d74a4a11b27b0f05d6794c382a] Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
> git bisect bad ed5f95f3349003d74a4a11b27b0f05d6794c382a
> # good: [a9b4a69e674abf5612e9201c0092f3be4ea47202] Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6.git
> git bisect good a9b4a69e674abf5612e9201c0092f3be4ea47202
> # good: [79548b7984e4c606c6caaad72a0864a83855ebc9] Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
> git bisect good 79548b7984e4c606c6caaad72a0864a83855ebc9
> # good: [bafe06064a0979c2955902038c7bcde9a642c919] Merge branch 'thermal/linux-next' of git://git.kernel.org/pub/scm/linux/kernel/git/thermal/linux.git
> git bisect good bafe06064a0979c2955902038c7bcde9a642c919
> # good: [a725238d9bbcc774b0561b6d10657dcee22a95c3] Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next.git
> git bisect good a725238d9bbcc774b0561b6d10657dcee22a95c3
> # bad: [b7e39d565fe1d32c6d8253340d577cc53fad03d8] wifi: iwlwifi: mvm: use STA link address
> git bisect bad b7e39d565fe1d32c6d8253340d577cc53fad03d8
> # good: [1595ecce1cf32688760281f40b58b7a1d4a69aa9] wifi: iwlwifi: mvm: add support for PTP HW clock (PHC)
> git bisect good 1595ecce1cf32688760281f40b58b7a1d4a69aa9
> # bad: [6cf882d9aa9e8f1f2d63182e179ac4b2e59c00db] wifi: iwlwifi: mvm: Use 64-bit division helper in iwl_mvm_get_crosstimestamp_fw()
> git bisect bad 6cf882d9aa9e8f1f2d63182e179ac4b2e59c00db
> # bad: [e626dad92383ca16d1d71e66124a272a0cbfe7bd] wifi: mac80211: fix race in mesh sequence number assignment
> git bisect bad e626dad92383ca16d1d71e66124a272a0cbfe7bd
> # bad: [f5034bcf6868bf5c2de272819aa6de23f5d588f7] wifi: iwlwifi: mvm: Don't send MAC CTXT cmd after deauthorization
> git bisect bad f5034bcf6868bf5c2de272819aa6de23f5d588f7
> # bad: [a5de7de7e78eddd3ae16aec01c5601ae36c1c2e8] wifi: iwlwifi: mvm: enable TX beacon protection
> git bisect bad a5de7de7e78eddd3ae16aec01c5601ae36c1c2e8
> # bad: [c7eca79def44f1faf024d8442044287bef749818] wifi: iwlwifi: mvm: report hardware timestamps in RX/TX status
> git bisect bad c7eca79def44f1faf024d8442044287bef749818
> # good: [21fb8da6ebe40ce83468d6198143b4b583b967f9] wifi: iwlwifi: mvm: read synced time from firmware if supported
> git bisect good 21fb8da6ebe40ce83468d6198143b4b583b967f9
> # first bad commit: [c7eca79def44f1faf024d8442044287bef749818] wifi: iwlwifi: mvm: report hardware timestamps in RX/TX status

Thanks for the report and bisect! I've sent a fix for this WARN_ON() error.

Best regards,
Gregory
diff mbox series

Patch

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
index 28c87a480246..111d96cbde6f 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/commands.h
@@ -265,6 +265,24 @@  enum iwl_legacy_cmds {
 	 */
 	HOT_SPOT_CMD = 0x53,
 
+	/**
+	 * @WNM_80211V_TIMING_MEASUREMENT_NOTIFICATION: Time Sync
+	 *	measurement notification for TM/FTM. Sent on receipt of
+	 *	respective WNM action frame for TM protocol or public action
+	 *	frame for FTM protocol from peer device along with additional
+	 *	meta data specified in &struct iwl_time_msmt_notify
+	 */
+	WNM_80211V_TIMING_MEASUREMENT_NOTIFICATION = 0x67,
+
+	/**
+	 * @WNM_80211V_TIMING_MEASUREMENT_CONFIRM_NOTIFICATION: Time Sync
+	 *	measurement confirmation notification for TM/FTM. Sent on
+	 *	receipt of Ack from peer for previously Tx'ed TM/FTM
+	 *	action frame along with additional meta data specified in
+	 *	&struct iwl_time_msmt_cfm_notify
+	 */
+	WNM_80211V_TIMING_MEASUREMENT_CONFIRM_NOTIFICATION = 0x68,
+
 	/**
 	 * @SCAN_OFFLOAD_COMPLETE:
 	 * notification, &struct iwl_periodic_scan_complete
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
index 59db52f32e43..6f59381b9f9a 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/datapath.h
@@ -31,6 +31,12 @@  enum iwl_data_path_subcmd_ids {
 	 */
 	WNM_PLATFORM_PTM_REQUEST_CMD = 0x3,
 
+	/**
+	 * @WNM_80211V_TIMING_MEASUREMENT_CONFIG_CMD:
+	 *	&struct iwl_time_sync_cfg_cmd
+	 */
+	WNM_80211V_TIMING_MEASUREMENT_CONFIG_CMD = 0x4,
+
 	/**
 	 * @STA_HE_CTXT_CMD: &struct iwl_he_sta_context_cmd
 	 */
@@ -151,6 +157,25 @@  enum iwl_channel_estimation_flags {
 	IWL_CHANNEL_ESTIMATION_COUNTER	= BIT(2),
 };
 
+enum iwl_time_sync_protocol_type {
+	IWL_TIME_SYNC_PROTOCOL_TM	= BIT(0),
+	IWL_TIME_SYNC_PROTOCOL_FTM	= BIT(1),
+}; /* WNM_TIMING_ENABLED_PROTOCOL_API_E_VER_1 */
+
+/**
+ * struct iwl_time_sync_cfg_cmd - TM/FTM time sync measurement configuration
+ *
+ * @protocols: The type of frames to raise notifications for. A bitmap
+ *	of @iwl_time_sync_protocol_type
+ * @peer_addr: peer address with which TM/FTM measurements are required
+ * @reserved: for alignment
+ */
+struct iwl_time_sync_cfg_cmd {
+	__le32 protocols;
+	u8 peer_addr[ETH_ALEN];
+	u8 reserved[2];
+} __packed; /* WNM_80211V_TIMING_MEASUREMENT_CONFIG_CMD_API_S_VER_1 */
+
 /**
  * enum iwl_synced_time_operation - PTM request options
  *
@@ -193,6 +218,116 @@  struct iwl_synced_time_rsp {
 	__le32 gp2_timestamp_lo;
 } __packed; /* WNM_80211V_TIMING_RSP_API_S_VER_1 */
 
+/* PTP_CTX_MAX_DATA_SIZE_IN_API_D_VER_1 */
+#define PTP_CTX_MAX_DATA_SIZE   128
+
+/**
+ * struct iwl_time_msmt_ptp_ctx - Vendor specific information element
+ * to allow a space for flexibility for the userspace App
+ *
+ * @element_id: element id of vendor specific ie
+ * @length: length of vendor specific ie
+ * @reserved: for alignment
+ * @data: vendor specific data blob
+ */
+struct iwl_time_msmt_ptp_ctx {
+	/* Differentiate between FTM and TM specific Vendor IEs */
+	union {
+		struct {
+			u8 element_id;
+			u8 length;
+			__le16 reserved;
+			u8 data[PTP_CTX_MAX_DATA_SIZE];
+		} ftm; /* FTM specific vendor IE */
+		struct {
+			u8 element_id;
+			u8 length;
+			u8 data[PTP_CTX_MAX_DATA_SIZE];
+		} tm; /* TM specific vendor IE */
+	};
+} __packed /* PTP_CTX_VER_1 */;
+
+/**
+ * struct iwl_time_msmt_notify - Time Sync measurement notification
+ * for TM/FTM, along with additional meta data.
+ *
+ * @peer_addr: peer address
+ * @reserved: for alignment
+ * @dialog_token: measurement flow dialog token number
+ * @followup_dialog_token: Measurement flow previous dialog token number
+ * @t1_hi: high dword of t1-time of the Tx'ed action frame departure on
+ *	sender side in units of 10 nano seconds
+ * @t1_lo: low dword of t1-time of the Tx'ed action frame departure on
+ *	sender side in units of 10 nano seconds
+ * @t1_max_err: maximum t1-time error in units of 10 nano seconds
+ * @t4_hi: high dword of t4-time of the Rx'ed action frame's Ack arrival on
+ *	sender side in units of 10 nano seconds
+ * @t4_lo: low dword of t4-time of the Rx'ed action frame's Ack arrival on
+ *	sender side in units of 10 nano seconds
+ * @t4_max_err: maximum t4-time error in units of 10 nano seconds
+ * @t2_hi: high dword of t2-time of the Rx'ed action frame arrival on
+ *	receiver side in units of 10 nano seconds
+ * @t2_lo: low dword of t2-time of the Rx'ed action frame arrival on
+ *	receiver side in units of 10 nano seconds
+ * @t2_max_err: maximum t2-time error in units of 10 nano seconds
+ * @t3_hi: high dword of t3-time of the Tx'ed action frame's Ack departure on
+ *	receiver side in units of 10 nano seconds
+ * @t3_lo: low dword of t3-time of the Tx'ed action frame's Ack departure on
+ *	receiver side in units of 10 nano seconds
+ * @t3_max_err: maximum t3-time error in units of 10 nano seconds
+ * @ptp: vendor specific information element
+ */
+struct iwl_time_msmt_notify {
+	u8 peer_addr[ETH_ALEN];
+	u8 reserved[2];
+	__le32 dialog_token;
+	__le32 followup_dialog_token;
+	__le32 t1_hi;
+	__le32 t1_lo;
+	__le32 t1_max_err;
+	__le32 t4_hi;
+	__le32 t4_lo;
+	__le32 t4_max_err;
+	__le32 t2_hi;
+	__le32 t2_lo;
+	__le32 t2_max_err;
+	__le32 t3_hi;
+	__le32 t3_lo;
+	__le32 t3_max_err;
+	struct iwl_time_msmt_ptp_ctx ptp;
+} __packed; /* WNM_80211V_TIMING_MEASUREMENT_NTFY_API_S_VER_1 */
+
+/**
+ * struct iwl_time_msmt_cfm_notify - Time Sync measurement confirmation
+ * notification for TM/FTM. Sent on receipt of 802.11 Ack from peer for the
+ * Tx'ed TM/FTM measurement action frame.
+ *
+ * @peer_addr: peer address
+ * @reserved: for alignment
+ * @dialog_token: measurement flow dialog token number
+ * @t1_hi: high dword of t1-time of the Tx'ed action frame departure on
+ *	sender side in units of 10 nano seconds
+ * @t1_lo: low dword of t1-time of the Tx'ed action frame departure on
+ *	sender side in units of 10 nano seconds
+ * @t1_max_err: maximum t1-time error in units of 10 nano seconds
+ * @t4_hi: high dword of t4-time of the Rx'ed action frame's Ack arrival on
+ *	sender side in units of 10 nano seconds
+ * @t4_lo: low dword of t4-time of the Rx'ed action frame's Ack arrival on
+ *	sender side in units of 10 nano seconds
+ * @t4_max_err: maximum t4-time error in units of 10 nano seconds
+ */
+struct iwl_time_msmt_cfm_notify {
+	u8 peer_addr[ETH_ALEN];
+	u8 reserved[2];
+	__le32 dialog_token;
+	__le32 t1_hi;
+	__le32 t1_lo;
+	__le32 t1_max_err;
+	__le32 t4_hi;
+	__le32 t4_lo;
+	__le32 t4_max_err;
+} __packed; /* WNM_80211V_TIMING_MEASUREMENT_CONFIRM_NTFY_API_S_VER_1 */
+
 /**
  * struct iwl_channel_estimation_cfg - channel estimation reporting config
  */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index e4b2f1a87575..1c47046e8f69 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -456,6 +456,7 @@  enum iwl_ucode_tlv_capa {
 	IWL_UCODE_TLV_CAPA_DRAM_FRAG_SUPPORT		= (__force iwl_ucode_tlv_capa_t)104,
 	IWL_UCODE_TLV_CAPA_DUMP_COMPLETE_SUPPORT	= (__force iwl_ucode_tlv_capa_t)105,
 	IWL_UCODE_TLV_CAPA_SYNCED_TIME			= (__force iwl_ucode_tlv_capa_t)106,
+	IWL_UCODE_TLV_CAPA_TIME_SYNC_BOTH_FTM_TM        = (__force iwl_ucode_tlv_capa_t)108,
 
 #ifdef __CHECKER__
 	/* sparse says it cannot increment the previous enum member */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/Makefile b/drivers/net/wireless/intel/iwlwifi/mvm/Makefile
index 943e8de9bc98..593fe28d89cf 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/Makefile
@@ -9,6 +9,7 @@  iwlmvm-y += ftm-responder.o ftm-initiator.o
 iwlmvm-y += rfi.o
 iwlmvm-y += mld-key.o mld-mac.o link.o mld-sta.o mld-mac80211.o
 iwlmvm-y += ptp.o
+iwlmvm-y += time-sync.o
 iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
 iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o
 iwlmvm-$(CONFIG_PM) += d3.o
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index 4d99e76811a3..b6b73164357d 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -781,6 +781,12 @@  struct ptp_data {
 	struct delayed_work dwork;
 };
 
+struct iwl_time_sync_data {
+	struct sk_buff_head frame_list;
+	u8 peer_addr[ETH_ALEN];
+	bool active;
+};
+
 struct iwl_mvm {
 	/* for logger access */
 	struct device *dev;
@@ -1126,6 +1132,8 @@  struct iwl_mvm {
 	bool sta_remove_requires_queue_remove;
 
 	bool pldr_sync;
+
+	struct iwl_time_sync_data time_sync;
 };
 
 /* Extract MVM priv from op_mode and _hw */
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
index e7def1a0f767..70926bb1df6c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
@@ -29,6 +29,7 @@ 
 #include "fw-api.h"
 #include "fw/acpi.h"
 #include "fw/uefi.h"
+#include "time-sync.h"
 
 #define DRV_DESCRIPTION	"The new Intel(R) wireless AGN driver for Linux"
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -404,6 +405,15 @@  static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
 	RX_HANDLER_GRP(SYSTEM_GROUP, RFI_DEACTIVATE_NOTIF,
 		       iwl_rfi_deactivate_notif_handler, RX_HANDLER_ASYNC_UNLOCKED,
 		       struct iwl_rfi_deactivate_notif),
+
+	RX_HANDLER_GRP(LEGACY_GROUP,
+		       WNM_80211V_TIMING_MEASUREMENT_NOTIFICATION,
+		       iwl_mvm_time_sync_msmt_event, RX_HANDLER_SYNC,
+		       struct iwl_time_msmt_notify),
+	RX_HANDLER_GRP(LEGACY_GROUP,
+		       WNM_80211V_TIMING_MEASUREMENT_CONFIRM_NOTIFICATION,
+		       iwl_mvm_time_sync_msmt_confirm_event, RX_HANDLER_SYNC,
+		       struct iwl_time_msmt_cfm_notify),
 };
 #undef RX_HANDLER
 #undef RX_HANDLER_GRP
@@ -449,6 +459,8 @@  static const struct iwl_hcmd_names iwl_mvm_legacy_names[] = {
 	HCMD_NAME(SCAN_OFFLOAD_PROFILES_QUERY_CMD),
 	HCMD_NAME(BT_COEX_UPDATE_REDUCED_TXP),
 	HCMD_NAME(BT_COEX_CI),
+	HCMD_NAME(WNM_80211V_TIMING_MEASUREMENT_CONFIRM_NOTIFICATION),
+	HCMD_NAME(WNM_80211V_TIMING_MEASUREMENT_NOTIFICATION),
 	HCMD_NAME(PHY_CONFIGURATION_CMD),
 	HCMD_NAME(CALIB_RES_NOTIF_PHY_DB),
 	HCMD_NAME(PHY_DB_CMD),
@@ -1338,6 +1350,8 @@  iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
 	else
 		memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx));
 
+	iwl_mvm_init_time_sync(&mvm->time_sync);
+
 	mvm->debugfs_dir = dbgfs_dir;
 
 	mvm->mei_registered = !iwl_mei_register(mvm, &mei_ops);
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 91556d43735a..6286132f165a 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -9,6 +9,7 @@ 
 #include "iwl-trans.h"
 #include "mvm.h"
 #include "fw-api.h"
+#include "time-sync.h"
 
 static inline int iwl_mvm_check_pn(struct iwl_mvm *mvm, struct sk_buff *skb,
 				   int queue, struct ieee80211_sta *sta)
@@ -2585,9 +2586,9 @@  void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
 		goto out;
 	}
 
-	if (!iwl_mvm_reorder(mvm, napi, queue, sta, skb, desc))
-		iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue,
-						sta);
+	if (!iwl_mvm_reorder(mvm, napi, queue, sta, skb, desc) &&
+	    (likely(!iwl_mvm_time_sync_frame(mvm, skb, hdr->addr2))))
+		iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue, sta);
 out:
 	rcu_read_unlock();
 }
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index bbcc7459f3a0..1594221abdba 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -9,6 +9,7 @@ 
 #include "mvm.h"
 #include "sta.h"
 #include "rs.h"
+#include "time-sync.h"
 
 /*
  * New version of ADD_STA_sta command added new fields at the end of the
@@ -1770,6 +1771,11 @@  int iwl_mvm_add_sta(struct iwl_mvm *mvm,
 		}
 	}
 
+	if (!sta->tdls)
+		iwl_mvm_time_sync_config(mvm, sta->addr,
+					 IWL_TIME_SYNC_PROTOCOL_TM |
+					 IWL_TIME_SYNC_PROTOCOL_FTM);
+
 	rcu_assign_pointer(mvm->fw_id_to_mac_id[sta_id], sta);
 
 	return 0;
@@ -1984,6 +1990,8 @@  int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
 	spin_lock_bh(&mvm_sta->lock);
 	spin_unlock_bh(&mvm_sta->lock);
 
+	iwl_mvm_time_sync_sta_rm(mvm, sta);
+
 	ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->sta_id);
 	RCU_INIT_POINTER(mvm->fw_id_to_mac_id[mvm_sta->sta_id], NULL);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.c
new file mode 100644
index 000000000000..b42e58e5ff24
--- /dev/null
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.c
@@ -0,0 +1,174 @@ 
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Copyright (C) 2022 Intel Corporation
+ */
+
+#include "mvm.h"
+#include "time-sync.h"
+#include <linux/ieee80211.h>
+
+void iwl_mvm_init_time_sync(struct iwl_time_sync_data *data)
+{
+	skb_queue_head_init(&data->frame_list);
+}
+
+static bool iwl_mvm_is_skb_match(struct sk_buff *skb, u8 *addr, u8 dialog_token)
+{
+	struct ieee80211_mgmt *mgmt = (void *)skb->data;
+	u8 skb_dialog_token;
+
+	if (ieee80211_is_timing_measurement(skb))
+		skb_dialog_token = mgmt->u.action.u.wnm_timing_msr.dialog_token;
+	else
+		skb_dialog_token = mgmt->u.action.u.ftm.dialog_token;
+
+	if ((ether_addr_equal(mgmt->sa, addr) ||
+	     ether_addr_equal(mgmt->da, addr)) &&
+	    skb_dialog_token == dialog_token)
+		return true;
+
+	return false;
+}
+
+static struct sk_buff *iwl_mvm_time_sync_find_skb(struct iwl_mvm *mvm, u8 *addr,
+						  u8 dialog_token)
+{
+	struct sk_buff *skb;
+
+	/* The queue is expected to have only one SKB. If there are other SKBs
+	 * in the queue, they did not get a time sync notification and are
+	 * probably obsolete by now, so drop them.
+	 */
+	while ((skb = skb_dequeue(&mvm->time_sync.frame_list))) {
+		if (iwl_mvm_is_skb_match(skb, addr, dialog_token))
+			break;
+
+		kfree_skb(skb);
+		skb = NULL;
+	}
+
+	return skb;
+}
+
+static u64 iwl_mvm_get_64_bit(__le32 high, __le32 low)
+{
+	return ((u64)le32_to_cpu(high) << 32) | le32_to_cpu(low);
+}
+
+void iwl_mvm_time_sync_msmt_event(struct iwl_mvm *mvm,
+				  struct iwl_rx_cmd_buffer *rxb)
+{
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
+	struct iwl_time_msmt_notify *notif = (void *)pkt->data;
+	struct ieee80211_rx_status *rx_status;
+	struct skb_shared_hwtstamps *shwt;
+	u64 ts_10ns;
+	struct sk_buff *skb =
+		iwl_mvm_time_sync_find_skb(mvm, notif->peer_addr,
+					   le32_to_cpu(notif->dialog_token));
+
+	if (!skb) {
+		IWL_DEBUG_INFO(mvm, "Time sync event but no pending skb\n");
+		return;
+	}
+
+	ts_10ns = iwl_mvm_get_64_bit(notif->t3_hi, notif->t3_lo);
+	rx_status = IEEE80211_SKB_RXCB(skb);
+	rx_status->ack_tx_hwtstamp = ktime_set(0, ts_10ns * 10);
+
+	ts_10ns = iwl_mvm_get_64_bit(notif->t2_hi, notif->t2_lo);
+	shwt = skb_hwtstamps(skb);
+	shwt->hwtstamp = ktime_set(0, ts_10ns * 10);
+
+	IWL_DEBUG_INFO(mvm,
+		       "Time sync: RX event - report frame t2=%llu t3=%llu\n",
+		       ktime_to_ns(shwt->hwtstamp),
+		       ktime_to_ns(rx_status->ack_tx_hwtstamp));
+	ieee80211_rx_napi(mvm->hw, NULL, skb, NULL);
+}
+
+void iwl_mvm_time_sync_msmt_confirm_event(struct iwl_mvm *mvm,
+					  struct iwl_rx_cmd_buffer *rxb)
+{
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
+	struct iwl_time_msmt_cfm_notify *notif = (void *)pkt->data;
+	struct ieee80211_tx_status status = {};
+	struct skb_shared_hwtstamps *shwt;
+	u64 ts_10ns;
+
+	status.skb =
+		iwl_mvm_time_sync_find_skb(mvm, notif->peer_addr,
+					   le32_to_cpu(notif->dialog_token));
+
+	if (!status.skb) {
+		IWL_DEBUG_INFO(mvm, "Time sync confirm but no pending skb\n");
+		return;
+	}
+
+	status.info = IEEE80211_SKB_CB(status.skb);
+
+	ts_10ns = iwl_mvm_get_64_bit(notif->t4_hi, notif->t4_lo);
+	status.ack_hwtstamp = ktime_set(0, ts_10ns * 10);
+
+	ts_10ns = iwl_mvm_get_64_bit(notif->t1_hi, notif->t1_lo);
+	shwt = skb_hwtstamps(status.skb);
+	shwt->hwtstamp = ktime_set(0, ts_10ns * 10);
+
+	IWL_DEBUG_INFO(mvm,
+		       "Time sync: TX event - report frame t1=%llu t4=%llu\n",
+		       ktime_to_ns(shwt->hwtstamp),
+		       ktime_to_ns(status.ack_hwtstamp));
+	ieee80211_tx_status_ext(mvm->hw, &status);
+}
+
+int iwl_mvm_time_sync_config(struct iwl_mvm *mvm, u8 *addr, u32 protocols)
+{
+	struct iwl_time_sync_cfg_cmd cmd = {};
+	int err;
+
+	lockdep_assert_held(&mvm->mutex);
+
+	if (!fw_has_capa(&mvm->fw->ucode_capa,
+			 IWL_UCODE_TLV_CAPA_TIME_SYNC_BOTH_FTM_TM))
+		return -EINVAL;
+
+	/* The fw only supports one peer. We do allow reconfiguration of the
+	 * same peer for cases of fw reset etc.
+	 */
+	if (mvm->time_sync.active &&
+	    !ether_addr_equal(addr, mvm->time_sync.peer_addr)) {
+		IWL_DEBUG_INFO(mvm, "Time sync: reject config for peer: %pM\n",
+			       addr);
+		return -ENOBUFS;
+	}
+
+	if (protocols & ~(IWL_TIME_SYNC_PROTOCOL_TM |
+			  IWL_TIME_SYNC_PROTOCOL_FTM))
+		return -EINVAL;
+
+	cmd.protocols = cpu_to_le32(protocols);
+
+	ether_addr_copy(cmd.peer_addr, addr);
+
+	err = iwl_mvm_send_cmd_pdu(mvm,
+				   WIDE_ID(DATA_PATH_GROUP,
+					   WNM_80211V_TIMING_MEASUREMENT_CONFIG_CMD),
+				   0, sizeof(cmd), &cmd);
+	if (err) {
+		IWL_ERR(mvm, "Failed to send time sync cfg cmd: %d\n", err);
+	} else {
+		mvm->time_sync.active = protocols != 0;
+		ether_addr_copy(mvm->time_sync.peer_addr, addr);
+		IWL_DEBUG_INFO(mvm, "Time sync: set peer addr=%pM\n", addr);
+	}
+
+	return err;
+}
+
+void iwl_mvm_time_sync_sta_rm(struct iwl_mvm *mvm, struct ieee80211_sta *sta)
+{
+	/* Disable time sync with this station */
+	iwl_mvm_time_sync_config(mvm, sta->addr, 0);
+
+	skb_queue_purge(&mvm->time_sync.frame_list);
+}
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h b/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h
new file mode 100644
index 000000000000..c43d1d0b25cb
--- /dev/null
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-sync.h
@@ -0,0 +1,30 @@ 
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
+/*
+ * Copyright (C) 2022 Intel Corporation
+ */
+#ifndef __TIME_SYNC_H__
+#define __TIME_SYNC_H__
+
+#include "mvm.h"
+#include <linux/ieee80211.h>
+
+void iwl_mvm_init_time_sync(struct iwl_time_sync_data *data);
+void iwl_mvm_time_sync_msmt_event(struct iwl_mvm *mvm,
+				  struct iwl_rx_cmd_buffer *rxb);
+void iwl_mvm_time_sync_msmt_confirm_event(struct iwl_mvm *mvm,
+					  struct iwl_rx_cmd_buffer *rxb);
+int iwl_mvm_time_sync_config(struct iwl_mvm *mvm, u8 *addr, u32 protocols);
+void iwl_mvm_time_sync_sta_rm(struct iwl_mvm *mvm, struct ieee80211_sta *sta);
+
+static inline
+bool iwl_mvm_time_sync_frame(struct iwl_mvm *mvm, struct sk_buff *skb, u8 *addr)
+{
+	if (ether_addr_equal(mvm->time_sync.peer_addr, addr) &&
+	    (ieee80211_is_timing_measurement(skb) || ieee80211_is_ftm(skb))) {
+		skb_queue_tail(&mvm->time_sync.frame_list, skb);
+		return true;
+	}
+
+	return false;
+}
+#endif
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
index a6d69885cd3f..6e2e0791d848 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
@@ -14,6 +14,7 @@ 
 #include "iwl-eeprom-parse.h"
 #include "mvm.h"
 #include "sta.h"
+#include "time-sync.h"
 
 static void
 iwl_mvm_bar_check_trigger(struct iwl_mvm *mvm, const u8 *addr,
@@ -1643,7 +1644,8 @@  static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
 		info->status.status_driver_data[0] =
 			RS_DRV_DATA_PACK(lq_color, tx_resp->reduced_tpc);
 
-		ieee80211_tx_status(mvm->hw, skb);
+		if (likely(!iwl_mvm_time_sync_frame(mvm, skb, hdr->addr1)))
+			ieee80211_tx_status(mvm->hw, skb);
 	}
 
 	/* This is an aggregation queue or might become one, so we use