* [PATCH 01/13 RFC net-next] net: ipv4: introduce CONFIG_IPV4 to decouple the IPv4 stack
From: Fernando Fernandez Mancera @ 2026-07-12 1:38 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, dsahern, horms, idosch,
Fernando Fernandez Mancera, Jason Gunthorpe, Leon Romanovsky,
Andrew Lunn, Tony Nguyen, Przemek Kitszel, Elad Nachman,
Saeed Mahameed, Tariq Toukan, Mark Bloch, Petr Machata,
Edward Cree, Maxime Coquelin, Alexandre Torgue, Arend van Spriel,
Miri Korenblit, Keith Busch, Jens Axboe, Christoph Hellwig,
Sagi Grimberg, Chaitanya Kulkarni, Saurav Kashyap, Javed Hasan,
GR-QLogic-Storage-Upstream, James E.J. Bottomley,
Martin K. Petersen, Nilesh Javali, Manish Rangankar,
Varun Prakash, Alexander Viro, Christian Brauner, Jan Kara,
David Howells, Marc Dionne, Trond Myklebust, Anna Schumaker,
Chuck Lever, Jeff Layton, NeilBrown, Olga Kornievskaia, Dai Ngo,
Tom Talpey, Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Sven Eckelmann, Nikolay Aleksandrov, Pablo Neira Ayuso,
Florian Westphal, Phil Sutter, Johannes Berg, Matthieu Baerts,
Mat Martineau, Geliang Tang, Julian Anastasov, Aaron Conole,
Eelco Chaudron, Ilya Maximets, Allison Henderson,
Jamal Hadi Salim, Jiri Pirko, Marcelo Ricardo Leitner, Xin Long,
D. Wythe, Dust Li, Sidraya Jayagond, Wenjia Zhang,
Mahanta Jambigi, Tony Lu, Wen Gu, Jon Maloy, Steffen Klassert,
Herbert Xu, Vikas Gupta, Rajashekar Hudumula, Justin Chen,
Bhargava Marreddy, Arnd Bergmann, Nicolai Buchwitz,
Florian Fainelli, Heiner Kallweit, Krzysztof Kozlowski,
Russell King (Oracle), Yao Zi, Yanteng Si, Maxime Chevallier,
Julian Braha, Joey Lu, Shangjuan Wei, Chen-Yu Tsai, Inochi Amaoto,
Lad Prabhakar, Qingfang Deng, Greg Kroah-Hartman, Eric Biggers,
Ethan Nelson-Moore, Ard Biesheuvel, Dmitry Safonov,
Kuniyuki Iwashima, Alyssa Ross, linux-rdma, linux-kernel,
intel-wired-lan, oss-drivers, linux-net-drivers, linux-stm32,
linux-arm-kernel, linux-wireless, brcm80211,
brcm80211-dev-list.pdl, linux-nvme, linux-scsi, target-devel,
linux-fsdevel, linux-afs, linux-nfs, b.a.t.m.a.n, bridge,
netfilter-devel, coreteam, mptcp, lvs-devel, dev, rds-devel,
linux-sctp, linux-s390, tipc-discussion
In-Reply-To: <20260712013941.4570-1-fmancera@suse.de>
Historically, the IPv4 protocol has been linked to the core INET
subsystem. Because shared infrastructure like the TCP/UDP engine,
routing or INET hashtables live inside net/ipv4/, it has been impossible
to compile a kernel with only IPv6 support.
This patch introduces the CONFIG_IPV4 Kconfig symbol, which is set to
'def_bool y' for now. This does not allow to completely disable the
IPv4 stack yet but it lays the necessary build-system work for that
goal.
In addition, multiple subsystems Kconfig symbols across networking
features like tunnels, drivers and filesystems have been adjusted to
depend on IPv4. Keep on mind that follow-up work is required to convert
the Kconfig symbol to bool and remove the dependency on IPv4 where it
makes sense.
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
---
drivers/infiniband/Kconfig | 2 +-
drivers/net/Kconfig | 24 ++++++++++---------
drivers/net/ethernet/broadcom/Kconfig | 2 ++
drivers/net/ethernet/chelsio/Kconfig | 2 +-
drivers/net/ethernet/intel/Kconfig | 2 ++
drivers/net/ethernet/marvell/prestera/Kconfig | 1 +
.../net/ethernet/mellanox/mlx5/core/Kconfig | 3 ++-
drivers/net/ethernet/mellanox/mlxsw/Kconfig | 1 +
drivers/net/ethernet/netronome/Kconfig | 1 +
drivers/net/ethernet/qlogic/Kconfig | 2 ++
drivers/net/ethernet/sfc/Kconfig | 1 +
drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 +
drivers/net/ethernet/via/Kconfig | 1 +
drivers/net/ppp/Kconfig | 1 +
.../broadcom/brcm80211/brcmfmac/Kconfig | 1 +
drivers/net/wireless/intel/iwlwifi/Kconfig | 1 +
drivers/nvme/host/Kconfig | 2 +-
drivers/nvme/target/Kconfig | 2 +-
drivers/scsi/bnx2fc/Kconfig | 1 +
drivers/scsi/bnx2i/Kconfig | 1 +
drivers/scsi/cxgbi/cxgb3i/Kconfig | 2 +-
drivers/scsi/cxgbi/cxgb4i/Kconfig | 2 +-
drivers/target/iscsi/Kconfig | 2 +-
fs/Kconfig | 1 +
fs/afs/Kconfig | 2 +-
fs/nfs/Kconfig | 2 +-
fs/nfsd/Kconfig | 2 +-
net/Kconfig | 6 ++---
net/batman-adv/Kconfig | 1 +
net/bridge/Kconfig | 3 ++-
net/bridge/netfilter/Kconfig | 6 ++---
net/ipv4/Kconfig | 21 +++++++++++++---
net/ipv4/Makefile | 21 ++++++++--------
net/ipv4/netfilter/Kconfig | 2 +-
net/ipv6/Kconfig | 17 +++++++++----
net/ipv6/netfilter/Kconfig | 2 +-
net/l2tp/Kconfig | 2 +-
net/mac80211/Kconfig | 2 +-
net/mpls/Kconfig | 1 +
net/mptcp/Kconfig | 2 +-
net/netfilter/Kconfig | 2 +-
net/netfilter/ipset/Kconfig | 2 +-
net/netfilter/ipvs/Kconfig | 2 +-
net/openvswitch/Kconfig | 2 +-
net/packet/Kconfig | 1 +
net/rds/Kconfig | 2 +-
net/rxrpc/Kconfig | 2 +-
net/sched/Kconfig | 2 +-
net/sctp/Kconfig | 2 +-
net/smc/Kconfig | 2 +-
net/sunrpc/Kconfig | 2 +-
net/tipc/Kconfig | 2 +-
net/xfrm/Kconfig | 12 ++++++++--
53 files changed, 121 insertions(+), 65 deletions(-)
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig
index 086195758a8a..e9302002b6ea 100644
--- a/drivers/infiniband/Kconfig
+++ b/drivers/infiniband/Kconfig
@@ -3,7 +3,7 @@ menuconfig INFINIBAND
tristate "InfiniBand support"
depends on HAS_IOMEM && HAS_DMA
depends on NET
- depends on INET
+ depends on INET && IPV4
depends on !ALPHA
select DMA_SHARED_BUFFER
select IRQ_POLL
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ff79c466712d..8e66b3015698 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -40,7 +40,7 @@ if NET_CORE
config BONDING
tristate "Bonding driver support"
- depends on INET
+ depends on INET && IPV4
depends on TLS || TLS_DEVICE=n
help
Say 'Y' or 'M' if you wish to be able to 'bond' multiple Ethernet
@@ -73,7 +73,7 @@ config DUMMY
config WIREGUARD
tristate "WireGuard secure network tunnel"
- depends on NET && INET
+ depends on NET && INET && IPV4
select NET_UDP_TUNNEL
select DST_CACHE
select CRYPTO_LIB_CURVE25519
@@ -102,7 +102,7 @@ config WIREGUARD_DEBUG
config OVPN
tristate "OpenVPN data channel offload"
- depends on NET && INET
+ depends on NET && INET && IPV4
select DST_CACHE
select NET_UDP_TUNNEL
select CRYPTO
@@ -164,6 +164,7 @@ source "drivers/net/team/Kconfig"
config MACVLAN
tristate "MAC-VLAN support"
+ depends on IPV4
help
This allows one to create virtual interfaces that map packets to
or from specific MAC addresses to a particular interface.
@@ -198,7 +199,7 @@ config IPVLAN_L3S
config IPVLAN
tristate "IP-VLAN support"
- depends on INET
+ depends on INET && IPV4
help
This allows one to create virtual devices off of a main interface
and packets will be delivered based on the dest L3 (IPv6/IPv4 addr)
@@ -229,7 +230,7 @@ config IPVTAP
config VXLAN
tristate "Virtual eXtensible Local Area Network (VXLAN)"
- depends on INET
+ depends on INET && IPV4
select NET_UDP_TUNNEL
select GRO_CELLS
help
@@ -244,7 +245,7 @@ config VXLAN
config GENEVE
tristate "Generic Network Virtualization Encapsulation"
- depends on INET
+ depends on INET && IPV4
select NET_UDP_TUNNEL
select GRO_CELLS
help
@@ -259,7 +260,7 @@ config GENEVE
config BAREUDP
tristate "Bare UDP Encapsulation"
- depends on INET
+ depends on INET && IPV4
select NET_UDP_TUNNEL
select GRO_CELLS
help
@@ -271,7 +272,7 @@ config BAREUDP
config GTP
tristate "GPRS Tunneling Protocol datapath (GTP-U)"
- depends on INET
+ depends on INET && IPV4
select NET_UDP_TUNNEL
help
This allows one to create gtp virtual interfaces that provide
@@ -288,7 +289,7 @@ config GTP
config PFCP
tristate "Packet Forwarding Control Protocol (PFCP)"
- depends on INET
+ depends on INET && IPV4
select NET_UDP_TUNNEL
help
This allows one to create PFCP virtual interfaces that allows to
@@ -301,7 +302,7 @@ config PFCP
config AMT
tristate "Automatic Multicast Tunneling (AMT)"
- depends on INET && IP_MULTICAST
+ depends on INET && IP_MULTICAST && IPV4
select NET_UDP_TUNNEL
help
This allows one to create AMT(Automatic Multicast Tunneling)
@@ -471,6 +472,7 @@ config NETKIT
config NET_VRF
tristate "Virtual Routing and Forwarding (Lite)"
+ depends on IPV4
depends on IP_MULTIPLE_TABLES
depends on NET_L3_MASTER_DEV
depends on IPV6_MULTIPLE_TABLES || IPV6=n
@@ -604,7 +606,7 @@ source "drivers/net/hyperv/Kconfig"
config NETDEVSIM
tristate "Simulated networking device"
depends on DEBUG_FS
- depends on INET
+ depends on INET && IPV4
depends on PSAMPLE || PSAMPLE=n
depends on PTP_1588_CLOCK_MOCK || PTP_1588_CLOCK_MOCK=n
select NET_DEVLINK
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
index f0bac0dd1439..02469b439127 100644
--- a/drivers/net/ethernet/broadcom/Kconfig
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -97,6 +97,7 @@ config BNX2
config CNIC
tristate "QLogic CNIC support"
+ depends on IPV4
depends on PCI
select BNX2
select UIO
@@ -208,6 +209,7 @@ config BNXT
tristate "Broadcom NetXtreme-C/E support"
depends on PCI
depends on PTP_1588_CLOCK_OPTIONAL
+ depends on IPV4
select FW_LOADER
select CRC32
select NET_DEVLINK
diff --git a/drivers/net/ethernet/chelsio/Kconfig b/drivers/net/ethernet/chelsio/Kconfig
index 96d7779cd2f0..c738820688e0 100644
--- a/drivers/net/ethernet/chelsio/Kconfig
+++ b/drivers/net/ethernet/chelsio/Kconfig
@@ -48,7 +48,7 @@ config CHELSIO_T1_1G
config CHELSIO_T3
tristate "Chelsio Communications T3 10Gb Ethernet support"
- depends on PCI && INET
+ depends on PCI && INET && IPV4
select FW_LOADER
select MDIO
help
diff --git a/drivers/net/ethernet/intel/Kconfig b/drivers/net/ethernet/intel/Kconfig
index 288fa8ce53af..d975e41a2b68 100644
--- a/drivers/net/ethernet/intel/Kconfig
+++ b/drivers/net/ethernet/intel/Kconfig
@@ -193,6 +193,7 @@ config IXGBE_DCB
config IXGBE_IPSEC
bool "IPSec XFRM cryptography-offload acceleration"
+ depends on IPV4
depends on IXGBE
depends on XFRM_OFFLOAD
default y
@@ -219,6 +220,7 @@ config IXGBEVF
config IXGBEVF_IPSEC
bool "IPSec XFRM cryptography-offload acceleration"
+ depends on IPV4
depends on IXGBEVF
depends on XFRM_OFFLOAD
default y
diff --git a/drivers/net/ethernet/marvell/prestera/Kconfig b/drivers/net/ethernet/marvell/prestera/Kconfig
index f2f7663c3d10..4c7486c7e706 100644
--- a/drivers/net/ethernet/marvell/prestera/Kconfig
+++ b/drivers/net/ethernet/marvell/prestera/Kconfig
@@ -7,6 +7,7 @@ config PRESTERA
tristate "Marvell Prestera Switch ASICs support"
depends on NET_SWITCHDEV && VLAN_8021Q
depends on BRIDGE || BRIDGE=n
+ depends on IPV4
select NET_DEVLINK
select PHYLINK
help
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
index 925ee25d05b4..86b0884968b6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Kconfig
@@ -12,6 +12,7 @@ config MLX5_CORE
depends on PTP_1588_CLOCK_OPTIONAL
depends on PCI_HYPERV_INTERFACE || !PCI_HYPERV_INTERFACE
depends on HWMON || !HWMON
+ depends on IPV4
help
Core driver for low level functionality of the ConnectX-4 and
Connect-IB cards by Mellanox Technologies.
@@ -28,7 +29,7 @@ config MLX5_FPGA
config MLX5_CORE_EN
bool "Mellanox 5th generation network adapters (ConnectX series) Ethernet support"
- depends on NETDEVICES && ETHERNET && INET && PCI && MLX5_CORE
+ depends on NETDEVICES && ETHERNET && INET && PCI && MLX5_CORE && IPV4
select PAGE_POOL
select PAGE_POOL_STATS
select DIMLIB
diff --git a/drivers/net/ethernet/mellanox/mlxsw/Kconfig b/drivers/net/ethernet/mellanox/mlxsw/Kconfig
index 2229a2694aa5..d12c33044a1d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/Kconfig
+++ b/drivers/net/ethernet/mellanox/mlxsw/Kconfig
@@ -53,6 +53,7 @@ config MLXSW_I2C
config MLXSW_SPECTRUM
tristate "Mellanox Technologies Spectrum family support"
+ depends on IPV4
depends on MLXSW_CORE && MLXSW_PCI && NET_SWITCHDEV && VLAN_8021Q
depends on PSAMPLE || PSAMPLE=n
depends on BRIDGE || BRIDGE=n
diff --git a/drivers/net/ethernet/netronome/Kconfig b/drivers/net/ethernet/netronome/Kconfig
index d115d16d4649..2ac3f89e1f26 100644
--- a/drivers/net/ethernet/netronome/Kconfig
+++ b/drivers/net/ethernet/netronome/Kconfig
@@ -18,6 +18,7 @@ if NET_VENDOR_NETRONOME
config NFP
tristate "Netronome(R) NFP4000/NFP6000 NIC driver"
+ depends on IPV4
depends on PCI_MSI
depends on VXLAN || VXLAN=n
depends on TLS && TLS_DEVICE || TLS_DEVICE=n
diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig
index 1203353238e5..d198f6add1a8 100644
--- a/drivers/net/ethernet/qlogic/Kconfig
+++ b/drivers/net/ethernet/qlogic/Kconfig
@@ -29,6 +29,7 @@ config QLA3XXX
config QLCNIC
tristate "QLOGIC QLCNIC 1/10Gb Converged Ethernet NIC Support"
depends on PCI
+ depends on IPV4
select FW_LOADER
help
This driver supports QLogic QLE8240 and QLE8242 Converged Ethernet
@@ -68,6 +69,7 @@ config QLCNIC_HWMON
config NETXEN_NIC
tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC"
+ depends on IPV4
depends on PCI
select FW_LOADER
help
diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig
index 979f2801e2a8..d2e32e8ffce8 100644
--- a/drivers/net/ethernet/sfc/Kconfig
+++ b/drivers/net/ethernet/sfc/Kconfig
@@ -18,6 +18,7 @@ if NET_VENDOR_SOLARFLARE
config SFC
tristate "Solarflare SFC9100/EF100-family support"
+ depends on IPV4
depends on PCI
depends on PTP_1588_CLOCK_OPTIONAL
select MDIO
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index e3dd5adda5ac..4ac59a43d71c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config STMMAC_ETH
tristate "STMicroelectronics Multi-Gigabit Ethernet driver"
+ depends on IPV4
depends on HAS_IOMEM && HAS_DMA
depends on PTP_1588_CLOCK_OPTIONAL
depends on ETHTOOL_NETLINK
diff --git a/drivers/net/ethernet/via/Kconfig b/drivers/net/ethernet/via/Kconfig
index 00773f5e4d7e..a62eb98f2e27 100644
--- a/drivers/net/ethernet/via/Kconfig
+++ b/drivers/net/ethernet/via/Kconfig
@@ -45,6 +45,7 @@ config VIA_RHINE_MMIO
config VIA_VELOCITY
tristate "VIA Velocity support"
+ depends on IPV4
depends on (PCI || (OF_ADDRESS && OF_IRQ))
depends on HAS_DMA
select CRC32
diff --git a/drivers/net/ppp/Kconfig b/drivers/net/ppp/Kconfig
index 4047f13b83dc..16826da75d1e 100644
--- a/drivers/net/ppp/Kconfig
+++ b/drivers/net/ppp/Kconfig
@@ -160,6 +160,7 @@ config PPPOE_HASH_BITS
config PPTP
tristate "PPP over IPv4 (PPTP)"
+ depends on IPV4
depends on NET_IPGRE_DEMUX
select PPPOX
help
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig
index 32794c1eca23..95d685f165ea 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig
@@ -1,6 +1,7 @@
config BRCMFMAC
tristate "Broadcom FullMAC WLAN driver"
depends on CFG80211
+ depends on IPV4
select BRCMUTIL
help
This module adds support for wireless adapters based on Broadcom
diff --git a/drivers/net/wireless/intel/iwlwifi/Kconfig b/drivers/net/wireless/intel/iwlwifi/Kconfig
index 153a8368b412..d2efd96cd513 100644
--- a/drivers/net/wireless/intel/iwlwifi/Kconfig
+++ b/drivers/net/wireless/intel/iwlwifi/Kconfig
@@ -2,6 +2,7 @@
config IWLWIFI
tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) "
depends on PCI && HAS_IOMEM && CFG80211
+ depends on IPV4
depends on IWLMEI || !IWLMEI
select FW_LOADER
help
diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig
index 31974c7dd20c..6e119cf475de 100644
--- a/drivers/nvme/host/Kconfig
+++ b/drivers/nvme/host/Kconfig
@@ -82,7 +82,7 @@ config NVME_FC
config NVME_TCP
tristate "NVM Express over Fabrics TCP host driver"
- depends on INET
+ depends on INET && IPV4
depends on BLOCK
select CRC32
select NET_CRC32C
diff --git a/drivers/nvme/target/Kconfig b/drivers/nvme/target/Kconfig
index 69bde270115e..f731a043f6a9 100644
--- a/drivers/nvme/target/Kconfig
+++ b/drivers/nvme/target/Kconfig
@@ -86,7 +86,7 @@ config NVME_TARGET_FCLOOP
config NVME_TARGET_TCP
tristate "NVMe over Fabrics TCP target support"
- depends on INET
+ depends on INET && IPV4
depends on NVME_TARGET
help
This enables the NVMe TCP target support, which allows exporting NVMe
diff --git a/drivers/scsi/bnx2fc/Kconfig b/drivers/scsi/bnx2fc/Kconfig
index d12eeb13384a..d5065b8fdea9 100644
--- a/drivers/scsi/bnx2fc/Kconfig
+++ b/drivers/scsi/bnx2fc/Kconfig
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config SCSI_BNX2X_FCOE
tristate "QLogic FCoE offload support"
+ depends on IPV4
depends on PCI
depends on LIBFC
depends on LIBFCOE
diff --git a/drivers/scsi/bnx2i/Kconfig b/drivers/scsi/bnx2i/Kconfig
index e649a04fab1d..0458e4811731 100644
--- a/drivers/scsi/bnx2i/Kconfig
+++ b/drivers/scsi/bnx2i/Kconfig
@@ -2,6 +2,7 @@
config SCSI_BNX2_ISCSI
tristate "QLogic NetXtreme II iSCSI support"
depends on NET
+ depends on IPV4
depends on PCI
select SCSI_ISCSI_ATTRS
select NETDEVICES
diff --git a/drivers/scsi/cxgbi/cxgb3i/Kconfig b/drivers/scsi/cxgbi/cxgb3i/Kconfig
index 143e881ec77e..abb4a462cb37 100644
--- a/drivers/scsi/cxgbi/cxgb3i/Kconfig
+++ b/drivers/scsi/cxgbi/cxgb3i/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config SCSI_CXGB3_ISCSI
tristate "Chelsio T3 iSCSI support"
- depends on PCI && INET
+ depends on PCI && INET && IPV4
select NETDEVICES
select ETHERNET
select NET_VENDOR_CHELSIO
diff --git a/drivers/scsi/cxgbi/cxgb4i/Kconfig b/drivers/scsi/cxgbi/cxgb4i/Kconfig
index dd1c8ff36b00..04b3e7b053dc 100644
--- a/drivers/scsi/cxgbi/cxgb4i/Kconfig
+++ b/drivers/scsi/cxgbi/cxgb4i/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config SCSI_CXGB4_ISCSI
tristate "Chelsio T4 iSCSI support"
- depends on PCI && INET
+ depends on PCI && INET && IPV4
depends on PTP_1588_CLOCK_OPTIONAL
depends on THERMAL || !THERMAL
depends on ETHERNET
diff --git a/drivers/target/iscsi/Kconfig b/drivers/target/iscsi/Kconfig
index 70d76f3dd693..362edff80c15 100644
--- a/drivers/target/iscsi/Kconfig
+++ b/drivers/target/iscsi/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config ISCSI_TARGET
tristate "SCSI Target Mode Stack"
- depends on INET
+ depends on INET && IPV4
select CRC32
select CRYPTO
select CRYPTO_HASH
diff --git a/fs/Kconfig b/fs/Kconfig
index cf6ae64776e6..20199c1cc93a 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -360,6 +360,7 @@ config GRACE_PERIOD
config LOCKD
tristate
+ depends on IPV4
depends on FILE_LOCKING
select CRC32
select GRACE_PERIOD
diff --git a/fs/afs/Kconfig b/fs/afs/Kconfig
index 682bd8ec2c10..e7ed46426f81 100644
--- a/fs/afs/Kconfig
+++ b/fs/afs/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config AFS_FS
tristate "Andrew File System support (AFS)"
- depends on INET
+ depends on INET && IPV4
select AF_RXRPC
select DNS_RESOLVER
select NETFS_SUPPORT
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 6bb30543eff0..52efd3664d21 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config NFS_FS
tristate "NFS client support"
- depends on INET && FILE_LOCKING && MULTIUSER
+ depends on INET && FILE_LOCKING && MULTIUSER && IPV4
select CRC32
select LOCKD
select SUNRPC
diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
index ffb76761d6a8..153a9918214d 100644
--- a/fs/nfsd/Kconfig
+++ b/fs/nfsd/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config NFSD
tristate "NFS server support"
- depends on INET
+ depends on INET && IPV4
depends on FILE_LOCKING
depends on FSNOTIFY
select CRC32
diff --git a/net/Kconfig b/net/Kconfig
index e38477393551..27de9e69b5f7 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -385,7 +385,7 @@ menu "Network testing"
config NET_PKTGEN
tristate "Packet Generator (USE WITH CAUTION)"
- depends on INET && PROC_FS
+ depends on INET && IPV4 && PROC_FS
help
This module will inject preconfigured packets, at a configurable
rate, out of a given interface. It is used for network interface
@@ -452,7 +452,7 @@ config LWTUNNEL
config LWTUNNEL_BPF
bool "Execute BPF program as route nexthop action"
- depends on LWTUNNEL && INET
+ depends on LWTUNNEL && INET && IPV4
default y if LWTUNNEL=y
help
Allows to run BPF programs as a nexthop action following a route
@@ -474,7 +474,7 @@ config NET_IEEE8021Q_HELPERS
config NET_SELFTESTS
def_tristate PHYLIB
- depends on PHYLIB && INET
+ depends on PHYLIB && INET && IPV4
config NET_SOCK_MSG
bool
diff --git a/net/batman-adv/Kconfig b/net/batman-adv/Kconfig
index 58c408b7a7d9..60ad4b09be6e 100644
--- a/net/batman-adv/Kconfig
+++ b/net/batman-adv/Kconfig
@@ -9,6 +9,7 @@
config BATMAN_ADV
tristate "B.A.T.M.A.N. Advanced Meshing Protocol"
+ depends on IPV4
select CRC32
help
B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is
diff --git a/net/bridge/Kconfig b/net/bridge/Kconfig
index 318715c8fc9b..421892a03129 100644
--- a/net/bridge/Kconfig
+++ b/net/bridge/Kconfig
@@ -7,6 +7,7 @@ config BRIDGE
tristate "802.1d Ethernet Bridging"
select LLC
select STP
+ depends on IPV4
help
If you say Y here, then your Linux box will be able to act as an
Ethernet bridge, which means that the different Ethernet segments it
@@ -36,7 +37,7 @@ config BRIDGE
config BRIDGE_IGMP_SNOOPING
bool "IGMP/MLD snooping"
depends on BRIDGE
- depends on INET
+ depends on INET && IPV4
default y
help
If you say Y here, then the Ethernet bridge will be able selectively
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index 4fd5a6ea26b4..003f055f8cfe 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -4,7 +4,7 @@
#
#
menuconfig NF_TABLES_BRIDGE
- depends on BRIDGE && NETFILTER && NF_TABLES
+ depends on BRIDGE && NETFILTER && NF_TABLES && IPV4
select NETFILTER_FAMILY_BRIDGE
tristate "Ethernet Bridge nf_tables support"
@@ -43,7 +43,7 @@ config NF_CONNTRACK_BRIDGE
config BRIDGE_NF_EBTABLES_LEGACY
tristate "Legacy EBTABLES support"
depends on BRIDGE && NETFILTER_XTABLES_LEGACY
- depends on NETFILTER_XTABLES
+ depends on NETFILTER_XTABLES && IPV4
default n
help
Legacy ebtables packet/frame classifier.
@@ -52,7 +52,7 @@ config BRIDGE_NF_EBTABLES_LEGACY
menuconfig BRIDGE_NF_EBTABLES
tristate "Ethernet Bridge tables (ebtables) support"
- depends on BRIDGE && NETFILTER && NETFILTER_XTABLES
+ depends on BRIDGE && NETFILTER && NETFILTER_XTABLES && IPV4
select NETFILTER_FAMILY_BRIDGE
help
ebtables is a general, extensible frame/packet identification
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 301b47660305..51bf05d9770c 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -2,6 +2,9 @@
#
# IP configuration
#
+config IPV4
+ def_bool y
+
config IP_MULTICAST
bool "IP: multicasting"
help
@@ -62,7 +65,7 @@ config IP_FIB_TRIE_STATS
config IP_MULTIPLE_TABLES
bool "IP: policy routing"
- depends on IP_ADVANCED_ROUTER
+ depends on IPV4 && IP_ADVANCED_ROUTER
select FIB_RULES
help
Normally, a router decides what to do with a received packet based
@@ -105,6 +108,7 @@ config IP_ROUTE_CLASSID
config IP_PNP
bool "IP: kernel level autoconfiguration"
+ depends on IPV4
help
This enables automatic configuration of IP addresses of devices and
of the routing table during kernel boot, based on either information
@@ -161,6 +165,7 @@ config IP_PNP_RARP
config NET_IPIP
tristate "IP: tunneling"
+ depends on IPV4
select INET_TUNNEL
select NET_IP_TUNNEL
help
@@ -185,12 +190,14 @@ config NET_IPGRE_DEMUX
config NET_IP_TUNNEL
tristate
+ depends on IPV4
select DST_CACHE
select GRO_CELLS
default n
config NET_IPGRE
tristate "IP: GRE tunnels over IP"
+ depends on IPV4
depends on NET_IPGRE_DEMUX
select NET_IP_TUNNEL
help
@@ -219,7 +226,7 @@ config IP_MROUTE_COMMON
config IP_MROUTE
bool "IP: multicast routing"
- depends on IP_MULTICAST
+ depends on IP_MULTICAST && IPV4
select IP_MROUTE_COMMON
help
This is used if you want your machine to act as a router for IP
@@ -267,6 +274,7 @@ config IP_PIMSM_V2
config SYN_COOKIES
bool "IP: TCP syncookie support"
+ depends on IPV4
help
Normal TCP/IP networking is open to an attack known as "SYN
flooding". This denial-of-service attack prevents legitimate remote
@@ -303,6 +311,7 @@ config SYN_COOKIES
config NET_IPVTI
tristate "Virtual (secure) IP: tunneling"
+ depends on IPV4
select INET_TUNNEL
select NET_IP_TUNNEL
select XFRM
@@ -315,11 +324,13 @@ config NET_IPVTI
config NET_UDP_TUNNEL
tristate
+ depends on IPV4
select NET_IP_TUNNEL
default n
config NET_FOU
tristate "IP: Foo (IP protocols) over UDP"
+ depends on IPV4
select NET_UDP_TUNNEL
help
Foo over UDP allows any IP protocol to be directly encapsulated
@@ -338,6 +349,7 @@ config NET_FOU_IP_TUNNELS
config INET_AH
tristate "IP: AH transformation"
+ depends on IPV4
select XFRM_AH
help
Support for IPsec AH (Authentication Header).
@@ -353,6 +365,7 @@ config INET_AH
config INET_ESP
tristate "IP: ESP transformation"
+ depends on IPV4
select XFRM_ESP
help
Support for IPsec ESP (Encapsulating Security Payload).
@@ -393,6 +406,7 @@ config INET_ESPINTCP
config INET_IPCOMP
tristate "IP: IPComp transformation"
+ depends on IPV4
select INET_XFRM_TUNNEL
select XFRM_IPCOMP
help
@@ -747,7 +761,7 @@ config TCP_AO
select CRYPTO_LIB_SHA1
select CRYPTO_LIB_SHA256
select CRYPTO_LIB_UTILS
- depends on 64BIT # seq-number extension needs WRITE_ONCE(u64)
+ depends on IPV4 && 64BIT # seq-number extension needs WRITE_ONCE(u64)
help
TCP-AO specifies the use of stronger Message Authentication Codes (MACs),
protects against replays for long-lived TCP connections, and
@@ -758,6 +772,7 @@ config TCP_AO
config TCP_MD5SIG
bool "TCP: MD5 Signature Option support (RFC2385)"
+ depends on IPV4
select CRYPTO_LIB_MD5
select CRYPTO_LIB_UTILS
help
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 06e21c26b76f..8b148be79fa4 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -3,18 +3,17 @@
# Makefile for the Linux TCP/IP (INET) layer.
#
-obj-y := route.o inetpeer.o protocol.o \
- ip_input.o ip_fragment.o ip_forward.o ip_options.o \
- ip_output.o ip_sockglue.o inet_hashtables.o \
- inet_timewait_sock.o inet_connection_sock.o \
- tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \
+obj-y := inetpeer.o protocol.o inet_hashtables.o inet_timewait_sock.o \
+ inet_connection_sock.o tcp.o tcp_input.o tcp_output.o tcp_timer.o \
tcp_minisocks.o tcp_cong.o tcp_metrics.o tcp_fastopen.o \
- tcp_recovery.o tcp_ulp.o \
- tcp_offload.o tcp_plb.o datagram.o raw.o udp.o \
- udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \
- fib_frontend.o fib_semantics.o fib_trie.o fib_notifier.o \
- inet_fragment.o ping.o ip_tunnel_core.o gre_offload.o \
- metrics.o netlink.o nexthop.o udp_tunnel_stub.o
+ tcp_recovery.o tcp_ulp.o tcp_offload.o tcp_plb.o raw.o udp.o \
+ udp_offload.o af_inet.o inet_fragment.o ping.o ip_tunnel_core.o \
+ gre_offload.o metrics.o netlink.o nexthop.o udp_tunnel_stub.o
+
+obj-$(CONFIG_IPV4) += route.o ip_input.o ip_fragment.o ip_forward.o ip_options.o \
+ ip_sockglue.o tcp_ipv4.o datagram.o icmp.o arp.o devinet.o \
+ igmp.o fib_notifier.o ip_output.o fib_frontend.o \
+ fib_semantics.o fib_trie.o
obj-$(CONFIG_NET_IP_TUNNEL) += ip_tunnel.o
obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 7dc9772fe2d8..ab4fa6a6d453 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -4,7 +4,7 @@
#
menu "IP: Netfilter Configuration"
- depends on INET && NETFILTER
+ depends on INET && NETFILTER && IPV4
config NF_DEFRAG_IPV4
tristate
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index c3806c6ac96f..f83efc1505cc 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -47,6 +47,7 @@ config IPV6_OPTIMISTIC_DAD
config INET6_AH
tristate "IPv6: AH transformation"
select XFRM_AH
+ depends on IPV4
help
Support for IPsec AH (Authentication Header).
@@ -61,6 +62,7 @@ config INET6_AH
config INET6_ESP
tristate "IPv6: ESP transformation"
+ depends on IPV4
select XFRM_ESP
help
Support for IPsec ESP (Encapsulating Security Payload).
@@ -101,6 +103,7 @@ config INET6_ESPINTCP
config INET6_IPCOMP
tristate "IPv6: IPComp transformation"
+ depends on IPV4
select INET6_XFRM_TUNNEL
select XFRM_IPCOMP
help
@@ -111,6 +114,7 @@ config INET6_IPCOMP
config IPV6_MIP6
tristate "IPv6: Mobility"
+ depends on IPV4
select XFRM
help
Support for IPv6 Mobility described in RFC 3775.
@@ -119,6 +123,7 @@ config IPV6_MIP6
config IPV6_ILA
tristate "IPv6: Identifier Locator Addressing (ILA)"
+ depends on IPV4
depends on NETFILTER
select DST_CACHE
select LWTUNNEL
@@ -149,6 +154,7 @@ config INET6_TUNNEL
config IPV6_VTI
tristate "Virtual (secure) IPv6: tunneling"
+ depends on IPV4
select IPV6_TUNNEL
select NET_IP_TUNNEL
select XFRM
@@ -161,6 +167,7 @@ config IPV6_VTI
config IPV6_SIT
tristate "IPv6: IPv6-in-IPv4 tunnel (SIT driver)"
+ depends on IPV4
select INET_TUNNEL
select NET_IP_TUNNEL
select IPV6_NDISC_NODETYPE
@@ -198,6 +205,7 @@ config IPV6_NDISC_NODETYPE
config IPV6_TUNNEL
tristate "IPv6: IP-in-IPv6 tunnel (RFC2473)"
+ depends on IPV4
select INET6_TUNNEL
select DST_CACHE
select GRO_CELLS
@@ -209,6 +217,7 @@ config IPV6_TUNNEL
config IPV6_GRE
tristate "IPv6: GRE tunnel"
+ depends on IPV4
select IPV6_TUNNEL
select NET_IP_TUNNEL
depends on NET_IPGRE_DEMUX
@@ -256,7 +265,7 @@ config IPV6_SUBTREES
config IPV6_MROUTE
bool "IPv6: multicast routing"
- depends on IPV6
+ depends on IPV4 && IPV6
select IP_MROUTE_COMMON
help
Support for IPv6 multicast forwarding.
@@ -285,7 +294,7 @@ config IPV6_PIMSM_V2
config IPV6_SEG6_LWTUNNEL
bool "IPv6: Segment Routing Header encapsulation support"
- depends on IPV6
+ depends on IPV4 && IPV6
select LWTUNNEL
select DST_CACHE
select IPV6_MULTIPLE_TABLES
@@ -316,7 +325,7 @@ config IPV6_SEG6_BPF
config IPV6_RPL_LWTUNNEL
bool "IPv6: RPL Source Routing Header support"
- depends on IPV6
+ depends on IPV4 && IPV6
select LWTUNNEL
select DST_CACHE
help
@@ -327,7 +336,7 @@ config IPV6_RPL_LWTUNNEL
config IPV6_IOAM6_LWTUNNEL
bool "IPv6: IOAM Pre-allocated Trace insertion support"
- depends on IPV6
+ depends on IPV4 && IPV6
select LWTUNNEL
select DST_CACHE
help
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 81daf82ddc2d..f99a2176bf3d 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -4,7 +4,7 @@
#
menu "IPv6: Netfilter Configuration"
- depends on INET && IPV6 && NETFILTER
+ depends on INET && IPV6 && NETFILTER && IPV4
# old sockopt interface and eval loop
config IP6_NF_IPTABLES_LEGACY
diff --git a/net/l2tp/Kconfig b/net/l2tp/Kconfig
index 0de178d5baba..e92cf6d94135 100644
--- a/net/l2tp/Kconfig
+++ b/net/l2tp/Kconfig
@@ -5,7 +5,7 @@
menuconfig L2TP
tristate "Layer Two Tunneling Protocol (L2TP)"
- depends on INET
+ depends on INET && IPV4
select NET_UDP_TUNNEL
help
Layer Two Tunneling Protocol
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index d6bc295e23a1..ec485da28373 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config MAC80211
tristate "Generic IEEE 802.11 Networking Stack (mac80211)"
- depends on CFG80211
+ depends on CFG80211 && IPV4
select CRYPTO
select CRYPTO_LIB_AES_CBC_MACS
select CRYPTO_LIB_ARC4
diff --git a/net/mpls/Kconfig b/net/mpls/Kconfig
index d672ab72ab12..541ba192e2a1 100644
--- a/net/mpls/Kconfig
+++ b/net/mpls/Kconfig
@@ -25,6 +25,7 @@ config NET_MPLS_GSO
config MPLS_ROUTING
tristate "MPLS: routing support"
+ depends on IPV4
depends on NET_IP_TUNNEL || NET_IP_TUNNEL=n
depends on PROC_SYSCTL
help
diff --git a/net/mptcp/Kconfig b/net/mptcp/Kconfig
index be71fc9b4638..c5b660fdda4c 100644
--- a/net/mptcp/Kconfig
+++ b/net/mptcp/Kconfig
@@ -1,7 +1,7 @@
config MPTCP
bool "MPTCP: Multipath TCP"
- depends on INET
+ depends on INET && IPV4
select SKB_EXTENSIONS
select CRYPTO_LIB_SHA256
select CRYPTO_LIB_UTILS
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 4c04cd8d40a2..3ee9bb726e40 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
menu "Core Netfilter Configuration"
- depends on INET && NETFILTER
+ depends on INET && IPV4 && NETFILTER
config NETFILTER_INGRESS
bool "Netfilter ingress support"
diff --git a/net/netfilter/ipset/Kconfig b/net/netfilter/ipset/Kconfig
index 6c4d54758106..e6537c842a45 100644
--- a/net/netfilter/ipset/Kconfig
+++ b/net/netfilter/ipset/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
menuconfig IP_SET
tristate "IP set support"
- depends on INET && NETFILTER
+ depends on INET && IPV4 && NETFILTER
select NETFILTER_NETLINK
help
This option adds IP set support to the kernel.
diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig
index 7724cb44e6de..fb09218d84d0 100644
--- a/net/netfilter/ipvs/Kconfig
+++ b/net/netfilter/ipvs/Kconfig
@@ -4,7 +4,7 @@
#
menuconfig IP_VS
tristate "IP virtual server support"
- depends on INET && NETFILTER
+ depends on INET && NETFILTER && IPV4
depends on (NF_CONNTRACK || NF_CONNTRACK=n)
help
IP Virtual Server support will let you build a high-performance
diff --git a/net/openvswitch/Kconfig b/net/openvswitch/Kconfig
index e6aaee92dba4..5931c28ef965 100644
--- a/net/openvswitch/Kconfig
+++ b/net/openvswitch/Kconfig
@@ -5,7 +5,7 @@
config OPENVSWITCH
tristate "Open vSwitch"
- depends on INET
+ depends on INET && IPV4
depends on !NF_CONNTRACK || \
(NF_CONNTRACK && ((!NF_DEFRAG_IPV6 || NF_DEFRAG_IPV6) && \
(!NF_NAT || NF_NAT) && \
diff --git a/net/packet/Kconfig b/net/packet/Kconfig
index 2997382d597c..00fda9e08cb0 100644
--- a/net/packet/Kconfig
+++ b/net/packet/Kconfig
@@ -5,6 +5,7 @@
config PACKET
tristate "Packet socket"
+ depends on IPV4
help
The Packet protocol is used by applications which communicate
directly with network devices without an intermediate network
diff --git a/net/rds/Kconfig b/net/rds/Kconfig
index f007730aa2bb..d33cf3d89632 100644
--- a/net/rds/Kconfig
+++ b/net/rds/Kconfig
@@ -2,7 +2,7 @@
config RDS
tristate "The Reliable Datagram Sockets Protocol"
- depends on INET
+ depends on INET && IPV4
help
The RDS (Reliable Datagram Sockets) protocol provides reliable,
sequenced delivery of datagrams over Infiniband or TCP.
diff --git a/net/rxrpc/Kconfig b/net/rxrpc/Kconfig
index 2cebb666dc07..2029d2d1065f 100644
--- a/net/rxrpc/Kconfig
+++ b/net/rxrpc/Kconfig
@@ -5,7 +5,7 @@
config AF_RXRPC
tristate "RxRPC session sockets"
- depends on INET
+ depends on INET && IPV4
select CRYPTO
select CRYPTO_LIB_DES if RXKAD
select KEYS
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 6ddff028b81a..bb782822c3fb 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -807,7 +807,7 @@ config NET_ACT_SKBEDIT
config NET_ACT_CSUM
tristate "Checksum Updating"
- depends on NET_CLS_ACT && INET
+ depends on NET_CLS_ACT && INET && IPV4
select NET_CRC32C
help
Say Y here to update some common checksum after some direct
diff --git a/net/sctp/Kconfig b/net/sctp/Kconfig
index fc989a3791b3..eb3e2bf1ec3a 100644
--- a/net/sctp/Kconfig
+++ b/net/sctp/Kconfig
@@ -5,7 +5,7 @@
menuconfig IP_SCTP
tristate "The SCTP Protocol"
- depends on INET
+ depends on INET && IPV4
select CRYPTO_LIB_SHA1
select CRYPTO_LIB_SHA256
select CRYPTO_LIB_UTILS
diff --git a/net/smc/Kconfig b/net/smc/Kconfig
index 277ef504bc26..52005e4bf77d 100644
--- a/net/smc/Kconfig
+++ b/net/smc/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config SMC
tristate "SMC socket protocol family"
- depends on INET && INFINIBAND && DIBS
+ depends on INET && INFINIBAND && DIBS && IPV4
help
SMC-R provides a "sockets over RDMA" solution making use of
RDMA over Converged Ethernet (RoCE) technology to upgrade
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig
index e7808e5714dc..58e6f6db3100 100644
--- a/net/sunrpc/Kconfig
+++ b/net/sunrpc/Kconfig
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
config SUNRPC
tristate
- depends on MULTIUSER
+ depends on MULTIUSER && IPV4
config SUNRPC_GSS
tristate
diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig
index 18f62135e47b..869e3fe961f9 100644
--- a/net/tipc/Kconfig
+++ b/net/tipc/Kconfig
@@ -5,7 +5,7 @@
menuconfig TIPC
tristate "The TIPC Protocol"
- depends on INET
+ depends on INET && IPV4
help
The Transparent Inter Process Communication (TIPC) protocol is
specially designed for intra cluster communication. This protocol
diff --git a/net/xfrm/Kconfig b/net/xfrm/Kconfig
index 4a62817a88f8..2e4d466c7bd3 100644
--- a/net/xfrm/Kconfig
+++ b/net/xfrm/Kconfig
@@ -4,7 +4,7 @@
#
config XFRM
bool
- depends on INET
+ depends on INET && IPV4
select GRO_CELLS
select SKB_EXTENSIONS
@@ -13,6 +13,7 @@ config XFRM_OFFLOAD
config XFRM_ALGO
tristate
+ depends on IPV4
select XFRM
select CRYPTO
select CRYPTO_AEAD
@@ -23,6 +24,7 @@ if INET
config XFRM_USER
tristate "Transformation user configuration interface"
select XFRM_ALGO
+ depends on IPV4
help
Support for Transformation(XFRM) user configuration interface
like IPsec used by native Linux tools.
@@ -42,7 +44,7 @@ config XFRM_USER_COMPAT
config XFRM_INTERFACE
tristate "Transformation virtual interface"
- depends on XFRM && IPV6
+ depends on XFRM && IPV4 && IPV6
help
This provides a virtual interface to route IPsec traffic.
@@ -83,6 +85,7 @@ config XFRM_STATISTICS
# RFC 8221 lists as MUST be implemented.
config XFRM_AH
tristate
+ depends on IPV4
select XFRM_ALGO
select CRYPTO
select CRYPTO_HMAC
@@ -92,6 +95,7 @@ config XFRM_AH
# algorithms that RFC 8221 lists as MUST be implemented.
config XFRM_ESP
tristate
+ depends on IPV4
select XFRM_ALGO
select CRYPTO
select CRYPTO_AES
@@ -105,12 +109,14 @@ config XFRM_ESP
config XFRM_IPCOMP
tristate
+ depends on IPV4
select XFRM_ALGO
select CRYPTO
select CRYPTO_DEFLATE
config NET_KEY
tristate "PF_KEY sockets (deprecated)"
+ depends on IPV4
select XFRM_ALGO
help
PF_KEYv2 socket family, compatible to KAME ones.
@@ -140,6 +146,7 @@ config NET_KEY_MIGRATE
config XFRM_IPTFS
tristate "IPsec IP-TFS/AGGFRAG (RFC 9347) encapsulation support"
+ depends on IPV4
depends on XFRM
help
Information on the IP-TFS/AGGFRAG encapsulation can be found
@@ -156,5 +163,6 @@ config XFRM_IPTFS
config XFRM_ESPINTCP
bool
+ depends on IPV4
endif # INET
--
2.54.0
^ permalink raw reply related
* RE: [PATCH] wifi: rtw89: 8852au: Add support for Mercusys MA72XH
From: Ping-Ke Shih @ 2026-07-12 1:50 UTC (permalink / raw)
To: Abhishek Tamboli
Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20260710030055.57438-1-abhishektamboli9@gmail.com>
Abhishek Tamboli <abhishektamboli9@gmail.com> wrote:
> Add the ID 2c4e:0124 to the rtw_8852au_id_table to
> support the Mercusys MA72XH usb adapter.
>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=221738
Not sure why I have no permission to access this. Maybe it gets broken.
I'll wait a while to see if people will fix it.
^ permalink raw reply
* Re: [PATCH rtw-next 01/15] wifi: rtw89: 8922d: remove CCK bandwidth compensation
From: Ping-Ke Shih @ 2026-07-12 1:55 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless; +Cc: gary.chang, echuang
In-Reply-To: <20260707091056.42771-2-pkshih@realtek.com>
Ping-Ke Shih <pkshih@realtek.com> wrote:
> From: Eric Huang <echuang@realtek.com>
>
> Remove the 40MHz bandwidth compensation from CCK efuse gain calculation.
> The design no longer requires the +3dB compensation for 40MHz channels.
>
> Signed-off-by: Eric Huang <echuang@realtek.com>
15 patch(es) applied to rtw-next branch of rtw.git, thanks.
be8aedb68c96 wifi: rtw89: 8922d: remove CCK bandwidth compensation
daa3fda5aeb9 wifi: rtw89: 8922d: dynamic adjust channel smoothing
8da4883c81ae wifi: rtw89: 8922d: fix EMLSR BB switch sequence for MLO mode transition
852927114f6e wifi: rtw89: phy: fix bandedge primary channel for 2.4GHz 40MHz and 6GHz
390f58e29de3 wifi: rtw89: 8922d: set TX compensation by format v2
d193bdc73396 wifi: rtw89: efuse: no need to export rtw89_efuse_read_ecv_be()
4260edb3b1a6 wifi: rtw89: efuse: read thermal calibration value for RTL8922D
4e199cd66614 wifi: rtw89: 8922d: read default digital voltage calibration values
47ad03f1eca5 wifi: rtw89: add thermal protect by digital voltage reduction
b7911466b6db wifi: rtw89: 8922d: set ANA CLK enter to 500KHz
79afed9426ce wifi: rtw89: 8922d: update scaling factor for RX path
9bf6bd6ed5ac wifi: rtw89: 8852a: fix RSSI report when average beacon RSSI is not ready
235fa79d7561 wifi: rtw89: phy: add NCTL check for WiFi 7 chips
5c925d7722c6 wifi: rtw89: unify access struct of TX power track tables
56d32cdc6040 wifi: rtw89: set needed firmware elements for early chips transition
---
https://github.com/pkshih/rtw.git
^ permalink raw reply
* [PATCH rtw-next 00/11] wifi: rtw89: coex: implement coex for RTL8922D
From: Ping-Ke Shih @ 2026-07-12 3:04 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
The BT-coexistence introduce many new formats and features for RTL8922D,
including dual-BT support, offload features to firmware and etc. Update
them accordingly and add a tag version for reference.
Ching-Te Ku (11):
wifi: rtw89: coex: Add Wi-Fi role info version 10
wifi: rtw89: coex: Rearrange coexistence control structure
wifi: rtw89: coex: Update driver outsource info to firmware version 6
wifi: rtw89: ceox: Update antenna & grant signal setting
wifi: rtw89: coex: Rearrange Bluetooth firmware report entry
wifi: rtw89: coex: Refine send firmware command function
wifi: rtw89: coex: Refine _reset_btc_var()
wifi: rtw89: coex: Correct SET_RFE settings
wifi: rtw89: coex: Add firmware report control report v11
wifi: rtw89: coex: update external control length by case
wifi: rtw89: coex: Update coexistence version to 9.24.0
drivers/net/wireless/realtek/rtw89/coex.c | 3781 ++++++++---------
drivers/net/wireless/realtek/rtw89/coex.h | 73 +
drivers/net/wireless/realtek/rtw89/core.c | 11 +-
drivers/net/wireless/realtek/rtw89/core.h | 486 ++-
drivers/net/wireless/realtek/rtw89/debug.c | 6 +-
drivers/net/wireless/realtek/rtw89/fw.c | 556 ++-
drivers/net/wireless/realtek/rtw89/fw.h | 60 +-
drivers/net/wireless/realtek/rtw89/mac.c | 27 +-
drivers/net/wireless/realtek/rtw89/mac_be.c | 21 +-
drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 +
.../net/wireless/realtek/rtw89/rtw8852bt.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8922a.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8922d.c | 214 +-
16 files changed, 2954 insertions(+), 2287 deletions(-)
base-commit: 56d32cdc6040440b08edfd5d7262250a721233f8
--
2.25.1
^ permalink raw reply
* [PATCH rtw-next 01/11] wifi: rtw89: coex: Add Wi-Fi role info version 10
From: Ping-Ke Shih @ 2026-07-12 3:04 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260712030506.43438-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
Because the new generation Bluetooth will able to work on 5/6GHz band,
it will suffer 5/6GHz Wi-Fi, the mechanism need to cover more scenario
with different Wi-Fi/Bluetooth combination.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 2445 +++++++----------
drivers/net/wireless/realtek/rtw89/coex.h | 34 +
drivers/net/wireless/realtek/rtw89/core.h | 153 +-
drivers/net/wireless/realtek/rtw89/fw.c | 392 ++-
drivers/net/wireless/realtek/rtw89/fw.h | 48 +-
drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 +
.../net/wireless/realtek/rtw89/rtw8852bt.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8922a.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8922d.c | 1 +
12 files changed, 1391 insertions(+), 1688 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 989344e93ab7..c02de0b4f7bf 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -436,11 +436,6 @@ union rtw89_fbtc_set_mon_reg {
struct rtw89_btc_btf_set_mon_reg_v7 v7;
} __packed;
-struct _wl_rinfo_now {
- u8 link_mode;
- u32 dbcc_2g_phy: 2;
-};
-
enum btc_btf_set_cx_policy {
CXPOLICY_TDMA = 0x0,
CXPOLICY_SLOT = 0x1,
@@ -570,9 +565,21 @@ enum btc_cx_poicy_type {
/* TDMA off + pri: WL > BT, Block-BT*/
BTC_CXP_OFF_WL2 = (BTC_CXP_OFF << 8) | 12,
- /* TDMA off+Bcn-Protect + pri: WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo*/
+ /* TDMA off+Bcn-Protect + pri: BT_Hi > WL > BT_Lo */
BTC_CXP_OFFB_BWB0 = (BTC_CXP_OFFB << 8) | 0,
+ /* TDMA off+Bcn-Protect + pri: BT_Hi_Tx = WL_Hi-Tx > BT_Hi_Rx, BT_Hi > WL > BT_Lo */
+ BTC_CXP_OFFB_BWB1 = (BTC_CXP_OFFB << 8) | 1,
+
+ /* TDMA off+Bcn-Protect + pri: WL_Hi-Tx > BT, BT_Hi > other-WL > BT_Lo */
+ BTC_CXP_OFFB_BWB2 = (BTC_CXP_OFFB << 8) | 2,
+
+ /* TDMA off+Bcn-Protect + pri: WL_Hi-Tx = BT*/
+ BTC_CXP_OFFB_BWB3 = (BTC_CXP_OFFB << 8) | 3,
+
+ /* TDMA off+Bcn-Protect + pri: BT > WL*/
+ BTC_CXP_OFFB_BWB4 = (BTC_CXP_OFFB << 8) | 4,
+
/* TDMA off + Ext-Ctrl + pri: default */
BTC_CXP_OFFE_DEF = (BTC_CXP_OFFE << 8) | 0,
@@ -752,19 +759,31 @@ enum btc_w2b_scoreboard {
BTC_WSCB_ALL = GENMASK(23, 0),
};
-enum btc_wl_link_mode {
+enum btc_wl_link_mode_v0 {
+ BTC_WLINK_V0_NOLINK = 0x0,
+ BTC_WLINK_V0_2G_STA,
+ BTC_WLINK_V0_2G_AP,
+ BTC_WLINK_V0_2G_GO,
+ BTC_WLINK_V0_2G_GC,
+ BTC_WLINK_V0_2G_SCC,
+ BTC_WLINK_V0_2G_MCC,
+ BTC_WLINK_V0_25G_MCC,
+ BTC_WLINK_V0_25G_DBCC,
+ BTC_WLINK_V0_5G,
+ BTC_WLINK_V0_2G_NAN,
+ BTC_WLINK_V0_OTHER,
+ BTC_WLINK_V0_MAX
+};
+
+enum btc_wl_link_mode_v1 {
BTC_WLINK_NOLINK = 0x0,
- BTC_WLINK_2G_STA,
- BTC_WLINK_2G_AP,
- BTC_WLINK_2G_GO,
- BTC_WLINK_2G_GC,
- BTC_WLINK_2G_SCC,
- BTC_WLINK_2G_MCC,
- BTC_WLINK_25G_MCC,
- BTC_WLINK_25G_DBCC,
- BTC_WLINK_5G,
- BTC_WLINK_2G_NAN,
- BTC_WLINK_OTHER,
+ BTC_WLINK_STA,
+ BTC_WLINK_AP,
+ BTC_WLINK_GO,
+ BTC_WLINK_GC,
+ BTC_WLINK_SCC,
+ BTC_WLINK_SB_MCC,
+ BTC_WLINK_DB_MCC, /* 2+0/0+2 Dual-RF-band MCC */
BTC_WLINK_MAX
};
@@ -774,16 +793,13 @@ static const char *id_to_linkmode(u8 id)
{
switch (id) {
CASE_BTC_WL_LINK_MODE(NOLINK);
- CASE_BTC_WL_LINK_MODE(2G_STA);
- CASE_BTC_WL_LINK_MODE(2G_AP);
- CASE_BTC_WL_LINK_MODE(2G_GO);
- CASE_BTC_WL_LINK_MODE(2G_GC);
- CASE_BTC_WL_LINK_MODE(2G_SCC);
- CASE_BTC_WL_LINK_MODE(2G_MCC);
- CASE_BTC_WL_LINK_MODE(25G_MCC);
- CASE_BTC_WL_LINK_MODE(25G_DBCC);
- CASE_BTC_WL_LINK_MODE(5G);
- CASE_BTC_WL_LINK_MODE(OTHER);
+ CASE_BTC_WL_LINK_MODE(STA);
+ CASE_BTC_WL_LINK_MODE(AP);
+ CASE_BTC_WL_LINK_MODE(GO);
+ CASE_BTC_WL_LINK_MODE(GC);
+ CASE_BTC_WL_LINK_MODE(SCC);
+ CASE_BTC_WL_LINK_MODE(SB_MCC);
+ CASE_BTC_WL_LINK_MODE(DB_MCC);
default:
return "unknown";
}
@@ -969,7 +985,7 @@ static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type)
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
struct rtw89_btc_wl_link_info *wl_linfo;
- u8 i;
+ u8 i, j;
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__);
@@ -990,12 +1006,11 @@ static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type)
if (type & BTC_RESET_DM) {
memset(&btc->dm, 0, sizeof(btc->dm));
memset(bt_linfo->rssi_state, 0, sizeof(bt_linfo->rssi_state));
- for (i = 0; i < RTW89_PORT_NUM; i++) {
- if (btc->ver->fwlrole == 8)
- wl_linfo = &wl->rlink_info[i][0];
- else
- wl_linfo = &wl->link_info[i];
- memset(wl_linfo->rssi_state, 0, sizeof(wl_linfo->rssi_state));
+ for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) {
+ for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) {
+ wl_linfo = &wl->rlink_info[i][j];
+ memset(wl_linfo->rssi_state, 0, sizeof(wl_linfo->rssi_state));
+ }
}
/* set the slot_now table to original */
@@ -2847,6 +2862,8 @@ static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 index)
rtw89_fw_h2c_cxdrv_role_v7(rtwdev, index);
else if (ver->fwlrole == 8)
rtw89_fw_h2c_cxdrv_role_v8(rtwdev, index);
+ else if (ver->fwlrole == 10)
+ rtw89_fw_h2c_cxdrv_role_v10(rtwdev, index);
break;
case CXDRVINFO_CTRL:
if (ver->drvinfo_ver != 0)
@@ -3396,29 +3413,17 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev)
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_wl_role_info *r = &wl->role_info;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_bt_link_info *b = &bt->link_info;
struct rtw89_btc_wl_smap *wl_smap = &wl->status.map;
struct rtw89_btc_rf_trx_para_v9 para;
- u8 lv, link_mode = 0, i, dbcc_2g_phy = 0;
- u8 ul_para_num, dl_para_num;
- u8 rf_band = RTW89_BAND_2G;
- u8 bid = BTC_BT_1ST;
- u32 wl_stb_chg = 0;
-
- if (ver->fwlrole == 0) {
- link_mode = wl->role_info.link_mode;
- for (i = 0; i < RTW89_PHY_NUM; i++) {
- if (wl->dbcc_info.real_band[i] == RTW89_BAND_2G)
- dbcc_2g_phy = i;
- }
- } else if (ver->fwlrole == 1) {
- link_mode = wl->role_info_v1.link_mode;
- dbcc_2g_phy = wl->role_info_v1.dbcc_2g_phy;
- } else if (ver->fwlrole == 2) {
- link_mode = wl->role_info_v2.link_mode;
- dbcc_2g_phy = wl->role_info_v2.dbcc_2g_phy;
- }
+ u8 bmode = dm->tdd_bind.wl_link_mode;
+ u8 rf_band = dm->tdd_bind.rf_band;
+ u8 i, ul_para_num, dl_para_num;
+ u8 mode = BTC_WLINK_NOLINK;
+ u8 bid = BTC_BT_1ST, lv;
+ u32 wl_stb_chg;
if (ver->fcxtrx == 9 && chip->rf_para_ulink_v9) {
ul_para_num = chip->rf_para_ulink_num_v9;
@@ -3434,6 +3439,19 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev)
goto next;
}
+ if (bmode == BTC_WLINK_NOLINK) {
+ return;
+ } else if (btc->ver->fwlrole == 10) {
+ if (rf_band == RTW89_BAND_5G) {
+ mode = BTC_WLINK_V0_5G;
+ } else if (rf_band == RTW89_BAND_2G &&
+ bmode == BTC_WLINK_STA) {
+ mode = BTC_WLINK_V0_2G_STA;
+ }
+ } else {
+ mode = r->link_mode_v0;
+ }
+
/* decide trx_para_level */
if (btc->ant_type == BTC_ANT_SHARED) {
/* fix LNA2 + TIA gain not change by GNT_BT */
@@ -3446,7 +3464,7 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev)
dm->trx_para_level = 5;
/* modify trx_para if WK 2.4G-STA-DL + bt link */
if (b->link_cnt.now != 0 &&
- link_mode == BTC_WLINK_2G_STA &&
+ mode == BTC_WLINK_V0_2G_STA &&
wl->status.map.traffic_dir & BIT(RTW89_TFC_UL)) { /* uplink */
if (wl->rssi_level == 4 && bt->rssi_level > 2)
dm->trx_para_level = 6;
@@ -3504,10 +3522,8 @@ static void _set_rf_trx_para(struct rtw89_dev *rtwdev)
next:
if (!bt->enable.now || dm->wl_only || wl_smap->rf_off ||
- wl_smap->lps == BTC_LPS_RF_OFF ||
- link_mode == BTC_WLINK_5G ||
- link_mode == BTC_WLINK_NOLINK ||
- (rtwdev->dbcc_en && dbcc_2g_phy != RTW89_PHY_1))
+ wl_smap->lps == BTC_LPS_RF_OFF || mode == BTC_WLINK_V0_5G ||
+ (rtwdev->dbcc_en && r->dbcc_2g_phy != RTW89_PHY_1))
wl_stb_chg = 0;
else
wl_stb_chg = 1;
@@ -3544,282 +3560,372 @@ static void _update_btc_state_map(struct rtw89_dev *rtwdev)
}
}
-static void _set_bt_afh_info_v0(struct rtw89_dev *rtwdev)
+static u8 _get_wl_guard_bw(struct rtw89_dev *rtwdev, u8 index)
{
- const struct rtw89_chip_info *chip = rtwdev->chip;
- struct rtw89_btc *btc = &rtwdev->btc;
- const struct rtw89_btc_ver *ver = btc->ver;
- struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
- struct rtw89_btc_bt_link_info *b = &bt->link_info;
- struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
- struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
- struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
- struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
- struct rtw89_btc_wl_active_role *r;
- struct rtw89_btc_wl_active_role_v1 *r1;
- struct rtw89_btc_wl_active_role_v2 *r2;
- struct rtw89_btc_wl_active_role_v7 *r7;
- struct rtw89_btc_wl_rlink *rlink;
- u8 en = 0, i, ch = 0, bw = 0;
- u8 mode, connect_cnt;
-
- if (btc->manual_ctrl || wl->status.map.scan)
- return;
-
- if (ver->fwlrole == 0) {
- mode = wl_rinfo->link_mode;
- connect_cnt = wl_rinfo->connect_cnt;
- } else if (ver->fwlrole == 1) {
- mode = wl_rinfo_v1->link_mode;
- connect_cnt = wl_rinfo_v1->connect_cnt;
- } else if (ver->fwlrole == 2) {
- mode = wl_rinfo_v2->link_mode;
- connect_cnt = wl_rinfo_v2->connect_cnt;
- } else if (ver->fwlrole == 7) {
- mode = wl_rinfo_v7->link_mode;
- connect_cnt = wl_rinfo_v7->connect_cnt;
- } else if (ver->fwlrole == 8) {
- mode = wl_rinfo_v8->link_mode;
- connect_cnt = wl_rinfo_v8->connect_cnt;
- } else {
- return;
- }
-
- if (wl->status.map.rf_off || bt->whql_test ||
- mode == BTC_WLINK_NOLINK || mode == BTC_WLINK_5G ||
- connect_cnt > BTC_TDMA_WLROLE_MAX) {
- en = false;
- } else if (mode == BTC_WLINK_2G_MCC || mode == BTC_WLINK_2G_SCC) {
- en = true;
- /* get p2p channel */
- for (i = 0; i < RTW89_PORT_NUM; i++) {
- r = &wl_rinfo->active_role[i];
- r1 = &wl_rinfo_v1->active_role_v1[i];
- r2 = &wl_rinfo_v2->active_role_v2[i];
- r7 = &wl_rinfo_v7->active_role[i];
- rlink = &wl_rinfo_v8->rlink[i][0];
-
- if (ver->fwlrole == 0 &&
- (r->role == RTW89_WIFI_ROLE_P2P_GO ||
- r->role == RTW89_WIFI_ROLE_P2P_CLIENT)) {
- ch = r->ch;
- bw = r->bw;
- break;
- } else if (ver->fwlrole == 1 &&
- (r1->role == RTW89_WIFI_ROLE_P2P_GO ||
- r1->role == RTW89_WIFI_ROLE_P2P_CLIENT)) {
- ch = r1->ch;
- bw = r1->bw;
- break;
- } else if (ver->fwlrole == 2 &&
- (r2->role == RTW89_WIFI_ROLE_P2P_GO ||
- r2->role == RTW89_WIFI_ROLE_P2P_CLIENT)) {
- ch = r2->ch;
- bw = r2->bw;
- break;
- } else if (ver->fwlrole == 7 &&
- (r7->role == RTW89_WIFI_ROLE_P2P_GO ||
- r7->role == RTW89_WIFI_ROLE_P2P_CLIENT)) {
- ch = r7->ch;
- bw = r7->bw;
- break;
- } else if (ver->fwlrole == 8 &&
- (rlink->role == RTW89_WIFI_ROLE_P2P_GO ||
- rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT)) {
- ch = rlink->ch;
- bw = rlink->bw;
- break;
- }
- }
- } else {
- en = true;
- /* get 2g channel */
- for (i = 0; i < RTW89_PORT_NUM; i++) {
- r = &wl_rinfo->active_role[i];
- r1 = &wl_rinfo_v1->active_role_v1[i];
- r2 = &wl_rinfo_v2->active_role_v2[i];
- r7 = &wl_rinfo_v7->active_role[i];
- rlink = &wl_rinfo_v8->rlink[i][0];
-
- if (ver->fwlrole == 0 &&
- r->connected && r->band == RTW89_BAND_2G) {
- ch = r->ch;
- bw = r->bw;
- break;
- } else if (ver->fwlrole == 1 &&
- r1->connected && r1->band == RTW89_BAND_2G) {
- ch = r1->ch;
- bw = r1->bw;
- break;
- } else if (ver->fwlrole == 2 &&
- r2->connected && r2->band == RTW89_BAND_2G) {
- ch = r2->ch;
- bw = r2->bw;
- break;
- } else if (ver->fwlrole == 7 &&
- r7->connected && r7->band == RTW89_BAND_2G) {
- ch = r7->ch;
- bw = r7->bw;
- break;
- } else if (ver->fwlrole == 8 &&
- rlink->connected && rlink->rf_band == RTW89_BAND_2G) {
- ch = rlink->ch;
- bw = rlink->bw;
- break;
- }
- }
- }
+ struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
+ u8 guard_ch = rtwdev->chip->afh_guard_ch;
+ u8 bw = 0;
- switch (bw) {
+ /* default AFH channel sapn = center-ch +- 6MHz */
+ switch (index) {
case RTW89_CHANNEL_WIDTH_20:
- bw = 20 + chip->afh_guard_ch * 2;
+ if (dm->freerun || dm->fddt_train)
+ bw = 48;
+ else
+ bw = 20 + guard_ch * 2;
break;
case RTW89_CHANNEL_WIDTH_40:
- bw = 40 + chip->afh_guard_ch * 2;
+ bw = 40 + guard_ch * 2;
+ break;
+ case RTW89_CHANNEL_WIDTH_80:
+ bw = 80 + guard_ch * 2;
+ break;
+ case RTW89_CHANNEL_WIDTH_160:
+ case RTW89_CHANNEL_WIDTH_80_80:
+ bw = 160 + guard_ch * 2;
+ break;
+ case RTW89_CHANNEL_WIDTH_320:
+ bw = 320 + guard_ch * 2;
break;
case RTW89_CHANNEL_WIDTH_5:
- bw = 5 + chip->afh_guard_ch * 2;
+ bw = 5 + guard_ch * 2;
break;
case RTW89_CHANNEL_WIDTH_10:
- bw = 10 + chip->afh_guard_ch * 2;
+ bw = 10 + guard_ch * 2;
break;
default:
bw = 0;
- en = false; /* turn off AFH info if BW > 40 */
break;
}
- if (wl->afh_info.en == en &&
- wl->afh_info.ch == ch &&
- wl->afh_info.bw == bw &&
- b->link_cnt.last == b->link_cnt.now) {
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): return because no change!\n",
- __func__);
+ return bw;
+}
+
+static void _set_wl_ch_map(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_wl_afh_info *afh;
+ u16 ch_start, ch_end, i;
+ u8 b_group, b_pos; /* byte-group, bit-position */
+ u8 hwb;
+
+ if (wl->afh_info[RTW89_MAC_0][RTW89_BAND_2G].en &&
+ wl->afh_info[RTW89_MAC_1][RTW89_BAND_2G].en) {
+ /* select wilder bw if 1+1 */
+ if (wl->afh_info[RTW89_MAC_1][RTW89_BAND_2G].bw >
+ wl->afh_info[RTW89_MAC_0][RTW89_BAND_2G].bw)
+ hwb = RTW89_MAC_1;
+ else
+ hwb = RTW89_MAC_0;
+ } else if (wl->afh_info[RTW89_MAC_1][RTW89_BAND_2G].en) {
+ hwb = RTW89_MAC_1;
+ } else {
+ hwb = RTW89_MAC_0;
+ }
+
+ afh = &wl->afh_info[hwb][RTW89_BAND_2G];
+
+ /* focus on WL 2.4GHz link */
+ if (!afh->en || afh->band != RTW89_BAND_2G)
return;
+
+ memset(wl->ch_map, 0x0, sizeof(wl->ch_map));
+ memset(wl->ch_map_le, 0x0, sizeof(wl->ch_map_le));
+
+ ch_start = afh->ch * 5 + 2407 - afh->bw / 2;
+ ch_end = ch_start + afh->bw;
+
+ for (i = ch_start; i < ch_end; i++) {
+ if (i < 2402 || i > 2480)
+ continue;
+ b_group = (i - 2402) / 8;
+ b_pos = 7 - ((i - 2402) % 8);
+ wl->ch_map[b_group] |= BIT(b_pos);
+
+ if (i % 2) /* BLE ch = even-freq (ex:2402,2404) */
+ continue;
+
+ b_group = (i - 2402) / 16;
+ b_pos = 7 - (((i - 2402) / 2) % 8);
+ wl->ch_map_le[b_group] |= BIT(b_pos);
}
+}
- wl->afh_info.en = en;
- wl->afh_info.ch = ch;
- wl->afh_info.bw = bw;
+static u8 _get_w2b_fbd_ch(struct rtw89_dev *rtwdev,
+ u8 bt_fb_band, u32 wl_vco_freq,
+ u32 *ch_lo_bound, u32 *ch_up_bound)
+{
+ u32 ch_lo, ch_pup, ch_min, ch_max;
+ u8 out_of_range = 0;
+ s32 val_lo, val_up;
+ u32 vco_lo_in_KHz; /* VCO pulling lower bound */
+ u32 vco_up_in_KHz; /* VCO pulling Upper bound */
+ u32 freq_start;
- _send_fw_cmd(rtwdev, BTFC_SET, SET_BT_WL_CH_INFO, &wl->afh_info, 3);
+ vco_lo_in_KHz = wl_vco_freq - BTC_VCO_GUARD_W2B * 1000; /* KHz */
+ vco_up_in_KHz = wl_vco_freq + BTC_VCO_GUARD_W2B * 1000;
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): en=%d, ch=%d, bw=%d\n",
- __func__, en, ch, bw);
- wl->wcnt[BTC_WCNT_CH_UPDATE]++;
+ switch (bt_fb_band) {
+ default:
+ case BTC_BT_B2G: /* BT 2GHz forbiddened Channel */
+ val_lo = vco_lo_in_KHz * BTC_LO_2G_DNM / BTC_LO_2G_NMR;
+ val_up = vco_up_in_KHz * BTC_LO_2G_DNM / BTC_LO_2G_NMR;
+ freq_start = BTC_FREQ_B2G * 1000; /* KHz */
+ ch_min = BTC_CH_B2G_MIN;
+ ch_max = BTC_CH_B2G_MAX;
+ break;
+ case BTC_BT_B5G: /* BT 5/6GHz forbiddened Channel */
+ val_lo = vco_lo_in_KHz * BTC_LO_6G_DNM / BTC_LO_6G_NMR;
+ val_up = vco_up_in_KHz * BTC_LO_6G_DNM / BTC_LO_6G_NMR;
+ freq_start = BTC_FREQ_B6G * 1000; /* KHz */
+ ch_min = BTC_CH_B5G_MIN;
+ ch_max = BTC_CH_B5G_MAX;
+ break;
+ }
+
+ /* Search forbiddened Channel (un-process range)*/
+ ch_lo = (val_lo - freq_start) / 1000;
+ if ((val_lo - freq_start) % 1000 != 0) /* Round-UP */
+ ch_lo++;
+
+ ch_pup = (val_up - freq_start) / 1000; /* Round-down */
+
+ /* Search forbiddened Channel */
+ if (ch_lo > ch_max || ch_pup < ch_min) { /* out-of-range -> NA */
+ out_of_range = 1;
+ *ch_lo_bound = 0;
+ *ch_up_bound = 0;
+ }
+
+ if (ch_lo < ch_min)
+ *ch_lo_bound = ch_min;
+ else if (ch_lo <= ch_max)
+ *ch_lo_bound = ch_lo;
+
+ if (ch_pup > ch_max)
+ *ch_up_bound = ch_max;
+ else if (ch_pup >= ch_min)
+ *ch_up_bound = ch_pup;
+
+ if (bt_fb_band == BTC_BT_B5G) { /* BT ch is 8MHz-spacing for 5/6GHz */
+ *ch_lo_bound = *ch_lo_bound / 8; /* low-bound -> Round-down */
+
+ if (*ch_up_bound % 8 != 0) /* Up-bound -> cover wider range */
+ *ch_up_bound = *ch_up_bound / 8 + 1;
+ else
+ *ch_up_bound = *ch_up_bound / 8;
+ }
+
+ return out_of_range;
}
-static void _set_bt_afh_info_v1(struct rtw89_dev *rtwdev)
+static void _set_wl_ch_info(struct rtw89_dev *rtwdev)
+{
+ static const u8 path_hwb[BTC_RF_NUM] = {RTW89_PHY_0, RTW89_PHY_1};
+ struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
+ struct rtw89_btc_cx *cx = &rtwdev->btc.cx;
+ struct rtw89_btc_wl_info *wl = &cx->wl;
+ u32 vco_freq, ch_lo = 0, ch_up = 0;
+ u16 rf_band, freq, f_diff;
+ u8 i, j, ch;
+
+ if (!(rtwdev->chip->para_ver & BTC_FEAT_MULTI_PTA)) /* only new-PTA require setup */
+ return;
+
+ for (i = RTW89_PHY_0; i <= RTW89_PHY_1; i++) {
+ if (wl->mlo_info.wmode[i] == RTW89_MR_WMODE_NONE) { /* no-connect */
+ dm->ost_info.rf_center_freq[i] = 0;
+ dm->ost_info.fbd_group_en[i][0] = 0;
+ dm->ost_info.fbd_group_en[i][1] = 0;
+ dm->ost_info.fbd_group_bound[i][0] = 0;
+ dm->ost_info.fbd_group_bound[i][1] = 0;
+ continue;
+ }
+
+ ch = wl->rf_ch_info[i].center_ch;
+ switch (wl->rf_ch_info[i].band) {
+ case RTW89_BAND_2G:
+ default:
+ rf_band = 0;
+ if (ch == 14)
+ freq = BTC_FREQ_W2G_CH14;
+ else
+ freq = BTC_FREQ_W2G + (ch - 1) * 5;
+ vco_freq = freq * 1000 * BTC_LO_2G_NMR / BTC_LO_2G_DNM;
+ break;
+ case RTW89_BAND_5G:
+ rf_band = BIT(15);
+ freq = BTC_FREQ_W5G + (ch - 1) * 5;
+ vco_freq = freq * 1000 * BTC_LO_5G_NMR / BTC_LO_5G_DNM;
+ break;
+ case RTW89_BAND_6G:
+ rf_band = BIT(15);
+ freq = BTC_FREQ_W6G + (ch - 1) * 5;
+ vco_freq = freq * 1000 * BTC_LO_6G_NMR / BTC_LO_6G_DNM;
+ break;
+ }
+
+ dm->ost_info.rf_center_freq[i] = rf_band + freq;
+
+ for (j = BTC_BT_B2G; j <= BTC_BT_B5G; j++) {
+ /* no WL->BT forbidden channel */
+ if (_get_w2b_fbd_ch(rtwdev, j, vco_freq, &ch_lo, &ch_up)) {
+ dm->ost_info.fbd_group_en[i][j] = j << 1;
+ dm->ost_info.fbd_group_bound[i][j] = 0;
+ continue;
+ }
+
+ dm->ost_info.fbd_group_en[i][j] = (j << 1) + 0x1;
+ dm->ost_info.fbd_group_bound[i][j] = (ch_up << 8) + ch_lo;
+ }
+ }
+
+ for (i = BTC_RF_S0; i <= BTC_RF_S1; i++) {
+ for (j = BTC_BT_1ST; j <= BTC_BT_EXT; j++) {
+ /*
+ * If WL & BT share same ANT/Path, set freq-diff > 2GHz,
+ * because TDD will always run in 5/6GHz band.
+ * Otherwise, the frq-diff thres is decided by the RF
+ * out-of-channel rejection capability.
+ */
+ if (dm->ant_xmap[i][j])
+ f_diff = 0x7ff; /* 2047MHz */
+ else
+ f_diff = rtwdev->chip->fdd_iso_freq;
+
+ dm->ost_info.freq_diff_thres[path_hwb[i]][j] = f_diff;
+ }
+ }
+}
+
+static void _set_bt_afh_info(struct rtw89_dev *rtwdev)
{
- const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8;
- struct rtw89_btc_wl_afh_info *wl_afh = &wl->afh_info;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
+ struct rtw89_btc_cx *cx = &btc->cx;
+ struct rtw89_btc_wl_info *wl = &cx->wl;
+ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_btc_wl_rlink *rlink;
- u8 en = 0, ch = 0, bw = 0, buf[3] = {};
- u8 i, j, link_mode;
+ u8 h2c_func, hwb, bt_link_chg;
+ u8 i, j, sz, bw;
+ u8 buf[4];
- if (btc->manual_ctrl || wl->status.map.scan)
+ if (btc->manual_ctrl || wl->status.map.rf_off ||
+ (wl->status.val & btc_scanning_map.val))
return;
- link_mode = wl_rinfo->link_mode;
+ memset(wl->afh_info, 0, sizeof(wl->afh_info));
- for (i = 0; i < btc->ver->max_role_num; i++) {
- for (j = RTW89_MAC_0; j < RTW89_MAC_NUM; j++) {
- if (wl->status.map.rf_off || bt->whql_test ||
- link_mode == BTC_WLINK_NOLINK ||
- link_mode == BTC_WLINK_5G)
- break;
+ for (j = RTW89_MAC_0; j < RTW89_MAC_NUM; j++) {
+ /* skip HW-Band if no fdd/fdd bind */
+ if ((!(btc->dm.tdd_bind.wl_hwb_sel & BIT(j))) &&
+ (!(btc->dm.fdd_bind.wl_hwb_sel & BIT(j))))
+ continue;
+ for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) {
rlink = &wl_rinfo->rlink[i][j];
- /* Don't care no-connected/non-2G-band role */
+ /* Skip no-active case */
if (!rlink->connected || !rlink->active ||
- rlink->rf_band != RTW89_BAND_2G)
+ rlink->rf_band >= RTW89_BAND_NUM)
continue;
- en = 1;
- ch = rlink->ch;
- bw = rlink->bw;
+ /* In addition to AP/P2P, skip if same-rf-band*/
+ if (wl->afh_info[j][rlink->rf_band].en &&
+ (rlink->role != RTW89_WIFI_ROLE_AP &&
+ rlink->role != RTW89_WIFI_ROLE_P2P_GO &&
+ rlink->role != RTW89_WIFI_ROLE_P2P_CLIENT))
+ continue;
- if (link_mode == BTC_WLINK_2G_MCC &&
- (rlink->role == RTW89_WIFI_ROLE_AP ||
- rlink->role == RTW89_WIFI_ROLE_P2P_GO ||
- rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT)) {
- /* for 2.4G MCC, take role = ap/go/gc */
- break;
- } else if (link_mode != BTC_WLINK_2G_SCC ||
- rlink->bw == RTW89_CHANNEL_WIDTH_40) {
- /* for 2.4G scc, take bw = 40M */
- break;
- }
+ bw = _get_wl_guard_bw(rtwdev, rlink->bw);
+ wl->afh_info[j][rlink->rf_band].en = 1;
+ wl->afh_info[j][rlink->rf_band].ch = rlink->ch;
+ wl->afh_info[j][rlink->rf_band].bw = bw;
+ wl->afh_info[j][rlink->rf_band].band = rlink->rf_band;
}
}
- /* default AFH channel sapn = center-ch +- 6MHz */
- switch (bw) {
- case RTW89_CHANNEL_WIDTH_20:
- if (btc->dm.freerun || btc->dm.fddt_train)
- bw = 48;
- else
- bw = 20 + chip->afh_guard_ch * 2;
- break;
- case RTW89_CHANNEL_WIDTH_40:
- if (btc->dm.freerun)
- bw = 40 + chip->afh_guard_ch * 2;
- else
- bw = 40;
- break;
- case RTW89_CHANNEL_WIDTH_5:
- bw = 5 + chip->afh_guard_ch * 2;
- break;
- case RTW89_CHANNEL_WIDTH_10:
- bw = 10 + chip->afh_guard_ch * 2;
- break;
- default:
- en = false; /* turn off AFH info if invalid BW */
- bw = 0;
- ch = 0;
- break;
- }
+ for (j = RTW89_BAND_2G; j < RTW89_BAND_NUM; j++) {
+ /* skip non-2.4GHz if BT is 2.4GHz only*/
+ if (!(rtwdev->chip->para_ver & BTC_FEAT_BT_6G)) {
+ if (j != RTW89_BAND_2G)
+ continue;
+ sz = 3;
+ } else {
+ sz = 4;
+ }
- if (!en || ch > 14 || ch == 0) {
- en = false;
- bw = 0;
- ch = 0;
- }
+ if (wl->afh_info[RTW89_MAC_0][j].en &&
+ wl->afh_info[RTW89_MAC_1][j].en) {
+ /* select wilder bw if 1+1 */
+ if (wl->afh_info[RTW89_MAC_1][j].bw >
+ wl->afh_info[RTW89_MAC_0][j].bw)
+ hwb = RTW89_MAC_1;
+ else
+ hwb = RTW89_MAC_0;
+ } else if (wl->afh_info[RTW89_MAC_1][j].en) {
+ hwb = RTW89_MAC_1;
+ } else {
+ hwb = RTW89_MAC_0;
+ }
- if (wl_afh->en == en &&
- wl_afh->ch == ch &&
- wl_afh->bw == bw &&
- (!bt->enable.now || bt->enable.last))
- return;
+ if (j == RTW89_BAND_2G) {
+ if (cx->bt0.link_info.link_cnt.chg ||
+ cx->bt1.link_info.link_cnt.chg)
+ bt_link_chg = 1;
+ else
+ bt_link_chg = 0;
+ } else {
+ if (cx->bt0.link_info_56g.link_cnt.chg ||
+ cx->bt1.link_info_56g.link_cnt.chg)
+ bt_link_chg = 1;
+ else
+ bt_link_chg = 0;
+ }
+
+ /* return if no-afh-info-change/no wl-bt link change */
+ if (!memcmp(&wl->afh_info_last[hwb][j],
+ &wl->afh_info[hwb][j],
+ sizeof(struct rtw89_btc_wl_afh_info)) &&
+ !bt_link_chg &&
+ !wl->link_mode_chg)
+ continue;
+
+ memcpy(&wl->afh_info_last[hwb][j],
+ &wl->afh_info[hwb][j],
+ sizeof(struct rtw89_btc_wl_afh_info));
+
+ buf[0] = wl->afh_info[hwb][j].en;
+ buf[1] = wl->afh_info[hwb][j].ch;
+ buf[2] = wl->afh_info[hwb][j].bw;
+ buf[3] = wl->afh_info[hwb][j].band;
+
+ h2c_func = SET_BT_WL_CH_INFO;
+ if (cx->bt0.enable.now)
+ _send_fw_cmd(rtwdev, BTFC_SET, h2c_func, buf, sz);
- wl_afh->en = buf[0];
- wl_afh->ch = buf[1];
- wl_afh->bw = buf[2];
+ /* send mailbox to 2nd-BT if exist */
+ if (cx->bt1.enable.now) {
+ h2c_func |= BT_H2C_FUNC_BT2ND;
+ _send_fw_cmd(rtwdev, BTFC_SET, h2c_func, buf, sz);
+ }
- if (_send_fw_cmd(rtwdev, BTFC_SET, SET_BT_WL_CH_INFO, &wl->afh_info, 3)) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): en=%d, ch=%d, bw=%d\n",
- __func__, en, ch, bw);
+ "[BTC], %s(): en=%d, ch=%d, bw=%d, rf_band=%d\n",
+ __func__, buf[0], buf[1], buf[2], buf[3]);
wl->wcnt[BTC_WCNT_CH_UPDATE]++;
+
+ /* ToDo: Remove if BT update new-define to support 6GHz */
+ if (j == RTW89_BAND_2G)
+ break;
}
-}
-static void _set_bt_afh_info(struct rtw89_dev *rtwdev)
-{
- if (rtwdev->chip->chip_id == RTL8922A)
- _set_bt_afh_info_v1(rtwdev);
- else
- _set_bt_afh_info_v0(rtwdev);
+ /* for AFH map display in coex log */
+ _set_wl_ch_map(rtwdev);
+
+ /* set HWB center-ch/forbidden group to ost_info for CR setup in FW */
+ _set_wl_ch_info(rtwdev);
}
static bool _check_freerun(struct rtw89_dev *rtwdev)
@@ -3828,39 +3934,24 @@ static bool _check_freerun(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
- struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
- struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
- struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
struct rtw89_btc_bt_hid_desc *hid = &bt_linfo->hid_desc;
union rtw89_btc_module_info *md = &btc->mdinfo;
const struct rtw89_btc_ver *ver = btc->ver;
- u8 isolation, connect_cnt = 0;
+ u8 isolation;
if (ver->fcxinit == 7)
isolation = md->md_v7.ant.isolation;
else
isolation = md->md.ant.isolation;
- if (ver->fwlrole == 0)
- connect_cnt = wl_rinfo->connect_cnt;
- else if (ver->fwlrole == 1)
- connect_cnt = wl_rinfo_v1->connect_cnt;
- else if (ver->fwlrole == 2)
- connect_cnt = wl_rinfo_v2->connect_cnt;
- else if (ver->fwlrole == 7)
- connect_cnt = wl_rinfo_v7->connect_cnt;
- else if (ver->fwlrole == 8)
- connect_cnt = wl_rinfo_v8->connect_cnt;
-
if (btc->ant_type == BTC_ANT_SHARED) {
btc->dm.trx_para_level = 0;
return false;
}
/* The below is dedicated antenna case */
- if (connect_cnt > BTC_TDMA_WLROLE_MAX) {
+ if (wl_rinfo->connect_cnt > BTC_TDMA_WLROLE_MAX) {
btc->dm.trx_para_level = 5;
return true;
}
@@ -4097,11 +4188,26 @@ void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type)
case BTC_CXP_OFFB: /* TDMA off + beacon protect */
tdma_on = false;
*t = t_def[CXTD_OFF_B2];
- s[CXST_OFF] = s_def[CXST_OFF];
+ _slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur,
+ s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype);
+ _slot_set(btc, CXST_B2, 10, cxtbl[1], SLOT_ISO);
+
switch (policy_type) {
case BTC_CXP_OFFB_BWB0:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[5]);
+ break;
+ case BTC_CXP_OFFB_BWB1:
_slot_set_tbl(btc, CXST_OFF, cxtbl[8]);
break;
+ case BTC_CXP_OFFB_BWB2:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[7]);
+ break;
+ case BTC_CXP_OFFB_BWB3:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[6]);
+ break;
+ case BTC_CXP_OFFB_BWB4:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[2]);
+ break;
}
break;
case BTC_CXP_OFFE: /* TDMA off + beacon protect + Ext_control */
@@ -4182,7 +4288,7 @@ void rtw89_btc_set_policy(struct rtw89_dev *rtwdev, u16 policy_type)
case BTC_CXP_PFIX: /* PS-TDMA Fix-Slot */
tdma_on = true;
*t = t_def[CXTD_PFIX];
- if (btc->cx.wl.role_info.role_map.role.ap)
+ if (btc->cx.wl.role_info.role_map & BIT(RTW89_WIFI_ROLE_AP))
_tdma_set_flctrl(btc, CXFLC_QOSNULL);
switch (policy_type) {
@@ -4461,12 +4567,23 @@ void rtw89_btc_set_policy_v1(struct rtw89_dev *rtwdev, u16 policy_type)
*t = t_def[CXTD_OFF_B2];
_slot_set_le(btc, CXST_OFF, s_def[CXST_OFF].dur,
s_def[CXST_OFF].cxtbl, s_def[CXST_OFF].cxtype);
+ _slot_set(btc, CXST_B2, 10, cxtbl[1], SLOT_ISO);
switch (policy_type) {
case BTC_CXP_OFFB_BWB0:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[5]);
+ break;
+ case BTC_CXP_OFFB_BWB1:
_slot_set_tbl(btc, CXST_OFF, cxtbl[8]);
break;
- default:
+ case BTC_CXP_OFFB_BWB2:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[7]);
+ break;
+ case BTC_CXP_OFFB_BWB3:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[6]);
+ break;
+ case BTC_CXP_OFFB_BWB4:
+ _slot_set_tbl(btc, CXST_OFF, cxtbl[2]);
break;
}
break;
@@ -4841,35 +4958,17 @@ static void _set_ant_v0(struct rtw89_dev *rtwdev, bool force_exec,
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_wl_role_info *r = &btc->cx.wl.role_info;
struct rtw89_btc_bt_info *bt = &cx->bt0;
struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
- u8 gwl, gwl0, gwl1, gbt, plt_ctrl, i, dbcc_2g_phy, b2g = 0;
- bool dbcc_chg = false, dbcc_en = false;
+ u8 gwl, gwl0, gwl1, gbt, plt_ctrl, i, b2g = 0;
u32 ant_path_type;
ant_path_type = ((phy_map << 8) + type);
- if (btc->ver->fwlrole == 1) {
- dbcc_chg = wl->role_info_v1.dbcc_chg;
- dbcc_en = wl->role_info_v1.dbcc_en;
- dbcc_2g_phy = wl->role_info_v1.dbcc_2g_phy;
- } else if (btc->ver->fwlrole == 2) {
- dbcc_chg = wl->role_info_v2.dbcc_chg;
- dbcc_en = wl->role_info_v2.dbcc_en;
- dbcc_2g_phy = wl->role_info_v2.dbcc_2g_phy;
- } else if (btc->ver->fwlrole == 7) {
- dbcc_chg = wl->role_info_v7.dbcc_chg;
- dbcc_en = wl->role_info_v7.dbcc_en;
- dbcc_2g_phy = wl->role_info_v7.dbcc_2g_phy;
- } else if (btc->ver->fwlrole == 8) {
- dbcc_chg = wl->role_info_v8.dbcc_chg;
- dbcc_en = wl->role_info_v8.dbcc_en;
- dbcc_2g_phy = wl->role_info_v8.dbcc_2g_phy;
- }
-
if (btc->dm.run_reason == BTC_RSN_NTFY_POWEROFF ||
btc->dm.run_reason == BTC_RSN_NTFY_RADIO_STATE ||
- btc->dm.run_reason == BTC_RSN_CMD_SET_COEX || dbcc_chg)
+ btc->dm.run_reason == BTC_RSN_CMD_SET_COEX || r->dbcc_chg)
force_exec = FC_EXEC;
if (!force_exec && ant_path_type == dm->set_ant_path) {
@@ -4967,12 +5066,12 @@ static void _set_ant_v0(struct rtw89_dev *rtwdev, bool force_exec,
default:
gbt = BTC_GNT_HW;
if ((rtwdev->chip->para_ver & BTC_FEAT_MULTI_PTA) ||
- !dbcc_en) {
+ !r->dbcc_en) {
gwl = BTC_GNT_HW;
_set_gnt(rtwdev, BTC_PHY_ALL, gwl, gbt);
} else {
/* for DBCC Only-1-PTA */
- if (dbcc_2g_phy == RTW89_PHY_0) {
+ if (r->dbcc_2g_phy == RTW89_PHY_0) {
gwl0 = BTC_GNT_HW;
gwl1 = BTC_GNT_SW_HI;
} else {
@@ -4994,7 +5093,7 @@ static void _set_ant_v1(struct rtw89_dev *rtwdev, bool force_exec,
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8;
+ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
u32 ant_path_type = rtw89_get_antpath_type(phy_map, type);
struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
struct rtw89_btc_dm *dm = &btc->dm;
@@ -5005,7 +5104,7 @@ static void _set_ant_v1(struct rtw89_dev *rtwdev, bool force_exec,
btc->dm.run_reason == BTC_RSN_CMD_SET_COEX || wl_rinfo->dbcc_chg)
force_exec = FC_EXEC;
- if (wl_rinfo->link_mode != BTC_WLINK_25G_MCC &&
+ if (wl_rinfo->link_mode != BTC_WLINK_DB_MCC &&
btc->dm.wl_btg_rx == 2)
force_exec = FC_EXEC;
@@ -5111,7 +5210,7 @@ static void _set_ant_v1(struct rtw89_dev *rtwdev, bool force_exec,
static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec,
u8 phy_map, u8 type)
{
- if (rtwdev->chip->chip_id == RTL8922A)
+ if (rtwdev->chip->chip_id >= RTL8922A)
_set_ant_v1(rtwdev, force_exec, phy_map, type);
else
_set_ant_v0(rtwdev, force_exec, phy_map, type);
@@ -5134,29 +5233,24 @@ static void _action_wl_init(struct rtw89_dev *rtwdev)
static void _action_wl_off(struct rtw89_dev *rtwdev, u8 mode)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ struct rtw89_btc_cx *cx = &btc->cx;
+ struct rtw89_btc_wl_info *wl = &cx->wl;
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): !!\n", __func__);
- if (wl->status.map.rf_off || btc->dm.bt_only) {
+ if (wl->status.map.rf_off || btc->dm.bt_only)
_set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_WOFF);
- } else if (wl->status.map.lps == BTC_LPS_RF_ON) {
- if (mode == BTC_WLINK_5G)
- _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_W5G);
- else
- _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_W2G);
- }
+ else if (wl->status.map.lps == BTC_LPS_RF_ON ||
+ cx->bt0.whql_test || cx->bt1.whql_test)
+ _set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_PTA);
- if (mode == BTC_WLINK_5G) {
+ if (dm->out_of_band)
_set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_OFF);
- } else if (wl->status.map.lps == BTC_LPS_RF_ON) {
- if (btc->cx.bt0.link_info.a2dp_desc.active)
- _set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_OFF);
- else
- _set_policy(rtwdev, BTC_CXP_OFF_BWB1, BTC_ACT_WL_OFF);
- } else {
+ else if (cx->bt0.whql_test || cx->bt1.whql_test)
+ _set_policy(rtwdev, BTC_CXP_OFFB_BWB4, BTC_ACT_WL_OFF);
+ else
_set_policy(rtwdev, BTC_CXP_OFF_BT, BTC_ACT_WL_OFF);
- }
}
static void _action_freerun(struct rtw89_dev *rtwdev)
@@ -5563,48 +5657,29 @@ static void _action_wl_rfk(struct rtw89_dev *rtwdev)
static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ struct rtw89_btc_fbtc_outsrc_set_info *o_info = &dm->ost_info;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
- struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
- struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
- struct rtw89_btc_fbtc_outsrc_set_info *o_info = &btc->dm.ost_info;
- struct rtw89_btc_wl_role_info *wl_rinfo_v0 = &wl->role_info;
+ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
const struct rtw89_chip_info *chip = rtwdev->chip;
- const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
- struct rtw89_btc_dm *dm = &btc->dm;
- struct _wl_rinfo_now wl_rinfo;
u32 is_btg = BTC_BTGCTRL_DISABLE;
if (btc->manual_ctrl)
return;
- if (ver->fwlrole == 0)
- wl_rinfo.link_mode = wl_rinfo_v0->link_mode;
- else if (ver->fwlrole == 1)
- wl_rinfo.link_mode = wl_rinfo_v1->link_mode;
- else if (ver->fwlrole == 2)
- wl_rinfo.link_mode = wl_rinfo_v2->link_mode;
- else if (ver->fwlrole == 7)
- wl_rinfo.link_mode = wl_rinfo_v7->link_mode;
- else if (ver->fwlrole == 8)
- wl_rinfo.link_mode = wl_rinfo_v8->link_mode;
- else
- return;
-
/* notify halbb ignore GNT_BT or not for WL BB Rx-AGC control */
if (btc->ant_type == BTC_ANT_SHARED) {
if (!(bt->run_patch_code && bt->enable.now))
is_btg = BTC_BTGCTRL_DISABLE;
- else if (wl_rinfo.link_mode != BTC_WLINK_5G)
+ else if (wl_rinfo->link_mode_v0 != BTC_WLINK_V0_5G)
is_btg = BTC_BTGCTRL_ENABLE;
else
is_btg = BTC_BTGCTRL_DISABLE;
/* bb call ctrl_btg() in WL FW by slot */
- if (!ver->fcxosi &&
- wl_rinfo.link_mode == BTC_WLINK_25G_MCC)
+ if (!btc->ver->fcxosi &&
+ wl_rinfo->link_mode_v0 == BTC_WLINK_V0_25G_MCC)
is_btg = BTC_BTGCTRL_BB_GNT_FWCTRL;
}
@@ -5614,7 +5689,7 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
dm->wl_btg_rx = is_btg;
/* skip setup if btg_ctrl set by wl fw */
- if (!ver->fcxosi && is_btg > BTC_BTGCTRL_ENABLE)
+ if (!btc->ver->fcxosi && is_btg > BTC_BTGCTRL_ENABLE)
return;
/* Below flow is for BTC_FEAT_NEW_BBAPI_FLOW = 1 */
@@ -5633,7 +5708,7 @@ static void _set_btg_ctrl(struct rtw89_dev *rtwdev)
o_info->btg_rx[BTC_RF_S1] = is_btg;
}
- if (ver->fcxosi)
+ if (btc->ver->fcxosi)
return;
chip->ops->ctrl_btg_bt_rx(rtwdev, o_info->btg_rx[BTC_RF_S0],
@@ -5651,40 +5726,20 @@ static void _set_wl_preagc_ctrl(struct rtw89_dev *rtwdev)
struct rtw89_btc_fbtc_outsrc_set_info *o_info = &btc->dm.ost_info;
struct rtw89_btc_bt_link_info *bt_linfo = &btc->cx.bt0.link_info;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_role_info_v2 *rinfo_v2 = &wl->role_info_v2;
- struct rtw89_btc_wl_role_info_v7 *rinfo_v7 = &wl->role_info_v7;
- struct rtw89_btc_wl_role_info_v8 *rinfo_v8 = &wl->role_info_v8;
+ struct rtw89_btc_wl_role_info *rinfo = &wl->role_info;
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_dm *dm = &btc->dm;
- u8 is_preagc, val, link_mode, dbcc_2g_phy;
- u8 role_ver = rtwdev->btc.ver->fwlrole;
- bool dbcc_en;
+ u8 is_preagc, val;
if (btc->manual_ctrl)
return;
- if (role_ver == 2) {
- dbcc_en = rinfo_v2->dbcc_en;
- link_mode = rinfo_v2->link_mode;
- dbcc_2g_phy = rinfo_v2->dbcc_2g_phy;
- } else if (role_ver == 7) {
- dbcc_en = rinfo_v7->dbcc_en;
- link_mode = rinfo_v7->link_mode;
- dbcc_2g_phy = rinfo_v7->dbcc_2g_phy;
- } else if (role_ver == 8) {
- dbcc_en = rinfo_v8->dbcc_en;
- link_mode = rinfo_v8->link_mode;
- dbcc_2g_phy = rinfo_v7->dbcc_2g_phy;
- } else {
- return;
- }
-
if (!(bt->run_patch_code && bt->enable.now)) {
is_preagc = BTC_PREAGC_DISABLE;
- } else if (link_mode == BTC_WLINK_5G) {
+ } else if (dm->tdd_bind.rf_band == BIT(RTW89_BAND_5G)) {
is_preagc = BTC_PREAGC_DISABLE;
- } else if (link_mode == BTC_WLINK_NOLINK ||
+ } else if (rinfo->link_mode == BTC_WLINK_NOLINK ||
btc->cx.bt0.link_info.link_cnt.now == 0) {
is_preagc = BTC_PREAGC_DISABLE;
} else if (dm->tdma_now.type != CXTDMA_OFF &&
@@ -5692,7 +5747,7 @@ static void _set_wl_preagc_ctrl(struct rtw89_dev *rtwdev)
!bt_linfo->hid_desc.exist &&
dm->fddt_train == BTC_FDDT_DISABLE) {
is_preagc = BTC_PREAGC_DISABLE;
- } else if (dbcc_en && (dbcc_2g_phy != RTW89_PHY_1)) {
+ } else if (rinfo->dbcc_en && (rinfo->dbcc_2g_phy != RTW89_PHY_1)) {
is_preagc = BTC_PREAGC_DISABLE;
} else if (btc->ant_type == BTC_ANT_SHARED) {
is_preagc = BTC_PREAGC_DISABLE;
@@ -5700,7 +5755,7 @@ static void _set_wl_preagc_ctrl(struct rtw89_dev *rtwdev)
is_preagc = BTC_PREAGC_ENABLE;
}
- if (!btc->ver->fcxosi && link_mode == BTC_WLINK_25G_MCC)
+ if (!btc->ver->fcxosi && rinfo->link_mode == BTC_WLINK_DB_MCC)
is_preagc = BTC_PREAGC_BB_FWCTRL;
if (dm->wl_pre_agc_rb != dm->wl_pre_agc &&
@@ -5771,10 +5826,7 @@ static void __rtw89_tx_time_iter(struct rtw89_vif_link *rtwvif_link,
u16 enable = iter_data->enable;
bool reenable = iter_data->reenable;
- if (btc->ver->fwlrole == 8)
- plink = &wl->rlink_info[port][0];
- else
- plink = &wl->link_info[port];
+ plink = &wl->rlink_info[port][rtwsta_link->link_id];
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): port = %d\n", __func__, port);
@@ -5840,39 +5892,23 @@ static void _set_wl_tx_limit(struct rtw89_dev *rtwdev)
struct rtw89_btc_bt_hfp_desc *hfp = &b->hfp_desc;
struct rtw89_btc_bt_hid_desc *hid = &b->hid_desc;
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
- struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
- struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
- struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
struct rtw89_txtime_data data = {.rtwdev = rtwdev};
- u8 mode, igno_bt, tx_retry;
+ bool reenable = false;
+ u8 igno_bt, tx_retry;
u32 tx_time;
u16 enable;
- bool reenable = false;
if (btc->manual_ctrl)
return;
- if (ver->fwlrole == 0)
- mode = wl_rinfo->link_mode;
- else if (ver->fwlrole == 1)
- mode = wl_rinfo_v1->link_mode;
- else if (ver->fwlrole == 2)
- mode = wl_rinfo_v2->link_mode;
- else if (ver->fwlrole == 7)
- mode = wl_rinfo_v7->link_mode;
- else if (ver->fwlrole == 8)
- mode = wl_rinfo_v8->link_mode;
- else
- return;
-
if (ver->fcxctrl == 7)
igno_bt = btc->ctrl.ctrl_v7.igno_bt;
else
igno_bt = btc->ctrl.ctrl.igno_bt;
if (btc->dm.freerun || igno_bt || b->link_cnt.now == 0 ||
- mode == BTC_WLINK_5G || mode == BTC_WLINK_NOLINK) {
+ dm->tdd_bind.rf_band == BIT(RTW89_BAND_5G) ||
+ wl_rinfo->link_mode == BTC_WLINK_NOLINK) {
enable = 0;
tx_time = BTC_MAX_TX_TIME_DEF;
tx_retry = BTC_MAX_TX_RETRY_DEF;
@@ -5915,31 +5951,12 @@ static void _set_wl_tx_limit(struct rtw89_dev *rtwdev)
static void _set_bt_rx_agc(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
- const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
- struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
- struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
- struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
bool bt_hi_lna_rx = false;
- u8 mode;
- if (ver->fwlrole == 0)
- mode = wl_rinfo->link_mode;
- else if (ver->fwlrole == 1)
- mode = wl_rinfo_v1->link_mode;
- else if (ver->fwlrole == 2)
- mode = wl_rinfo_v2->link_mode;
- else if (ver->fwlrole == 7)
- mode = wl_rinfo_v7->link_mode;
- else if (ver->fwlrole == 8)
- mode = wl_rinfo_v8->link_mode;
- else
- return;
-
- if (mode != BTC_WLINK_NOLINK && btc->dm.wl_btg_rx)
+ if (wl_rinfo->link_mode != BTC_WLINK_NOLINK && btc->dm.wl_btg_rx)
bt_hi_lna_rx = true;
if (bt_hi_lna_rx == bt->hi_lna_rx)
@@ -5985,20 +6002,51 @@ static void _wl_req_mac(struct rtw89_dev *rtwdev, u8 mac)
rtw89_write32_set(rtwdev, add, B_AX_WL_SRC);
}
-static void _action_common(struct rtw89_dev *rtwdev)
+static void _update_zb_coex_tbl(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_role_info_v8 *rinfo_v8 = &wl->role_info_v8;
- struct rtw89_btc_wl_smap *wl_smap = &wl->status.map;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
- struct rtw89_btc_dm *dm = &btc->dm;
- u32 bt_rom_code_id, bt_fw_ver;
- u8 i;
-
- if (btc->ver->fwlrole == 8)
- _wl_req_mac(rtwdev, rinfo_v8->pta_req_band);
+ const struct rtw89_btc_ver *ver = btc->ver;
+ u32 zb_tbl0 = 0xda5a5a5a, zb_tbl1 = 0xda5a5a5a;
+ u8 link_mode_chg = btc->cx.wl.link_mode_chg;
+ u8 mode = btc->cx.wl.role_info.link_mode;
+ u8 wa_type;
+
+ if (btc->dm.run_reason != BTC_RSN_NTFY_INIT && !link_mode_chg)
+ return;
+
+ if (ver->fcxinit == 7)
+ wa_type = btc->mdinfo.md_v7.wa_type;
+ else
+ wa_type = btc->mdinfo.md.wa_type;
+ if (!(wa_type & BTC_WA_HFP_ZB))
+ return;
+
+ if (btc->dm.tdd_bind.rf_band == BIT(RTW89_BAND_5G) ||
+ rtwdev->btc.dm.freerun) {
+ zb_tbl0 = 0xffffffff;
+ zb_tbl1 = 0xffffffff;
+ } else if (mode == BTC_WLINK_DB_MCC) {
+ zb_tbl0 = 0xffffffff; /* for E5G slot */
+ zb_tbl1 = 0xda5a5a5a; /* for E2G slot */
+ }
+ rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_0, zb_tbl0);
+ rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_1, zb_tbl1);
+}
+
+static void _action_common(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_wl_role_info *rinfo = &wl->role_info;
+ struct rtw89_btc_wl_smap *wl_smap = &wl->status.map;
+ struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ u32 bt_rom_code_id, bt_fw_ver;
+ u8 i;
+
+ _wl_req_mac(rtwdev, rinfo->pta_req_band);
+ _update_zb_coex_tbl(rtwdev);
_set_btg_ctrl(rtwdev);
_set_wl_preagc_ctrl(rtwdev);
_set_wl_tx_limit(rtwdev);
@@ -6041,7 +6089,10 @@ static void _action_common(struct rtw89_dev *rtwdev)
}
dm->tdma_instant_excute = 0;
dm->lps_ctrl_change = false;
+ wl->role_info.link_mode_chg = 0;
wl->pta_reg_mac_chg = false;
+ dm->pre_agc_chg = false;
+ wl->dbcc_chg = 0;
}
static void _action_by_bt(struct rtw89_dev *rtwdev)
@@ -6407,473 +6458,29 @@ void _update_dbcc_band(struct rtw89_dev *rtwdev, enum rtw89_phy_idx phy_idx)
btc->cx.wl.dbcc_info.op_band[phy_idx];
}
-static void _update_wl_info(struct rtw89_dev *rtwdev)
-{
- struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info;
- struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
- struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
- u8 i, cnt_connect = 0, cnt_connecting = 0, cnt_active = 0;
- u8 cnt_2g = 0, cnt_5g = 0, phy;
- u32 wl_2g_ch[2] = {0}, wl_5g_ch[2] = {0};
- bool b2g = false, b5g = false, client_joined = false;
-
- memset(wl_rinfo, 0, sizeof(*wl_rinfo));
-
- for (i = 0; i < RTW89_PORT_NUM; i++) {
- /* check if role active? */
- if (!wl_linfo[i].active)
- continue;
-
- cnt_active++;
- wl_rinfo->active_role[cnt_active - 1].role = wl_linfo[i].role;
- wl_rinfo->active_role[cnt_active - 1].pid = wl_linfo[i].pid;
- wl_rinfo->active_role[cnt_active - 1].phy = wl_linfo[i].phy;
- wl_rinfo->active_role[cnt_active - 1].band = wl_linfo[i].band;
- wl_rinfo->active_role[cnt_active - 1].noa = (u8)wl_linfo[i].noa;
- wl_rinfo->active_role[cnt_active - 1].connected = 0;
-
- wl->port_id[wl_linfo[i].role] = wl_linfo[i].pid;
-
- phy = wl_linfo[i].phy;
-
- /* check dbcc role */
- if (rtwdev->dbcc_en && phy < RTW89_PHY_NUM) {
- wl_dinfo->role[phy] = wl_linfo[i].role;
- wl_dinfo->op_band[phy] = wl_linfo[i].band;
- _update_dbcc_band(rtwdev, phy);
- _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC);
- }
-
- if (wl_linfo[i].connected == MLME_NO_LINK) {
- continue;
- } else if (wl_linfo[i].connected == MLME_LINKING) {
- cnt_connecting++;
- } else {
- cnt_connect++;
- if ((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO ||
- wl_linfo[i].role == RTW89_WIFI_ROLE_AP) &&
- wl_linfo[i].client_cnt > 1)
- client_joined = true;
- }
-
- wl_rinfo->role_map.val |= BIT(wl_linfo[i].role);
- wl_rinfo->active_role[cnt_active - 1].ch = wl_linfo[i].ch;
- wl_rinfo->active_role[cnt_active - 1].bw = wl_linfo[i].bw;
- wl_rinfo->active_role[cnt_active - 1].connected = 1;
-
- /* only care 2 roles + BT coex */
- if (wl_linfo[i].band != RTW89_BAND_2G) {
- if (cnt_5g <= ARRAY_SIZE(wl_5g_ch) - 1)
- wl_5g_ch[cnt_5g] = wl_linfo[i].ch;
- cnt_5g++;
- b5g = true;
- } else {
- if (cnt_2g <= ARRAY_SIZE(wl_2g_ch) - 1)
- wl_2g_ch[cnt_2g] = wl_linfo[i].ch;
- cnt_2g++;
- b2g = true;
- }
- }
-
- wl_rinfo->connect_cnt = cnt_connect;
-
- /* Be careful to change the following sequence!! */
- if (cnt_connect == 0) {
- wl_rinfo->link_mode = BTC_WLINK_NOLINK;
- wl_rinfo->role_map.role.none = 1;
- } else if (!b2g && b5g) {
- wl_rinfo->link_mode = BTC_WLINK_5G;
- } else if (wl_rinfo->role_map.role.nan) {
- wl_rinfo->link_mode = BTC_WLINK_2G_NAN;
- } else if (cnt_connect > BTC_TDMA_WLROLE_MAX) {
- wl_rinfo->link_mode = BTC_WLINK_OTHER;
- } else if (b2g && b5g && cnt_connect == 2) {
- if (rtwdev->dbcc_en) {
- switch (wl_dinfo->role[RTW89_PHY_0]) {
- case RTW89_WIFI_ROLE_STATION:
- wl_rinfo->link_mode = BTC_WLINK_2G_STA;
- break;
- case RTW89_WIFI_ROLE_P2P_GO:
- wl_rinfo->link_mode = BTC_WLINK_2G_GO;
- break;
- case RTW89_WIFI_ROLE_P2P_CLIENT:
- wl_rinfo->link_mode = BTC_WLINK_2G_GC;
- break;
- case RTW89_WIFI_ROLE_AP:
- wl_rinfo->link_mode = BTC_WLINK_2G_AP;
- break;
- default:
- wl_rinfo->link_mode = BTC_WLINK_OTHER;
- break;
- }
- } else {
- wl_rinfo->link_mode = BTC_WLINK_25G_MCC;
- }
- } else if (!b5g && cnt_connect == 2) {
- if (wl_rinfo->role_map.role.station &&
- (wl_rinfo->role_map.role.p2p_go ||
- wl_rinfo->role_map.role.p2p_gc ||
- wl_rinfo->role_map.role.ap)) {
- if (wl_2g_ch[0] == wl_2g_ch[1])
- wl_rinfo->link_mode = BTC_WLINK_2G_SCC;
- else
- wl_rinfo->link_mode = BTC_WLINK_2G_MCC;
- } else {
- wl_rinfo->link_mode = BTC_WLINK_2G_MCC;
- }
- } else if (!b5g && cnt_connect == 1) {
- if (wl_rinfo->role_map.role.station)
- wl_rinfo->link_mode = BTC_WLINK_2G_STA;
- else if (wl_rinfo->role_map.role.ap)
- wl_rinfo->link_mode = BTC_WLINK_2G_AP;
- else if (wl_rinfo->role_map.role.p2p_go)
- wl_rinfo->link_mode = BTC_WLINK_2G_GO;
- else if (wl_rinfo->role_map.role.p2p_gc)
- wl_rinfo->link_mode = BTC_WLINK_2G_GC;
- else
- wl_rinfo->link_mode = BTC_WLINK_OTHER;
- }
-
- /* if no client_joined, don't care P2P-GO/AP role */
- if (wl_rinfo->role_map.role.p2p_go || wl_rinfo->role_map.role.ap) {
- if (!client_joined) {
- if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC ||
- wl_rinfo->link_mode == BTC_WLINK_2G_MCC) {
- wl_rinfo->link_mode = BTC_WLINK_2G_STA;
- wl_rinfo->connect_cnt = 1;
- } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO ||
- wl_rinfo->link_mode == BTC_WLINK_2G_AP) {
- wl_rinfo->link_mode = BTC_WLINK_NOLINK;
- wl_rinfo->connect_cnt = 0;
- }
- }
- }
-
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], cnt_connect = %d, connecting = %d, link_mode = %d\n",
- cnt_connect, cnt_connecting, wl_rinfo->link_mode);
-
- _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
-}
-
-static void _update_wl_info_v1(struct rtw89_dev *rtwdev)
-{
- struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info;
- struct rtw89_btc_wl_role_info_v1 *wl_rinfo = &wl->role_info_v1;
- struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
- u8 cnt_connect = 0, cnt_connecting = 0, cnt_active = 0;
- u8 cnt_2g = 0, cnt_5g = 0, phy;
- u32 wl_2g_ch[2] = {}, wl_5g_ch[2] = {};
- bool b2g = false, b5g = false, client_joined = false;
- u8 i;
-
- memset(wl_rinfo, 0, sizeof(*wl_rinfo));
-
- for (i = 0; i < RTW89_PORT_NUM; i++) {
- if (!wl_linfo[i].active)
- continue;
-
- cnt_active++;
- wl_rinfo->active_role_v1[cnt_active - 1].role = wl_linfo[i].role;
- wl_rinfo->active_role_v1[cnt_active - 1].pid = wl_linfo[i].pid;
- wl_rinfo->active_role_v1[cnt_active - 1].phy = wl_linfo[i].phy;
- wl_rinfo->active_role_v1[cnt_active - 1].band = wl_linfo[i].band;
- wl_rinfo->active_role_v1[cnt_active - 1].noa = (u8)wl_linfo[i].noa;
- wl_rinfo->active_role_v1[cnt_active - 1].connected = 0;
-
- wl->port_id[wl_linfo[i].role] = wl_linfo[i].pid;
-
- phy = wl_linfo[i].phy;
-
- if (rtwdev->dbcc_en && phy < RTW89_PHY_NUM) {
- wl_dinfo->role[phy] = wl_linfo[i].role;
- wl_dinfo->op_band[phy] = wl_linfo[i].band;
- _update_dbcc_band(rtwdev, phy);
- _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC);
- }
-
- if (wl_linfo[i].connected == MLME_NO_LINK) {
- continue;
- } else if (wl_linfo[i].connected == MLME_LINKING) {
- cnt_connecting++;
- } else {
- cnt_connect++;
- if ((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO ||
- wl_linfo[i].role == RTW89_WIFI_ROLE_AP) &&
- wl_linfo[i].client_cnt > 1)
- client_joined = true;
- }
-
- wl_rinfo->role_map.val |= BIT(wl_linfo[i].role);
- wl_rinfo->active_role_v1[cnt_active - 1].ch = wl_linfo[i].ch;
- wl_rinfo->active_role_v1[cnt_active - 1].bw = wl_linfo[i].bw;
- wl_rinfo->active_role_v1[cnt_active - 1].connected = 1;
-
- /* only care 2 roles + BT coex */
- if (wl_linfo[i].band != RTW89_BAND_2G) {
- if (cnt_5g <= ARRAY_SIZE(wl_5g_ch) - 1)
- wl_5g_ch[cnt_5g] = wl_linfo[i].ch;
- cnt_5g++;
- b5g = true;
- } else {
- if (cnt_2g <= ARRAY_SIZE(wl_2g_ch) - 1)
- wl_2g_ch[cnt_2g] = wl_linfo[i].ch;
- cnt_2g++;
- b2g = true;
- }
- }
-
- wl_rinfo->connect_cnt = cnt_connect;
-
- /* Be careful to change the following sequence!! */
- if (cnt_connect == 0) {
- wl_rinfo->link_mode = BTC_WLINK_NOLINK;
- wl_rinfo->role_map.role.none = 1;
- } else if (!b2g && b5g) {
- wl_rinfo->link_mode = BTC_WLINK_5G;
- } else if (wl_rinfo->role_map.role.nan) {
- wl_rinfo->link_mode = BTC_WLINK_2G_NAN;
- } else if (cnt_connect > BTC_TDMA_WLROLE_MAX) {
- wl_rinfo->link_mode = BTC_WLINK_OTHER;
- } else if (b2g && b5g && cnt_connect == 2) {
- if (rtwdev->dbcc_en) {
- switch (wl_dinfo->role[RTW89_PHY_0]) {
- case RTW89_WIFI_ROLE_STATION:
- wl_rinfo->link_mode = BTC_WLINK_2G_STA;
- break;
- case RTW89_WIFI_ROLE_P2P_GO:
- wl_rinfo->link_mode = BTC_WLINK_2G_GO;
- break;
- case RTW89_WIFI_ROLE_P2P_CLIENT:
- wl_rinfo->link_mode = BTC_WLINK_2G_GC;
- break;
- case RTW89_WIFI_ROLE_AP:
- wl_rinfo->link_mode = BTC_WLINK_2G_AP;
- break;
- default:
- wl_rinfo->link_mode = BTC_WLINK_OTHER;
- break;
- }
- } else {
- wl_rinfo->link_mode = BTC_WLINK_25G_MCC;
- }
- } else if (!b5g && cnt_connect == 2) {
- if (wl_rinfo->role_map.role.station &&
- (wl_rinfo->role_map.role.p2p_go ||
- wl_rinfo->role_map.role.p2p_gc ||
- wl_rinfo->role_map.role.ap)) {
- if (wl_2g_ch[0] == wl_2g_ch[1])
- wl_rinfo->link_mode = BTC_WLINK_2G_SCC;
- else
- wl_rinfo->link_mode = BTC_WLINK_2G_MCC;
- } else {
- wl_rinfo->link_mode = BTC_WLINK_2G_MCC;
- }
- } else if (!b5g && cnt_connect == 1) {
- if (wl_rinfo->role_map.role.station)
- wl_rinfo->link_mode = BTC_WLINK_2G_STA;
- else if (wl_rinfo->role_map.role.ap)
- wl_rinfo->link_mode = BTC_WLINK_2G_AP;
- else if (wl_rinfo->role_map.role.p2p_go)
- wl_rinfo->link_mode = BTC_WLINK_2G_GO;
- else if (wl_rinfo->role_map.role.p2p_gc)
- wl_rinfo->link_mode = BTC_WLINK_2G_GC;
- else
- wl_rinfo->link_mode = BTC_WLINK_OTHER;
- }
-
- /* if no client_joined, don't care P2P-GO/AP role */
- if (wl_rinfo->role_map.role.p2p_go || wl_rinfo->role_map.role.ap) {
- if (!client_joined) {
- if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC ||
- wl_rinfo->link_mode == BTC_WLINK_2G_MCC) {
- wl_rinfo->link_mode = BTC_WLINK_2G_STA;
- wl_rinfo->connect_cnt = 1;
- } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO ||
- wl_rinfo->link_mode == BTC_WLINK_2G_AP) {
- wl_rinfo->link_mode = BTC_WLINK_NOLINK;
- wl_rinfo->connect_cnt = 0;
- }
- }
- }
-
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], cnt_connect = %d, connecting = %d, link_mode = %d\n",
- cnt_connect, cnt_connecting, wl_rinfo->link_mode);
-
- _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
-}
-
-static void _update_wl_info_v2(struct rtw89_dev *rtwdev)
-{
- struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info;
- struct rtw89_btc_wl_role_info_v2 *wl_rinfo = &wl->role_info_v2;
- struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
- u8 cnt_connect = 0, cnt_connecting = 0, cnt_active = 0;
- u8 cnt_2g = 0, cnt_5g = 0, phy;
- u32 wl_2g_ch[2] = {}, wl_5g_ch[2] = {};
- bool b2g = false, b5g = false, client_joined = false;
- u8 i;
-
- memset(wl_rinfo, 0, sizeof(*wl_rinfo));
-
- for (i = 0; i < RTW89_PORT_NUM; i++) {
- if (!wl_linfo[i].active)
- continue;
-
- cnt_active++;
- wl_rinfo->active_role_v2[cnt_active - 1].role = wl_linfo[i].role;
- wl_rinfo->active_role_v2[cnt_active - 1].pid = wl_linfo[i].pid;
- wl_rinfo->active_role_v2[cnt_active - 1].phy = wl_linfo[i].phy;
- wl_rinfo->active_role_v2[cnt_active - 1].band = wl_linfo[i].band;
- wl_rinfo->active_role_v2[cnt_active - 1].noa = (u8)wl_linfo[i].noa;
- wl_rinfo->active_role_v2[cnt_active - 1].connected = 0;
-
- wl->port_id[wl_linfo[i].role] = wl_linfo[i].pid;
-
- phy = wl_linfo[i].phy;
-
- if (rtwdev->dbcc_en && phy < RTW89_PHY_NUM) {
- wl_dinfo->role[phy] = wl_linfo[i].role;
- wl_dinfo->op_band[phy] = wl_linfo[i].band;
- _update_dbcc_band(rtwdev, phy);
- _fw_set_drv_info(rtwdev, CXDRVINFO_DBCC);
- }
-
- if (wl_linfo[i].connected == MLME_NO_LINK) {
- continue;
- } else if (wl_linfo[i].connected == MLME_LINKING) {
- cnt_connecting++;
- } else {
- cnt_connect++;
- if ((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO ||
- wl_linfo[i].role == RTW89_WIFI_ROLE_AP) &&
- wl_linfo[i].client_cnt > 1)
- client_joined = true;
- }
-
- wl_rinfo->role_map.val |= BIT(wl_linfo[i].role);
- wl_rinfo->active_role_v2[cnt_active - 1].ch = wl_linfo[i].ch;
- wl_rinfo->active_role_v2[cnt_active - 1].bw = wl_linfo[i].bw;
- wl_rinfo->active_role_v2[cnt_active - 1].connected = 1;
-
- /* only care 2 roles + BT coex */
- if (wl_linfo[i].band != RTW89_BAND_2G) {
- if (cnt_5g <= ARRAY_SIZE(wl_5g_ch) - 1)
- wl_5g_ch[cnt_5g] = wl_linfo[i].ch;
- cnt_5g++;
- b5g = true;
- } else {
- if (cnt_2g <= ARRAY_SIZE(wl_2g_ch) - 1)
- wl_2g_ch[cnt_2g] = wl_linfo[i].ch;
- cnt_2g++;
- b2g = true;
- }
- }
-
- wl_rinfo->connect_cnt = cnt_connect;
-
- /* Be careful to change the following sequence!! */
- if (cnt_connect == 0) {
- wl_rinfo->link_mode = BTC_WLINK_NOLINK;
- wl_rinfo->role_map.role.none = 1;
- } else if (!b2g && b5g) {
- wl_rinfo->link_mode = BTC_WLINK_5G;
- } else if (wl_rinfo->role_map.role.nan) {
- wl_rinfo->link_mode = BTC_WLINK_2G_NAN;
- } else if (cnt_connect > BTC_TDMA_WLROLE_MAX) {
- wl_rinfo->link_mode = BTC_WLINK_OTHER;
- } else if (b2g && b5g && cnt_connect == 2) {
- if (rtwdev->dbcc_en) {
- switch (wl_dinfo->role[RTW89_PHY_0]) {
- case RTW89_WIFI_ROLE_STATION:
- wl_rinfo->link_mode = BTC_WLINK_2G_STA;
- break;
- case RTW89_WIFI_ROLE_P2P_GO:
- wl_rinfo->link_mode = BTC_WLINK_2G_GO;
- break;
- case RTW89_WIFI_ROLE_P2P_CLIENT:
- wl_rinfo->link_mode = BTC_WLINK_2G_GC;
- break;
- case RTW89_WIFI_ROLE_AP:
- wl_rinfo->link_mode = BTC_WLINK_2G_AP;
- break;
- default:
- wl_rinfo->link_mode = BTC_WLINK_OTHER;
- break;
- }
- } else {
- wl_rinfo->link_mode = BTC_WLINK_25G_MCC;
- }
- } else if (!b5g && cnt_connect == 2) {
- if (wl_rinfo->role_map.role.station &&
- (wl_rinfo->role_map.role.p2p_go ||
- wl_rinfo->role_map.role.p2p_gc ||
- wl_rinfo->role_map.role.ap)) {
- if (wl_2g_ch[0] == wl_2g_ch[1])
- wl_rinfo->link_mode = BTC_WLINK_2G_SCC;
- else
- wl_rinfo->link_mode = BTC_WLINK_2G_MCC;
- } else {
- wl_rinfo->link_mode = BTC_WLINK_2G_MCC;
- }
- } else if (!b5g && cnt_connect == 1) {
- if (wl_rinfo->role_map.role.station)
- wl_rinfo->link_mode = BTC_WLINK_2G_STA;
- else if (wl_rinfo->role_map.role.ap)
- wl_rinfo->link_mode = BTC_WLINK_2G_AP;
- else if (wl_rinfo->role_map.role.p2p_go)
- wl_rinfo->link_mode = BTC_WLINK_2G_GO;
- else if (wl_rinfo->role_map.role.p2p_gc)
- wl_rinfo->link_mode = BTC_WLINK_2G_GC;
- else
- wl_rinfo->link_mode = BTC_WLINK_OTHER;
- }
-
- /* if no client_joined, don't care P2P-GO/AP role */
- if (wl_rinfo->role_map.role.p2p_go || wl_rinfo->role_map.role.ap) {
- if (!client_joined) {
- if (wl_rinfo->link_mode == BTC_WLINK_2G_SCC ||
- wl_rinfo->link_mode == BTC_WLINK_2G_MCC) {
- wl_rinfo->link_mode = BTC_WLINK_2G_STA;
- wl_rinfo->connect_cnt = 1;
- } else if (wl_rinfo->link_mode == BTC_WLINK_2G_GO ||
- wl_rinfo->link_mode == BTC_WLINK_2G_AP) {
- wl_rinfo->link_mode = BTC_WLINK_NOLINK;
- wl_rinfo->connect_cnt = 0;
- }
- }
- }
-
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], cnt_connect = %d, connecting = %d, link_mode = %d\n",
- cnt_connect, cnt_connecting, wl_rinfo->link_mode);
-
- _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
-}
-
#define BTC_CHK_HANG_MAX 3
#define BTC_SCB_INV_VALUE GENMASK(31, 0)
-static u8 _get_role_link_mode(u8 role)
+static u8 _get_role_link_mode(struct rtw89_btc_wl_role_info *r, u8 role, bool notv10)
{
switch (role) {
case RTW89_WIFI_ROLE_STATION:
- return BTC_WLINK_2G_STA;
+ default:
+ if (notv10)
+ r->link_mode_v0 = BTC_WLINK_V0_2G_STA;
+ return BTC_WLINK_STA;
case RTW89_WIFI_ROLE_P2P_GO:
- return BTC_WLINK_2G_GO;
+ if (notv10)
+ r->link_mode_v0 = BTC_WLINK_V0_2G_GO;
+ return BTC_WLINK_GO;
case RTW89_WIFI_ROLE_P2P_CLIENT:
- return BTC_WLINK_2G_GC;
+ if (notv10)
+ r->link_mode_v0 = BTC_WLINK_V0_2G_GC;
+ return BTC_WLINK_GC;
case RTW89_WIFI_ROLE_AP:
- return BTC_WLINK_2G_AP;
- default:
- return BTC_WLINK_OTHER;
+ if (notv10)
+ r->link_mode_v0 = BTC_WLINK_V0_2G_AP;
+ return BTC_WLINK_AP;
}
}
@@ -6891,13 +6498,13 @@ static bool _chk_role_ch_group(const struct rtw89_btc_chdef *r1,
}
static u8 _chk_dbcc(struct rtw89_dev *rtwdev, struct rtw89_btc_chdef *ch,
- u8 *phy, u8 *role, u8 link_cnt)
+ u8 *phy, u8 *role, u8 link_cnt, bool notv10)
{
struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl;
- struct rtw89_btc_wl_role_info_v7 *rinfo_v7 = &wl->role_info_v7;
- struct rtw89_btc_wl_role_info_v8 *rinfo_v8 = &wl->role_info_v8;
+ struct rtw89_btc_wl_role_info *rinfo = &wl->role_info;
bool is_2g_ch_exist = false, is_multi_role_in_2g_phy = false;
- u8 j, k, dbcc_2g_cid, dbcc_2g_cid2, dbcc_2g_phy, pta_req_band;
+ u8 j, k, dbcc_2g_cid = 0, dbcc_2g_cid2 = 0;
+ u8 mode;
/* find out the 2G-PHY by connect-id ->ch */
for (j = 0; j < link_cnt; j++) {
@@ -6908,34 +6515,31 @@ static u8 _chk_dbcc(struct rtw89_dev *rtwdev, struct rtw89_btc_chdef *ch,
}
/* If no any 2G-port exist, it's impossible because 5G-exclude */
- if (!is_2g_ch_exist)
- return BTC_WLINK_5G;
+ if (!is_2g_ch_exist) {
+ mode = BTC_WLINK_SB_MCC;
+ if (notv10)
+ rinfo->link_mode_v0 = BTC_WLINK_V0_5G;
+ return mode;
+ }
dbcc_2g_cid = j;
- dbcc_2g_phy = phy[dbcc_2g_cid];
+ rinfo->dbcc_2g_phy = phy[dbcc_2g_cid];
- if (dbcc_2g_phy == RTW89_PHY_1)
- pta_req_band = RTW89_PHY_1;
+ if (rinfo->dbcc_2g_phy == RTW89_PHY_1)
+ rinfo->pta_req_band = RTW89_PHY_1;
else
- pta_req_band = RTW89_PHY_0;
-
- if (rtwdev->btc.ver->fwlrole == 7) {
- rinfo_v7->dbcc_2g_phy = dbcc_2g_phy;
- } else if (rtwdev->btc.ver->fwlrole == 8) {
- rinfo_v8->dbcc_2g_phy = dbcc_2g_phy;
- rinfo_v8->pta_req_band = pta_req_band;
- }
+ rinfo->pta_req_band = RTW89_PHY_0;
/* connect_cnt <= 2 */
if (link_cnt < BTC_TDMA_WLROLE_MAX)
- return (_get_role_link_mode((role[dbcc_2g_cid])));
+ return _get_role_link_mode(rinfo, role[dbcc_2g_cid], notv10);
/* find the other-port in the 2G-PHY, ex: PHY-0:6G, PHY1: mcc/scc */
for (k = 0; k < link_cnt; k++) {
if (k == dbcc_2g_cid)
continue;
- if (phy[k] == dbcc_2g_phy) {
+ if (phy[k] == rinfo->dbcc_2g_phy) {
is_multi_role_in_2g_phy = true;
dbcc_2g_cid2 = k;
break;
@@ -6944,319 +6548,151 @@ static u8 _chk_dbcc(struct rtw89_dev *rtwdev, struct rtw89_btc_chdef *ch,
/* Single-role in 2G-PHY */
if (!is_multi_role_in_2g_phy)
- return (_get_role_link_mode(role[dbcc_2g_cid]));
+ return _get_role_link_mode(rinfo, role[dbcc_2g_cid], notv10);
/* 2-role in 2G-PHY */
- if (ch[dbcc_2g_cid2].center_ch > 14)
- return BTC_WLINK_25G_MCC;
- else if (_chk_role_ch_group(&ch[dbcc_2g_cid], &ch[dbcc_2g_cid2]))
- return BTC_WLINK_2G_SCC;
- else
- return BTC_WLINK_2G_MCC;
-}
-
-static void _update_role_link_mode(struct rtw89_dev *rtwdev,
- bool client_joined, u32 noa)
-{
- struct rtw89_btc_wl_role_info_v8 *rinfo_v8 = &rtwdev->btc.cx.wl.role_info_v8;
- struct rtw89_btc_wl_role_info_v7 *rinfo_v7 = &rtwdev->btc.cx.wl.role_info_v7;
- u8 role_ver = rtwdev->btc.ver->fwlrole;
- u32 type = BTC_WLMROLE_NONE, dur = 0;
- u8 link_mode, connect_cnt;
- u32 wl_role;
-
- if (role_ver == 7) {
- wl_role = rinfo_v7->role_map;
- link_mode = rinfo_v7->link_mode;
- connect_cnt = rinfo_v7->connect_cnt;
- } else if (role_ver == 8) {
- wl_role = rinfo_v8->role_map;
- link_mode = rinfo_v8->link_mode;
- connect_cnt = rinfo_v8->connect_cnt;
+ if (ch[dbcc_2g_cid2].center_ch > 14) {
+ if (notv10)
+ rinfo->link_mode_v0 = BTC_WLINK_V0_25G_MCC;
+ return BTC_WLINK_DB_MCC;
+ } else if (_chk_role_ch_group(&ch[dbcc_2g_cid], &ch[dbcc_2g_cid2])) {
+ if (notv10)
+ rinfo->link_mode_v0 = BTC_WLINK_V0_2G_SCC;
+ return BTC_WLINK_SCC;
} else {
- return;
- }
-
- /* if no client_joined, don't care P2P-GO/AP role */
- if (((wl_role & BIT(RTW89_WIFI_ROLE_P2P_GO)) ||
- (wl_role & BIT(RTW89_WIFI_ROLE_AP))) && !client_joined) {
- if (link_mode == BTC_WLINK_2G_SCC) {
- if (role_ver == 7) {
- rinfo_v7->link_mode = BTC_WLINK_2G_STA;
- rinfo_v7->connect_cnt--;
- } else if (role_ver == 8) {
- rinfo_v8->link_mode = BTC_WLINK_2G_STA;
- rinfo_v8->connect_cnt--;
- }
- } else if (link_mode == BTC_WLINK_2G_GO ||
- link_mode == BTC_WLINK_2G_AP) {
- if (role_ver == 7) {
- rinfo_v7->link_mode = BTC_WLINK_NOLINK;
- rinfo_v7->connect_cnt--;
- } else if (role_ver == 8) {
- rinfo_v8->link_mode = BTC_WLINK_NOLINK;
- rinfo_v8->connect_cnt--;
- }
- }
- }
-
- /* Identify 2-Role type */
- if (connect_cnt >= 2 &&
- (link_mode == BTC_WLINK_2G_SCC ||
- link_mode == BTC_WLINK_2G_MCC ||
- link_mode == BTC_WLINK_25G_MCC ||
- link_mode == BTC_WLINK_5G)) {
- if ((wl_role & BIT(RTW89_WIFI_ROLE_P2P_GO)) ||
- (wl_role & BIT(RTW89_WIFI_ROLE_AP)))
- type = noa ? BTC_WLMROLE_STA_GO_NOA : BTC_WLMROLE_STA_GO;
- else if (wl_role & BIT(RTW89_WIFI_ROLE_P2P_CLIENT))
- type = noa ? BTC_WLMROLE_STA_GC_NOA : BTC_WLMROLE_STA_GC;
- else
- type = BTC_WLMROLE_STA_STA;
-
- dur = noa;
- }
-
- if (role_ver == 7) {
- rinfo_v7->mrole_type = type;
- rinfo_v7->mrole_noa_duration = dur;
- } else if (role_ver == 8) {
- rinfo_v8->mrole_type = type;
- rinfo_v8->mrole_noa_duration = dur;
+ if (notv10)
+ rinfo->link_mode_v0 = BTC_WLINK_V0_2G_MCC;
+ return BTC_WLINK_SB_MCC;
}
}
-static void _update_wl_info_v7(struct rtw89_dev *rtwdev, u8 rid)
+static void _update_wl_link_mode(struct rtw89_dev *rtwdev, u8 hw_band, u8 type)
{
- struct rtw89_btc_chdef cid_ch[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER];
struct rtw89_btc *btc = &rtwdev->btc;
+ const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_role_info_v7 *wl_rinfo = &wl->role_info_v7;
- struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
- struct rtw89_btc_wl_link_info *wl_linfo = wl->link_info;
- struct rtw89_btc_wl_active_role_v7 *act_role = NULL;
- u8 i, mode, cnt = 0, cnt_2g = 0, cnt_5g = 0, phy_now = RTW89_PHY_NUM, phy_dbcc;
- bool b2g = false, b5g = false, client_joined = false, client_inc_2g = false;
- u8 client_cnt_last[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
- u8 cid_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
- u8 cid_phy[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
- u8 mac = RTW89_MAC_0, dbcc_2g_phy = RTW89_PHY_0;
- u32 noa_duration = 0;
-
- memset(wl_rinfo, 0, sizeof(*wl_rinfo));
-
- for (i = 0; i < RTW89_PORT_NUM; i++) {
- if (!wl_linfo[i].active || wl_linfo[i].phy >= RTW89_PHY_NUM)
- continue;
-
- act_role = &wl_rinfo->active_role[i];
- act_role->role = wl_linfo[i].role;
-
- /* check if role connect? */
- if (wl_linfo[i].connected == MLME_NO_LINK) {
- act_role->connected = 0;
- continue;
- } else if (wl_linfo[i].connected == MLME_LINKING) {
- continue;
- }
-
- cnt++;
- act_role->connected = 1;
- act_role->pid = wl_linfo[i].pid;
- act_role->phy = wl_linfo[i].phy;
- act_role->band = wl_linfo[i].band;
- act_role->ch = wl_linfo[i].ch;
- act_role->bw = wl_linfo[i].bw;
- act_role->noa = wl_linfo[i].noa;
- act_role->noa_dur = wl_linfo[i].noa_duration;
- cid_ch[cnt - 1] = wl_linfo[i].chdef;
- cid_phy[cnt - 1] = wl_linfo[i].phy;
- cid_role[cnt - 1] = wl_linfo[i].role;
- wl_rinfo->role_map |= BIT(wl_linfo[i].role);
-
- if (rid == i)
- phy_now = act_role->phy;
-
- if (wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO ||
- wl_linfo[i].role == RTW89_WIFI_ROLE_AP) {
- if (wl_linfo[i].client_cnt > 1)
- client_joined = true;
- if (client_cnt_last[i] < wl_linfo[i].client_cnt &&
- wl_linfo[i].chdef.band == RTW89_BAND_2G)
- client_inc_2g = true;
- act_role->client_cnt = wl_linfo[i].client_cnt;
- } else {
- act_role->client_cnt = 0;
- }
-
- if (act_role->noa && act_role->noa_dur > 0)
- noa_duration = act_role->noa_dur;
-
- if (rtwdev->dbcc_en) {
- phy_dbcc = wl_linfo[i].phy;
- wl_dinfo->role[phy_dbcc] |= BIT(wl_linfo[i].role);
- wl_dinfo->op_band[phy_dbcc] = wl_linfo[i].chdef.band;
- }
-
- if (wl_linfo[i].chdef.band != RTW89_BAND_2G) {
- cnt_5g++;
- b5g = true;
- } else {
- if (((wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_GO ||
- wl_linfo[i].role == RTW89_WIFI_ROLE_AP) &&
- client_joined) ||
- wl_linfo[i].role == RTW89_WIFI_ROLE_P2P_CLIENT)
- wl_rinfo->p2p_2g = 1;
-
- if ((wl_linfo[i].mode & BIT(BTC_WL_MODE_11B)) ||
- (wl_linfo[i].mode & BIT(BTC_WL_MODE_11G)))
- wl->bg_mode = 1;
- else if (wl_linfo[i].mode & BIT(BTC_WL_MODE_HE))
- wl->he_mode = true;
-
- cnt_2g++;
- b2g = true;
- }
-
- if (act_role->band == RTW89_BAND_5G && act_role->ch >= 100)
- wl->is_5g_hi_channel = 1;
- else
- wl->is_5g_hi_channel = 0;
- }
-
- wl_rinfo->connect_cnt = cnt;
- wl->client_cnt_inc_2g = client_inc_2g;
-
- if (cnt == 0) {
- mode = BTC_WLINK_NOLINK;
- wl_rinfo->role_map = BIT(RTW89_WIFI_ROLE_NONE);
- } else if (!b2g && b5g) {
- mode = BTC_WLINK_5G;
- } else if (wl_rinfo->role_map & BIT(RTW89_WIFI_ROLE_NAN)) {
- mode = BTC_WLINK_2G_NAN;
- } else if (cnt > BTC_TDMA_WLROLE_MAX) {
- mode = BTC_WLINK_OTHER;
- } else if (rtwdev->dbcc_en) {
- mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, cnt);
-
- /* correct 2G-located PHY band for gnt ctrl */
- if (dbcc_2g_phy < RTW89_PHY_NUM)
- wl_dinfo->op_band[dbcc_2g_phy] = RTW89_BAND_2G;
- } else if (b2g && b5g && cnt == 2) {
- mode = BTC_WLINK_25G_MCC;
- } else if (!b5g && cnt == 2) { /* cnt_connect = 2 */
- if (_chk_role_ch_group(&cid_ch[0], &cid_ch[cnt - 1]))
- mode = BTC_WLINK_2G_SCC;
- else
- mode = BTC_WLINK_2G_MCC;
- } else if (!b5g && cnt == 1) { /* cnt_connect = 1 */
- mode = _get_role_link_mode(cid_role[0]);
- } else {
- mode = BTC_WLINK_NOLINK;
- }
-
- wl_rinfo->link_mode = mode;
- _update_role_link_mode(rtwdev, client_joined, noa_duration);
-
- /* todo DBCC related event */
- rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] wl_info phy_now=%d\n", phy_now);
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC] rlink cnt_2g=%d cnt_5g=%d\n", cnt_2g, cnt_5g);
-
- if (wl_rinfo->dbcc_en != rtwdev->dbcc_en) {
- wl_rinfo->dbcc_chg = 1;
- wl_rinfo->dbcc_en = rtwdev->dbcc_en;
- wl->wcnt[BTC_WCNT_DBCC_CHG]++;
- }
-
- if (rtwdev->dbcc_en) {
- wl_rinfo->dbcc_2g_phy = dbcc_2g_phy;
-
- if (dbcc_2g_phy == RTW89_PHY_1)
- mac = RTW89_MAC_1;
-
- _update_dbcc_band(rtwdev, RTW89_PHY_0);
- _update_dbcc_band(rtwdev, RTW89_PHY_1);
- }
- _wl_req_mac(rtwdev, mac);
- _fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
-}
-
-static u8 _update_wl_link_mode(struct rtw89_dev *rtwdev, u8 hw_band, u8 type)
-{
- struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl;
struct rtw89_btc_wl_mlo_info *mlo_info = &wl->mlo_info;
- u8 mode = BTC_WLINK_NOLINK;
+ struct rtw89_btc_wl_role_info *r = &wl->role_info;
+ u8 p2p_exist = wl->role_info.p2p_exist;
+ if (hw_band == RTW89_PHY_1)
+ p2p_exist = wl->role_info.p2p_exist_hb1;
+
+ /* MLD: nLmR --> 2L1R: 2-Link by 1-RF, 2L2R: 2-link by 2-RF */
switch (type) {
case RTW89_MR_WTYPE_NONE: /* no-link */
- mode = BTC_WLINK_NOLINK;
+ r->link_mode = BTC_WLINK_NOLINK;
break;
case RTW89_MR_WTYPE_NONMLD: /* Non_MLO 1-role 2+0/0+2 */
case RTW89_MR_WTYPE_MLD1L1R: /* MLO only-1 link 2+0/0+2 */
+ if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1AP) {
+ r->link_mode = BTC_WLINK_GO;
+ } else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1CLIENT &&
+ p2p_exist) {
+ r->link_mode = BTC_WLINK_GC;
+ } else {
+ r->link_mode = BTC_WLINK_STA;
+ }
+
+ if (ver->fwlrole >= 10)
+ break;
+
if (mlo_info->hwb_rf_band[hw_band] != RTW89_BAND_2G) {
- mode = BTC_WLINK_5G;
+ r->link_mode_v0 = BTC_WLINK_V0_5G;
} else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1AP) {
- mode = BTC_WLINK_2G_GO;
+ r->link_mode_v0 = BTC_WLINK_V0_2G_GO;
} else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1CLIENT) {
- if (wl->role_info_v8.p2p_2g)
- mode = BTC_WLINK_2G_GC;
+ if (wl->role_info.p2p_2g)
+ r->link_mode_v0 = BTC_WLINK_V0_2G_GC;
else
- mode = BTC_WLINK_2G_STA;
+ r->link_mode_v0 = BTC_WLINK_V0_2G_STA;
}
break;
case RTW89_MR_WTYPE_NONMLD_NONMLD: /* Non_MLO 2-role 2+0/0+2 */
case RTW89_MR_WTYPE_MLD1L1R_NONMLD: /* MLO only-1 link + P2P 2+0/0+2 */
+ if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ_5GHZ ||
+ mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ_6GHZ) {
+ r->link_mode = BTC_WLINK_DB_MCC;
+ } else if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ ||
+ mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_5GHZ ||
+ mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_6GHZ ||
+ mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_5GHZ_6GHZ) {
+ r->link_mode = BTC_WLINK_SB_MCC;
+ } else {
+ r->link_mode = BTC_WLINK_SCC;
+ }
+
+ if (ver->fwlrole >= 10)
+ break;
+
if (mlo_info->hwb_rf_band[hw_band] != RTW89_BAND_2G) {
- mode = BTC_WLINK_5G;
+ r->link_mode_v0 = BTC_WLINK_V0_5G;
} else if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ_5GHZ ||
mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ_6GHZ) {
- mode = BTC_WLINK_25G_MCC;
+ r->link_mode_v0 = BTC_WLINK_V0_25G_MCC;
} else if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX2_2GHZ) {
- mode = BTC_WLINK_2G_MCC;
+ r->link_mode_v0 = BTC_WLINK_V0_2G_MCC;
} else if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX1_2GHZ) {
- mode = BTC_WLINK_2G_SCC;
+ r->link_mode_v0 = BTC_WLINK_V0_2G_SCC;
}
break;
case RTW89_MR_WTYPE_MLD2L1R: /* MLO_MLSR 2+0/0+2 */
+ if (p2p_exist) /* MLO_MLSR only support STA/GC */
+ r->link_mode = BTC_WLINK_GC;
+ else
+ r->link_mode = BTC_WLINK_STA;
+
+ if (ver->fwlrole >= 10)
+ break;
+
if (mlo_info->hwb_rf_band[hw_band] != RTW89_BAND_2G)
- mode = BTC_WLINK_5G;
- else if (wl->role_info_v8.p2p_2g)
- mode = BTC_WLINK_2G_GC;
+ r->link_mode_v0 = BTC_WLINK_V0_5G;
+ else if (wl->role_info.p2p_2g)
+ r->link_mode_v0 = BTC_WLINK_V0_2G_GC;
else
- mode = BTC_WLINK_2G_STA;
+ r->link_mode_v0 = BTC_WLINK_V0_2G_STA;
break;
case RTW89_MR_WTYPE_MLD2L1R_NONMLD: /* MLO_MLSR + P2P 2+0/0+2 */
- case RTW89_MR_WTYPE_MLD2L2R_NONMLD: /* MLO_MLMR + P2P 1+1/2+2 */
- /* driver may doze 1-link to
+ case RTW89_MR_WTYPE_MLD2L2R_NONMLD: /* MLO_MLMR + P2P 1+1/2+2*/
+ /* driver may doze 1-link (1+1) or 2+0->0+2->1+1
* 2G+5G -> TDMA slot switch by E2G/E5G
* 5G only -> TDMA slot switch by E5G
*/
- mode = BTC_WLINK_25G_MCC;
+ r->link_mode = BTC_WLINK_DB_MCC;
+
+ if (ver->fwlrole >= 10)
+ break;
+
+ r->link_mode_v0 = BTC_WLINK_V0_25G_MCC;
break;
case RTW89_MR_WTYPE_MLD2L2R: /* MLO_MLMR 1+1/2+2 */
+ /* MLMR only support STA now (2024) */
+ r->link_mode = BTC_WLINK_STA;
+
+ if (ver->fwlrole >= 10)
+ break;
+
if (mlo_info->hwb_rf_band[hw_band] != RTW89_BAND_2G) {
- mode = BTC_WLINK_5G;
+ r->link_mode_v0 = BTC_WLINK_V0_5G;
} else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1AP) {
- mode = BTC_WLINK_2G_GO;
+ r->link_mode_v0 = BTC_WLINK_V0_2G_GO;
} else if (mlo_info->wmode[hw_band] == RTW89_MR_WMODE_1CLIENT) {
- if (wl->role_info_v8.p2p_2g)
- mode = BTC_WLINK_2G_GC;
+ if (wl->role_info.p2p_2g)
+ r->link_mode_v0 = BTC_WLINK_V0_2G_GC;
else
- mode = BTC_WLINK_2G_STA;
+ r->link_mode_v0 = BTC_WLINK_V0_2G_STA;
}
break;
}
- return mode;
}
-static void _update_wl_mlo_info(struct rtw89_dev *rtwdev)
+static void _update_wl_mlo_info(struct rtw89_dev *rtwdev, u8 hw_band)
{
struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8;
+ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_btc_wl_mlo_info *mlo_info = &wl->mlo_info;
struct rtw89_mr_chanctx_info qinfo;
- u8 track_band = RTW89_PHY_0;
+ struct rtw89_chanctx *ch;
u8 rf_band = RTW89_BAND_2G;
u8 i, type;
@@ -7265,19 +6701,46 @@ static void _update_wl_mlo_info(struct rtw89_dev *rtwdev)
memset(&qinfo, 0, sizeof(qinfo));
rtw89_query_mr_chanctx_info(rtwdev, i, &qinfo);
+
+ switch (qinfo.ctxtype) {
+ default:
+ mlo_info->hwb_rf_band[i] = 0;
+ break;
+ case RTW89_MR_CTX1_2GHZ:
+ case RTW89_MR_CTX2_2GHZ:
+ mlo_info->hwb_rf_band[i] = BIT(RTW89_BAND_2G);
+ break;
+ case RTW89_MR_CTX1_5GHZ:
+ case RTW89_MR_CTX2_5GHZ:
+ mlo_info->hwb_rf_band[i] = BIT(RTW89_BAND_5G);
+ break;
+ case RTW89_MR_CTX1_6GHZ:
+ case RTW89_MR_CTX2_6GHZ:
+ mlo_info->hwb_rf_band[i] = BIT(RTW89_BAND_6G);
+ break;
+ case RTW89_MR_CTX2_2GHZ_5GHZ:
+ mlo_info->hwb_rf_band[i] = BIT(RTW89_BAND_2G) |
+ BIT(RTW89_BAND_5G);
+ break;
+ case RTW89_MR_CTX2_2GHZ_6GHZ:
+ mlo_info->hwb_rf_band[i] = BIT(RTW89_BAND_2G) |
+ BIT(RTW89_BAND_6G);
+ break;
+ case RTW89_MR_CTX2_5GHZ_6GHZ:
+ mlo_info->hwb_rf_band[i] = BIT(RTW89_BAND_5G) |
+ BIT(RTW89_BAND_6G);
+ break;
+ }
mlo_info->wmode[i] = qinfo.wmode;
mlo_info->ch_type[i] = qinfo.ctxtype;
mlo_info->wtype = qinfo.wtype;
-
- if (mlo_info->ch_type[i] == RTW89_MR_CTX1_5GHZ ||
- mlo_info->ch_type[i] == RTW89_MR_CTX2_5GHZ ||
- mlo_info->ch_type[i] == RTW89_MR_CTX2_5GHZ_6GHZ)
- mlo_info->hwb_rf_band[i] = RTW89_BAND_5G;
- else if (mlo_info->ch_type[i] == RTW89_MR_CTX1_6GHZ ||
- mlo_info->ch_type[i] == RTW89_MR_CTX2_6GHZ)
- mlo_info->hwb_rf_band[i] = RTW89_BAND_6G;
- else /* check if "2G-included" or unknown in each HW-band */
- mlo_info->hwb_rf_band[i] = RTW89_BAND_2G;
+ wl->rf_band_map[i] = mlo_info->hwb_rf_band[i];
+ ch = &rtwdev->hal.chanctx[i];
+ wl->rf_ch_info[i].center_ch = ch->chan.channel;
+ wl->rf_ch_info[i].band = ch->chan.band_type;
+ wl->rf_ch_info[i].chan = ch->chan.channel;
+ wl->rf_ch_info[i].offset = ch->chan.pri_ch_idx;
+ wl->rf_ch_info[i].bw = ch->chan.band_width;
}
mlo_info->link_status = rtwdev->mlo_dbcc_mode;
@@ -7312,71 +6775,64 @@ static void _update_wl_mlo_info(struct rtw89_dev *rtwdev)
default:
case MLO_2_PLUS_0_1RF: /* 2+0 */
case MLO_2_PLUS_0_2RF:
- mlo_info->rf_combination = BTC_MLO_RF_2_PLUS_0;
- track_band = RTW89_MAC_0;
- rf_band = mlo_info->hwb_rf_band[RTW89_MAC_0];
- mlo_info->path_rf_band[BTC_RF_S0] = rf_band;
- mlo_info->path_rf_band[BTC_RF_S1] = rf_band;
-
+ _update_wl_link_mode(rtwdev, RTW89_MAC_0, type);
+ wl_rinfo->link_mode_hb1 = wl_rinfo->link_mode;
wl_rinfo->pta_req_band = RTW89_MAC_0;
wl_rinfo->dbcc_2g_phy = RTW89_PHY_0;
wl_rinfo->dbcc_en = 0;
+
+ rf_band = wl->rf_band_map[RTW89_PHY_0];
+ mlo_info->path_rf_band[BTC_RF_S0] = rf_band;
+ mlo_info->path_rf_band[BTC_RF_S1] = rf_band;
break;
case MLO_0_PLUS_2_1RF: /* 0+2 */
case MLO_0_PLUS_2_2RF:
- mlo_info->rf_combination = BTC_MLO_RF_0_PLUS_2;
- track_band = RTW89_MAC_1;
- rf_band = mlo_info->hwb_rf_band[RTW89_MAC_1];
- mlo_info->path_rf_band[BTC_RF_S0] = rf_band;
- mlo_info->path_rf_band[BTC_RF_S1] = rf_band;
-
+ _update_wl_link_mode(rtwdev, RTW89_MAC_1, type);
+ wl_rinfo->link_mode_hb1 = wl_rinfo->link_mode;
wl_rinfo->pta_req_band = RTW89_MAC_1;
wl_rinfo->dbcc_2g_phy = RTW89_PHY_1;
wl_rinfo->dbcc_en = 0;
+
+ rf_band = wl->rf_band_map[RTW89_PHY_1];
+ mlo_info->path_rf_band[BTC_RF_S0] = rf_band;
+ mlo_info->path_rf_band[BTC_RF_S1] = rf_band;
break;
case MLO_1_PLUS_1_1RF: /* 1+1 */
case MLO_1_PLUS_1_2RF: /* 1+1 */
case MLO_2_PLUS_2_2RF: /* 2+2 */
case DBCC_LEGACY: /* DBCC 1+1 */
- if (mlo_info->link_status == MLO_2_PLUS_2_2RF)
- mlo_info->rf_combination = BTC_MLO_RF_2_PLUS_2;
- else
- mlo_info->rf_combination = BTC_MLO_RF_1_PLUS_1;
-
- if (mlo_info->hwb_rf_band[RTW89_MAC_0] == RTW89_BAND_2G)
- track_band = RTW89_MAC_0;
+ /* Check ch count from ch_type and modify type*/
+ if (mlo_info->ch_type[hw_band] == RTW89_MR_CTX1_2GHZ ||
+ mlo_info->ch_type[hw_band] == RTW89_MR_CTX1_5GHZ ||
+ mlo_info->ch_type[hw_band] == RTW89_MR_CTX1_6GHZ)
+ type = RTW89_MR_WTYPE_NONMLD; /* only 1-role */
else
- track_band = RTW89_MAC_1;
+ type = RTW89_MR_WTYPE_NONMLD_NONMLD;
- mlo_info->path_rf_band[BTC_RF_S0] =
- mlo_info->hwb_rf_band[RTW89_MAC_0];
- mlo_info->path_rf_band[BTC_RF_S1] =
- mlo_info->hwb_rf_band[RTW89_MAC_1];
+ rf_band = wl->rf_band_map[hw_band];
+ _update_wl_link_mode(rtwdev, hw_band, type);
- /* Check ch count from ch_type @ 2.4G HW-band, and modify type */
- if (mlo_info->ch_type[track_band] == RTW89_MR_CTX1_2GHZ)
- type = RTW89_MR_WTYPE_NONMLD; /* only 1-role at 2G */
- else
- type = RTW89_MR_WTYPE_NONMLD_NONMLD;
+ if (hw_band == RTW89_MAC_0) {
+ mlo_info->path_rf_band[BTC_RF_S0] = rf_band;
+ } else {
+ wl_rinfo->link_mode_hb1 = wl_rinfo->link_mode;
+ mlo_info->path_rf_band[BTC_RF_S1] = rf_band;
+ }
- if (mlo_info->hwb_rf_band[RTW89_MAC_0] == RTW89_BAND_2G) {
+ /* set pta_req_band for 1-PTA architecture */
+ if (wl->rf_band_map[RTW89_MAC_0] & BIT(RTW89_BAND_2G)) {
wl_rinfo->pta_req_band = RTW89_MAC_0;
wl_rinfo->dbcc_2g_phy = RTW89_PHY_0;
- } else {
+ } else if (wl->rf_band_map[RTW89_MAC_1] & BIT(RTW89_BAND_2G)) {
wl_rinfo->pta_req_band = RTW89_MAC_1;
wl_rinfo->dbcc_2g_phy = RTW89_PHY_1;
+ } else { /* Both HW-BAND are not on 2.4G*/
+ wl_rinfo->pta_req_band = RTW89_MAC_0;
+ wl_rinfo->dbcc_2g_phy = RTW89_PHY_0;
}
-
- if (mlo_info->wmode[RTW89_MAC_0] == RTW89_MR_WMODE_NONE &&
- mlo_info->wmode[RTW89_MAC_1] == RTW89_MR_WMODE_NONE)
- wl_rinfo->dbcc_en = 0;
- else
- wl_rinfo->dbcc_en = 1;
break;
}
- wl_rinfo->link_mode = _update_wl_link_mode(rtwdev, track_band, type);
-
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(), mode=%s, pta_band=%d",
__func__, id_to_linkmode(wl_rinfo->link_mode),
wl_rinfo->pta_req_band);
@@ -7386,16 +6842,19 @@ static void _update_wl_non_mlo_info(struct rtw89_dev *rtwdev)
{
struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl;
struct rtw89_btc_wl_rlink *rlink = NULL;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8;
+ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_btc_chdef cid_ch[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
u8 cid_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
u8 cid_phy[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER] = {};
bool b2g = false, b5g = false, outloop = false;
+ bool notv10 = rtwdev->btc.ver->fwlrole != 10;
+ u8 mode_v0 = BTC_WLINK_V0_NOLINK;
u8 mode = BTC_WLINK_NOLINK;
u8 cnt_2g = 0, cnt_5g = 0;
u8 i, j, cnt = 0;
for (j = RTW89_PHY_0; j < RTW89_PHY_NUM; j++) {
+ wl->rf_band_map[j] = 0; /* j=link id, is the link use which band */
for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) {
rlink = &wl_rinfo->rlink[i][j];
@@ -7419,6 +6878,7 @@ static void _update_wl_non_mlo_info(struct rtw89_dev *rtwdev)
cnt_2g++;
b2g = true;
}
+ wl->rf_band_map[j] |= BIT(rlink->rf_band);
}
if (outloop)
break;
@@ -7427,56 +6887,73 @@ static void _update_wl_non_mlo_info(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): cnt_2g=%d, cnt_5g=%d\n", __func__, cnt_2g, cnt_5g);
+ wl_rinfo->pta_req_band = RTW89_PHY_0; /* no 0+2 for non-MLO */
wl_rinfo->dbcc_en = rtwdev->dbcc_en;
+
/* Be careful to change the following sequence!! */
if (cnt == 0) {
mode = BTC_WLINK_NOLINK;
- } else if (!b2g && b5g) {
- mode = BTC_WLINK_5G;
+ mode_v0 = BTC_WLINK_V0_NOLINK;
} else if (wl_rinfo->dbcc_en) {
- mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, cnt);
+ /* update pta_req_band to 2.4GHz HW-BAND for DBCC = 1*/
+ mode = _chk_dbcc(rtwdev, cid_ch, cid_phy, cid_role, cnt, notv10);
+ mode_v0 = wl_rinfo->link_mode_v0;
+ } else if (!b2g && b5g && notv10) {
+ mode_v0 = BTC_WLINK_V0_5G;
} else if (b2g && b5g) {
- mode = BTC_WLINK_25G_MCC;
- } else if (!b5g && cnt >= 2) {
- if (_chk_role_ch_group(&cid_ch[0], &cid_ch[1]))
- mode = BTC_WLINK_2G_SCC;
- else
- mode = BTC_WLINK_2G_MCC;
- } else if (!b5g) { /* cnt_connect = 1 */
- mode = _get_role_link_mode(cid_role[0]);
+ mode = BTC_WLINK_DB_MCC;
+ mode_v0 = BTC_WLINK_V0_25G_MCC;
+ } else if (cnt >= 2) {
+ if (_chk_role_ch_group(&cid_ch[0], &cid_ch[1])) {
+ mode = BTC_WLINK_SCC;
+ mode_v0 = BTC_WLINK_V0_2G_SCC;
+ } else {
+ mode = BTC_WLINK_SB_MCC;
+ mode_v0 = BTC_WLINK_V0_2G_MCC;
+ }
+ } else {
+ mode = _get_role_link_mode(wl_rinfo, cid_role[0], notv10);
}
wl_rinfo->link_mode = mode;
+ wl_rinfo->link_mode_hb1 = mode;
+ wl_rinfo->link_mode_v0 = mode_v0;
}
-static void _modify_role_link_mode(struct rtw89_dev *rtwdev)
+static void _modify_role_link_mode(struct rtw89_dev *rtwdev, u8 hw_band)
{
- struct rtw89_btc_wl_info *wl = &rtwdev->btc.cx.wl;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8;
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
u8 go_cleint_exist = wl->go_client_exist;
- u8 link_mode = wl_rinfo->link_mode;
+ u8 *link_mode = &wl_rinfo->link_mode;
u32 role_map = wl_rinfo->role_map;
u8 noa_exist = wl->noa_exist;
u32 mrole = BTC_WLMROLE_NONE;
+ if (hw_band == RTW89_PHY_1) {
+ *link_mode = wl_rinfo->link_mode_hb1;
+ role_map = wl_rinfo->role_map_hb1;
+ go_cleint_exist = wl->go_client_exist_hb1;
+ }
+
/* if no client_joined, don't care P2P-GO/AP role */
if (((role_map & BIT(RTW89_WIFI_ROLE_P2P_GO)) ||
- (role_map & BIT(RTW89_WIFI_ROLE_AP))) && !go_cleint_exist) {
- if (link_mode == BTC_WLINK_2G_SCC) {
- wl_rinfo->link_mode = BTC_WLINK_2G_STA;
- } else if (link_mode == BTC_WLINK_2G_GO ||
- link_mode == BTC_WLINK_2G_AP) {
- wl_rinfo->link_mode = BTC_WLINK_NOLINK;
+ (role_map & BIT(RTW89_WIFI_ROLE_AP))) && !go_cleint_exist) {
+ if (*link_mode == BTC_WLINK_SCC) {
+ *link_mode = BTC_WLINK_STA;
+ } else if (*link_mode == BTC_WLINK_GO ||
+ *link_mode == BTC_WLINK_AP) {
+ *link_mode = BTC_WLINK_NOLINK;
}
}
- /* Identify 2-Role type */
- if (link_mode == BTC_WLINK_2G_SCC ||
- link_mode == BTC_WLINK_2G_MCC ||
- link_mode == BTC_WLINK_25G_MCC ||
- link_mode == BTC_WLINK_5G) {
+ /* Identify 2-Role type */
+ if (*link_mode == BTC_WLINK_SCC ||
+ *link_mode == BTC_WLINK_SB_MCC ||
+ *link_mode == BTC_WLINK_DB_MCC) {
if ((role_map & BIT(RTW89_WIFI_ROLE_P2P_GO)) ||
- (role_map & BIT(RTW89_WIFI_ROLE_AP))) {
+ (role_map & BIT(RTW89_WIFI_ROLE_AP))) {
if (noa_exist)
mrole = BTC_WLMROLE_STA_GO_NOA;
else
@@ -7489,127 +6966,147 @@ static void _modify_role_link_mode(struct rtw89_dev *rtwdev)
} else {
mrole = BTC_WLMROLE_STA_STA;
}
- }
- wl_rinfo->mrole_type = mrole;
+ if (hw_band == RTW89_PHY_0) {
+ wl_rinfo->mrole_type &= GENMASK(31, 16); /* clear Low-Word */
+ wl_rinfo->mrole_type |= mrole;
+ } else {
+ wl_rinfo->mrole_type &= GENMASK(15, 0); /* clear high-Word */
+ wl_rinfo->mrole_type |= (mrole << 16);
+ }
+ } else {
+ wl_rinfo->mrole_type = BTC_WLMROLE_NONE;
+ }
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): link_mode=%s, mrole_type=%d\n", __func__,
id_to_linkmode(wl_rinfo->link_mode), wl_rinfo->mrole_type);
}
-static void _update_wl_info_v8(struct rtw89_dev *rtwdev, u8 role_id, u8 rlink_id,
- enum btc_role_state state)
+static void _update_wl_info(struct rtw89_dev *rtwdev, struct rtw89_btc_wl_link_info *wl_linfo)
{
- struct rtw89_btc_wl_rlink *rlink = NULL;
- struct rtw89_btc_wl_link_info *wl_linfo;
struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo = &wl->role_info_v8;
- bool client_joined = false, noa_exist = false, p2p_exist = false;
- bool is_5g_hi_channel = false, bg_mode = false, dbcc_en_ori;
- u8 i, j, link_mode_ori;
+ struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
+ struct rtw89_btc_wl_rlink *rlink = NULL;
+ u8 dbcc_en_ori, is_5g_hi_ch = 0, bg_mode = 0, p2p_exist = 0;
+ u8 go_client_exist = 0, noa_exist = 0;
+ u8 rlink_id = wl_linfo->phy;
+ u8 role_id = wl_linfo->pid;
+ u8 i, link_mode_ori;
u32 role_map = 0;
- if (role_id >= RTW89_BE_BTC_WL_MAX_ROLE_NUMBER || rlink_id >= RTW89_MAC_NUM)
+ if (role_id >= RTW89_BE_BTC_WL_MAX_ROLE_NUMBER || rlink_id >= RTW89_BAND_NUM)
return;
- /* Extract wl->link_info[role_id][rlink_id] to wl->role_info
+ /*
+ * Extract wl->link_info[role_id][rlink_id] to wl->role_info
* role_id: role index
* rlink_id: rlink index (= HW-band index)
* pid: port_index
*/
-
- wl_linfo = &wl->rlink_info[role_id][rlink_id];
rlink = &wl_rinfo->rlink[role_id][rlink_id];
rlink->role = wl_linfo->role;
rlink->active = wl_linfo->active; /* Doze or not */
rlink->pid = wl_linfo->pid;
+ rlink->mac_id = wl_linfo->mac_id;
rlink->phy = wl_linfo->phy;
- rlink->rf_band = wl_linfo->band;
- rlink->ch = wl_linfo->ch;
- rlink->bw = wl_linfo->bw;
+ rlink->rf_band = wl_linfo->chdef.band;
+ rlink->ch = wl_linfo->chdef.center_ch;
+ rlink->bw = wl_linfo->chdef.bw;
rlink->noa = wl_linfo->noa;
rlink->noa_dur = wl_linfo->noa_duration / 1000;
rlink->client_cnt = wl_linfo->client_cnt;
rlink->mode = wl_linfo->mode;
+ /* check if rlink connect? */
switch (wl_linfo->connected) {
case MLME_NO_LINK:
rlink->connected = 0;
break;
case MLME_LINKED:
rlink->connected = 1;
+
+ /* reset special-AP flag if station mode linked */
+ dm->leak_ap = 0;
break;
default:
return;
}
- for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) {
- for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) {
- rlink = &wl_rinfo->rlink[i][j];
-
- if (!rlink->active || !rlink->connected)
- continue;
+ /* update by HW-Band */
+ for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) { /* i = role_id */
+ rlink = &wl_rinfo->rlink[i][rlink_id];
- role_map |= BIT(rlink->role);
+ if (!rlink->active || !rlink->connected)
+ continue;
- /* only one noa-role exist */
- if (rlink->noa && rlink->noa_dur > 0)
- noa_exist = true;
+ role_map |= BIT(rlink->role);
- /* for WL 5G-Rx interfered with BT issue */
- if (rlink->rf_band == RTW89_BAND_5G) {
- if (rlink->ch >= 100)
- is_5g_hi_channel = true;
+ /* Identify if P2P-Go (GO/GC/AP) exist at 2GHz band */
+ if (((rlink->role == RTW89_WIFI_ROLE_P2P_GO ||
+ rlink->role == RTW89_WIFI_ROLE_AP) &&
+ rlink->client_cnt > 1)) {
+ p2p_exist = 1;
+ go_client_exist = 1;
+ }
- continue;
- }
+ if (rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT)
+ p2p_exist = 1;
- /* only if client connect for p2p-Go/AP */
- if ((rlink->role == RTW89_WIFI_ROLE_P2P_GO ||
- rlink->role == RTW89_WIFI_ROLE_AP) &&
- rlink->client_cnt > 1) {
- p2p_exist = true;
- client_joined = true;
- }
+ /* only one noa-role exist */
+ if (rlink->noa && rlink->noa_dur > 0)
+ noa_exist = 1;
- /* Identify if P2P-Go (GO/GC/AP) exist at 2G band */
- if (rlink->role == RTW89_WIFI_ROLE_P2P_CLIENT)
- p2p_exist = true;
+ /* for WL 5G-Rx interfered with BT issue */
+ if (rlink->rf_band == RTW89_BAND_5G && rlink->ch >= 100)
+ is_5g_hi_ch = 1;
- if ((rlink->mode & BIT(BTC_WL_MODE_11B)) ||
- (rlink->mode & BIT(BTC_WL_MODE_11G)))
- bg_mode = true;
- }
+ if ((rlink->mode & BIT(BTC_WL_MODE_11B)) ||
+ (rlink->mode & BIT(BTC_WL_MODE_11G)))
+ bg_mode = 1;
}
- link_mode_ori = wl_rinfo->link_mode;
- wl->is_5g_hi_channel = is_5g_hi_channel;
- wl->bg_mode = bg_mode;
- wl->go_client_exist = client_joined;
- wl->noa_exist = noa_exist;
- wl_rinfo->p2p_2g = p2p_exist;
- wl_rinfo->role_map = role_map;
+ if (rlink_id == RTW89_PHY_0) {
+ link_mode_ori = wl_rinfo->link_mode;
+ wl->is_5g_hi_ch = is_5g_hi_ch;
+ wl->bg_mode = bg_mode;
+ wl->go_client_exist = go_client_exist;
+ wl->noa_exist = noa_exist;
+ wl_rinfo->p2p_exist = p2p_exist;
+ wl_rinfo->role_map = role_map;
+ } else {
+ link_mode_ori = wl_rinfo->link_mode_hb1;
+ wl->is_5g_hi_ch_hb1 = is_5g_hi_ch;
+ wl->bg_mode_hb1 = bg_mode;
+ wl->go_client_exist_hb1 = go_client_exist;
+ wl->noa_exist_hb1 = noa_exist;
+ wl_rinfo->p2p_exist_hb1 = p2p_exist;
+ wl_rinfo->role_map_hb1 = role_map;
+ }
dbcc_en_ori = wl_rinfo->dbcc_en;
+ /* for MLO-supported, link-mode from driver directly */
if (rtwdev->chip->para_ver & BTC_FEAT_MLO_SUPPORT) {
- /* for MLO-supported, link-mode from driver directly */
- _update_wl_mlo_info(rtwdev);
- } else {
- /* for non-MLO-supported, link-mode by BTC */
+ _update_wl_mlo_info(rtwdev, rlink_id);
+ } else { /* for non-MLO-supported, link-mode by BTC */
_update_wl_non_mlo_info(rtwdev);
}
- _modify_role_link_mode(rtwdev);
+ _modify_role_link_mode(rtwdev, rlink_id);
- if (link_mode_ori != wl_rinfo->link_mode)
- wl->link_mode_chg = true;
+ if ((rlink_id == RTW89_PHY_0 && wl_rinfo->link_mode != link_mode_ori) ||
+ (rlink_id == RTW89_PHY_1 && wl_rinfo->link_mode_hb1 != link_mode_ori)) {
+ wl_rinfo->link_mode_chg = 1;
+ wl->link_mode_chg = 1;
+ }
if (wl_rinfo->dbcc_en != dbcc_en_ori) {
- wl->dbcc_chg = true;
+ wl->dbcc_chg = 1;
+ wl->role_info.dbcc_chg = 1;
wl->wcnt[BTC_WCNT_DBCC_CHG]++;
}
}
@@ -7685,25 +7182,21 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid)
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_bt_info *bt;
u32 val, any_bt_connect, any_bt_6g_connect = 0;
- u8 id, id_start, id_stop, mode;
+ u8 id, id_start, id_stop, mode = 0;
bool bt_link_change = false;
bool lps_ctrl = false;
if (!rtwdev->chip->scbd || bid > BTC_ALL_BT)
return;
- if (ver->fwlrole == 0)
- mode = wl->role_info.link_mode;
- else if (ver->fwlrole == 1)
- mode = wl->role_info_v1.link_mode;
- else if (ver->fwlrole == 2)
- mode = wl->role_info_v2.link_mode;
- else if (ver->fwlrole == 7)
- mode = wl->role_info_v7.link_mode;
- else if (ver->fwlrole == 8)
- mode = wl->role_info_v8.link_mode;
- else
- return;
+ if (ver->fwlrole == 10) {
+ if (wl->role_info.link_mode == BTC_WLINK_STA &&
+ (dm->tdd_en && wl->rf_band_map[RTW89_MAC_0] &
+ BIT(RTW89_BAND_2G)))
+ mode = BTC_WLINK_V0_2G_STA;
+ } else {
+ mode = wl->role_info.link_mode_v0;
+ }
if (bid == BTC_ALL_BT) {
id_start = BTC_BT_1ST;
@@ -7796,7 +7289,7 @@ static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid)
if (((bt->link_info.a2dp_desc.exist ||
bt->link_info.pan_desc.exist ||
bt->link_info.hfp_desc.exist) &&
- mode == BTC_WLINK_2G_STA) ||
+ mode == BTC_WLINK_V0_2G_STA) ||
bt->whql_test)
lps_ctrl = true;
@@ -7900,7 +7393,12 @@ static void _set_bind_info(struct rtw89_btc *btc, u8 type)
* HW-Band is decided by wl->mlo_info.mrcx_act_hwb_map
*/
if (wl->mlo_info.wtype == RTW89_MR_WTYPE_MLD2L1R_NONMLD) {
- /* TODO: Should patched WiFi mode & WiFi role patch */
+ if (wl->role_info.link_mode != BTC_WLINK_DB_MCC) { /* mode chg */
+ if (wl->mlo_info.mrcx_act_hwb_map == BIT(RTW89_MAC_1))
+ path_hwb[BTC_RF_S0] = RTW89_PHY_1; /* S0/1->HWB1 */
+ else
+ path_hwb[BTC_RF_S1] = RTW89_PHY_0; /* S0/1->HWB0 */
+ }
} else {
/*
* Dual-RF_band(HWB)TDMA if BT-profile is TDMA-type at both
@@ -7933,7 +7431,22 @@ static void _set_bind_info(struct rtw89_btc *btc, u8 type)
}
}
- /* TODO: Should patched WiFi mode & WiFi role patch */
+ if (wl->mlo_info.wtype == RTW89_MR_WTYPE_MLD2L2R &&
+ (bd->wl_hwb_sel == (BIT(RTW89_MAC_1) | BIT(RTW89_MAC_0)))) {
+ if (wl->role_info.link_mode == BTC_WLINK_AP ||
+ wl->role_info.link_mode_hb1 == BTC_WLINK_AP)
+ bd->wl_link_mode = BTC_WLINK_DB_MCC;
+ else
+ bd->wl_link_mode = BTC_WLINK_STA;
+ bd->wl_bg_mode = wl->bg_mode | wl->bg_mode_hb1;
+ } else if (bd->wl_hwb_sel == (BIT(RTW89_MAC_1))) {
+ bd->wl_link_mode = wl->role_info.link_mode_hb1;
+ bd->wl_bg_mode = wl->bg_mode_hb1;
+ } else {/* HW-BAND-0 or no-hw-band */
+ bd->wl_hwb_sel = BIT(RTW89_MAC_0);
+ bd->wl_link_mode = wl->role_info.link_mode;
+ bd->wl_bg_mode = wl->bg_mode;
+ }
/* update Bind-BT status map for BT0/BT1 */
for (i = BTC_BT_1ST; i < BTC_ALL_BT_EZL; i++) {
@@ -7966,9 +7479,9 @@ static void _set_bind_info(struct rtw89_btc *btc, u8 type)
bd->bt_smap.a2dp_sink |= b->a2dp_desc.sink;
bd->bt_smap.pan_active |= b->pan_desc.active;
bd->bt_smap.connect |= b->status.map.connect;
- bd->bt_smap.hid_cnt += (u8)b->hid_desc.pair_cnt;
+ bd->bt_smap.hid_cnt += b->hid_desc.pair_cnt;
bd->bt_smap.hid_type |= b->hid_desc.type;
- bd->bt_smap.cis_cnt += (u8)b->leaudio_desc.cis_cnt;
+ bd->bt_smap.cis_cnt += b->leaudio_desc.cis_cnt;
bd->bt_smap.link_cnt += b->link_cnt.now;
bd->bt_smap.inq_page |= b->status.map.inq_pag;
bd->bt_smap.page |= b->pag;
@@ -8028,7 +7541,7 @@ static void _set_coex_binding(struct rtw89_btc *btc)
* ==> 1: interference, 0: no-interference
*
* fdm_map(Frequency-Division-Multiplexing): WL/BT RF_Band overlap-map
- * 2bit-map: bit[1]:5GHz/6GHz, bit[0]:2.4GHz
+ * 2bit-map: bit[1]:5/6GHz, bit[0]:2.4GHz
*/
for (i = 0; i < RTW89_PHY_NUM; i++) {
if (wl->rf_band_map[i] & BIT(RTW89_BAND_2G))
@@ -8050,9 +7563,7 @@ static void _set_coex_binding(struct rtw89_btc *btc)
* In this case, BTC_RF_S0->HWB0, BTC_RF_S1->HWB1
*/
if (wl->mlo_info.wtype == RTW89_MR_WTYPE_MLD2L1R_NONMLD) {
- if (wl->role_info.link_mode != BTC_WLINK_2G_MCC &&
- wl->role_info.link_mode != BTC_WLINK_25G_MCC &&
- wl->role_info.link_mode != BTC_WLINK_25G_DBCC) {/* mode chg */
+ if (wl->role_info.link_mode != BTC_WLINK_DB_MCC) {/* mode chg */
if (wl->mlo_info.mrcx_act_hwb_map == BIT(RTW89_PHY_1))
path_hwb[BTC_RF_S0] = RTW89_PHY_1;/* S0/1->HWB1 */
else
@@ -8114,31 +7625,14 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
- struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
- struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
- struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
- struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
- u8 mode, igno_bt, always_freerun;
+ u8 mode = btc->dm.tdd_bind.wl_link_mode;
+ u8 mode_v0 = wl->role_info.link_mode_v0;
+ u8 igno_bt, always_freerun;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
dm->run_reason = reason;
_update_dm_step(rtwdev, reason);
- _update_btc_state_map(rtwdev);
-
- if (ver->fwlrole == 0)
- mode = wl_rinfo->link_mode;
- else if (ver->fwlrole == 1)
- mode = wl_rinfo_v1->link_mode;
- else if (ver->fwlrole == 2)
- mode = wl_rinfo_v2->link_mode;
- else if (ver->fwlrole == 7)
- mode = wl_rinfo_v7->link_mode;
- else if (ver->fwlrole == 8)
- mode = wl_rinfo_v8->link_mode;
- else
- return;
if (ver->fcxctrl == 7) {
igno_bt = btc->ctrl.ctrl_v7.igno_bt;
@@ -8206,6 +7700,7 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
igno_bt = false;
_set_coex_binding(btc);
+ _update_btc_state_map(rtwdev);
dm->freerun_chk = _check_freerun(rtwdev); /* check if meet freerun */
@@ -8253,43 +7748,76 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
goto exit;
}
- switch (mode) {
+ if (mode == BTC_WLINK_NOLINK) {
+ mode_v0 = BTC_WLINK_V0_NOLINK;
+ } else if (btc->dm.tdd_bind.rf_band == BIT(RTW89_BAND_5G)) {
+ mode_v0 = BTC_WLINK_V0_5G;
+ } else if (btc->dm.tdd_bind.rf_band & BIT(RTW89_BAND_5G) &&
+ btc->dm.tdd_bind.rf_band & BIT(RTW89_BAND_2G)) {
+ mode_v0 = BTC_WLINK_V0_25G_MCC;
+ } else if (btc->dm.tdd_bind.rf_band == BIT(RTW89_BAND_2G)) {
+ switch (mode) {
+ case BTC_WLINK_STA:
+ mode_v0 = BTC_WLINK_V0_2G_STA;
+ break;
+ case BTC_WLINK_AP:
+ mode_v0 = BTC_WLINK_V0_2G_AP;
+ break;
+ case BTC_WLINK_GO:
+ mode_v0 = BTC_WLINK_V0_2G_GO;
+ break;
+ case BTC_WLINK_GC:
+ mode_v0 = BTC_WLINK_V0_2G_GC;
+ break;
+ case BTC_WLINK_SCC:
+ mode_v0 = BTC_WLINK_V0_2G_SCC;
+ break;
+ case BTC_WLINK_SB_MCC:
+ mode_v0 = BTC_WLINK_V0_2G_MCC;
+ break;
+ default:
+ mode_v0 = BTC_WLINK_V0_OTHER;
+ break;
+ }
+ }
+
+ switch (mode_v0) {
case BTC_WLINK_NOLINK:
_action_wl_nc(rtwdev);
break;
- case BTC_WLINK_2G_STA:
+ case BTC_WLINK_V0_2G_STA:
if (wl->status.map.traffic_dir & BIT(RTW89_TFC_DL))
bt->scan_rx_low_pri = true;
_action_wl_2g_sta(rtwdev);
break;
- case BTC_WLINK_2G_AP:
+ case BTC_WLINK_V0_2G_AP:
bt->scan_rx_low_pri = true;
_action_wl_2g_ap(rtwdev);
break;
- case BTC_WLINK_2G_GO:
+ case BTC_WLINK_V0_2G_GO:
bt->scan_rx_low_pri = true;
_action_wl_2g_go(rtwdev);
break;
- case BTC_WLINK_2G_GC:
+ case BTC_WLINK_V0_2G_GC:
bt->scan_rx_low_pri = true;
_action_wl_2g_gc(rtwdev);
break;
- case BTC_WLINK_2G_SCC:
+ case BTC_WLINK_V0_2G_SCC:
bt->scan_rx_low_pri = true;
_action_wl_2g_scc(rtwdev);
break;
- case BTC_WLINK_2G_MCC:
+ case BTC_WLINK_V0_2G_MCC:
bt->scan_rx_low_pri = true;
_action_wl_2g_mcc(rtwdev);
break;
- case BTC_WLINK_25G_MCC:
+ case BTC_WLINK_V0_25G_MCC:
bt->scan_rx_low_pri = true;
_action_wl_25g_mcc(rtwdev);
break;
- case BTC_WLINK_5G:
+ case BTC_WLINK_V0_5G:
_action_wl_5g(rtwdev);
break;
- case BTC_WLINK_2G_NAN:
+ case BTC_WLINK_V0_2G_NAN:
_action_wl_2g_nan(rtwdev);
break;
default:
@@ -8678,22 +8206,6 @@ static u8 _update_bt_rssi_level(struct rtw89_dev *rtwdev, u8 rssi)
return rssi_level;
}
-static void _update_zb_coex_tbl(struct rtw89_dev *rtwdev)
-{
- u8 mode = rtwdev->btc.cx.wl.role_info.link_mode;
- u32 zb_tbl0 = 0xda5a5a5a, zb_tbl1 = 0xda5a5a5a;
-
- if (mode == BTC_WLINK_5G || rtwdev->btc.dm.freerun) {
- zb_tbl0 = 0xffffffff;
- zb_tbl1 = 0xffffffff;
- } else if (mode == BTC_WLINK_25G_MCC) {
- zb_tbl0 = 0xffffffff; /* for E5G slot */
- zb_tbl1 = 0xda5a5a5a; /* for E2G slot */
- }
- rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_0, zb_tbl0);
- rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_1, zb_tbl1);
-}
-
#define BT_PROFILE_PROTOCOL_MASK GENMASK(7, 4)
static void _update_bt_info(struct rtw89_dev *rtwdev, u8 *buf, u32 len)
@@ -8842,11 +8354,10 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
struct ieee80211_bss_conf *bss_conf;
struct ieee80211_link_sta *link_sta;
struct rtw89_btc *btc = &rtwdev->btc;
- const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_link_info r = {0};
struct rtw89_btc_wl_link_info *wlinfo = NULL;
- u8 mode = 0, rlink_id, link_mode_ori, pta_req_mac_ori, wa_type;
+ u8 mode = 0;
rcu_read_lock();
@@ -8894,66 +8405,32 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], wifi_role=%d\n", rtwvif_link->wifi_role);
- r.role = rtwvif_link->wifi_role;
- r.phy = rtwvif_link->phy_idx;
- r.pid = rtwvif_link->port;
- r.active = true;
- r.connected = MLME_LINKED;
- r.bcn_period = bss_conf->beacon_int;
- r.dtim_period = bss_conf->dtim_period;
- r.band = chan->band_type;
- r.ch = chan->channel;
- r.bw = chan->band_width;
- r.chdef.band = chan->band_type;
- r.chdef.center_ch = chan->channel;
- r.chdef.bw = chan->band_width;
- r.chdef.chan = chan->primary_channel;
+ wlinfo = &wl->rlink_info[rtwvif_link->port][rtwvif_link->phy_idx];
+
+ wlinfo->mode = mode;
+ wlinfo->role = rtwvif_link->wifi_role;
+ wlinfo->phy = rtwvif_link->phy_idx;
+ wlinfo->pid = rtwvif_link->port;
+ wlinfo->active = true;
+ wlinfo->connected = MLME_LINKED;
+ wlinfo->bcn_period = bss_conf->beacon_int;
+ wlinfo->dtim_period = bss_conf->dtim_period;
+ wlinfo->band = chan->band_type;
+ wlinfo->ch = chan->channel;
+ wlinfo->bw = chan->band_width;
+ wlinfo->chdef.band = chan->band_type;
+ wlinfo->chdef.center_ch = chan->channel;
+ wlinfo->chdef.bw = chan->band_width;
+ wlinfo->chdef.chan = chan->primary_channel;
ether_addr_copy(r.mac_addr, rtwvif_link->mac_addr);
rcu_read_unlock();
if (rtwsta_link && vif->type == NL80211_IFTYPE_STATION)
- r.mac_id = rtwsta_link->mac_id;
+ wlinfo->mac_id = rtwsta_link->mac_id;
btc->dm.cnt_notify[BTC_NCNT_ROLE_INFO]++;
- wlinfo = &wl->link_info[r.pid];
-
- if (ver->fwlrole == 0) {
- *wlinfo = r;
- _update_wl_info(rtwdev);
- } else if (ver->fwlrole == 1) {
- *wlinfo = r;
- _update_wl_info_v1(rtwdev);
- } else if (ver->fwlrole == 2) {
- *wlinfo = r;
- _update_wl_info_v2(rtwdev);
- } else if (ver->fwlrole == 7) {
- *wlinfo = r;
- _update_wl_info_v7(rtwdev, r.pid);
- } else if (ver->fwlrole == 8) {
- rlink_id = rtwvif_link->mac_idx;
- wlinfo = &wl->rlink_info[r.pid][rlink_id];
- *wlinfo = r;
- link_mode_ori = wl->role_info_v8.link_mode;
- pta_req_mac_ori = wl->pta_req_mac;
- _update_wl_info_v8(rtwdev, r.pid, rlink_id, state);
-
- if (wl->role_info_v8.link_mode != link_mode_ori) {
- wl->role_info_v8.link_mode_chg = 1;
- if (ver->fcxinit == 7)
- wa_type = btc->mdinfo.md_v7.wa_type;
- else
- wa_type = btc->mdinfo.md.wa_type;
-
- if (wa_type & BTC_WA_HFP_ZB)
- _update_zb_coex_tbl(rtwdev);
- }
-
- if (wl->pta_req_mac != pta_req_mac_ori)
- wl->pta_reg_mac_chg = 1;
- }
-
if (wlinfo->role == RTW89_WIFI_ROLE_STATION &&
wlinfo->connected == MLME_NO_LINK)
btc->dm.leak_ap = 0;
@@ -8967,6 +8444,8 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
state == BTC_ROLE_MSTS_STA_CONN_END)
wl->status.map._4way = false;
+ _update_wl_info(rtwdev, wlinfo);
+
_run_coex(rtwdev, BTC_RSN_NTFY_ROLE_INFO);
}
@@ -9150,15 +8629,14 @@ void __rtw89_btc_ntfy_wl_sta_iter(struct rtw89_vif_link *rtwvif_link,
struct rtw89_dev *rtwdev = iter_data->rtwdev;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
- const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_link_info *link_info = NULL;
struct rtw89_traffic_stats *link_info_t = NULL;
struct rtw89_traffic_stats *stats = &rtwvif->stats;
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc_wl_role_info *r;
- struct rtw89_btc_wl_role_info_v1 *r1;
u32 last_tx_rate, last_rx_rate;
+ u8 link = rtwvif_link->phy_idx;
u16 last_tx_lvl, last_rx_lvl;
u8 port = rtwvif_link->port;
u8 rssi;
@@ -9171,10 +8649,7 @@ void __rtw89_btc_ntfy_wl_sta_iter(struct rtw89_vif_link *rtwvif_link,
rssi = ewma_rssi_read(&rtwsta_link->avg_rssi) >> RSSI_FACTOR;
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], rssi=%d\n", rssi);
- if (btc->ver->fwlrole != 8)
- link_info = &wl->link_info[port];
- else
- link_info = &wl->rlink_info[port][rtwvif_link->mac_idx];
+ link_info = &wl->rlink_info[port][link];
link_info->stat.traffic = *stats;
link_info_t = &link_info->stat.traffic;
@@ -9214,7 +8689,6 @@ void __rtw89_btc_ntfy_wl_sta_iter(struct rtw89_vif_link *rtwvif_link,
else
dir = RTW89_TFC_DL;
- link_info = &wl->link_info[port];
if (link_info->busy != busy || link_info->dir != dir) {
is_sta_change = true;
link_info->busy = busy;
@@ -9244,19 +8718,11 @@ void __rtw89_btc_ntfy_wl_sta_iter(struct rtw89_vif_link *rtwvif_link,
dm->trx_info.rx_rate = link_info_t->rx_rate;
}
- if (ver->fwlrole == 0) {
- r = &wl->role_info;
- r->active_role[port].tx_lvl = stats->tx_tfc_lv;
- r->active_role[port].rx_lvl = stats->rx_tfc_lv;
- r->active_role[port].tx_rate = rtwsta_link->ra_report.hw_rate;
- r->active_role[port].rx_rate = rtwsta_link->rx_hw_rate;
- } else if (ver->fwlrole == 1) {
- r1 = &wl->role_info_v1;
- r1->active_role_v1[port].tx_lvl = stats->tx_tfc_lv;
- r1->active_role_v1[port].rx_lvl = stats->rx_tfc_lv;
- r1->active_role_v1[port].tx_rate = rtwsta_link->ra_report.hw_rate;
- r1->active_role_v1[port].rx_rate = rtwsta_link->rx_hw_rate;
- }
+ r = &wl->role_info;
+ r->rlink[port][link].tx_lvl = stats->tx_tfc_lv;
+ r->rlink[port][link].rx_lvl = stats->rx_tfc_lv;
+ r->rlink[port][link].tx_rate = rtwsta_link->ra_report.hw_rate;
+ r->rlink[port][link].rx_rate = rtwsta_link->rx_hw_rate;
dm->trx_info.tx_lvl = stats->tx_tfc_lv;
dm->trx_info.rx_lvl = stats->rx_tfc_lv;
@@ -9584,10 +9050,7 @@ static int _show_wl_role_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
for (i = 0; i < btc->ver->max_role_num; i++) {
for (j = 0; j < RTW89_MAC_NUM; j++) {
- if (btc->ver->fwlrole == 8)
- plink = &btc->cx.wl.rlink_info[i][j];
- else
- plink = &btc->cx.wl.link_info[i];
+ plink = &btc->cx.wl.rlink_info[i][j];
if (!plink->active)
continue;
@@ -9630,14 +9093,9 @@ static int _show_wl_role_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
static int _show_wl_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
- const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &cx->wl;
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
- struct rtw89_btc_wl_role_info_v1 *wl_rinfo_v1 = &wl->role_info_v1;
- struct rtw89_btc_wl_role_info_v2 *wl_rinfo_v2 = &wl->role_info_v2;
- struct rtw89_btc_wl_role_info_v7 *wl_rinfo_v7 = &wl->role_info_v7;
- struct rtw89_btc_wl_role_info_v8 *wl_rinfo_v8 = &wl->role_info_v8;
char *p = buf, *end = buf + bufsz;
u8 mode;
@@ -9646,18 +9104,7 @@ static int _show_wl_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += scnprintf(p, end - p, "========== [WL Status] ==========\n");
- if (ver->fwlrole == 0)
- mode = wl_rinfo->link_mode;
- else if (ver->fwlrole == 1)
- mode = wl_rinfo_v1->link_mode;
- else if (ver->fwlrole == 2)
- mode = wl_rinfo_v2->link_mode;
- else if (ver->fwlrole == 7)
- mode = wl_rinfo_v7->link_mode;
- else if (ver->fwlrole == 8)
- mode = wl_rinfo_v8->link_mode;
- else
- goto out;
+ mode = wl_rinfo->link_mode;
p += scnprintf(p, end - p, " %-15s : link_mode:%s, ", "[status]",
id_to_linkmode(mode));
@@ -9677,7 +9124,6 @@ static int _show_wl_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += _show_wl_role_info(rtwdev, p, end - p);
-out:
return p - buf;
}
@@ -9755,6 +9201,8 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
union rtw89_btc_module_info *md = &btc->mdinfo;
s8 br_dbm = bt->link_info.bt_txpwr_desc.br_dbm;
s8 le_dbm = bt->link_info.bt_txpwr_desc.le_dbm;
+ u8 hw_band = wl->role_info.pta_req_band;
+ struct rtw89_btc_wl_afh_info *wl_afh;
char *p = buf, *end = buf + bufsz;
u8 *afh = bt_linfo->afh_map;
u8 *afh_le = bt_linfo->afh_map_le;
@@ -9822,8 +9270,9 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
afh_le[0], afh_le[1], afh_le[2],
afh_le[3], afh_le[4]);
- p += scnprintf(p, end - p, "wl_ch_map[en:%d/ch:%d/bw:%d]\n",
- wl->afh_info.en, wl->afh_info.ch, wl->afh_info.bw);
+ wl_afh = &wl->afh_info[hw_band][RTW89_BAND_2G];
+ p += scnprintf(p, end - p, "wl_ch_map[hwb:%d/en:%d/ch:%d/bw:%d/rf_band:%d]\n",
+ hw_band, wl_afh->en, wl_afh->ch, wl_afh->bw, wl_afh->band);
p += scnprintf(p, end - p,
" %-15s : retry:%d, relink:%d, rate_chg:%d, reinit:%d, reenable:%d, ",
diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h
index 74027ca4eccc..c127bd80d31c 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.h
+++ b/drivers/net/wireless/realtek/rtw89/coex.h
@@ -11,6 +11,40 @@
#define BTC_TLV_SLOT_ID_LEN_V7 1
#define BTC_SLOT_REQ_TH 2
+#define BTC_FREQ_W2G 2412
+#define BTC_FREQ_W5G 5005
+#define BTC_FREQ_W6G 5955
+
+#define BTC_FREQ_B2G 2402
+#define BTC_FREQ_B6G 5125
+
+#define BTC_FREQ_W2G_CH14 2484
+
+#define BTC_LO_2G_DNM 125 /* LO Coefficient Denominator */
+#define BTC_LO_5G_DNM 125
+#define BTC_LO_6G_DNM 150
+
+#define BTC_LO_2G_NMR 400 /* LO Coefficient Numerator */
+#define BTC_LO_5G_NMR 200
+#define BTC_LO_6G_NMR 200
+
+#define BTC_CH_W2G_MIN 1 /* start from 2412MHz */
+#define BTC_CH_W2G_MAX 14
+#define BTC_CH_W5G_MIN 1 /* start from 5005MHz */
+#define BTC_CH_W5G_MAX 165
+#define BTC_CH_W6G_MIN 1 /* start from 5955MHz */
+#define BTC_CH_W6G_MAX 233
+
+#define BTC_CH_B2G_MIN 0 /* start from 2402MHz */
+#define BTC_CH_B2G_MAX 78
+
+#define BTC_CH_B5G_MIN 600 /* start from 5725MHz */
+#define BTC_CH_B5G_MAX 1300
+
+#define BTC_VCO_GUARD_W2W 10 /* WiFi to WiFi VCO freq forbiddened range (MHZ) */
+#define BTC_VCO_GUARD_W2B 25 /* WiFi to WiFi VCO freq forbiddened range (MHZ) */
+#define BTC_VCO_GUARD_B2B 10 /* WiFi to WiFi VCO freq forbiddened range (MHZ) */
+
enum btc_mode {
BTC_MODE_NORMAL,
BTC_MODE_WL,
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 174349c6bc58..ded788534651 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1854,7 +1854,7 @@ union rtw89_btc_wl_role_info_map {
struct rtw89_btc_wl_role_info_bpos role;
};
-struct rtw89_btc_wl_role_info { /* struct size must be n*4 bytes */
+struct rtw89_btc_wl_role_info_v0 { /* struct size must be n*4 bytes */
u8 connect_cnt;
u8 link_mode;
union rtw89_btc_wl_role_info_map role_map;
@@ -1891,7 +1891,7 @@ struct rtw89_btc_wl_role_info_v2 { /* struct size must be n*4 bytes */
u32 rsvd: 27;
};
-struct rtw89_btc_wl_rlink { /* H2C info, struct size must be n*4 bytes */
+struct rtw89_btc_wl_rlink_v0 { /* H2C info, struct size must be n*4 bytes */
u8 connected;
u8 pid;
u8 phy;
@@ -1908,6 +1908,28 @@ struct rtw89_btc_wl_rlink { /* H2C info, struct size must be n*4 bytes */
u8 mode; /* wifi protocol */
} __packed;
+struct rtw89_btc_wl_rlink_v10 { /* H2C info, struct size must be n*4 bytes */
+ u8 connected;
+ u8 pid;
+ u8 phy;
+ u8 noa;
+
+ u8 rf_band; /* enum band_type RF band: 2.4G/5G/6G */
+ u8 active; /* 0:rlink is under doze */
+ u8 bw; /* enum channel_width */
+ u8 role; /*enum role_type */
+
+ u8 ch;
+ u8 noa_dur; /* ms */
+ u8 client_cnt; /* for Role = P2P-Go/AP */
+ u8 mode; /* wifi protocol */
+
+ u8 mac_id;
+ u8 rsvd0;
+ u8 rsvd1;
+ u8 rsvd2;
+} __packed;
+
#define RTW89_BE_BTC_WL_MAX_ROLE_NUMBER 6
struct rtw89_btc_wl_role_info_v7 { /* struct size must be n*4 bytes */
u8 connect_cnt;
@@ -1917,12 +1939,12 @@ struct rtw89_btc_wl_role_info_v7 { /* struct size must be n*4 bytes */
struct rtw89_btc_wl_active_role_v7 active_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER];
- u32 role_map;
- u32 mrole_type; /* btc_wl_mrole_type */
- u32 mrole_noa_duration; /* ms */
- u32 dbcc_en;
- u32 dbcc_chg;
- u32 dbcc_2g_phy; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */
+ __le32 role_map;
+ __le32 mrole_type; /* btc_wl_mrole_type */
+ __le32 mrole_noa_duration; /* ms */
+ __le32 dbcc_en;
+ __le32 dbcc_chg;
+ __le32 dbcc_2g_phy; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */
} __packed;
struct rtw89_btc_wl_role_info_v8 { /* H2C info, struct size must be n*4 bytes */
@@ -1936,12 +1958,90 @@ struct rtw89_btc_wl_role_info_v8 { /* H2C info, struct size must be n*4 bytes */
u8 dbcc_chg;
u8 dbcc_2g_phy; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */
+ struct rtw89_btc_wl_rlink_v0 rlink[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM];
+
+ __le32 role_map;
+ __le32 mrole_type; /* btc_wl_mrole_type */
+ __le32 mrole_noa_duration; /* ms */
+} __packed;
+
+struct rtw89_btc_wl_role_info_v10 { /* H2C info, struct size must be n*4 bytes */
+ struct rtw89_btc_wl_rlink_v10 rlink[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM];
+ u8 link_mode;
+ u8 link_mode_hb1;
+ u8 p2p_exist;
+ u8 p2p_exist_hb1;
+
+ u8 pta_req_band;
+ u8 dbcc_en; /* 1+1 and 2.4G-included */
+ u8 dbcc_2g_phy; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */
+ u8 rsvd;
+
+ __le32 role_map;
+ __le32 role_map_hb1;
+ __le32 mrole_type; /* btc_wl_mrole_type: [31:16]:band1, [15:0]:band0 */
+} __packed;
+
+struct rtw89_btc_wl_rlink { /* Logic dynamic using */
+ u8 connected;
+ u8 pid;
+ u8 phy;
+ u8 noa;
+
+ u8 rf_band; /* enum band_type RF band: 2.4G/5G/6G */
+ u8 active; /* 0:rlink is under doze */
+ u8 bw; /* enum channel_width */
+ u8 role; /*enum role_type */
+
+ u8 ch;
+ u8 noa_dur; /* ms */
+ u8 client_cnt; /* for Role = P2P-Go/AP */
+ u8 mode; /* wifi protocol */
+
+ /*v0 v1*/
+ u16 tx_lvl;
+ u16 rx_lvl;
+ u16 tx_rate;
+ u16 rx_rate;
+
+ /* v7 */
+ u8 client_ps; /*v7 v2 v1 v0*/
+
+ /* v10 */
+ u8 mac_id;
+ u8 rsvd0;
+ u8 rsvd1;
+ u8 rsvd2;
+};
+
+struct rtw89_btc_wl_role_info { /* Logic dynamic using */
struct rtw89_btc_wl_rlink rlink[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM];
+ u8 link_mode;
+ u8 link_mode_hb1;
+ u8 p2p_exist;
+ u8 p2p_exist_hb1;
+
+ u8 pta_req_band;
+ u8 dbcc_en; /* 1+1 and 2.4G-included */
+ u8 dbcc_2g_phy; /* which phy operate in 2G, HW_PHY_0 or HW_PHY_1 */
+ u8 rsvd;
u32 role_map;
- u32 mrole_type; /* btc_wl_mrole_type */
- u32 mrole_noa_duration; /* ms */
-} __packed;
+ u32 role_map_hb1;
+ u32 mrole_type; /* btc_wl_mrole_type: [31:16]:band1, [15:0]:band0 */
+
+ /* Before v10 use this linkmode */
+ u8 link_mode_v0;
+
+ /* v7 */
+ u8 connect_cnt;
+ u32 dbcc_chg; /* v7 v2*/
+
+ /* v8 */
+ u8 link_mode_chg; /* v8, v7 v2*/
+ u8 p2p_2g; /* v8, v7 */
+ u32 mrole_noa_duration; /* v8, v7 v2*/
+};
struct rtw89_btc_wl_ver_info {
u32 fw_coex; /* match with which coex_ver */
@@ -1955,7 +2055,7 @@ struct rtw89_btc_wl_afh_info {
u8 en;
u8 ch;
u8 bw;
- u8 rsvd;
+ u8 band;
} __packed;
struct rtw89_btc_wl_rfk_info {
@@ -2167,16 +2267,13 @@ struct rtw89_btc_wl_nhm {
};
struct rtw89_btc_wl_info {
- struct rtw89_btc_wl_link_info link_info[RTW89_PORT_NUM];
struct rtw89_btc_wl_link_info rlink_info[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM];
+ struct rtw89_btc_chdef rf_ch_info[RTW89_PHY_NUM];
struct rtw89_btc_wl_rfk_info rfk_info;
- struct rtw89_btc_wl_ver_info ver_info;
- struct rtw89_btc_wl_afh_info afh_info;
+ struct rtw89_btc_wl_ver_info ver_info;
+ struct rtw89_btc_wl_afh_info afh_info[RTW89_MAC_NUM][RTW89_BAND_NUM];
+ struct rtw89_btc_wl_afh_info afh_info_last[RTW89_MAC_NUM][RTW89_BAND_NUM];
struct rtw89_btc_wl_role_info role_info;
- struct rtw89_btc_wl_role_info_v1 role_info_v1;
- struct rtw89_btc_wl_role_info_v2 role_info_v2;
- struct rtw89_btc_wl_role_info_v7 role_info_v7;
- struct rtw89_btc_wl_role_info_v8 role_info_v8;
struct rtw89_btc_wl_scan_info scan_info;
struct rtw89_btc_wl_dbcc_info dbcc_info;
struct rtw89_btc_wl_mlo_info mlo_info;
@@ -2191,12 +2288,18 @@ struct rtw89_btc_wl_info {
u8 pta_req_mac;
u8 bt_polut_type[RTW89_PHY_NUM]; /* BT polluted WL-Tx type for phy0/1 */
u8 rf_band_map[RTW89_PHY_NUM]; /* rf_band bit-map */
+ u8 ch_map[12];
+ u8 ch_map_le[5];
- bool is_5g_hi_channel;
+ bool is_5g_hi_ch;
+ bool is_5g_hi_ch_hb1;
bool go_client_exist;
+ bool go_client_exist_hb1;
bool noa_exist;
+ bool noa_exist_hb1;
bool pta_reg_mac_chg;
bool bg_mode;
+ bool bg_mode_hb1;
bool he_mode;
bool scbd_chg[BTC_ALL_BT];
bool fw_ver_mismatch;
@@ -3280,6 +3383,14 @@ struct rtw89_btc_fbtc_outsrc_set_info {
u8 rf_gbt_source;
u8 bt_enable_state;
u8 wl_btg_standby_chg;
+ /* bit[15]-> 0:2G/1:5G,6G, bit[14:0]-> WL HWBx ch freq in MHz */
+ /* forbidden group-> bit[1]:fbd rf-band, bit[0]: fbd enable */
+ u8 fbd_group_en[RTW89_MAC_NUM][2]; /* HWB0/1 +.Group0/1 */
+ u16 rf_center_freq[RTW89_MAC_NUM]; /* HWB0/1 */
+ /* forbidden group boundary: [15:8]->UP, [7:0]->LO */
+ u16 fbd_group_bound[RTW89_MAC_NUM][2]; /* HWB0/1 +.Group0/1 */
+ /* 11-bit in MHz, freq diff threshold */
+ u16 freq_diff_thres[RTW89_MAC_NUM][BTC_ALL_BT_EZL]; /* HWB0/1 vs.BT0/1/2 */
} __packed;
union rtw89_btc_fbtc_slot_u {
@@ -3363,6 +3474,7 @@ struct rtw89_btc_dm {
u8 lps_ctrl_change: 1;
u8 scbd_write_instant;
bool scbd_b2w_update;
+ bool pre_agc_chg;
};
struct rtw89_btc_ctrl {
@@ -4961,6 +5073,7 @@ struct rtw89_chip_info {
u8 mailbox;
u8 afh_guard_ch;
+ u16 fdd_iso_freq;
const u8 *wl_rssi_thres;
const u8 *bt_rssi_thres;
u8 rssi_tol;
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 0e7168605850..41c033d2ae7b 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -5922,14 +5922,14 @@ int rtw89_fw_h2c_cxdrv_init_v10(struct rtw89_dev *rtwdev, u8 type)
int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev, u8 type)
{
struct rtw89_btc *btc = &rtwdev->btc;
- const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_role_info *role_info = &wl->role_info;
- struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
- struct rtw89_btc_wl_active_role *active = role_info->active_role;
+ struct rtw89_btc_wl_role_info *r = &wl->role_info;
+ const struct rtw89_btc_ver *ver = btc->ver;
+ struct rtw89_btc_wl_rlink *rl;
struct sk_buff *skb;
- u32 len;
+ u32 rmap = r->role_map;
u8 offset = 0;
+ u32 len;
u8 *cmd;
int ret;
int i;
@@ -5947,36 +5947,37 @@ int rtw89_fw_h2c_cxdrv_role(struct rtw89_dev *rtwdev, u8 type)
RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
- RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
- RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
-
- RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
- RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
- RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
- RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
- RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
- RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
- RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
- RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
- RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
- RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
- RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
- RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
-
- for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
- RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset);
+ RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, r->connect_cnt);
+ RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, r->link_mode);
+
+ RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NONE)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_STATION)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP_VLAN)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC_MASTER)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MESH_POINT)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MONITOR)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_DEVICE)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_CLIENT)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_GO)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NAN)));
+
+ for (i = 0; i < RTW89_PORT_NUM; i++) {
+ rl = &r->rlink[i][RTW89_MAC_0];
+ RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, rl->connected, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, rl->pid, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, rl->phy, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, rl->noa, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, rl->rf_band, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, rl->client_ps, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, rl->bw, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, rl->role, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, rl->ch, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, rl->tx_lvl, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, rl->rx_lvl, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, rl->tx_rate, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, rl->rx_rate, i, offset);
}
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
@@ -6005,12 +6006,12 @@ int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev, u8 type)
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_role_info_v1 *role_info = &wl->role_info_v1;
- struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
- struct rtw89_btc_wl_active_role_v1 *active = role_info->active_role_v1;
+ struct rtw89_btc_wl_role_info *r = &wl->role_info;
+ struct rtw89_btc_wl_rlink *rl;
struct sk_buff *skb;
- u32 len;
+ u32 rmap = r->role_map;
u8 *cmd, offset;
+ u32 len;
int ret;
int i;
@@ -6027,47 +6028,49 @@ int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev, u8 type)
RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
- RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
- RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
-
- RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
- RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
- RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
- RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
- RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
- RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
- RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
- RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
- RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
- RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
- RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
- RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
+ RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, r->connect_cnt);
+ RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, r->link_mode);
+
+ RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NONE)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_STATION)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP_VLAN)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC_MASTER)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MESH_POINT)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MONITOR)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_DEVICE)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_CLIENT)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_GO)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NAN)));
offset = PORT_DATA_OFFSET;
- for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
- RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, active->connected, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, active->pid, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, active->phy, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, active->noa, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, active->band, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, active->client_ps, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, active->bw, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, active->role, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, active->ch, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, active->tx_lvl, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, active->rx_lvl, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, active->tx_rate, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, active->rx_rate, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, active->noa_duration, i, offset);
+
+ for (i = 0; i < RTW89_PORT_NUM; i++) {
+ rl = &r->rlink[i][RTW89_MAC_0];
+ RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED(cmd, rl->connected, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_PID(cmd, rl->pid, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_PHY(cmd, rl->phy, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_NOA(cmd, rl->noa, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_BAND(cmd, rl->rf_band, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS(cmd, rl->client_ps, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_BW(cmd, rl->bw, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_ROLE(cmd, rl->role, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_CH(cmd, rl->ch, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_TX_LVL(cmd, rl->tx_lvl, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_RX_LVL(cmd, rl->rx_lvl, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_TX_RATE(cmd, rl->tx_rate, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_RX_RATE(cmd, rl->rx_rate, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR(cmd, rl->noa_dur, i, offset);
}
offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
- RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset);
- RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset);
- RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset);
- RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset);
- RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset);
- RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset);
+ RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, r->mrole_type, offset);
+ RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, r->mrole_noa_duration, offset);
+ RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, r->dbcc_en, offset);
+ RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, r->dbcc_chg, offset);
+ RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, r->dbcc_2g_phy, offset);
+ RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, r->link_mode_chg, offset);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, BTFC_SET,
@@ -6095,10 +6098,10 @@ int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type)
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_role_info_v2 *role_info = &wl->role_info_v2;
- struct rtw89_btc_wl_role_info_bpos *bpos = &role_info->role_map.role;
- struct rtw89_btc_wl_active_role_v2 *active = role_info->active_role_v2;
+ struct rtw89_btc_wl_role_info *r = &wl->role_info;
+ struct rtw89_btc_wl_rlink *rl;
struct sk_buff *skb;
+ u32 rmap = r->role_map;
u32 len;
u8 *cmd, offset;
int ret;
@@ -6117,43 +6120,45 @@ int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type)
RTW89_SET_FWCMD_CXHDR_TYPE(cmd, type);
RTW89_SET_FWCMD_CXHDR_LEN(cmd, len - H2C_LEN_CXDRVHDR);
- RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, role_info->connect_cnt);
- RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, role_info->link_mode);
-
- RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, bpos->none);
- RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, bpos->station);
- RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, bpos->ap);
- RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, bpos->vap);
- RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, bpos->adhoc);
- RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, bpos->adhoc_master);
- RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, bpos->mesh);
- RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, bpos->moniter);
- RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, bpos->p2p_device);
- RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, bpos->p2p_gc);
- RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, bpos->p2p_go);
- RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, bpos->nan);
+ RTW89_SET_FWCMD_CXROLE_CONNECT_CNT(cmd, r->connect_cnt);
+ RTW89_SET_FWCMD_CXROLE_LINK_MODE(cmd, r->link_mode);
+
+ RTW89_SET_FWCMD_CXROLE_ROLE_NONE(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NONE)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_STA(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_STATION)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_AP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_VAP(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_AP_VLAN)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_ADHOC_MASTER(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_ADHOC_MASTER)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_MESH(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MESH_POINT)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_MONITOR(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_MONITOR)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_DEV(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_DEVICE)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GC(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_CLIENT)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_P2P_GO(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_P2P_GO)));
+ RTW89_SET_FWCMD_CXROLE_ROLE_NAN(cmd, !!(rmap & BIT(RTW89_WIFI_ROLE_NAN)));
offset = PORT_DATA_OFFSET;
- for (i = 0; i < RTW89_PORT_NUM; i++, active++) {
- RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED_V2(cmd, active->connected, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_PID_V2(cmd, active->pid, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_PHY_V2(cmd, active->phy, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_NOA_V2(cmd, active->noa, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_BAND_V2(cmd, active->band, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS_V2(cmd, active->client_ps, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_BW_V2(cmd, active->bw, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_ROLE_V2(cmd, active->role, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_CH_V2(cmd, active->ch, i, offset);
- RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR_V2(cmd, active->noa_duration, i, offset);
+
+ for (i = 0; i < RTW89_PORT_NUM; i++) {
+ rl = &r->rlink[i][RTW89_MAC_0];
+ RTW89_SET_FWCMD_CXROLE_ACT_CONNECTED_V2(cmd, rl->connected, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_PID_V2(cmd, rl->pid, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_PHY_V2(cmd, rl->phy, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_NOA_V2(cmd, rl->noa, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_BAND_V2(cmd, rl->rf_band, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_CLIENT_PS_V2(cmd, rl->client_ps, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_BW_V2(cmd, rl->bw, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_ROLE_V2(cmd, rl->role, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_CH_V2(cmd, rl->ch, i, offset);
+ RTW89_SET_FWCMD_CXROLE_ACT_NOA_DUR_V2(cmd, rl->noa_dur, i, offset);
}
offset = len - H2C_LEN_CXDRVINFO_ROLE_DBCC_LEN;
- RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, role_info->mrole_type, offset);
- RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, role_info->mrole_noa_duration, offset);
- RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, role_info->dbcc_en, offset);
- RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, role_info->dbcc_chg, offset);
- RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, role_info->dbcc_2g_phy, offset);
- RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, role_info->link_mode_chg, offset);
+ RTW89_SET_FWCMD_CXROLE_MROLE_TYPE(cmd, r->mrole_type, offset);
+ RTW89_SET_FWCMD_CXROLE_MROLE_NOA(cmd, r->mrole_noa_duration, offset);
+ RTW89_SET_FWCMD_CXROLE_DBCC_EN(cmd, r->dbcc_en, offset);
+ RTW89_SET_FWCMD_CXROLE_DBCC_CHG(cmd, r->dbcc_chg, offset);
+ RTW89_SET_FWCMD_CXROLE_DBCC_2G_PHY(cmd, r->dbcc_2g_phy, offset);
+ RTW89_SET_FWCMD_CXROLE_LINK_MODE_CHG(cmd, r->link_mode_chg, offset);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, BTFC_SET,
@@ -6175,12 +6180,14 @@ int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type)
int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type)
{
- struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_wl_role_info_v7 *role = &btc->cx.wl.role_info_v7;
+ struct rtw89_btc_wl_role_info *r = &rtwdev->btc.cx.wl.role_info;
struct rtw89_h2c_cxrole_v7 *h2c;
+ struct rtw89_btc_wl_rlink *rl;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
+ __le32 rm;
int ret;
+ u8 i;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
@@ -6190,16 +6197,35 @@ int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type)
skb_put(skb, len);
h2c = (struct rtw89_h2c_cxrole_v7 *)skb->data;
- h2c->hdr.type = type;
- h2c->hdr.ver = btc->ver->fwlrole;
- h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
- memcpy(&h2c->_u8, role, sizeof(h2c->_u8));
- h2c->_u32.role_map = cpu_to_le32(role->role_map);
- h2c->_u32.mrole_type = cpu_to_le32(role->mrole_type);
- h2c->_u32.mrole_noa_duration = cpu_to_le32(role->mrole_noa_duration);
- h2c->_u32.dbcc_en = cpu_to_le32(role->dbcc_en);
- h2c->_u32.dbcc_chg = cpu_to_le32(role->dbcc_chg);
- h2c->_u32.dbcc_2g_phy = cpu_to_le32(role->dbcc_2g_phy);
+ h2c->r.connect_cnt = r->connect_cnt;
+ h2c->r.link_mode = r->link_mode;
+ h2c->r.link_mode_chg = r->link_mode_chg;
+ h2c->r.p2p_2g = r->p2p_2g;
+
+ for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) {
+ rl = &r->rlink[i][RTW89_MAC_0];
+ h2c->r.active_role[i].connected = rl->connected;
+ h2c->r.active_role[i].pid = rl->pid;
+ h2c->r.active_role[i].phy = rl->phy;
+ h2c->r.active_role[i].noa = rl->noa;
+
+ h2c->r.active_role[i].band = rl->rf_band;
+ h2c->r.active_role[i].client_ps = rl->client_ps;
+ h2c->r.active_role[i].bw = rl->bw;
+ h2c->r.active_role[i].role = rl->role;
+
+ h2c->r.active_role[i].ch = rl->ch;
+ h2c->r.active_role[i].noa_dur = rl->noa_dur;
+ h2c->r.active_role[i].client_cnt = rl->client_cnt;
+ }
+
+ rm = cpu_to_le32(r->role_map);
+ memcpy(&h2c->r.role_map, &rm, sizeof(h2c->r.role_map));
+ h2c->r.mrole_type = cpu_to_le32(r->mrole_type);
+ h2c->r.mrole_noa_duration = cpu_to_le32(r->mrole_noa_duration);
+ h2c->r.dbcc_en = cpu_to_le32((u32)r->dbcc_en);
+ h2c->r.dbcc_chg = cpu_to_le32(r->dbcc_chg);
+ h2c->r.dbcc_2g_phy = cpu_to_le32(r->dbcc_2g_phy);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, BTFC_SET,
@@ -6221,12 +6247,14 @@ int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type)
int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type)
{
- struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_wl_role_info_v8 *role = &btc->cx.wl.role_info_v8;
+ struct rtw89_btc_wl_role_info *r = &rtwdev->btc.cx.wl.role_info;
struct rtw89_h2c_cxrole_v8 *h2c;
+ struct rtw89_btc_wl_rlink *rl;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
+ __le32 rm;
int ret;
+ u8 i, j;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
@@ -6237,12 +6265,118 @@ int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type)
h2c = (struct rtw89_h2c_cxrole_v8 *)skb->data;
h2c->hdr.type = type;
- h2c->hdr.ver = btc->ver->fwlrole;
+ h2c->hdr.ver = rtwdev->btc.ver->fwlrole;
+ h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
+ h2c->r.connect_cnt = r->connect_cnt;
+ h2c->r.link_mode = r->link_mode;
+ h2c->r.link_mode_chg = r->link_mode_chg;
+ h2c->r.p2p_2g = r->p2p_2g;
+ h2c->r.pta_req_band = r->pta_req_band;
+ h2c->r.dbcc_en = r->dbcc_en;
+ h2c->r.dbcc_chg = r->dbcc_chg;
+ h2c->r.dbcc_2g_phy = r->dbcc_2g_phy;
+
+ for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) {
+ for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) {
+ rl = &r->rlink[i][j];
+ h2c->r.rlink[i][j].connected = rl->connected;
+ h2c->r.rlink[i][j].pid = rl->pid;
+ h2c->r.rlink[i][j].phy = rl->phy;
+ h2c->r.rlink[i][j].noa = rl->noa;
+
+ h2c->r.rlink[i][j].rf_band = rl->rf_band;
+ h2c->r.rlink[i][j].active = rl->active;
+ h2c->r.rlink[i][j].bw = rl->bw;
+ h2c->r.rlink[i][j].role = rl->role;
+
+ h2c->r.rlink[i][j].ch = rl->ch;
+ h2c->r.rlink[i][j].noa_dur = rl->noa_dur;
+ h2c->r.rlink[i][j].client_cnt = rl->client_cnt;
+ h2c->r.rlink[i][j].mode = rl->mode;
+ }
+ }
+
+ rm = cpu_to_le32(r->role_map);
+ memcpy(&h2c->r.role_map, &rm, sizeof(h2c->r.role_map));
+ h2c->r.mrole_type = cpu_to_le32(r->mrole_type);
+ h2c->r.mrole_noa_duration = cpu_to_le32(r->mrole_noa_duration);
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_OUTSRC, BTFC_SET,
+ SET_DRV_INFO, 0, 0,
+ len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
+int rtw89_fw_h2c_cxdrv_role_v10(struct rtw89_dev *rtwdev, u8 type)
+{
+ struct rtw89_btc_wl_role_info *r = &rtwdev->btc.cx.wl.role_info;
+ struct rtw89_h2c_cxrole_v10 *h2c;
+ struct rtw89_btc_wl_rlink *rl;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ __le32 rm;
+ int ret;
+ u8 i, j;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_role\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_cxrole_v10 *)skb->data;
+
+ h2c->hdr.type = type;
+ h2c->hdr.ver = rtwdev->btc.ver->fwlrole;
h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
- memcpy(&h2c->_u8, role, sizeof(h2c->_u8));
- h2c->_u32.role_map = cpu_to_le32(role->role_map);
- h2c->_u32.mrole_type = cpu_to_le32(role->mrole_type);
- h2c->_u32.mrole_noa_duration = cpu_to_le32(role->mrole_noa_duration);
+
+ for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) {
+ for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) {
+ rl = &r->rlink[i][j];
+ h2c->r.rlink[i][j].connected = rl->connected;
+ h2c->r.rlink[i][j].pid = rl->pid;
+ h2c->r.rlink[i][j].phy = rl->phy;
+ h2c->r.rlink[i][j].noa = rl->noa;
+
+ h2c->r.rlink[i][j].rf_band = rl->rf_band;
+ h2c->r.rlink[i][j].active = rl->active;
+ h2c->r.rlink[i][j].bw = rl->bw;
+ h2c->r.rlink[i][j].role = rl->role;
+
+ h2c->r.rlink[i][j].ch = rl->ch;
+ h2c->r.rlink[i][j].noa_dur = rl->noa_dur;
+ h2c->r.rlink[i][j].client_cnt = rl->client_cnt;
+ h2c->r.rlink[i][j].mode = rl->mode;
+ h2c->r.rlink[i][j].mac_id = rl->mac_id;
+ }
+ }
+
+ h2c->r.link_mode = r->link_mode;
+ h2c->r.link_mode_hb1 = r->link_mode_hb1;
+ h2c->r.p2p_exist = r->p2p_exist;
+ h2c->r.p2p_exist_hb1 = r->p2p_exist_hb1;
+
+ h2c->r.pta_req_band = r->pta_req_band;
+ h2c->r.dbcc_en = r->dbcc_en;
+ h2c->r.dbcc_2g_phy = r->dbcc_2g_phy;
+
+ rm = cpu_to_le32(r->role_map);
+ memcpy(&h2c->r.role_map, &rm, sizeof(h2c->r.role_map));
+ rm = cpu_to_le32(r->role_map_hb1);
+ memcpy(&h2c->r.role_map_hb1, &rm, sizeof(h2c->r.role_map_hb1));
+ h2c->r.mrole_type = cpu_to_le32(r->mrole_type);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, BTFC_SET,
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index af126d15a1fb..1e4267b22b36 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -2433,54 +2433,19 @@ struct rtw89_h2c_cxctrl_v7 {
#define H2C_LEN_CXDRVHDR sizeof(struct rtw89_h2c_cxhdr)
#define H2C_LEN_CXDRVHDR_V7 sizeof(struct rtw89_h2c_cxhdr_v7)
-struct rtw89_btc_wl_role_info_v7_u8 {
- u8 connect_cnt;
- u8 link_mode;
- u8 link_mode_chg;
- u8 p2p_2g;
-
- struct rtw89_btc_wl_active_role_v7 active_role[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER];
-} __packed;
-
-struct rtw89_btc_wl_role_info_v7_u32 {
- __le32 role_map;
- __le32 mrole_type;
- __le32 mrole_noa_duration;
- __le32 dbcc_en;
- __le32 dbcc_chg;
- __le32 dbcc_2g_phy;
-} __packed;
-
struct rtw89_h2c_cxrole_v7 {
struct rtw89_h2c_cxhdr_v7 hdr;
- struct rtw89_btc_wl_role_info_v7_u8 _u8;
- struct rtw89_btc_wl_role_info_v7_u32 _u32;
-} __packed;
-
-struct rtw89_btc_wl_role_info_v8_u8 {
- u8 connect_cnt;
- u8 link_mode;
- u8 link_mode_chg;
- u8 p2p_2g;
-
- u8 pta_req_band;
- u8 dbcc_en;
- u8 dbcc_chg;
- u8 dbcc_2g_phy;
-
- struct rtw89_btc_wl_rlink rlink[RTW89_BE_BTC_WL_MAX_ROLE_NUMBER][RTW89_MAC_NUM];
+ struct rtw89_btc_wl_role_info_v7 r;
} __packed;
-struct rtw89_btc_wl_role_info_v8_u32 {
- __le32 role_map;
- __le32 mrole_type;
- __le32 mrole_noa_duration;
+struct rtw89_h2c_cxrole_v8 {
+ struct rtw89_h2c_cxhdr_v7 hdr;
+ struct rtw89_btc_wl_role_info_v8 r;
} __packed;
-struct rtw89_h2c_cxrole_v8 {
+struct rtw89_h2c_cxrole_v10 {
struct rtw89_h2c_cxhdr_v7 hdr;
- struct rtw89_btc_wl_role_info_v8_u8 _u8;
- struct rtw89_btc_wl_role_info_v8_u32 _u32;
+ struct rtw89_btc_wl_role_info_v10 r;
} __packed;
struct rtw89_h2c_cxosi {
@@ -5413,6 +5378,7 @@ int rtw89_fw_h2c_cxdrv_role_v1(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_role_v2(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type);
+int rtw89_fw_h2c_cxdrv_role_v10(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
index 50480f72c96d..91d6cddc713e 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
@@ -2725,6 +2725,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
.mailbox = 0x1,
.afh_guard_ch = 6,
+ .fdd_iso_freq = 1000,
.wl_rssi_thres = rtw89_btc_8851b_wl_rssi_thres,
.bt_rssi_thres = rtw89_btc_8851b_bt_rssi_thres,
.rssi_tol = 2,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 0c7794742650..ed6dee63694f 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -2464,6 +2464,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
.mailbox = 0x1,
.afh_guard_ch = 6,
+ .fdd_iso_freq = 1000,
.wl_rssi_thres = rtw89_btc_8852a_wl_rssi_thres,
.bt_rssi_thres = rtw89_btc_8852a_bt_rssi_thres,
.rssi_tol = 2,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
index 5904127cc836..4f55a153d169 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
@@ -1060,6 +1060,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
.mailbox = 0x1,
.afh_guard_ch = 6,
+ .fdd_iso_freq = 1000,
.wl_rssi_thres = rtw89_btc_8852b_wl_rssi_thres,
.bt_rssi_thres = rtw89_btc_8852b_bt_rssi_thres,
.rssi_tol = 2,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
index e68f73827fa5..9e0c48fde2fa 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
@@ -898,6 +898,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
.mailbox = 0x1,
.afh_guard_ch = 6,
+ .fdd_iso_freq = 1000,
.wl_rssi_thres = rtw89_btc_8852bt_wl_rssi_thres,
.bt_rssi_thres = rtw89_btc_8852bt_bt_rssi_thres,
.rssi_tol = 2,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index 968666280c89..f21dd87e3846 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -3266,6 +3266,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
.mailbox = 0x1,
.afh_guard_ch = 6,
+ .fdd_iso_freq = 1000,
.wl_rssi_thres = rtw89_btc_8852c_wl_rssi_thres,
.bt_rssi_thres = rtw89_btc_8852c_bt_rssi_thres,
.rssi_tol = 2,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
index fe87b4929ddc..cdcce091b922 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
@@ -3249,6 +3249,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
.mailbox = 0x1,
.afh_guard_ch = 6,
+ .fdd_iso_freq = 1000,
.wl_rssi_thres = rtw89_btc_8922a_wl_rssi_thres,
.bt_rssi_thres = rtw89_btc_8922a_bt_rssi_thres,
.rssi_tol = 2,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index 768434db14c6..aeade858ce95 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -3535,6 +3535,7 @@ const struct rtw89_chip_info rtw8922d_chip_info = {
.mailbox = 0x1,
.afh_guard_ch = 6,
+ .fdd_iso_freq = 1000,
.wl_rssi_thres = rtw89_btc_8922d_wl_rssi_thres,
.bt_rssi_thres = rtw89_btc_8922d_bt_rssi_thres,
.rssi_tol = 2,
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 02/11] wifi: rtw89: coex: Rearrange coexistence control structure
From: Ping-Ke Shih @ 2026-07-12 3:04 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260712030506.43438-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
The control structure will record some Wi-Fi/Bluetooth status, and
packed send to firmware. The new generation chip had offloaded many
mechanism control to firmware, firmware may need update these very
often to make sure run in correct mechanism.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 154 ++++++++++-----------
drivers/net/wireless/realtek/rtw89/core.h | 76 ++++++++--
drivers/net/wireless/realtek/rtw89/debug.c | 6 +-
drivers/net/wireless/realtek/rtw89/fw.c | 63 ++++++++-
drivers/net/wireless/realtek/rtw89/fw.h | 6 +
5 files changed, 207 insertions(+), 98 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index c02de0b4f7bf..72586179ec2c 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -295,10 +295,11 @@ static const struct rtw89_btc_ver rtw89_btc_ver_defs[] = {
static const union rtw89_btc_wl_state_map btc_scanning_map = {
.map = {
.scan = 1,
- .connecting = 1,
+ .dhcp = 1,
.roaming = 1,
- .dbccing = 1,
+ .transacting = 1,
._4way = 1,
+ .handshake = 1,
},
};
@@ -998,8 +999,7 @@ static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type)
if (type & BTC_RESET_CTRL) {
memset(&btc->ctrl, 0, sizeof(btc->ctrl));
btc->manual_ctrl = false;
- if (ver->fcxctrl != 7)
- btc->ctrl.ctrl.trace_step = FCXDEF_STEP;
+ btc->ctrl.trace_step = FCXDEF_STEP;
}
/* Init Coex variables that are not zero */
@@ -1601,7 +1601,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
case BTC_RPT_TYPE_STEP:
pcinfo = &pfwinfo->rpt_fbtc_step.cinfo;
if (ver->fcxctrl != 7)
- trace_step = btc->ctrl.ctrl.trace_step;
+ trace_step = btc->ctrl.trace_step;
if (ver->fcxstep == 2) {
pfinfo = &pfwinfo->rpt_fbtc_step.finfo.v2;
@@ -3542,8 +3542,9 @@ static void _update_btc_state_map(struct rtw89_dev *rtwdev)
struct rtw89_btc_bt_info *bt = &cx->bt0;
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
- if (wl->status.map.connecting || wl->status.map._4way ||
- wl->status.map.roaming || wl->status.map.dbccing) {
+ if (wl->status.map.dhcp || wl->status.map._4way ||
+ wl->status.map.roaming || wl->status.map.transacting ||
+ wl->status.map.handshake) {
cx->state_map = BTC_WLINKING;
} else if (wl->status.map.scan) { /* wl scan */
if (bt_linfo->status.map.inq_pag)
@@ -5883,7 +5884,6 @@ static void rtw89_tx_time_iter(void *data, struct ieee80211_sta *sta)
static void _set_wl_tx_limit(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
- const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_info *wl = &cx->wl;
@@ -5894,19 +5894,14 @@ static void _set_wl_tx_limit(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
struct rtw89_txtime_data data = {.rtwdev = rtwdev};
bool reenable = false;
- u8 igno_bt, tx_retry;
+ u8 tx_retry;
u32 tx_time;
u16 enable;
if (btc->manual_ctrl)
return;
- if (ver->fcxctrl == 7)
- igno_bt = btc->ctrl.ctrl_v7.igno_bt;
- else
- igno_bt = btc->ctrl.ctrl.igno_bt;
-
- if (btc->dm.freerun || igno_bt || b->link_cnt.now == 0 ||
+ if (btc->dm.freerun || btc->ctrl.igno_bt || b->link_cnt.now == 0 ||
dm->tdd_bind.rf_band == BIT(RTW89_BAND_5G) ||
wl_rinfo->link_mode == BTC_WLINK_NOLINK) {
enable = 0;
@@ -6216,7 +6211,7 @@ static void _action_wl_scan(struct rtw89_dev *rtwdev)
struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
if (btc->cx.state_map != BTC_WLINKING &&
- RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw)) {
+ btc->ctrl.wl_ctrl_info.fw_scan) {
_action_wl_25g_mcc(rtwdev);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], Scan offload!\n");
} else if (rtwdev->dbcc_en) {
@@ -7124,11 +7119,13 @@ void rtw89_coex_act1_work(struct wiphy *wiphy, struct wiphy_work *work)
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): enter\n", __func__);
dm->cnt_notify[BTC_NCNT_TIMER]++;
- if (wl->status.map._4way)
- wl->status.map._4way = false;
- if (wl->status.map.connecting)
- wl->status.map.connecting = false;
-
+ if (wl->status.map.handshake ||
+ wl->status.map._4way ||
+ wl->status.map.dhcp) {
+ wl->status.map._4way = 0;
+ wl->status.map.dhcp = 0;
+ wl->status.map.handshake = 0;
+ }
_run_coex(rtwdev, BTC_RSN_ACT1_WORK);
}
@@ -7616,32 +7613,53 @@ static void _set_coex_binding(struct rtw89_btc *btc)
dm->ost_info.bt_enable_state = dm->bt_only ? _bind_is_btonly : val;
}
+static void _update_run_ctrl_info(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ struct rtw89_btc_wl_info *wl = &btc->cx.wl;
+ struct rtw89_btc_ctrl ctrl = btc->ctrl;
+ struct rtw89_fbtc_wl_ctrl_info *wl_ctrl_info = &ctrl.wl_ctrl_info;
+ u8 i;
+
+ ctrl.wl_only = dm->wl_only;
+ ctrl.bt_only = dm->bt_only;
+ ctrl.ntfy_type = dm->run_reason;
+
+ wl_ctrl_info->smap_val = wl->status.val;
+ wl_ctrl_info->rfk_state = wl->rfk_info.state;
+ wl_ctrl_info->rfk_type = wl->rfk_info.type;
+ wl_ctrl_info->client_pstdma_on = dm->client_ps_tdma_on;
+ wl_ctrl_info->fw_scan = wl->scan_info.fw_scan;
+
+ for (i = RTW89_MAC_0; i <= RTW89_MAC_1; i++) {
+ wl_ctrl_info->rf_band_map[i] = wl->rf_band_map[i];
+ wl_ctrl_info->rf_ch[i] = wl->rf_ch_info[i].center_ch;
+ }
+
+ if (!memcmp(&btc->ctrl, &ctrl, sizeof(struct rtw89_btc_ctrl))) {
+ memcpy(&btc->ctrl, &ctrl, sizeof(struct rtw89_btc_ctrl));
+ if (btc->ver->fcxctrl >= 9)
+ _fw_set_drv_info(rtwdev, CXDRVINFO_CTRL);
+ }
+}
+
static
void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
{
struct rtw89_btc *btc = &rtwdev->btc;
- const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
u8 mode = btc->dm.tdd_bind.wl_link_mode;
u8 mode_v0 = wl->role_info.link_mode_v0;
- u8 igno_bt, always_freerun;
lockdep_assert_wiphy(rtwdev->hw->wiphy);
dm->run_reason = reason;
_update_dm_step(rtwdev, reason);
- if (ver->fcxctrl == 7) {
- igno_bt = btc->ctrl.ctrl_v7.igno_bt;
- always_freerun = btc->ctrl.ctrl_v7.always_freerun;
- } else {
- igno_bt = btc->ctrl.ctrl.igno_bt;
- always_freerun = btc->ctrl.ctrl.always_freerun;
- }
-
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): reason=%d, mode=%d\n",
__func__, reason, mode);
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): wl_only=%d, bt_only=%d\n",
@@ -7655,15 +7673,6 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
return;
}
- if (igno_bt &&
- (reason == BTC_RSN_UPDATE_BT_INFO ||
- reason == BTC_RSN_UPDATE_BT_SCBD)) {
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): return for Stop Coex DM!!\n",
- __func__);
- return;
- }
-
if (!wl->status.map.init_ok) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): return for WL init fail!!\n",
@@ -7690,6 +7699,8 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
}
}
+ _update_run_ctrl_info(rtwdev);
+
if (reason == BTC_RSN_NTFY_INIT || reason == BTC_RSN_NTFY_RADIO_STATE)
_update_bt_scbd(rtwdev, false);
@@ -7697,28 +7708,24 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
dm->cnt_dm[BTC_DCNT_RUN]++;
dm->fddt_train = BTC_FDDT_DISABLE;
bt->scan_rx_low_pri = false;
- igno_bt = false;
_set_coex_binding(btc);
_update_btc_state_map(rtwdev);
dm->freerun_chk = _check_freerun(rtwdev); /* check if meet freerun */
- if (always_freerun) {
+ if (btc->ctrl.always_freerun) {
_action_freerun(rtwdev);
- igno_bt = true;
goto exit;
}
if (dm->wl_only) {
_action_wl_only(rtwdev);
- igno_bt = true;
goto exit;
}
if (wl->status.map.rf_off || dm->bt_only || wl->status.map.lps) {
_action_wl_off(rtwdev, mode);
- igno_bt = true;
goto exit;
}
@@ -7827,10 +7834,6 @@ void _run_coex(struct rtw89_dev *rtwdev, enum btc_reason_and_action reason)
exit:
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): exit\n", __func__);
- if (ver->fcxctrl == 7)
- btc->ctrl.ctrl_v7.igno_bt = igno_bt;
- else
- btc->ctrl.ctrl.igno_bt = igno_bt;
_action_common(rtwdev);
}
@@ -7839,7 +7842,6 @@ void rtw89_btc_init(struct rtw89_dev *rtwdev)
const struct rtw89_chip_info *chip = rtwdev->chip;
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- const struct rtw89_btc_ver *ver = btc->ver;
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): Init %s !!\n", __func__,
@@ -7849,10 +7851,6 @@ void rtw89_btc_init(struct rtw89_dev *rtwdev)
btc->dm.run_reason = BTC_RSN_NONE;
btc->dm.run_action = BTC_ACT_NONE;
- if (ver->fcxctrl >= 7)
- btc->ctrl.ctrl_v7.igno_bt = true;
- else
- btc->ctrl.ctrl.igno_bt = true;
wl->status.map.init_ok = true;
}
@@ -7937,7 +7935,6 @@ void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode)
struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
const struct rtw89_chip_info *chip = rtwdev->chip;
- const struct rtw89_btc_ver *ver = btc->ver;
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): mode=%d\n", __func__, mode);
@@ -7948,10 +7945,7 @@ void rtw89_btc_ntfy_init(struct rtw89_dev *rtwdev, u8 mode)
dm->bt_only = mode == BTC_MODE_BT ? 1 : 0;
wl->status.map.rf_off = mode == BTC_MODE_WLOFF ? 1 : 0;
dm->vid = rtwdev->custid;
- if (ver->fcxctrl >= 7)
- btc->ctrl.ctrl_v7.always_freerun = mode == BTC_MODE_COTX;
- else
- btc->ctrl.ctrl.always_freerun = mode == BTC_MODE_COTX;
+ btc->ctrl.always_freerun = mode == BTC_MODE_COTX;
if (!wl->status.map.init_ok) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
@@ -8020,6 +8014,9 @@ void rtw89_btc_ntfy_scan_start(struct rtw89_dev *rtwdev, u8 phy_idx, u8 band)
_fw_set_drv_info(rtwdev, CXDRVINFO_DBCC);
}
+ if (RTW89_CHK_FW_FEATURE(SCAN_OFFLOAD, &rtwdev->fw))
+ btc->ctrl.wl_ctrl_info.fw_scan = 1;
+
_run_coex(rtwdev, BTC_RSN_NTFY_SCAN_START);
}
@@ -8086,14 +8083,18 @@ void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev,
cnt = ++wl->wcnt[BTC_WCNT_DHCP];
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): DHCP cnt=%d\n", __func__, cnt);
- wl->status.map.connecting = true;
+ wl->status.map.handshake = 0;
+ wl->status.map._4way = 0;
+ wl->status.map.dhcp = 1;
delay_work = true;
break;
case PACKET_EAPOL:
cnt = ++wl->wcnt[BTC_WCNT_EAPOL];
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): EAPOL cnt=%d\n", __func__, cnt);
- wl->status.map._4way = true;
+ wl->status.map.handshake = 0;
+ wl->status.map._4way = 1;
+ wl->status.map.dhcp = 0;
delay_work = true;
if (hfp->exist || hid->exist)
delay /= 2;
@@ -8103,7 +8104,7 @@ void rtw89_btc_ntfy_specific_packet(struct rtw89_dev *rtwdev,
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): EAPOL_End cnt=%d\n",
__func__, cnt);
- wl->status.map._4way = false;
+ wl->status.map._4way = 0;
wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_act1_work);
break;
case PACKET_ARP:
@@ -8435,10 +8436,16 @@ void rtw89_btc_ntfy_role_info(struct rtw89_dev *rtwdev,
wlinfo->connected == MLME_NO_LINK)
btc->dm.leak_ap = 0;
- if (state == BTC_ROLE_MSTS_STA_CONN_START)
- wl->status.map.connecting = 1;
- else
- wl->status.map.connecting = 0;
+ if (state == BTC_ROLE_MSTS_STA_CONN_START) {
+ wl->status.map.transacting = 1;
+ wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_act1_work);
+ wiphy_delayed_work_queue(rtwdev->hw->wiphy,
+ &rtwdev->coex_act1_work,
+ RTW89_COEX_ACT1_WORK_PERIOD);
+ } else {
+ wiphy_delayed_work_cancel(rtwdev->hw->wiphy, &rtwdev->coex_act1_work);
+ wl->status.map.transacting = 0;
+ }
if (state == BTC_ROLE_MSTS_STA_DIS_CONN ||
state == BTC_ROLE_MSTS_STA_CONN_END)
@@ -9116,8 +9123,8 @@ static int _show_wl_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
wl->scan_info.band[RTW89_PHY_0], wl->scan_info.phy_map);
p += scnprintf(p, end - p,
- "connecting:%s, roam:%s, 4way:%s, init_ok:%s\n",
- wl->status.map.connecting ? "Y" : "N",
+ "handshake:%s, roam:%s, 4way:%s, init_ok:%s\n",
+ wl->status.map.handshake ? "Y" : "N",
wl->status.map.roaming ? "Y" : "N",
wl->status.map._4way ? "Y" : "N",
wl->status.map.init_ok ? "Y" : "N");
@@ -9718,12 +9725,10 @@ static int _show_dm_step(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
static int _show_dm_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
- const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
char *p = buf, *end = buf + bufsz;
- u8 igno_bt;
if (!(dm->coex_info_map & BTC_COEX_INFO_DM))
return 0;
@@ -9744,14 +9749,9 @@ static int _show_dm_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += _show_dm_step(rtwdev, p, end - p);
- if (ver->fcxctrl == 7)
- igno_bt = btc->ctrl.ctrl_v7.igno_bt;
- else
- igno_bt = btc->ctrl.ctrl.igno_bt;
-
p += scnprintf(p, end - p,
" %-15s : wl_only:%d, bt_only:%d, igno_bt:%d, free_run:%d, wl_ps_ctrl:%d, wl_mimo_ps:%d, ",
- "[dm_flag]", dm->wl_only, dm->bt_only, igno_bt,
+ "[dm_flag]", dm->wl_only, dm->bt_only, btc->ctrl.igno_bt,
dm->freerun, btc->btc_ctrl_lps, dm->wl_mimo_ps);
p += scnprintf(p, end - p, "leak_ap:%d, fw_offload:%s%s\n",
@@ -10742,7 +10742,7 @@ static int _show_fbtc_step_v2(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
if (ver->fcxctrl == 7 || ver->fcxctrl == 1)
trace_step = 50;
else
- trace_step = btc->ctrl.ctrl.trace_step;
+ trace_step = btc->ctrl.trace_step;
n_start = pos_old;
if (pos_new >= pos_old)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index ded788534651..0b20ee7d7a28 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1531,19 +1531,20 @@ enum rtw89_tfc_dir {
struct rtw89_btc_wl_smap {
u32 busy: 1;
u32 scan: 1;
- u32 connecting: 1;
+ u32 dhcp: 1;
u32 roaming: 1;
- u32 dbccing: 1;
+ u32 transacting: 1;
u32 _4way: 1;
+ u32 handshake: 1;
u32 rf_off: 1;
- u32 lps: 2;
- u32 ips: 1;
- u32 init_ok: 1;
- u32 traffic_dir : 2;
u32 rf_off_pre: 1;
+ u32 ips: 1;
+ u32 lps: 2;
u32 lps_pre: 2;
u32 lps_exiting: 1;
u32 emlsr: 1;
+ u32 init_ok: 1;
+ u32 traffic_dir : 2;
};
enum rtw89_tfc_interval {
@@ -1725,7 +1726,9 @@ struct rtw89_btc_u8_sta_chg {
struct rtw89_btc_wl_scan_info {
u8 band[RTW89_PHY_NUM];
u8 phy_map;
- u8 rsvd;
+ u8 hw_band_map;
+ u8 type;
+ u8 fw_scan;
};
struct rtw89_btc_wl_dbcc_info {
@@ -3458,6 +3461,7 @@ struct rtw89_btc_dm {
u8 run_action;
u8 wl_tx_pwr_phy_map;
u8 vid;
+ u8 client_ps_tdma_on;
u8 wl_pre_agc: 2;
u8 wl_lna2: 1;
@@ -3477,13 +3481,38 @@ struct rtw89_btc_dm {
bool pre_agc_chg;
};
+struct rtw89_fbtc_wl_ctrl_info {
+ u8 rf_band_map[RTW89_MAC_NUM];
+ u8 rf_ch[RTW89_MAC_NUM];
+
+ u8 client_pstdma_on;
+ u8 fw_scan;
+ u8 rfk_state;
+ u8 rfk_type;
+
+ u32 smap_val;
+};
+
struct rtw89_btc_ctrl {
+ u32 manual;
+ u32 igno_bt: 1;
+ u32 always_freerun: 1;
+ u32 trace_step: 16;
+
+ u8 wl_only;
+ u8 bt_only;
+
+ u8 ntfy_type;
+ struct rtw89_fbtc_wl_ctrl_info wl_ctrl_info;
+};
+
+struct rtw89_btc_ctrl_v0 {
u32 manual: 1;
u32 igno_bt: 1;
u32 always_freerun: 1;
u32 trace_step: 16;
u32 rsvd: 12;
-};
+} __packed;
struct rtw89_btc_ctrl_v7 {
u8 manual;
@@ -3492,10 +3521,31 @@ struct rtw89_btc_ctrl_v7 {
u8 rsvd;
} __packed;
-union rtw89_btc_ctrl_list {
- struct rtw89_btc_ctrl ctrl;
- struct rtw89_btc_ctrl_v7 ctrl_v7; /* ver 8, 9 is the same */
-};
+struct rtw89_fbtc_wl_ctrl_info_v9 {
+ u8 rf_band_map[RTW89_MAC_NUM];
+ u8 rf_ch[RTW89_MAC_NUM];
+
+ u8 client_pstdma_on;
+ u8 fw_scan;
+ u8 rfk_state;
+ u8 rfk_type;
+
+ __le32 smap_val;
+} __packed;
+
+struct rtw89_btc_ctrl_v9 {
+ u8 manual;
+ u8 always_freerun;
+ u8 wl_only;
+ u8 bt_only;
+
+ u8 ntfy_type;
+ u8 rsvd0;
+ u8 rsvd1;
+ u8 rsvd2;
+
+ struct rtw89_fbtc_wl_ctrl_info_v9 wl_ctrl_info;
+} __packed;
struct rtw89_btc_dbg {
/* cmd "rb" */
@@ -3701,7 +3751,7 @@ struct rtw89_btc {
struct rtw89_btc_cx cx;
struct rtw89_btc_dm dm;
- union rtw89_btc_ctrl_list ctrl;
+ struct rtw89_btc_ctrl ctrl;
union rtw89_btc_module_info mdinfo;
struct rtw89_btc_btf_fwinfo fwinfo;
struct rtw89_btc_dbg dbg;
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index e42dc5707576..8b41991963e8 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -3900,17 +3900,13 @@ static ssize_t rtw89_debug_priv_btc_manual_set(struct rtw89_dev *rtwdev,
const char *buf, size_t count)
{
struct rtw89_btc *btc = &rtwdev->btc;
- const struct rtw89_btc_ver *ver = btc->ver;
int ret;
ret = kstrtobool(buf, &btc->manual_ctrl);
if (ret)
return ret;
- if (ver->fcxctrl == 7)
- btc->ctrl.ctrl_v7.manual = btc->manual_ctrl;
- else
- btc->ctrl.ctrl.manual = btc->manual_ctrl;
+ btc->ctrl.manual = btc->manual_ctrl;
return count;
}
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 41c033d2ae7b..59e51e67d51b 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -6441,7 +6441,7 @@ int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type)
{
struct rtw89_btc *btc = &rtwdev->btc;
const struct rtw89_btc_ver *ver = btc->ver;
- struct rtw89_btc_ctrl *ctrl = &btc->ctrl.ctrl;
+ struct rtw89_btc_ctrl *ctrl = &btc->ctrl;
struct sk_buff *skb;
u8 *cmd;
int ret;
@@ -6484,7 +6484,7 @@ int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type)
int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_ctrl_v7 *ctrl = &btc->ctrl.ctrl_v7;
+ struct rtw89_btc_ctrl *ctrl = &btc->ctrl;
struct rtw89_h2c_cxctrl_v7 *h2c;
u32 len = sizeof(*h2c);
struct sk_buff *skb;
@@ -6501,7 +6501,64 @@ int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type)
h2c->hdr.type = type;
h2c->hdr.ver = btc->ver->fcxctrl;
h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7;
- h2c->ctrl = *ctrl;
+
+ h2c->ctrl.manual = ctrl->manual;
+ h2c->ctrl.igno_bt = ctrl->igno_bt;
+ h2c->ctrl.always_freerun = ctrl->always_freerun;
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_OUTSRC, BTFC_SET,
+ SET_DRV_INFO, 0, 0, len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
+int rtw89_fw_h2c_cxdrv_ctrl_v9(struct rtw89_dev *rtwdev, u8 type)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_ctrl *ctrl = &btc->ctrl;
+ struct rtw89_fbtc_wl_ctrl_info_v9 *cinfo;
+ struct rtw89_h2c_cxctrl_v9 *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ int ret;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_ctrl_v7\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_cxctrl_v9 *)skb->data;
+ cinfo = &h2c->ctrl.wl_ctrl_info;
+
+ h2c->hdr.type = type;
+ h2c->hdr.ver = btc->ver->fcxctrl;
+ h2c->hdr.len = sizeof(*h2c) - H2C_LEN_CXDRVHDR_V7;
+
+ h2c->ctrl.manual = ctrl->manual;
+ h2c->ctrl.always_freerun = ctrl->always_freerun;
+ h2c->ctrl.wl_only = ctrl->wl_only;
+ h2c->ctrl.bt_only = ctrl->bt_only;
+ h2c->ctrl.ntfy_type = ctrl->ntfy_type;
+ memcpy(cinfo->rf_band_map, ctrl->wl_ctrl_info.rf_band_map,
+ sizeof(cinfo->rf_band_map));
+ memcpy(cinfo->rf_ch, ctrl->wl_ctrl_info.rf_ch, sizeof(cinfo->rf_ch));
+ cinfo->client_pstdma_on = ctrl->wl_ctrl_info.client_pstdma_on;
+ cinfo->fw_scan = ctrl->wl_ctrl_info.fw_scan;
+ cinfo->rfk_state = ctrl->wl_ctrl_info.rfk_state;
+ cinfo->rfk_type = ctrl->wl_ctrl_info.rfk_type;
+ cinfo->smap_val = cpu_to_le32(ctrl->wl_ctrl_info.smap_val);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, BTFC_SET,
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 1e4267b22b36..72f56d32e3b0 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -2430,6 +2430,11 @@ struct rtw89_h2c_cxctrl_v7 {
struct rtw89_btc_ctrl_v7 ctrl;
} __packed;
+struct rtw89_h2c_cxctrl_v9 {
+ struct rtw89_h2c_cxhdr_v7 hdr;
+ struct rtw89_btc_ctrl_v9 ctrl;
+} __packed;
+
#define H2C_LEN_CXDRVHDR sizeof(struct rtw89_h2c_cxhdr)
#define H2C_LEN_CXDRVHDR_V7 sizeof(struct rtw89_h2c_cxhdr_v7)
@@ -5382,6 +5387,7 @@ int rtw89_fw_h2c_cxdrv_role_v10(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type);
+int rtw89_fw_h2c_cxdrv_ctrl_v9(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_trx_v7(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_trx_v9(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_rfk(struct rtw89_dev *rtwdev, u8 type);
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 03/11] wifi: rtw89: coex: Update driver outsource info to firmware version 6
From: Ping-Ke Shih @ 2026-07-12 3:04 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260712030506.43438-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
In order to make dual MAC Wi-Fi performance more stable, and take effect
in time, offload more register/ hardware control to firmware.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 13 ++-
drivers/net/wireless/realtek/rtw89/core.h | 89 +++++++++++++++++--
drivers/net/wireless/realtek/rtw89/fw.c | 101 +++++++++++++++++++++-
drivers/net/wireless/realtek/rtw89/fw.h | 8 +-
4 files changed, 199 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 72586179ec2c..78360e73d959 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -2923,7 +2923,12 @@ static void _fw_set_drv_info(struct rtw89_dev *rtwdev, u8 index)
else
return;
- rtw89_fw_h2c_cxdrv_osi_info(rtwdev, index);
+ if (ver->fcxosi == 1)
+ rtw89_fw_h2c_cxdrv_osi_info(rtwdev, index);
+ else if (ver->fcxosi == 6)
+ rtw89_fw_h2c_cxdrv_osi_info_v6(rtwdev, index);
+ else
+ return;
break;
default:
break;
@@ -3090,7 +3095,11 @@ static void _set_gnt_v1(struct rtw89_dev *rtwdev, u8 phy_map,
}
memcpy(osi->gnt_set, dm->gnt.band, sizeof(osi->gnt_set));
- memcpy(osi->wlact_set, dm->gnt.bt, sizeof(osi->wlact_set));
+
+ for (i = 0; i < BTC_ALL_BT; i++) {
+ osi->wlact_set[i].wlan_act_en = dm->gnt.bt[i].wlan_act_en;
+ osi->wlact_set[i].wlan_act = dm->gnt.bt[i].wlan_act;
+ }
/* GBT source should be GBT_S1 in 1+1 (HWB0:5G + HWB1:2G) case */
if (osi->rf_band[BTC_RF_S0] == 1 &&
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 0b20ee7d7a28..676d3ba855d7 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1322,6 +1322,17 @@ struct rtw89_mac_ax_gnt {
u8 gnt_wl;
} __packed;
+struct rtw89_btc_gnt_ctrl {
+ u8 gnt_zb_sw_en;
+ u8 gnt_zb;
+ u8 gnt_bt1_sw_en;
+ u8 gnt_bt1;
+ u8 gnt_bt0_sw_en;
+ u8 gnt_bt0;
+ u8 gnt_wl_sw_en;
+ u8 gnt_wl;
+} __packed;
+
struct rtw89_mac_ax_wl_act {
u8 wlan_act_en;
u8 wlan_act;
@@ -3374,27 +3385,89 @@ enum btc_rf_path {
BTC_RF_NUM,
};
-struct rtw89_btc_fbtc_outsrc_set_info {
- u8 rf_band[BTC_RF_NUM]; /* 0:2G, 1:non-2G */
+struct rtw89_btc_fbtc_outsrc_set_info_v1 {
+ u8 rf_band[BTC_RF_NUM];
u8 btg_rx[BTC_RF_NUM];
u8 nbtg_tx[BTC_RF_NUM];
- struct rtw89_mac_ax_gnt gnt_set[BTC_RF_NUM]; /* refer to btc_gnt_ctrl */
- struct rtw89_mac_ax_wl_act wlact_set[BTC_RF_NUM]; /* BT0/BT1 */
+ struct rtw89_mac_ax_gnt gnt_set[BTC_RF_NUM];
+ struct rtw89_mac_ax_wl_act wlact_set[BTC_ALL_BT];
u8 pta_req_hw_band;
u8 rf_gbt_source;
u8 bt_enable_state;
u8 wl_btg_standby_chg;
- /* bit[15]-> 0:2G/1:5G,6G, bit[14:0]-> WL HWBx ch freq in MHz */
+
+ u8 fbd_group_en[RTW89_MAC_NUM][2];
+ __le16 rf_center_freq[RTW89_MAC_NUM];
+ __le16 fbd_group_bound[RTW89_MAC_NUM][2];
+ __le16 freq_diff_thres[RTW89_MAC_NUM][BTC_ALL_BT];
+} __packed;
+
+struct rtw89_btc_fbtc_outsrc_set_info_v6 {
+ u8 rf_band[BTC_RF_NUM];
+ u8 btg_rx[BTC_RF_NUM];
+ u8 nbtg_tx[BTC_RF_NUM];
+
+ struct rtw89_btc_gnt_ctrl gnt_set[RTW89_MAC_AX_COEX_GNT_NR];
+ struct rtw89_mac_ax_wl_act wlact_set[BTC_ALL_BT_EZL];
+
+ u8 pta_req_hw_band;
+ u8 rf_gbt_source;
+ u8 bt_enable_state;
+ u8 bt_plut_type;
+ u8 wl_tx_limit_en;
+ u8 fc_exec;
+ u8 wl_btg_standby_chg;
+ u8 rsvd;
+ u8 bb_path_sel_bt[BTC_RF_NUM];
+ u8 bb_phy_sel_bt[RTW89_PHY_NUM];
+ u8 fbd_group_en[RTW89_MAC_NUM][2];
+ __le16 rf_center_freq[RTW89_MAC_NUM];
+ __le16 freq_diff_thres[RTW89_MAC_NUM][BTC_ALL_BT_EZL];
+ __le16 fbd_group_bound[RTW89_MAC_NUM][2];
+ __le32 wl_tx_limit_time;
+} __packed;
+
+struct rtw89_btc_fbtc_outsrc_set_info {
+ u8 rf_band[BTC_RF_NUM]; /* 0:2GHz/1:5GHz for MPI_bb_hwsi_ignore_gnt_wl() */
+ u8 btg_rx[BTC_RF_NUM]; /* for MPI_bb_btg_bt_rx() */
+ u8 nbtg_tx[BTC_RF_NUM]; /* for MPI_bb_nbtg_bt_tx pre=AGC control */
+
+ struct rtw89_mac_ax_gnt gnt_set[BTC_RF_NUM]; /* refer to btc_gnt_ctrl */
+ struct rtw89_btc_gnt_ctrl gnt_set_be[RTW89_MAC_AX_COEX_GNT_NR];
+ struct rtw89_mac_ax_wl_act wlact_set[BTC_ALL_BT_EZL];
+
+ u8 pta_req_hw_band; /* Bind PTA to HWB0 or HWB1, only for 8922a 1-PTA */
+ u8 rf_gbt_source; /* gbt from S0 or S1 for RF 0x2[9], only for 8922a */
+
+ /* The followngs are for 8922c/d new Multi-PTA design */
+ /* 0:BT0/1:BT1/2:ZB on/off for MAC(0xe580[0]/0xe680[0])/ RF 0x4[3:2] */
+ u8 bt_enable_state;
+ u8 bt_plut_type; /* BT polluted type, refer to enum btc_plt_map */
+
+ u8 wl_tx_limit_en;
+ u8 fc_exec;
+ u8 wl_btg_standby_chg; /* keep RX-IQGen on in standby mode */
+ u8 rsvd;
+
+ u8 bb_path_sel_bt[BTC_RF_NUM]; /* bb s0(1) select GNT_BT0 or BT1 */
+ u8 bb_phy_sel_bt[RTW89_PHY_NUM]; /* bb phy0(1) select GNT_BT0 or BT1 */
+
/* forbidden group-> bit[1]:fbd rf-band, bit[0]: fbd enable */
u8 fbd_group_en[RTW89_MAC_NUM][2]; /* HWB0/1 +.Group0/1 */
+
+ /* bit[15]-> 0:2G/1:5G,6G, bit[14:0]-> WL HWBx ch freq in MHz */
u16 rf_center_freq[RTW89_MAC_NUM]; /* HWB0/1 */
- /* forbidden group boundary: [15:8]->UP, [7:0]->LO */
- u16 fbd_group_bound[RTW89_MAC_NUM][2]; /* HWB0/1 +.Group0/1 */
+
/* 11-bit in MHz, freq diff threshold */
u16 freq_diff_thres[RTW89_MAC_NUM][BTC_ALL_BT_EZL]; /* HWB0/1 vs.BT0/1/2 */
-} __packed;
+
+ /* forbidden group boundary: [15:8]->UP, [7:0]->LO */
+ u16 fbd_group_bound[RTW89_MAC_NUM][2]; /* HWB0/1 +.Group0/1 */
+
+ u32 wl_tx_limit_time;
+};
union rtw89_btc_fbtc_slot_u {
struct rtw89_btc_fbtc_slot v1[CXST_MAX];
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 59e51e67d51b..027f8121efd1 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -6404,6 +6404,7 @@ int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type)
u32 len = sizeof(*h2c);
struct sk_buff *skb;
int ret;
+ u8 i, j;
skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
if (!skb) {
@@ -6416,7 +6417,105 @@ int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type)
h2c->hdr.type = type;
h2c->hdr.ver = btc->ver->fcxosi;
h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
- h2c->osi = *osi;
+
+ memcpy(h2c->osi.rf_band, osi->rf_band, sizeof(osi->rf_band));
+ memcpy(h2c->osi.btg_rx, osi->btg_rx, sizeof(osi->btg_rx));
+ memcpy(h2c->osi.nbtg_tx, osi->nbtg_tx, sizeof(osi->nbtg_tx));
+
+ for (i = 0; i < BTC_RF_NUM; i++) {
+ h2c->osi.gnt_set[i] = osi->gnt_set[i];
+ h2c->osi.wlact_set[i] = osi->wlact_set[i];
+ }
+
+ h2c->osi.pta_req_hw_band = osi->pta_req_hw_band;
+ h2c->osi.rf_gbt_source = osi->rf_gbt_source;
+ h2c->osi.bt_enable_state = osi->bt_enable_state;
+ h2c->osi.wl_btg_standby_chg = osi->wl_btg_standby_chg;
+
+ memcpy(h2c->osi.fbd_group_en, osi->fbd_group_en, sizeof(osi->fbd_group_en));
+
+ for (i = 0; i < RTW89_MAC_NUM; i++) {
+ h2c->osi.rf_center_freq[i] = cpu_to_le16(osi->rf_center_freq[i]);
+ for (j = 0; j < BTC_RF_NUM; j++)
+ h2c->osi.fbd_group_bound[i][j] = cpu_to_le16(osi->fbd_group_bound[i][j]);
+ }
+
+ for (i = 0; i < RTW89_MAC_NUM; i++) {
+ for (j = 0; j < BTC_ALL_BT; j++)
+ h2c->osi.freq_diff_thres[i][j] = cpu_to_le16(osi->freq_diff_thres[i][j]);
+ }
+
+ rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
+ H2C_CAT_OUTSRC, BTFC_SET,
+ SET_DRV_INFO, 0, 0,
+ len);
+
+ ret = rtw89_h2c_tx(rtwdev, skb, false);
+ if (ret) {
+ rtw89_err(rtwdev, "failed to send h2c\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ dev_kfree_skb_any(skb);
+
+ return ret;
+}
+
+int rtw89_fw_h2c_cxdrv_osi_info_v6(struct rtw89_dev *rtwdev, u8 type)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_fbtc_outsrc_set_info *osi = &btc->dm.ost_info;
+ struct rtw89_h2c_cxosi_v6 *h2c;
+ u32 len = sizeof(*h2c);
+ struct sk_buff *skb;
+ int ret;
+ u8 i, j;
+
+ skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, len);
+ if (!skb) {
+ rtw89_err(rtwdev, "failed to alloc skb for h2c cxdrv_osi_v6\n");
+ return -ENOMEM;
+ }
+ skb_put(skb, len);
+ h2c = (struct rtw89_h2c_cxosi_v6 *)skb->data;
+
+ h2c->hdr.type = type;
+ h2c->hdr.ver = btc->ver->fcxosi;
+ h2c->hdr.len = len - H2C_LEN_CXDRVHDR_V7;
+
+ memcpy(h2c->osi.rf_band, osi->rf_band, sizeof(osi->rf_band));
+ memcpy(h2c->osi.btg_rx, osi->btg_rx, sizeof(osi->btg_rx));
+ memcpy(h2c->osi.nbtg_tx, osi->nbtg_tx, sizeof(osi->nbtg_tx));
+ memcpy(h2c->osi.gnt_set, osi->gnt_set, sizeof(osi->gnt_set));
+ memcpy(h2c->osi.wlact_set, osi->wlact_set, sizeof(osi->wlact_set));
+
+ h2c->osi.pta_req_hw_band = osi->pta_req_hw_band;
+ h2c->osi.rf_gbt_source = osi->rf_gbt_source;
+ h2c->osi.bt_enable_state = osi->bt_enable_state;
+ h2c->osi.bt_plut_type = osi->bt_plut_type;
+ h2c->osi.wl_tx_limit_en = osi->wl_tx_limit_en;
+ h2c->osi.fc_exec = osi->fc_exec;
+ h2c->osi.wl_btg_standby_chg = osi->wl_btg_standby_chg;
+ h2c->osi.rsvd = osi->rsvd;
+
+ memcpy(h2c->osi.bb_path_sel_bt, osi->bb_path_sel_bt, sizeof(osi->bb_path_sel_bt));
+ memcpy(h2c->osi.bb_phy_sel_bt, osi->bb_phy_sel_bt, sizeof(osi->bb_phy_sel_bt));
+ memcpy(h2c->osi.fbd_group_en, osi->fbd_group_en, sizeof(osi->fbd_group_en));
+
+ for (i = 0; i < RTW89_MAC_NUM; i++) {
+ h2c->osi.rf_center_freq[i] = cpu_to_le16(osi->rf_center_freq[i]);
+ for (j = 0; j < BTC_RF_NUM; j++)
+ h2c->osi.fbd_group_bound[i][j] = cpu_to_le16(osi->fbd_group_bound[i][j]);
+ }
+
+ for (i = 0; i < RTW89_MAC_NUM; i++) {
+ for (j = 0; j < BTC_ALL_BT_EZL; j++)
+ h2c->osi.freq_diff_thres[i][j] = cpu_to_le16(osi->freq_diff_thres[i][j]);
+ }
+
+ h2c->osi.wl_tx_limit_time = cpu_to_le32(osi->wl_tx_limit_time);
rtw89_h2c_pkt_set_hdr(rtwdev, skb, FWCMD_TYPE_H2C,
H2C_CAT_OUTSRC, BTFC_SET,
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index 72f56d32e3b0..c6131778f6a2 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -2455,7 +2455,12 @@ struct rtw89_h2c_cxrole_v10 {
struct rtw89_h2c_cxosi {
struct rtw89_h2c_cxhdr_v7 hdr;
- struct rtw89_btc_fbtc_outsrc_set_info osi;
+ struct rtw89_btc_fbtc_outsrc_set_info_v1 osi;
+} __packed;
+
+struct rtw89_h2c_cxosi_v6 {
+ struct rtw89_h2c_cxhdr_v7 hdr;
+ struct rtw89_btc_fbtc_outsrc_set_info_v6 osi;
} __packed;
struct rtw89_h2c_cxinit {
@@ -5385,6 +5390,7 @@ int rtw89_fw_h2c_cxdrv_role_v7(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_role_v8(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_role_v10(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_osi_info(struct rtw89_dev *rtwdev, u8 type);
+int rtw89_fw_h2c_cxdrv_osi_info_v6(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl_v7(struct rtw89_dev *rtwdev, u8 type);
int rtw89_fw_h2c_cxdrv_ctrl_v9(struct rtw89_dev *rtwdev, u8 type);
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 04/11] wifi: rtw89: ceox: Update antenna & grant signal setting
From: Ping-Ke Shih @ 2026-07-12 3:04 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260712030506.43438-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
Merge set antenna & grant signal logic. Combine all information to big
structure for runtime logic using, only separate to version format while
it is going to assign value to register or offload to firmware. Add new
format for dual-BT & external BT for RTL8922D.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 501 ++++++++------------
drivers/net/wireless/realtek/rtw89/core.h | 4 +-
drivers/net/wireless/realtek/rtw89/mac.c | 27 +-
drivers/net/wireless/realtek/rtw89/mac_be.c | 21 +-
4 files changed, 216 insertions(+), 337 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 78360e73d959..2ca6090e9f62 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -492,7 +492,7 @@ enum btc_ant_phase {
BTC_ANT_WONLY,
BTC_ANT_WOFF,
BTC_ANT_W2G,
- BTC_ANT_W5G,
+ BTC_ANT_FDD,
BTC_ANT_W25G,
BTC_ANT_FREERUN,
BTC_ANT_WRFK,
@@ -841,7 +841,9 @@ enum btc_gnt_state {
BTC_GNT_HW = 0,
BTC_GNT_SW_LO,
BTC_GNT_SW_HI,
- BTC_GNT_MAX
+ BTC_GNT_MAX,
+
+ BTC_GNT_SET_SKIP = 0xff,
};
enum btc_ctr_path {
@@ -1787,8 +1789,8 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
dm->wl_fw_cx_offload = !!le32_to_cpu(prpt->v4.wl_fw_info.cx_offload);
for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++)
- memcpy(&dm->gnt.band[i], &prpt->v4.gnt_val[i],
- sizeof(dm->gnt.band[i]));
+ memcpy(&dm->gnt_set[i], &prpt->v4.gnt_val[i],
+ sizeof(dm->gnt_set[i]));
bt->bcnt[BTC_BCNT_HIPRI_TX] =
le32_to_cpu(prpt->v4.bt_cnt[BTC_BCNT_HI_TX]);
@@ -1819,8 +1821,8 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
dm->wl_fw_cx_offload = 0;
for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++)
- memcpy(&dm->gnt.band[i], &prpt->v5.gnt_val[i][0],
- sizeof(dm->gnt.band[i]));
+ memcpy(&dm->gnt_set[i], &prpt->v5.gnt_val[i],
+ sizeof(dm->gnt_set[i]));
bt->bcnt[BTC_BCNT_HIPRI_TX] =
le16_to_cpu(prpt->v5.bt_cnt[BTC_BCNT_HI_TX]);
@@ -1846,8 +1848,8 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
dm->wl_fw_cx_offload = 0;
for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++)
- memcpy(&dm->gnt.band[i], &prpt->v105.gnt_val[i][0],
- sizeof(dm->gnt.band[i]));
+ memcpy(&dm->gnt_set[i], &prpt->v105.gnt_val[i],
+ sizeof(dm->gnt_set[i]));
bt->bcnt[BTC_BCNT_HIPRI_TX] =
le16_to_cpu(prpt->v105.bt_cnt[BTC_BCNT_HI_TX_V105]);
@@ -1872,8 +1874,8 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
wl->ver_info.fw = le32_to_cpu(prpt->v7.rpt_info.fw_ver);
for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++)
- memcpy(&dm->gnt.band[i], &prpt->v7.gnt_val[i][0],
- sizeof(dm->gnt.band[i]));
+ memcpy(&dm->gnt_set[i], &prpt->v7.gnt_val[i],
+ sizeof(dm->gnt_set[i]));
bt->bcnt[BTC_BCNT_HIPRI_TX] =
le16_to_cpu(prpt->v7.bt_cnt[BTC_BCNT_HI_TX_V105]);
@@ -1904,8 +1906,8 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
wl->ver_info.fw = le32_to_cpu(prpt->v8.rpt_info.fw_ver);
for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++)
- memcpy(&dm->gnt.band[i], &prpt->v8.gnt_val[i][0],
- sizeof(dm->gnt.band[i]));
+ memcpy(&dm->gnt_set[i], &prpt->v8.gnt_val[i],
+ sizeof(dm->gnt_set[i]));
bt->bcnt[BTC_BCNT_HIPRI_TX] =
le16_to_cpu(prpt->v8.bt_cnt[BTC_BCNT_HI_TX_V105]);
@@ -2971,11 +2973,14 @@ void btc_fw_event(struct rtw89_dev *rtwdev, u8 evt_id, void *data, u32 len)
btc->dm.scbd_b2w_update = 0;
}
-static void _set_gnt(struct rtw89_dev *rtwdev, u8 phy_map, u8 wl_state, u8 bt_state)
+static void _set_gnt(struct rtw89_dev *rtwdev, u8 phy_map,
+ u8 wl_state, u8 bt_state, u8 wlact_state)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_dm *dm = &btc->dm;
- struct rtw89_mac_ax_gnt *g = dm->gnt.band;
+ struct rtw89_btc_fbtc_outsrc_set_info *o = &dm->ost_info;
+ struct rtw89_mac_ax_wl_act *wlact_set;
+ struct rtw89_mac_ax_coex_gnt mg;
u8 i;
if (phy_map > BTC_PHY_ALL)
@@ -2987,126 +2992,118 @@ static void _set_gnt(struct rtw89_dev *rtwdev, u8 phy_map, u8 wl_state, u8 bt_st
switch (wl_state) {
case BTC_GNT_HW:
- g[i].gnt_wl_sw_en = 0;
- g[i].gnt_wl = 0;
+ dm->gnt_set[i].gnt_wl_sw_en = 0;
+ dm->gnt_set[i].gnt_wl = 0;
break;
case BTC_GNT_SW_LO:
- g[i].gnt_wl_sw_en = 1;
- g[i].gnt_wl = 0;
+ dm->gnt_set[i].gnt_wl_sw_en = 1;
+ dm->gnt_set[i].gnt_wl = 0;
break;
case BTC_GNT_SW_HI:
- g[i].gnt_wl_sw_en = 1;
- g[i].gnt_wl = 1;
+ dm->gnt_set[i].gnt_wl_sw_en = 1;
+ dm->gnt_set[i].gnt_wl = 1;
+ break;
+ case BTC_GNT_SET_SKIP:
+ default:
break;
}
switch (bt_state) {
case BTC_GNT_HW:
- g[i].gnt_bt_sw_en = 0;
- g[i].gnt_bt = 0;
+ dm->gnt_set[i].gnt_bt0_sw_en = 0;
+ dm->gnt_set[i].gnt_bt0 = 0;
+ dm->gnt_set[i].gnt_bt1_sw_en = 0;
+ dm->gnt_set[i].gnt_bt1 = 0;
+ dm->gnt_set[i].gnt_zb_sw_en = 0;
+ dm->gnt_set[i].gnt_zb = 0;
break;
case BTC_GNT_SW_LO:
- g[i].gnt_bt_sw_en = 1;
- g[i].gnt_bt = 0;
+ dm->gnt_set[i].gnt_bt0_sw_en = 1;
+ dm->gnt_set[i].gnt_bt0 = 0;
+ dm->gnt_set[i].gnt_bt1_sw_en = 1;
+ dm->gnt_set[i].gnt_bt1 = 0;
+ dm->gnt_set[i].gnt_zb_sw_en = 1;
+ dm->gnt_set[i].gnt_zb = 0;
break;
case BTC_GNT_SW_HI:
- g[i].gnt_bt_sw_en = 1;
- g[i].gnt_bt = 1;
+ dm->gnt_set[i].gnt_bt0_sw_en = 1;
+ dm->gnt_set[i].gnt_bt0 = 1;
+ dm->gnt_set[i].gnt_bt1_sw_en = 1;
+ dm->gnt_set[i].gnt_bt1 = 1;
+ dm->gnt_set[i].gnt_zb_sw_en = 1;
+ dm->gnt_set[i].gnt_zb = 1;
+ break;
+ case BTC_GNT_SET_SKIP:
+ default:
break;
}
}
- rtw89_chip_mac_cfg_gnt(rtwdev, &dm->gnt);
-}
-
-static void _set_gnt_v1(struct rtw89_dev *rtwdev, u8 phy_map,
- u8 wl_state, u8 bt_state, u8 wlact_state)
-{
- struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_dm *dm = &btc->dm;
- struct rtw89_btc_fbtc_outsrc_set_info *osi = &dm->ost_info;
- struct rtw89_mac_ax_wl_act *b = dm->gnt.bt;
- struct rtw89_mac_ax_gnt *g = dm->gnt.band;
- u8 i, bt_idx = dm->bt_select + 1;
-
- if (phy_map > BTC_PHY_ALL)
- return;
-
- for (i = 0; i < RTW89_PHY_NUM; i++) {
- if (!(phy_map & BIT(i)))
- continue;
+ for (i = 0; i < BTC_ALL_BT_EZL; i++) {
+ if (!(rtwdev->chip->para_ver & BTC_FEAT_WLAN_ACT_MUX))
+ break;
- switch (wl_state) {
- case BTC_GNT_HW:
- g[i].gnt_wl_sw_en = 0;
- g[i].gnt_wl = 0;
+ switch (wlact_state) {
+ case BTC_WLACT_HW:
+ dm->wlact_set[i].wlan_act_en = 0;
+ dm->wlact_set[i].wlan_act = 0;
break;
- case BTC_GNT_SW_LO:
- g[i].gnt_wl_sw_en = 1;
- g[i].gnt_wl = 0;
+ case BTC_WLACT_SW_LO:
+ dm->wlact_set[i].wlan_act_en = 1;
+ dm->wlact_set[i].wlan_act = 0;
break;
- case BTC_GNT_SW_HI:
- g[i].gnt_wl_sw_en = 1;
- g[i].gnt_wl = 1;
+ case BTC_WLACT_SW_HI:
+ dm->wlact_set[i].wlan_act_en = 1;
+ dm->wlact_set[i].wlan_act = 1;
+ break;
+ default:
break;
}
- switch (bt_state) {
- case BTC_GNT_HW:
- g[i].gnt_bt_sw_en = 0;
- g[i].gnt_bt = 0;
- break;
- case BTC_GNT_SW_LO:
- g[i].gnt_bt_sw_en = 1;
- g[i].gnt_bt = 0;
- break;
- case BTC_GNT_SW_HI:
- g[i].gnt_bt_sw_en = 1;
- g[i].gnt_bt = 1;
+ if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT))
break;
- }
}
- if (rtwdev->chip->para_ver & BTC_FEAT_WLAN_ACT_MUX) {
- for (i = 0; i < 2; i++) {
- if (!(bt_idx & BIT(i)))
- continue;
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s(): phy_map=0x%x, gnt_wl:%d, gnt_bt:%d, wl_act:%d\n",
+ __func__, phy_map, wl_state, bt_state, wlact_state);
- switch (wlact_state) {
- case BTC_WLACT_HW:
- b[i].wlan_act_en = 0;
- b[i].wlan_act = 0;
- break;
- case BTC_WLACT_SW_LO:
- b[i].wlan_act_en = 1;
- b[i].wlan_act = 0;
- break;
- case BTC_WLACT_SW_HI:
- b[i].wlan_act_en = 1;
- b[i].wlan_act = 1;
- break;
+ if (rtwdev->chip->para_ver & BTC_FEAT_H2C_MACRO) {
+ if (o->rf_band[BTC_RF_S0] == 1 && o->rf_band[BTC_RF_S1] == 0)
+ o->rf_gbt_source = BTC_RF_S1;
+ else
+ o->rf_gbt_source = BTC_RF_S0;
+
+ memcpy(o->wlact_set, dm->wlact_set, sizeof(o->wlact_set));
+
+ if (btc->ver->fcxosi == 6) {
+ memcpy(o->gnt_set_be, dm->gnt_set, sizeof(o->gnt_set_be));
+ return;
+ } else if (btc->ver->fcxosi == 1) {
+ for (i = 0; i < RTW89_PHY_NUM; i++) { /* gnt[MAC0/MAC1] */
+ mg.band[i].gnt_bt_sw_en = dm->gnt_set[i].gnt_bt0_sw_en;
+ mg.band[i].gnt_bt = dm->gnt_set[i].gnt_bt0;
+ mg.band[i].gnt_wl_sw_en = dm->gnt_set[i].gnt_wl_sw_en;
+ mg.band[i].gnt_wl = dm->gnt_set[i].gnt_wl;
+ memcpy(o->gnt_set, mg.band, sizeof(o->gnt_set));
}
+ return;
}
}
- if (!btc->ver->fcxosi) {
- rtw89_mac_cfg_gnt_v2(rtwdev, &dm->gnt);
- return;
+ for (i = 0; i < RTW89_PHY_NUM; i++) { /* gnt[MAC0/MAC1] */
+ mg.band[i].gnt_bt_sw_en = dm->gnt_set[i].gnt_bt0_sw_en;
+ mg.band[i].gnt_bt = dm->gnt_set[i].gnt_bt0;
+ mg.band[i].gnt_wl_sw_en = dm->gnt_set[i].gnt_wl_sw_en;
+ mg.band[i].gnt_wl = dm->gnt_set[i].gnt_wl;
}
-
- memcpy(osi->gnt_set, dm->gnt.band, sizeof(osi->gnt_set));
-
- for (i = 0; i < BTC_ALL_BT; i++) {
- osi->wlact_set[i].wlan_act_en = dm->gnt.bt[i].wlan_act_en;
- osi->wlact_set[i].wlan_act = dm->gnt.bt[i].wlan_act;
+ for (i = 0; i < BTC_ALL_BT; i++) { /* wlact[BT0/BT1] */
+ wlact_set = &dm->wlact_set[i];
+ mg.bt[i].wlan_act_en = wlact_set->wlan_act_en;
+ mg.bt[i].wlan_act = wlact_set->wlan_act;
}
- /* GBT source should be GBT_S1 in 1+1 (HWB0:5G + HWB1:2G) case */
- if (osi->rf_band[BTC_RF_S0] == 1 &&
- osi->rf_band[BTC_RF_S1] == 0)
- osi->rf_gbt_source = BTC_RF_S1;
- else
- osi->rf_gbt_source = BTC_RF_S0;
+ rtw89_chip_mac_cfg_gnt(rtwdev, &mg);
}
#define BTC_TDMA_WLROLE_MAX 3
@@ -4961,157 +4958,22 @@ static void _set_bt_plut(struct rtw89_dev *rtwdev, u8 phy_map,
}
}
-static void _set_ant_v0(struct rtw89_dev *rtwdev, bool force_exec,
- u8 phy_map, u8 type)
+static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec,
+ u8 phy_map, u8 type)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_wl_role_info *r = &btc->cx.wl.role_info;
- struct rtw89_btc_bt_info *bt = &cx->bt0;
- struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
- u8 gwl, gwl0, gwl1, gbt, plt_ctrl, i, b2g = 0;
- u32 ant_path_type;
-
- ant_path_type = ((phy_map << 8) + type);
-
- if (btc->dm.run_reason == BTC_RSN_NTFY_POWEROFF ||
- btc->dm.run_reason == BTC_RSN_NTFY_RADIO_STATE ||
- btc->dm.run_reason == BTC_RSN_CMD_SET_COEX || r->dbcc_chg)
- force_exec = FC_EXEC;
-
- if (!force_exec && ant_path_type == dm->set_ant_path) {
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): return by no change!!\n",
- __func__);
- return;
- } else if (bt->rfk_info.map.run) {
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): return by bt rfk!!\n", __func__);
- return;
- } else if (btc->dm.run_reason != BTC_RSN_NTFY_WL_RFK &&
- wl->rfk_info.state != BTC_WRFK_STOP) {
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): return by wl rfk!!\n", __func__);
- return;
- }
-
- dm->set_ant_path = ant_path_type;
-
- rtw89_debug(rtwdev,
- RTW89_DBG_BTC,
- "[BTC], %s(): path=0x%x, set_type=0x%x\n",
- __func__, phy_map, dm->set_ant_path & 0xff);
-
- switch (type) {
- case BTC_ANT_WPOWERON:
- rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_BT);
- break;
- case BTC_ANT_WINIT:
- if (bt->enable.now)
- _set_gnt(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI);
- else
- _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO);
-
- rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
- _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_BT, BTC_PLT_BT);
- break;
- case BTC_ANT_WONLY:
- _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO);
- rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
- _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE);
- break;
- case BTC_ANT_WOFF:
- rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_BT);
- _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE);
- break;
- case BTC_ANT_W2G:
- rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
- if (rtwdev->dbcc_en) {
- for (i = 0; i < RTW89_PHY_NUM; i++) {
- b2g = (wl_dinfo->real_band[i] == RTW89_BAND_2G);
-
- gwl = b2g ? BTC_GNT_HW : BTC_GNT_SW_HI;
- gbt = b2g ? BTC_GNT_HW : BTC_GNT_SW_HI;
- /* BT should control by GNT_BT if WL_2G at S0 */
- if (i == 1 &&
- wl_dinfo->real_band[0] == RTW89_BAND_2G &&
- wl_dinfo->real_band[1] == RTW89_BAND_5G)
- gbt = BTC_GNT_HW;
- _set_gnt(rtwdev, BIT(i), gwl, gbt);
- plt_ctrl = b2g ? BTC_PLT_BT : BTC_PLT_NONE;
- _set_bt_plut(rtwdev, BIT(i),
- plt_ctrl, plt_ctrl);
- }
- } else {
- _set_gnt(rtwdev, phy_map, BTC_GNT_HW, BTC_GNT_HW);
- _set_bt_plut(rtwdev, BTC_PHY_ALL,
- BTC_PLT_BT, BTC_PLT_BT);
- }
- break;
- case BTC_ANT_W5G:
- rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
- _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_HW);
- _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE);
- break;
- case BTC_ANT_W25G:
- rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
- _set_gnt(rtwdev, phy_map, BTC_GNT_HW, BTC_GNT_HW);
- _set_bt_plut(rtwdev, BTC_PHY_ALL,
- BTC_PLT_GNT_WL, BTC_PLT_GNT_WL);
- break;
- case BTC_ANT_FREERUN:
- rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
- _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_HI);
- _set_bt_plut(rtwdev, BTC_PHY_ALL, BTC_PLT_NONE, BTC_PLT_NONE);
- break;
- case BTC_ANT_WRFK:
- case BTC_ANT_WRFK2:
- rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
- _set_gnt(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO);
- _set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE);
- break;
- case BTC_ANT_PTA:
- default:
- gbt = BTC_GNT_HW;
- if ((rtwdev->chip->para_ver & BTC_FEAT_MULTI_PTA) ||
- !r->dbcc_en) {
- gwl = BTC_GNT_HW;
- _set_gnt(rtwdev, BTC_PHY_ALL, gwl, gbt);
- } else {
- /* for DBCC Only-1-PTA */
- if (r->dbcc_2g_phy == RTW89_PHY_0) {
- gwl0 = BTC_GNT_HW;
- gwl1 = BTC_GNT_SW_HI;
- } else {
- gwl0 = BTC_GNT_SW_HI;
- gwl1 = BTC_GNT_HW;
- }
- _set_gnt(rtwdev, BTC_PHY_0, gwl0, gbt);
- _set_gnt(rtwdev, BTC_PHY_1, gwl1, gbt);
- }
- rtw89_chip_cfg_ctrl_path(rtwdev, BTC_CTRL_BY_WL);
- _set_bt_plut(rtwdev, phy_map, BTC_PLT_NONE, BTC_PLT_NONE);
- break;
- }
-}
-
-static void _set_ant_v1(struct rtw89_dev *rtwdev, bool force_exec,
- u8 phy_map, u8 type)
-{
- struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_wl_role_info *wl_rinfo = &wl->role_info;
u32 ant_path_type = rtw89_get_antpath_type(phy_map, type);
- struct rtw89_btc_wl_dbcc_info *wl_dinfo = &wl->dbcc_info;
struct rtw89_btc_dm *dm = &btc->dm;
u8 gwl = BTC_GNT_HW, gwl0, gwl1, gbt;
+ bool cx_ctrl;
- if (btc->dm.run_reason == BTC_RSN_NTFY_POWEROFF ||
- btc->dm.run_reason == BTC_RSN_NTFY_RADIO_STATE ||
- btc->dm.run_reason == BTC_RSN_CMD_SET_COEX || wl_rinfo->dbcc_chg)
+ if (btc->cli_h2c_cmd || wl_rinfo->dbcc_chg ||
+ dm->run_reason == BTC_RSN_NTFY_POWEROFF ||
+ dm->run_reason == BTC_RSN_NTFY_RADIO_STATE ||
+ dm->run_reason == BTC_RSN_CMD_SET_COEX)
force_exec = FC_EXEC;
if (wl_rinfo->link_mode != BTC_WLINK_DB_MCC &&
@@ -5123,10 +4985,6 @@ static void _set_ant_v1(struct rtw89_dev *rtwdev, bool force_exec,
"[BTC], %s(): return by no change!!\n",
__func__);
return;
- } else if (bt->rfk_info.map.run) {
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): return by bt rfk!!\n", __func__);
- return;
} else if (btc->dm.run_reason != BTC_RSN_NTFY_WL_RFK &&
wl->rfk_info.state != BTC_WRFK_STOP) {
rtw89_debug(rtwdev, RTW89_DBG_BTC,
@@ -5141,64 +4999,38 @@ static void _set_ant_v1(struct rtw89_dev *rtwdev, bool force_exec,
__func__, phy_map, dm->set_ant_path & 0xff);
switch (type) {
+ case BTC_ANT_WPOWERON:
+ cx_ctrl = BTC_CTRL_BY_BT;
+ break;
case BTC_ANT_WINIT:
+ cx_ctrl = BTC_CTRL_BY_WL;
/* To avoid BT MP driver case (bt_enable but no mailbox) */
- if (bt->enable.now && bt->run_patch_code)
- _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI,
- BTC_WLACT_SW_LO);
+ if ((cx->bt0.enable.now && cx->bt0.run_patch_code) ||
+ (cx->bt1.enable.now && cx->bt1.run_patch_code))
+ _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_LO, BTC_GNT_SW_HI,
+ BTC_WLACT_SW_LO);
else
- _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO,
- BTC_WLACT_SW_HI);
+ _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_HI, BTC_GNT_SW_LO,
+ BTC_WLACT_SW_HI);
break;
case BTC_ANT_WONLY:
- _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO,
- BTC_WLACT_SW_HI);
+ cx_ctrl = BTC_CTRL_BY_WL;
+ _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_HI, BTC_GNT_SW_LO,
+ BTC_WLACT_SW_HI);
break;
case BTC_ANT_WOFF:
- _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_LO, BTC_GNT_SW_HI,
- BTC_WLACT_SW_LO);
- break;
- case BTC_ANT_W2G:
- case BTC_ANT_W25G:
- if (wl_rinfo->dbcc_en) {
- if (wl_dinfo->real_band[RTW89_PHY_0] == RTW89_BAND_2G)
- gwl = BTC_GNT_HW;
- else
- gwl = BTC_GNT_SW_HI;
- _set_gnt_v1(rtwdev, BTC_PHY_0, gwl, BTC_GNT_HW, BTC_WLACT_HW);
-
- if (wl_dinfo->real_band[RTW89_PHY_1] == RTW89_BAND_2G)
- gwl = BTC_GNT_HW;
- else
- gwl = BTC_GNT_SW_HI;
- _set_gnt_v1(rtwdev, BTC_PHY_1, gwl, BTC_GNT_HW, BTC_WLACT_HW);
- } else {
- gwl = BTC_GNT_HW;
- _set_gnt_v1(rtwdev, phy_map, gwl, BTC_GNT_HW, BTC_WLACT_HW);
- }
- break;
- case BTC_ANT_W5G:
- _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_HW, BTC_WLACT_HW);
- break;
- case BTC_ANT_FREERUN:
- _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_HI,
- BTC_WLACT_SW_LO);
- break;
- case BTC_ANT_WRFK:
- _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO,
- BTC_WLACT_HW);
- break;
- case BTC_ANT_WRFK2:
- _set_gnt_v1(rtwdev, phy_map, BTC_GNT_SW_HI, BTC_GNT_SW_LO,
- BTC_WLACT_SW_HI); /* no BT-Tx */
+ cx_ctrl = BTC_CTRL_BY_BT;
+ _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_LO, BTC_GNT_SW_HI,
+ BTC_WLACT_SW_LO);
break;
case BTC_ANT_PTA:
default:
+ cx_ctrl = BTC_CTRL_BY_WL;
gbt = BTC_GNT_HW;
if ((rtwdev->chip->para_ver & BTC_FEAT_MULTI_PTA) ||
!wl_rinfo->dbcc_en) {
gwl = BTC_GNT_HW;
- _set_gnt_v1(rtwdev, BTC_PHY_ALL, gwl, gbt, BTC_WLACT_HW);
+ _set_gnt(rtwdev, BTC_PHY_ALL, gwl, gbt, BTC_WLACT_HW);
} else {
/* for DBCC Only-1-PTA */
if (wl_rinfo->dbcc_2g_phy == RTW89_PHY_0) {
@@ -5208,24 +5040,36 @@ static void _set_ant_v1(struct rtw89_dev *rtwdev, bool force_exec,
gwl0 = BTC_GNT_SW_HI;
gwl1 = BTC_GNT_HW;
}
- _set_gnt_v1(rtwdev, BTC_PHY_0, gwl0, gbt, BTC_WLACT_HW);
- _set_gnt_v1(rtwdev, BTC_PHY_1, gwl1, gbt, BTC_WLACT_HW);
+ _set_gnt(rtwdev, BTC_PHY_0, gwl0, gbt, BTC_WLACT_HW);
+ _set_gnt(rtwdev, BTC_PHY_1, gwl1, gbt, BTC_WLACT_HW);
}
break;
+ case BTC_ANT_FDD:
+ cx_ctrl = BTC_CTRL_BY_WL;
+ _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_HI, BTC_GNT_HW,
+ BTC_WLACT_HW);
+ break;
+ case BTC_ANT_FREERUN:
+ cx_ctrl = BTC_CTRL_BY_WL;
+ _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_HI, BTC_GNT_SW_HI,
+ BTC_WLACT_SW_LO);
+ break;
+ case BTC_ANT_WRFK:
+ cx_ctrl = BTC_CTRL_BY_WL;
+ _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_HI, BTC_GNT_SW_LO,
+ BTC_WLACT_HW);
+ break;
+ case BTC_ANT_WRFK2:
+ cx_ctrl = BTC_CTRL_BY_WL;
+ _set_gnt(rtwdev, BTC_PHY_ALL, BTC_GNT_SW_HI, BTC_GNT_SW_LO,
+ BTC_WLACT_SW_HI); /* no BT-Tx */
+ break;
}
+ rtw89_chip_cfg_ctrl_path(rtwdev, cx_ctrl);
_set_bt_plut(rtwdev, phy_map, BTC_PLT_GNT_WL, BTC_PLT_GNT_WL);
}
-static void _set_ant(struct rtw89_dev *rtwdev, bool force_exec,
- u8 phy_map, u8 type)
-{
- if (rtwdev->chip->chip_id >= RTL8922A)
- _set_ant_v1(rtwdev, force_exec, phy_map, type);
- else
- _set_ant_v0(rtwdev, force_exec, phy_map, type);
-}
-
static void _action_wl_only(struct rtw89_dev *rtwdev)
{
_set_ant(rtwdev, FC_EXEC, BTC_PHY_ALL, BTC_ANT_WONLY);
@@ -5619,7 +5463,7 @@ static void _action_bt_a2dp_pan_hid(struct rtw89_dev *rtwdev)
static void _action_wl_5g(struct rtw89_dev *rtwdev)
{
- _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_W5G);
+ _set_ant(rtwdev, NM_EXEC, BTC_PHY_ALL, BTC_ANT_FDD);
_set_policy(rtwdev, BTC_CXP_OFF_EQ0, BTC_ACT_WL_5G);
}
@@ -9674,7 +9518,7 @@ static const char *id_to_ant(u32 id)
CASE_BTC_ANTPATH_STR(WONLY);
CASE_BTC_ANTPATH_STR(WOFF);
CASE_BTC_ANTPATH_STR(W2G);
- CASE_BTC_ANTPATH_STR(W5G);
+ CASE_BTC_ANTPATH_STR(FDD);
CASE_BTC_ANTPATH_STR(W25G);
CASE_BTC_ANTPATH_STR(FREERUN);
CASE_BTC_ANTPATH_STR(WRFK);
@@ -10898,6 +10742,7 @@ static int _show_fw_dm_msg(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt_cfg)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_mac_ax_wl_act *bt;
struct rtw89_mac_ax_gnt *gnt;
u32 val, status;
@@ -10932,7 +10777,39 @@ static void _get_gnt(struct rtw89_dev *rtwdev, struct rtw89_mac_ax_coex_gnt *gnt
gnt->gnt_bt = !!(status & B_AX_GNT_BT_RFC_S1);
gnt->gnt_wl_sw_en = !!(val & B_AX_GNT_WL_RFC_S1_SWCTRL);
gnt->gnt_wl = !!(status & B_AX_GNT_WL_RFC_S1);
- } else {
+
+ bt = &gnt_cfg->bt[0];
+ bt->wlan_act_en = !!(val & B_BE_WL_ACT_SWCTRL);
+ bt->wlan_act = !!(status & B_BE_WL_ACT_VAL);
+
+ bt = &gnt_cfg->bt[1];
+ bt->wlan_act_en = !!(val & B_BE_WL_ACT2_SWCTRL);
+ bt->wlan_act = !!(status & B_BE_WL_ACT2_VAL);
+ } else if (chip->chip_id == RTL8922A) {
+ val = rtw89_read32(rtwdev, R_BE_GNT_SW_CTRL);
+ status = rtw89_read32(rtwdev, R_BE_PTA_GNT_VAL);
+
+ gnt = &gnt_cfg->band[0];
+ gnt->gnt_bt_sw_en = !!(val & B_BE_GNT_BT_BB0_SWCTRL);
+ gnt->gnt_bt = !!(status & B_BE_GNT_BT_BB0_VAL);
+ gnt->gnt_wl_sw_en = !!(val & B_BE_GNT_WL_BB0_SWCTRL);
+ gnt->gnt_wl = !!(status & B_BE_GNT_WL_BB0_VAL);
+
+ gnt = &gnt_cfg->band[1];
+ gnt->gnt_bt_sw_en = !!(val & B_BE_GNT_BT_BB1_SWCTRL);
+ gnt->gnt_bt = !!(status & B_BE_GNT_BT_BB1_VAL);
+ gnt->gnt_wl_sw_en = !!(val & B_BE_GNT_WL_BB1_SWCTRL);
+ gnt->gnt_wl = !!(status & B_BE_GNT_WL_BB1_VAL);
+
+ bt = &gnt_cfg->bt[0];
+ bt->wlan_act_en = !!(val & B_BE_WL_ACT_SWCTRL);
+ bt->wlan_act = !!(status & B_BE_WL_ACT_VAL);
+
+ bt = &gnt_cfg->bt[1];
+ bt->wlan_act_en = !!(val & B_BE_WL_ACT2_SWCTRL);
+ bt->wlan_act = !!(status & B_BE_WL_ACT2_VAL);
+ } else if (chip->chip_id == RTL8922D) {
+ /* Get from firmware */
return;
}
}
@@ -11181,7 +11058,6 @@ static int _show_mreg_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
struct rtw89_btc_bt_info *bt0 = &cx->bt0;
struct rtw89_btc_bt_info *bt1 = &cx->bt1;
struct rtw89_btc_wl_info *wl = &cx->wl;
- struct rtw89_mac_ax_gnt *gnt = NULL;
struct rtw89_btc_dm *dm = &btc->dm;
char *p = buf, *end = buf + bufsz;
u8 i, type, cnt = 0;
@@ -11219,18 +11095,19 @@ static int _show_mreg_v7(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
wl->pta_req_mac,
id_to_polut(wl->bt_polut_type[wl->pta_req_mac]));
- gnt = &dm->gnt.band[RTW89_PHY_0];
-
p += scnprintf(p, end - p, ", phy-0[gnt_wl:%s-%d/gnt_bt:%s-%d]",
- gnt->gnt_wl_sw_en ? "SW" : "HW", gnt->gnt_wl,
- gnt->gnt_bt_sw_en ? "SW" : "HW", gnt->gnt_bt);
+ dm->gnt_set[RTW89_PHY_0].gnt_wl_sw_en ? "SW" : "HW",
+ dm->gnt_set[RTW89_PHY_0].gnt_wl,
+ dm->gnt_set[RTW89_PHY_0].gnt_bt0_sw_en ? "SW" : "HW",
+ dm->gnt_set[RTW89_PHY_0].gnt_bt0);
if (rtwdev->dbcc_en) {
- gnt = &dm->gnt.band[RTW89_PHY_1];
p += scnprintf(p, end - p,
", phy-1[gnt_wl:%s-%d/gnt_bt:%s-%d]",
- gnt->gnt_wl_sw_en ? "SW" : "HW", gnt->gnt_wl,
- gnt->gnt_bt_sw_en ? "SW" : "HW", gnt->gnt_bt);
+ dm->gnt_set[RTW89_PHY_1].gnt_wl_sw_en ? "SW" : "HW",
+ dm->gnt_set[RTW89_PHY_1].gnt_wl,
+ dm->gnt_set[RTW89_PHY_1].gnt_bt0_sw_en ? "SW" : "HW",
+ dm->gnt_set[RTW89_PHY_1].gnt_bt0);
}
pcinfo = &pfwinfo->rpt_fbtc_mregval.cinfo;
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 676d3ba855d7..a928140300b9 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -3481,7 +3481,9 @@ struct rtw89_btc_dm {
union rtw89_btc_fbtc_slot_u slot_now;
struct rtw89_btc_fbtc_tdma tdma;
struct rtw89_btc_fbtc_tdma tdma_now;
- struct rtw89_mac_ax_coex_gnt gnt;
+ struct rtw89_btc_gnt_ctrl gnt_set[RTW89_MAC_AX_COEX_GNT_NR];
+ struct rtw89_btc_gnt_ctrl gnt_val[RTW89_MAC_AX_COEX_GNT_NR];
+ struct rtw89_mac_ax_wl_act wlact_set[BTC_ALL_BT_EZL];
union rtw89_btc_init_info_u init_info; /* pass to wl_fw if offload */
struct rtw89_btc_rf_trx_para_v9 rf_trx_para;
struct rtw89_btc_wl_tx_limit_para wl_tx_limit;
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 6e3da5e4a1b3..b9cd7fd8d76b 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -6538,8 +6538,6 @@ int rtw89_mac_cfg_gnt_v1(struct rtw89_dev *rtwdev,
if (gnt_cfg->band[0].gnt_bt)
val |= B_AX_GNT_BT_RFC_S0_VAL | B_AX_GNT_BT_RX_VAL |
B_AX_GNT_BT_TX_VAL;
- else
- val |= B_AX_WL_ACT_VAL;
if (gnt_cfg->band[0].gnt_bt_sw_en)
val |= B_AX_GNT_BT_RFC_S0_SWCTRL | B_AX_GNT_BT_RX_SWCTRL |
@@ -6556,8 +6554,6 @@ int rtw89_mac_cfg_gnt_v1(struct rtw89_dev *rtwdev,
if (gnt_cfg->band[1].gnt_bt)
val |= B_AX_GNT_BT_RFC_S1_VAL | B_AX_GNT_BT_RX_VAL |
B_AX_GNT_BT_TX_VAL;
- else
- val |= B_AX_WL_ACT_VAL;
if (gnt_cfg->band[1].gnt_bt_sw_en)
val |= B_AX_GNT_BT_RFC_S1_SWCTRL | B_AX_GNT_BT_RX_SWCTRL |
@@ -6571,6 +6567,15 @@ int rtw89_mac_cfg_gnt_v1(struct rtw89_dev *rtwdev,
val |= B_AX_GNT_WL_RFC_S1_SWCTRL | B_AX_GNT_WL_RX_SWCTRL |
B_AX_GNT_WL_TX_SWCTRL | B_AX_GNT_WL_BB_SWCTRL;
+ if (gnt_cfg->bt[0].wlan_act_en)
+ val |= B_AX_WL_ACT_SWCTRL;
+ if (gnt_cfg->bt[0].wlan_act)
+ val |= B_AX_WL_ACT_VAL;
+ if (gnt_cfg->bt[1].wlan_act_en)
+ val |= B_AX_WL_ACT2_SWCTRL;
+ if (gnt_cfg->bt[1].wlan_act)
+ val |= B_AX_WL_ACT2_VAL;
+
rtw89_write32(rtwdev, R_AX_GNT_SW_CTRL, val);
return 0;
@@ -6645,22 +6650,20 @@ EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path);
int rtw89_mac_cfg_ctrl_path_v1(struct rtw89_dev *rtwdev, bool wl)
{
- struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_dm *dm = &btc->dm;
- struct rtw89_mac_ax_gnt *g = dm->gnt.band;
+ struct rtw89_mac_ax_coex_gnt gnt = {};
int i;
if (wl)
return 0;
for (i = 0; i < RTW89_PHY_NUM; i++) {
- g[i].gnt_bt_sw_en = 1;
- g[i].gnt_bt = 1;
- g[i].gnt_wl_sw_en = 1;
- g[i].gnt_wl = 0;
+ gnt.band[i].gnt_bt_sw_en = 1;
+ gnt.band[i].gnt_bt = 1;
+ gnt.band[i].gnt_wl_sw_en = 1;
+ gnt.band[i].gnt_wl = 0;
}
- return rtw89_mac_cfg_gnt_v1(rtwdev, &dm->gnt);
+ return rtw89_mac_cfg_gnt_v1(rtwdev, &gnt);
}
EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path_v1);
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
index 4bdf20b7ba6d..33513b283d84 100644
--- a/drivers/net/wireless/realtek/rtw89/mac_be.c
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -2466,29 +2466,26 @@ EXPORT_SYMBOL(rtw89_mac_cfg_gnt_v3);
int rtw89_mac_cfg_ctrl_path_v2(struct rtw89_dev *rtwdev, bool wl)
{
- struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_dm *dm = &btc->dm;
- struct rtw89_mac_ax_gnt *g = dm->gnt.band;
- struct rtw89_mac_ax_wl_act *gbt = dm->gnt.bt;
const struct rtw89_chip_info *chip = rtwdev->chip;
+ struct rtw89_mac_ax_coex_gnt gnt = {};
int i;
if (wl)
return 0;
for (i = 0; i < RTW89_PHY_NUM; i++) {
- g[i].gnt_bt_sw_en = 1;
- g[i].gnt_bt = 1;
- g[i].gnt_wl_sw_en = 1;
- g[i].gnt_wl = 0;
- gbt[i].wlan_act = 1;
- gbt[i].wlan_act_en = 0;
+ gnt.band[i].gnt_bt_sw_en = 1;
+ gnt.band[i].gnt_bt = 1;
+ gnt.band[i].gnt_wl_sw_en = 1;
+ gnt.band[i].gnt_wl = 0;
+ gnt.bt[i].wlan_act = 1;
+ gnt.bt[i].wlan_act_en = 0;
}
if (chip->chip_id == RTL8922A)
- return rtw89_mac_cfg_gnt_v2(rtwdev, &dm->gnt);
+ return rtw89_mac_cfg_gnt_v2(rtwdev, &gnt);
else
- return rtw89_mac_cfg_gnt_v3(rtwdev, &dm->gnt);
+ return rtw89_mac_cfg_gnt_v3(rtwdev, &gnt);
}
EXPORT_SYMBOL(rtw89_mac_cfg_ctrl_path_v2);
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 05/11] wifi: rtw89: coex: Rearrange Bluetooth firmware report entry
From: Ping-Ke Shih @ 2026-07-12 3:05 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260712030506.43438-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
To enable/disable firmware report once at the end of mechanism round.
This can make the logic more clearly, and make sure every round the
mechanism running can refresh the settings. It can avoid some report
missing after driver status change.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 209 +++++++++++-----------
1 file changed, 104 insertions(+), 105 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 2ca6090e9f62..ff3345824a2a 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -2659,37 +2659,27 @@ static void rtw89_btc_fw_set_slots(struct rtw89_dev *rtwdev)
}
static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev,
- u32 rpt_map, bool rpt_state)
+ bool force_exec, u32 rpt_map)
{
struct rtw89_btc *btc = &rtwdev->btc;
- struct rtw89_btc_wl_smap *wl_smap = &btc->cx.wl.status.map;
struct rtw89_btc_btf_fwinfo *fwinfo = &btc->fwinfo;
union rtw89_fbtc_rtp_ctrl r;
- u32 val, bit_map;
int ret;
+ u32 i;
- if ((wl_smap->rf_off || wl_smap->lps != BTC_LPS_OFF) && rpt_state != 0)
+ if (!force_exec && rpt_map == fwinfo->rpt_en_map)
return;
- bit_map = rtw89_btc_fw_rpt_ver(rtwdev, rpt_map);
-
- rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "[BTC], %s(): rpt_map=%x, rpt_state=%x\n",
- __func__, rpt_map, rpt_state);
-
- if (rpt_state)
- val = fwinfo->rpt_en_map | bit_map;
- else
- val = fwinfo->rpt_en_map & ~bit_map;
-
- if (val == fwinfo->rpt_en_map)
- return;
+ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s(): rpt_map=%x\n",
+ __func__, fwinfo->rpt_en_map);
- if (btc->ver->fcxbtcrpt == 7 || btc->ver->fcxbtcrpt == 8) {
+ if (btc->ver->fcxbtcrpt == 7 ||
+ btc->ver->fcxbtcrpt == 8 ||
+ btc->ver->fcxbtcrpt == 11) {
r.v8.type = SET_REPORT_EN;
r.v8.fver = btc->ver->fcxbtcrpt;
r.v8.len = sizeof(r.v8.map);
- r.v8.map = cpu_to_le32(val);
+ r.v8.map = cpu_to_le32(rpt_map);
ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN, &r.v8,
sizeof(r.v8));
} else {
@@ -2697,14 +2687,21 @@ static void rtw89_btc_fw_en_rpt(struct rtw89_dev *rtwdev,
r.v1.fver = 5;
else
r.v1.fver = btc->ver->fcxbtcrpt;
- r.v1.enable = cpu_to_le32(val);
- r.v1.para = cpu_to_le32(rpt_state);
- ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN, &r.v1,
- sizeof(r.v1));
+
+ for (i = 0; i < RPT_EN_MONITER; i++) {
+ r.v1.enable = cpu_to_le32(i);
+ if (rpt_map & BIT(i))
+ r.v1.para = cpu_to_le32(1);
+ else
+ r.v1.para = 0;
+
+ ret = _send_fw_cmd(rtwdev, BTFC_SET, SET_REPORT_EN,
+ &r.v1, sizeof(r.v1));
+ }
}
if (!ret)
- fwinfo->rpt_en_map = val;
+ fwinfo->rpt_en_map = rpt_map;
}
static void btc_fw_set_monreg(struct rtw89_dev *rtwdev)
@@ -2766,8 +2763,6 @@ static void btc_fw_set_monreg(struct rtw89_dev *rtwdev)
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): sz=%d ulen=%d n=%d\n",
__func__, sz, ulen, n);
-
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, 1);
}
static void _update_dm_step(struct rtw89_dev *rtwdev,
@@ -5882,15 +5877,72 @@ static void _update_zb_coex_tbl(struct rtw89_dev *rtwdev)
rtw89_write32(rtwdev, R_BTC_ZB_COEX_TBL_1, zb_tbl1);
}
+static void _set_fw_report_map(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_wl_smap *wl_smap = &btc->cx.wl.status.map;
+ struct rtw89_btc_bt_info *bt0 = &btc->cx.bt0;
+ struct rtw89_btc_bt_info *bt1 = &btc->cx.bt1;
+ u32 rpt_map = btc->fwinfo.rpt_en_map;
+ u32 bt_rom_code_id, bt_fw_ver;
+ bool bt_ver_unknown = false;
+ u32 bitmap;
+
+ if (wl_smap->rf_off == 1 || wl_smap->lps != BTC_LPS_OFF) {
+ rtw89_btc_fw_en_rpt(rtwdev, false, 0);
+ return;
+ }
+
+ rpt_map |= rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_MREG);
+
+ bitmap = rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_BT_SCAN_INFO);
+ if ((bt0->run_patch_code && bt0->enable.now) ||
+ (bt1->run_patch_code && bt1->enable.now))
+ rpt_map |= bitmap;
+ else
+ rpt_map &= ~bitmap;
+
+ bt_rom_code_id = chip_id_to_bt_rom_code_id(rtwdev->btc.ver->chip_id);
+ bt_fw_ver = bt0->ver_info.fw & 0xffff;
+ if (bt_fw_ver == 0 ||
+ (bt_fw_ver == bt_rom_code_id && bt0->run_patch_code))
+ bt_ver_unknown = true;
+
+ bitmap = rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_BT_VER_INFO);
+ if (bt0->enable.now && bt_ver_unknown)
+ rpt_map |= bitmap;
+ else
+ rpt_map &= ~bitmap;
+
+ bitmap = rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_BT_AFH_MAP) |
+ rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_BT_AFH_MAP_LE) |
+ rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_BT_TX_PWR_LVL);
+ if (bt0->link_info.link_cnt.now ||
+ bt0->link_info_56g.link_cnt.now ||
+ bt1->link_info.link_cnt.now ||
+ bt1->link_info_56g.link_cnt.now)
+ rpt_map |= bitmap;
+ else
+ rpt_map &= ~bitmap;
+
+ bitmap = rtw89_btc_fw_rpt_ver(rtwdev, RPT_EN_BT_DEVICE_INFO);
+ if ((bt0->link_info.a2dp_desc.exist &&
+ bt0->link_info.a2dp_desc.play_latency) ||
+ (bt1->link_info.a2dp_desc.exist &&
+ bt1->link_info.a2dp_desc.play_latency))
+ rpt_map |= bitmap;
+ else
+ rpt_map &= ~bitmap;
+
+ rtw89_btc_fw_en_rpt(rtwdev, false, rpt_map);
+}
+
static void _action_common(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_wl_role_info *rinfo = &wl->role_info;
- struct rtw89_btc_wl_smap *wl_smap = &wl->status.map;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
struct rtw89_btc_dm *dm = &btc->dm;
- u32 bt_rom_code_id, bt_fw_ver;
u8 i;
_wl_req_mac(rtwdev, rinfo->pta_req_band);
@@ -5902,27 +5954,13 @@ static void _action_common(struct rtw89_dev *rtwdev)
_set_bt_rx_agc(rtwdev);
_set_rf_trx_para(rtwdev);
_set_bt_rx_scan_pri(rtwdev);
-
- bt_rom_code_id = chip_id_to_bt_rom_code_id(rtwdev->btc.ver->chip_id);
- bt_fw_ver = bt->ver_info.fw & 0xffff;
- if (bt->enable.now &&
- (bt_fw_ver == 0 ||
- (bt_fw_ver == bt_rom_code_id && bt->run_patch_code && rtwdev->chip->scbd)))
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, 1);
- else
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, 0);
+ _set_fw_report_map(rtwdev);
if (dm->run_reason == BTC_RSN_NTFY_INIT ||
dm->run_reason == BTC_RSN_NTFY_RADIO_STATE ||
- dm->run_reason == BTC_RSN_NTFY_POWEROFF) {
+ dm->run_reason == BTC_RSN_NTFY_POWEROFF)
_fw_set_drv_info(rtwdev, CXDRVINFO_ROLE);
- if (wl_smap->rf_off == 1 || wl_smap->lps != BTC_LPS_OFF)
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, 0);
- else
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, 1);
- }
-
for (i = BTC_BT_1ST; i <= BTC_BT_2ND; i++)
_sned_h2c_w2bscbd(rtwdev, false, i);
@@ -7730,8 +7768,6 @@ void rtw89_btc_ntfy_poweroff(struct rtw89_dev *rtwdev)
_write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_ALL, false);
_run_coex(rtwdev, BTC_RSN_NTFY_POWEROFF);
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, 0);
-
btc->cx.wl.status.map.rf_off_pre = btc->cx.wl.status.map.rf_off;
}
@@ -8344,12 +8380,10 @@ void rtw89_btc_ntfy_radio_state(struct rtw89_dev *rtwdev, enum btc_rfctrl rf_sta
}
if (rf_state == BTC_RFCTRL_WL_ON) {
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_MREG, true);
val = BTC_WSCB_ACTIVE | BTC_WSCB_ON | BTC_WSCB_BTLOG;
_write_scbd(rtwdev, BTC_ALL_BT, val, true);
chip->ops->btc_init_cfg(rtwdev);
} else {
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_ALL, false);
if (rf_state == BTC_RFCTRL_FW_CTRL)
_write_scbd(rtwdev, BTC_ALL_BT, BTC_WSCB_ACTIVE, false);
else if (rf_state == BTC_RFCTRL_WL_OFF)
@@ -8857,11 +8891,6 @@ static int _show_cx_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
(bt->ver_info.fw_coex >= ver->bt_desired ?
"Match" : "Mismatch"), ver->bt_desired);
- if (bt->enable.now && bt->ver_info.fw == 0)
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, true);
- else
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_VER_INFO, false);
-
ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw);
ver_sub = FIELD_GET(GENMASK(23, 16), wl->ver_info.fw);
ver_hotfix = FIELD_GET(GENMASK(15, 8), wl->ver_info.fw);
@@ -9056,7 +9085,6 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_bt_info *bt = &cx->bt0;
struct rtw89_btc_wl_info *wl = &cx->wl;
- u32 ver_main = FIELD_GET(GENMASK(31, 24), wl->ver_info.fw_coex);
struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
union rtw89_btc_module_info *md = &btc->mdinfo;
s8 br_dbm = bt->link_info.bt_txpwr_desc.br_dbm;
@@ -9167,39 +9195,28 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
bt->bcnt[BTC_BCNT_LOPRI_TX],
bt->bcnt[BTC_BCNT_POLLUTED]);
- if (!bt->scan_info_update) {
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, true);
- p += scnprintf(p, end - p, "\n");
- } else {
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_SCAN_INFO, false);
- if (ver->fcxbtscan == 1) {
- p += scnprintf(p, end - p,
- "(INQ:%d-%d/PAGE:%d-%d/LE:%d-%d/INIT:%d-%d)",
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].win),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].intvl),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].win),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].intvl),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].win),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].intvl),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].win),
- le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].intvl));
- } else if (ver->fcxbtscan == 2) {
- p += scnprintf(p, end - p,
- "(BG:%d-%d/INIT:%d-%d/LE:%d-%d)",
- le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].win),
- le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].intvl),
- le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].win),
- le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].intvl),
- le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].win),
- le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].intvl));
- }
- p += scnprintf(p, end - p, "\n");
+ if (ver->fcxbtscan == 1) {
+ p += scnprintf(p, end - p,
+ "(INQ:%d-%d/PAGE:%d-%d/LE:%d-%d/INIT:%d-%d)",
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].win),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INQ].intvl),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].win),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_PAGE].intvl),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].win),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_BLE].intvl),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].win),
+ le16_to_cpu(bt->scan_info_v1[BTC_SCAN_INIT].intvl));
+ } else if (ver->fcxbtscan == 2) {
+ p += scnprintf(p, end - p,
+ "(BG:%d-%d/INIT:%d-%d/LE:%d-%d)",
+ le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].win),
+ le16_to_cpu(bt->scan_info_v2[CXSCAN_BG].intvl),
+ le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].win),
+ le16_to_cpu(bt->scan_info_v2[CXSCAN_INIT].intvl),
+ le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].win),
+ le16_to_cpu(bt->scan_info_v2[CXSCAN_LE].intvl));
}
-
- if (ver_main >= 9 && bt_linfo->link_cnt.now)
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_TX_PWR_LVL, true);
- else
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_TX_PWR_LVL, false);
+ p += scnprintf(p, end - p, "\n");
if (bt->bcnt[BTC_BCNT_TXPWR_UPDATE]) {
p += scnprintf(p, end - p,
@@ -9218,24 +9235,6 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
}
p += scnprintf(p, end - p, "\n");
- if (bt_linfo->link_cnt.now || bt_linfo->status.map.ble_connect)
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, true);
- else
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP, false);
-
- if (ver->fcxbtafh == 2 && bt_linfo->status.map.ble_connect)
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP_LE, true);
- else
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_AFH_MAP_LE, false);
-
- if (bt_linfo->a2dp_desc.exist &&
- (bt_linfo->a2dp_desc.flush_time == 0 ||
- bt_linfo->a2dp_desc.vendor_id == 0 ||
- bt_linfo->a2dp_desc.play_latency == 1))
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, true);
- else
- rtw89_btc_fw_en_rpt(rtwdev, RPT_EN_BT_DEVICE_INFO, false);
-
return p - buf;
}
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 06/11] wifi: rtw89: coex: Refine send firmware command function
From: Ping-Ke Shih @ 2026-07-12 3:05 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260712030506.43438-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
Because the coexistence offload more register/ hardware setting I/O to
firmware by coexistence itself, and it goes with the same entry with other
control action, so the firmware command entry need to add different
condition to judge should it followed coexistence TLV format or not.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 107 +++++++++++++++++++++-
drivers/net/wireless/realtek/rtw89/core.h | 4 +
2 files changed, 110 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index ff3345824a2a..07d054f59eb5 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -936,6 +936,14 @@ static void _run_coex(struct rtw89_dev *rtwdev,
static void _write_scbd(struct rtw89_dev *rtwdev, u8 bid, u32 val, bool state);
static u8 _sned_h2c_w2bscbd(struct rtw89_dev *rtwdev, bool force_exec, u8 bid);
static void _update_bt_scbd(struct rtw89_dev *rtwdev, u8 bid);
+static const char *id_to_h2c(u32 id);
+
+static void _reset_h2c_macro(struct rtw89_btc *btc)
+{
+ btc->hbuf_len = 0;
+ btc->hbuf_cnt = 0;
+ memset(btc->hbuf, 0, BTC_H2C_MAXLEN);
+}
static int _send_fw_cmd(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func,
void *param, u16 len)
@@ -945,6 +953,8 @@ static int _send_fw_cmd(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func,
struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &cx->wl;
struct rtw89_btc_dm *dm = &btc->dm;
+ u8 h2c_func_mask, bid = BTC_BT_1ST;
+ u8 *buf = param;
int ret;
if (len > BTC_H2C_MAXLEN || len == 0) {
@@ -966,7 +976,69 @@ static int _send_fw_cmd(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func,
return -EINVAL;
}
- ret = rtw89_fw_h2c_raw_with_hdr(rtwdev, h2c_class, h2c_func, param, len,
+ h2c_func_mask = h2c_func & (~BT_H2C_FUNC_BT2ND);
+ if (rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT)
+ bid = !!(h2c_func & BT_H2C_FUNC_BT2ND);
+
+ if (btc->io_oflld_type != BTC_IO_OFLD_BTC_H2C || btc->cli_h2c_cmd ||
+ h2c_func_mask == SET_H2C_MACRO ||
+ (h2c_func_mask == SET_DRV_INFO && buf[0] == CXDRVINFO_TRX) ||
+ (h2c_func_mask == SET_IOFLD_SCBD && dm->scbd_write_instant) ||
+ h2c_func_mask == SET_BT_LNA_CONSTRAIN) {
+ h2c_class = BTFC_SET;
+
+ ret = rtw89_fw_h2c_raw_with_hdr(rtwdev, h2c_class, h2c_func,
+ buf, len, false, true);
+
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s():class=%d, bt%d-func=%s, len=%d\n",
+ __func__, h2c_class, bid,
+ id_to_h2c(h2c_func_mask), len);
+
+ if (h2c_func_mask == SET_H2C_MACRO) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s():Send H2C-MACRO cnt=%d, len=%d\n",
+ __func__, btc->hbuf_cnt, btc->hbuf_len);
+ _reset_h2c_macro(btc); /* clear H2C MACRO buffer */
+ }
+
+ if (ret != 0) { /* Send H2C fail */
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s():return by rtw_hal_mac_send_h2c\n",
+ __func__);
+ btc->fwinfo.cnt_h2c_fail++;
+ return 0;
+ }
+
+ btc->fwinfo.cnt_h2c++;
+ } else { /* Fill H2C MACRO buffer(TLV format) temporarily */
+ if (btc->hbuf_cnt == 0)
+ _reset_h2c_macro(btc);
+
+ /* Type:1 byte, Length:2 Bytes, Data:len bytes */
+ if (btc->hbuf_len + len + 3 >= BTC_H2C_MAXLEN) {
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s():return by MACRO buf full(%d)\n",
+ __func__, btc->hbuf_len + len + 3);
+ btc->fwinfo.cnt_h2c_fail++;
+ return 0;
+ }
+
+ btc->hbuf[btc->hbuf_len] = h2c_func;
+ btc->hbuf[btc->hbuf_len + 1] = len & GENMASK(7, 0);
+ btc->hbuf[btc->hbuf_len + 2] = (len & GENMASK(15, 8)) >> 8;
+
+ memcpy(&btc->hbuf[btc->hbuf_len + 3], buf, len);
+ btc->hbuf_len = btc->hbuf_len + len + 3;
+ btc->hbuf_cnt++;
+
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s():Buffer H2C-MACRO cnt=%d/bt%d-func=%s/len=%d\n",
+ __func__, btc->hbuf_cnt, bid,
+ id_to_h2c(h2c_func_mask), len);
+ }
+
+ ret = rtw89_fw_h2c_raw_with_hdr(rtwdev, h2c_class, h2c_func, buf, len,
false, true);
if (ret)
pfwinfo->cnt_h2c_fail++;
@@ -9249,6 +9321,7 @@ static int _show_bt_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
#define CASE_BTC_POLUT_STR(e) case BTC_PLT_## e: return #e
#define CASE_BTC_REGTYPE_STR(e) case REG_## e: return #e
#define CASE_BTC_GDBG_STR(e) case BTC_DBG_## e: return #e
+#define CASE_BTC_H2CCMD(e) case SET_##e: return #e
static const char *id_to_polut(u32 id)
{
@@ -9529,6 +9602,38 @@ static const char *id_to_ant(u32 id)
}
}
+static const char *id_to_h2c(u32 id)
+{
+ switch (id) {
+ CASE_BTC_H2CCMD(REPORT_EN);
+ CASE_BTC_H2CCMD(SLOT_TABLE);
+ CASE_BTC_H2CCMD(MREG_TABLE);
+ CASE_BTC_H2CCMD(CX_POLICY);
+ CASE_BTC_H2CCMD(GPIO_DBG);
+ CASE_BTC_H2CCMD(DRV_INFO);
+ CASE_BTC_H2CCMD(DRV_EVENT);
+ CASE_BTC_H2CCMD(BT_WREG_ADDR);
+ CASE_BTC_H2CCMD(BT_WREG_VAL);
+ CASE_BTC_H2CCMD(BT_RREG_ADDR);
+ CASE_BTC_H2CCMD(BT_WL_CH_INFO);
+ CASE_BTC_H2CCMD(BT_INFO_REPORT);
+ CASE_BTC_H2CCMD(BT_IGNORE_WLAN_ACT);
+ CASE_BTC_H2CCMD(BT_TX_PWR);
+ CASE_BTC_H2CCMD(BT_LNA_CONSTRAIN);
+ CASE_BTC_H2CCMD(BT_QUERY_DEV_LIST);
+ CASE_BTC_H2CCMD(BT_QUERY_DEV_INFO);
+ CASE_BTC_H2CCMD(BT_PSD_REPORT);
+ CASE_BTC_H2CCMD(H2C_TEST);
+ CASE_BTC_H2CCMD(IOFLD_RF);
+ CASE_BTC_H2CCMD(IOFLD_BB);
+ CASE_BTC_H2CCMD(IOFLD_MAC);
+ CASE_BTC_H2CCMD(IOFLD_SCBD);
+ CASE_BTC_H2CCMD(H2C_MACRO);
+ default:
+ return "unknown";
+ }
+}
+
static
int scnprintf_segment(char *buf, size_t bufsz, const char *prefix, const u16 *data,
u8 len, u8 seg_len, u8 start_idx, u8 ring_len)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index a928140300b9..cb3a740e4719 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -3820,6 +3820,7 @@ struct rtw89_btc_btf_fwinfo {
};
#define RTW89_BTC_POLICY_MAXLEN 512
+#define BTC_H2C_MAXLENC 2020
struct rtw89_btc {
const struct rtw89_btc_ver *ver;
@@ -3839,11 +3840,14 @@ struct rtw89_btc {
u32 bt_req_len[RTW89_PHY_NUM];
u8 policy[RTW89_BTC_POLICY_MAXLEN];
+ u8 hbuf[BTC_H2C_MAXLENC]; /* H2C Macro buffer */
+ u8 hbuf_cnt; /* H2C cmd count in buffer */
u8 ant_type;
u8 btg_pos;
u8 io_oflld_type;
u16 policy_len;
u16 policy_type;
+ u16 hbuf_len; /* H2C used length, it sshould be <= BTC_H2C_MAXLEN */
u32 hubmsg_cnt;
bool bt_req_en;
bool update_policy_force;
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 07/11] wifi: rtw89: coex: Refine _reset_btc_var()
From: Ping-Ke Shih @ 2026-07-12 3:05 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260712030506.43438-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
To avoid the default value not match the real using scenario, it should
after assign desired default value after variable reset.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 68 ++++++++----
drivers/net/wireless/realtek/rtw89/coex.h | 8 ++
drivers/net/wireless/realtek/rtw89/core.h | 127 ++++++++++++++++++++++
3 files changed, 180 insertions(+), 23 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 07d054f59eb5..17290b2cb2c8 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -1048,44 +1048,52 @@ static int _send_fw_cmd(struct rtw89_dev *rtwdev, u8 h2c_class, u8 h2c_func,
return ret;
}
-#define BTC_BT_DEF_BR_TX_PWR 4
-#define BTC_BT_DEF_LE_TX_PWR 4
+#define BTC_DEFAULT_SIR_THRES 51 /* dB, BT Pin - This = TDD/FDD swtch thres */
+#define BTC_FDDR_TP_SETUP_TIME 1 /* in second */
+#define BTC_FDDR_TP_HOLD_TIME 3 /* in second */
+#define BTC_FDDR_RX_LOW_RATE_THRES 4 /* low rate for TDD swotch */
static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type)
{
struct rtw89_btc *btc = &rtwdev->btc;
- const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_cx *cx = &btc->cx;
- struct rtw89_btc_wl_info *wl = &btc->cx.wl;
- struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
- struct rtw89_btc_bt_link_info *bt_linfo = &bt->link_info;
- struct rtw89_btc_wl_link_info *wl_linfo;
- u8 i, j;
+ const struct rtw89_btc_ver *ver = btc->ver;
+ struct rtw89_btc_bt_info *bt0 = &cx->bt0;
+ struct rtw89_btc_bt_info *bt1 = &cx->bt1;
+ u8 i;
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s\n", __func__);
- if (type & BTC_RESET_CX)
+ if (type & BTC_RESET_CX) {
memset(cx, 0, sizeof(*cx));
-
- if (type & BTC_RESET_BTINFO) /* only for BT enable */
- memset(bt, 0, sizeof(*bt));
+ cx->bt_ext.max_tx_pwr = RTW89_BTC_BT_DEF_LE_TX_PWR;
+ cx->bt_ext.ant_iso_to_wl = RTW89_BTC_DEFAULT_ANISO;
+ }
+
+ if (type & BTC_RESET_BTINFO) {/* only for BT enable */
+ memset(bt0, 0, sizeof(*bt0));
+ bt0->link_info.bt_txpwr_desc.br_dbm = RTW89_BTC_BT_DEF_BR_TX_PWR;
+ bt0->link_info_56g.bt_txpwr_desc.br_dbm = RTW89_BTC_BT_DEF_BR_TX_PWR;
+ bt0->link_info.bt_txpwr_desc.le_dbm = RTW89_BTC_BT_DEF_LE_TX_PWR;
+ bt0->link_info_56g.bt_txpwr_desc.le_dbm = RTW89_BTC_BT_DEF_LE_TX_PWR;
+ bt0->ant_iso_to_wl = RTW89_BTC_DEFAULT_ANISO;
+ } else if (type & BTC_RESET_BTINFO2) {
+ memset(bt1, 0, sizeof(*bt1));
+ bt1->link_info.bt_txpwr_desc.br_dbm = RTW89_BTC_BT_DEF_BR_TX_PWR;
+ bt1->link_info_56g.bt_txpwr_desc.br_dbm = RTW89_BTC_BT_DEF_BR_TX_PWR;
+ bt1->link_info.bt_txpwr_desc.le_dbm = RTW89_BTC_BT_DEF_LE_TX_PWR;
+ bt1->link_info_56g.bt_txpwr_desc.le_dbm = RTW89_BTC_BT_DEF_LE_TX_PWR;
+ bt1->ant_iso_to_wl = RTW89_BTC_DEFAULT_ANISO;
+ }
if (type & BTC_RESET_CTRL) {
memset(&btc->ctrl, 0, sizeof(btc->ctrl));
- btc->manual_ctrl = false;
btc->ctrl.trace_step = FCXDEF_STEP;
}
/* Init Coex variables that are not zero */
if (type & BTC_RESET_DM) {
memset(&btc->dm, 0, sizeof(btc->dm));
- memset(bt_linfo->rssi_state, 0, sizeof(bt_linfo->rssi_state));
- for (j = RTW89_MAC_0; j <= RTW89_MAC_1; j++) {
- for (i = 0; i < RTW89_BE_BTC_WL_MAX_ROLE_NUMBER; i++) {
- wl_linfo = &wl->rlink_info[i][j];
- memset(wl_linfo->rssi_state, 0, sizeof(wl_linfo->rssi_state));
- }
- }
/* set the slot_now table to original */
btc->dm.tdma_now = t_def[CXTD_OFF];
@@ -1108,18 +1116,32 @@ static void _reset_btc_var(struct rtw89_dev *rtwdev, u8 type)
btc->policy_len = 0;
btc->bt_req_len[RTW89_PHY_0] = 0;
btc->bt_req_len[RTW89_PHY_1] = 0;
+ btc->hubmsg_cnt = 0;
+
btc->dm.coex_info_map = BTC_COEX_INFO_ALL;
btc->dm.wl_tx_limit.tx_time = BTC_MAX_TX_TIME_DEF;
btc->dm.wl_tx_limit.tx_retry = BTC_MAX_TX_RETRY_DEF;
+ btc->dm.bt_slot_flood = BTC_B1_MAX;
+ btc->dm.sir_thres = BTC_DEFAULT_SIR_THRES;
+ btc->dm.fddr_info.tp_setup_time = BTC_FDDR_TP_SETUP_TIME;
+ btc->dm.fddr_info.tp_hold_time = BTC_FDDR_TP_HOLD_TIME;
+ btc->dm.fddr_info.wl_rx_rate_thres = BTC_FDDR_RX_LOW_RATE_THRES;
+ btc->dm.fddt_info.type = BTC_FDDT_TYPE_AUTO;
+
btc->dm.wl_pre_agc_rb = BTC_PREAGC_NOTFOUND;
btc->dm.wl_btg_rx_rb = BTC_BTGCTRL_BB_GNT_NOTFOUND;
}
- if (type & BTC_RESET_MDINFO)
+ if (type & BTC_RESET_MDINFO) {
memset(&btc->mdinfo, 0, sizeof(btc->mdinfo));
- bt->link_info.bt_txpwr_desc.br_dbm = BTC_BT_DEF_BR_TX_PWR;
- bt->link_info.bt_txpwr_desc.le_dbm = BTC_BT_DEF_LE_TX_PWR;
+ if (ver->fcxinit == 10)
+ btc->mdinfo.md_v10.ant.isolation = RTW89_BTC_DEFAULT_ANISO;
+ else if (ver->fcxinit == 7)
+ btc->mdinfo.md_v7.ant.isolation = RTW89_BTC_DEFAULT_ANISO;
+ else
+ btc->mdinfo.md.ant.isolation = RTW89_BTC_DEFAULT_ANISO;
+ }
}
static u8 _search_reg_index(struct rtw89_dev *rtwdev, u8 mreg_num, u16 reg_type, u32 target)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h
index c127bd80d31c..fdd63e2c0837 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.h
+++ b/drivers/net/wireless/realtek/rtw89/coex.h
@@ -241,6 +241,14 @@ enum btc_3cx_type {
BTC_3CX_MAX,
};
+enum btc_fddt_type {
+ BTC_FDDT_TYPE_STOP,
+ BTC_FDDT_TYPE_AUTO,
+ BTC_FDDT_TYPE_FIX_TDD,
+ BTC_FDDT_TYPE_FIX_FULL_FDD,
+ BTC_FDDT_MAX,
+};
+
enum btc_chip_feature {
BTC_FEAT_PTA_ONOFF_CTRL = BIT(0), /* on/off ctrl by HW (not 0x73[2]) */
BTC_FEAT_NONBTG_GWL_THRU = BIT(1), /* non-BTG GNT_WL!=0 if GNT_BT = 1 */
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index cb3a740e4719..f784e8437292 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2462,6 +2462,9 @@ enum rtw89_btc_bt_func_type {
#define RTW89_BTC_BTC_SCAN_V1_FLAG_ENABLE BIT(0)
#define RTW89_BTC_BTC_SCAN_V1_FLAG_INTERLACE BIT(1)
+#define RTW89_BTC_BT_DEF_BR_TX_PWR 4
+#define RTW89_BTC_BT_DEF_LE_TX_PWR 4
+#define RTW89_BTC_DEFAULT_ANISO 10
struct rtw89_btc_bt_scan_info_v1 {
__le16 win;
@@ -2521,6 +2524,7 @@ struct rtw89_btc_bt_info {
u8 func_type;
u8 tx_power_now;
u8 tx_power_now_6g;
+ u8 ant_iso_to_wl; /* ant isolation between BTx and WL */
u8 fw_ver_mismatch: 1;
u8 band_56G_support: 1;
@@ -3474,6 +3478,123 @@ union rtw89_btc_fbtc_slot_u {
struct rtw89_btc_fbtc_slot_v7 v7[CXST_MAX];
};
+struct rtw89_btc_fddr_cell {
+ u8 en;
+ u8 wl_rx_max;
+ u8 wl_rx_min;
+};
+
+struct rtw89_btc_fddr_result {
+ u8 wl_rx_limit;
+ u8 wl_rx_limit_step[6]; /* record search process */
+ u8 search_cnt; /* the rx-limit serach count */
+ u32 wl_tp;
+ u32 wl_tp_step[6]; /* record search process */
+};
+
+struct rtw89_btc_fddr_train_info {
+ u8 rx_limit_pre;
+ u8 rx_limit_now;
+
+ u32 tp_rec_cnt;
+ u32 tp_avg_cnt;
+
+ u32 wl_tp_pre;
+ u32 wl_tp_now;
+};
+
+struct rtw89_btc_fddr_info {
+ u8 state; /* refer to enum btc_fddr_state */
+ u8 cell_now; /* wl rssi_level after filter LNA != 6 */
+ u8 cell_change;
+ u8 wl_low_rate;
+
+ u8 tp_setup_time; /* calculate TP after this value (in second) */
+ u8 tp_hold_time; /* TP calculation period (in second) */
+ u8 wl_rssi_thres[BTC_WL_RSSI_THMAX]; /* index 0 -> Max RSSI */
+
+ u8 search_mode; /* 0: search, 1:look-up */
+ u8 search_dir; /* 0: Max->Min, 1:Min->Max */
+
+ struct rtw89_btc_fddr_train_info tctrl; /* train flag */
+ struct rtw89_btc_fddr_result cell_result[BTC_WL_RSSI_THMAX + 1];
+ struct rtw89_btc_fddr_cell cell[BTC_WL_RSSI_THMAX + 1]; /* parameters */
+
+ u16 wl_rx_rate_thres; /* switch to TDD if rx_rate < this threshold */
+
+ u32 nrsn_map; /* the reason map for no-run fdd-traing */
+ u32 wl_rx_rate_now;
+};
+
+struct rtw89_btc_rpt_ctrl_a2dp_empty {
+ u32 cnt_empty; /* a2dp empty count */
+ u32 cnt_flowctrl; /* a2dp empty flow control counter */
+ u32 cnt_tx;
+ u32 cnt_ack;
+ u32 cnt_nack;
+};
+
+struct rtw89_btc_fddt_bt_stat {
+ struct rtw89_btc_rpt_ctrl_a2dp_empty a2dp_last;
+ u32 retry_last;
+};
+
+struct rtw89_btc_fddt_cell {
+ s8 wl_pwr_min;
+ s8 wl_pwr_max;
+ s8 bt_pwr_dec_max;
+ s8 bt_rx_gain;
+};
+
+struct rtw89_btc_fddt_fail_check { /* for cell stay in training */
+ u8 check_map; /* check pass condition if bit-map = 1 */
+ u8 bt_no_empty_cnt; /* 0-fail if no bt-empty >= th in train_cycle */
+ u8 wl_tp_ratio; /* 1-fail if wl tp rise ratio < th */
+ u8 wl_kpibtr_ratio; /* 2-fail if phase_now_tp < phase_last_tp * kpibtr_ratio */
+};
+
+struct rtw89_btc_fddt_break_check { /* for cell stay in training or train-ok */
+ u8 check_map; /* check break condition if bit-map = 1 */
+ u8 bt_no_empty_cnt; /* 0-break if no empty count >= th */
+ u8 wl_tp_ratio; /* 1-break if wl tp ratio < th (%) */
+ u8 wl_tp_low_bound; /* 2-break if wl tp (in Mbps) < th */
+
+ u8 cn; /* 3-break if (cn >= cn_limit) >= th cycle */
+ u8 cell_chg; /* 4-break if non-matched-RSSI >= th cycle */
+ s8 nhm_limit; /* 5-break if nhm >= th --> ill-condition */
+ u8 cn_limit; /* if condition number >= th --> ill-condition */
+};
+
+struct rtw89_btc_fddt_time_ctrl {
+ /* 1 TDD cycle = w1 + b1, FDD 1cycle = w1fdd-slot + b1fdd-slot */
+ u8 m_cycle; /* KPI Moving-Average-Cycle: 1~32 cycles */
+ u8 w_cycle; /* Start to calcul WKPI after this if train-phase change */
+ u8 k_cycle; /* Total kpi-estimate cycles for each training-step */
+ u8 rsvd;
+};
+
+struct rtw89_btc_fddt_train_info {
+ struct rtw89_btc_fddt_time_ctrl t_ctrl;
+ struct rtw89_btc_fddt_break_check b_chk;
+ struct rtw89_btc_fddt_fail_check f_chk;
+ struct rtw89_btc_fddt_cell cell_ul[5][5];
+ struct rtw89_btc_fddt_cell cell_dl[5][5];
+};
+
+struct rtw89_btc_fddt_info {
+ u8 type; /* refer to enum btc_fddt_type */
+ u8 result; /* fw send fdd-training status by c2h */
+ u8 state; /* refer to enum btc_fddt_state */
+
+ u8 wl_iot[6]; /* wl bssid */
+ u16 bt_iot; /* bt vendor-id */
+
+ u32 nrsn_map; /* the reason map for no-run fdd-traing */
+ struct rtw89_btc_fddt_bt_stat bt_stat; /* bt statistics */
+ struct rtw89_btc_fddt_train_info train;
+ struct rtw89_btc_fddt_train_info train_now;
+};
+
struct rtw89_btc_dm {
struct rtw89_btc_fbtc_outsrc_set_info ost_info_last; /* outsrc API setup info */
struct rtw89_btc_fbtc_outsrc_set_info ost_info; /* outsrc API setup info */
@@ -3493,6 +3614,8 @@ struct rtw89_btc_dm {
union rtw89_btc_dm_error_map error;
struct rtw89_btc_bind_info tdd_bind;
struct rtw89_btc_bind_info fdd_bind;
+ struct rtw89_btc_fddt_info fddt_info;
+ struct rtw89_btc_fddr_info fddr_info;
u32 cnt_dm[BTC_DCNT_NUM];
u32 cnt_notify[BTC_NCNT_NUM];
u8 ant_xmap[BTC_RF_NUM][BTC_ALL_BT_EZL]; /* WL-BT ANT interact-map */
@@ -3506,6 +3629,10 @@ struct rtw89_btc_dm {
u8 sit_xmap_last[BTC_RF_NUM][BTC_ALL_BT_EZL];
u8 fit_xmap_last[RTW89_PHY_NUM][BTC_ALL_BT_EZL];
+ u8 tdd_rssi_thres; /* The FDD/TDD switch RSSI (in %) */
+ u8 sir_thres; /* WL(Signal) to BT(interference Pin) ratio */
+ u8 sir_state[BTC_ALL_BT_EZL]; /* 1: WL RSSI > BTx-interference */
+
u32 update_slot_map;
u32 set_ant_path;
u32 e2g_slot_limit;
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 08/11] wifi: rtw89: coex: Correct SET_RFE settings
From: Ping-Ke Shih @ 2026-07-12 3:05 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260712030506.43438-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
Because of dual-BT & dual-MAC, RTL8922D has more complex antenna settings.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.h | 31 +++
drivers/net/wireless/realtek/rtw89/core.h | 11 +
drivers/net/wireless/realtek/rtw89/rtw8922d.c | 213 ++++++++++++++++--
3 files changed, 231 insertions(+), 24 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.h b/drivers/net/wireless/realtek/rtw89/coex.h
index fdd63e2c0837..e17407696d8a 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.h
+++ b/drivers/net/wireless/realtek/rtw89/coex.h
@@ -143,6 +143,11 @@ enum btc_switch {
BTC_SWITCH_EXTERNAL
};
+enum btc_ant_switch_type {
+ BTC_SWITCH_V1_NONE = 0, /* independent antenna */
+ BTC_SWITCH_V1_INTERNAL, /* internal-switch: BTGA structure */
+};
+
enum btc_pkt_type {
PACKET_DHCP,
PACKET_ARP,
@@ -262,6 +267,32 @@ enum btc_chip_feature {
BTC_FEAT_DUAL_BTGA = BIT(9) /* the future A-Die */
};
+enum btc_efuse_ant_function_map {
+ BTC_EFMAP_NONE = 0,
+ BTC_EFMAP_BT0 = BIT(0),
+ BTC_EFMAP_BT1 = BIT(1),
+ BTC_EFMAP_ZB = BIT(2), /* ZB or thread */
+ BTC_EFMAP_24GP = BIT(3),
+ BTC_EFMAP_ULL = BIT(4),
+};
+
+enum btc_extsoc_interface { /* cx->other.hw_coex */
+ BTC_EXTSOC_INTF_NONE = 0,
+ BTC_EXTSOC_INTF_PTA = BIT(0),
+ BTC_EXTSOC_INTF_MBX = BIT(1),
+ BTC_EXTSOC_INTF_SWIO = BIT(2),
+ BTC_EXTSOC_INTF_MAX,
+};
+
+enum btc_esoc_type {
+ BTC_ESOC_NONE,
+ BTC_ESOC_8761,
+ BTC_ESOC_8771,
+ BTC_ESOC_SILAB_MG21,
+ BTC_ESOC_NORDI_NRF52840,
+ BTC_ESOC_MAX,
+};
+
enum btc_wl_mode {
BTC_WL_MODE_11B = 0,
BTC_WL_MODE_11A = 1,
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index f784e8437292..d876de21482f 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -2434,6 +2434,15 @@ struct rtw89_btc_wl_tx_limit_para {
u16 tx_retry;
};
+struct rtw89_btc_wl_trx_nss_para {
+ u8 tx_limit;
+ u8 rx_limit;
+ u8 tx_ss;
+ u8 rx_ss;
+ u8 tx_path;
+ u8 rx_path;
+};
+
enum rtw89_btc_bt_scan_type {
BTC_SCAN_INQ = 0,
BTC_SCAN_PAGE,
@@ -3616,6 +3625,7 @@ struct rtw89_btc_dm {
struct rtw89_btc_bind_info fdd_bind;
struct rtw89_btc_fddt_info fddt_info;
struct rtw89_btc_fddr_info fddr_info;
+ struct rtw89_btc_wl_trx_nss_para wl_trx_nss;
u32 cnt_dm[BTC_DCNT_NUM];
u32 cnt_notify[BTC_NCNT_NUM];
u8 ant_xmap[BTC_RF_NUM][BTC_ALL_BT_EZL]; /* WL-BT ANT interact-map */
@@ -3664,6 +3674,7 @@ struct rtw89_btc_dm {
u8 wl_tx_pwr_phy_map;
u8 vid;
u8 client_ps_tdma_on;
+ u8 wl_trx_nss_en;
u8 wl_pre_agc: 2;
u8 wl_lna2: 1;
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index aeade858ce95..c28670e82c3e 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -3106,46 +3106,211 @@ static u32 rtw8922d_chan_to_rf18_val(struct rtw89_dev *rtwdev,
static void rtw8922d_btc_set_rfe(struct rtw89_dev *rtwdev)
{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ struct rtw89_btc_cx *cx = &btc->cx;
union rtw89_btc_module_info *md = &rtwdev->btc.mdinfo;
- struct rtw89_btc_module_v7 *module = &md->md_v7;
+ struct rtw89_btc_module_v10 *module = &md->md_v10;
+ u8 efuse_bt_func, efuse_ant_info, bt_sw_gpio_pos;
+ u8 is_combo, is_bt_share;
+ rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC], %s !!\n", __func__);
+
+ /* get from final capability of device */
module->rfe_type = rtwdev->efuse.rfe_type;
module->kt_ver = rtwdev->hal.cv;
- module->bt_solo = 0;
- module->switch_type = BTC_SWITCH_INTERNAL;
+ module->kt_ver_adie = rtwdev->hal.acv;
module->wa_type = 0;
+ dm->wl_trx_nss_en = 0;
- module->ant.type = BTC_ANT_SHARED;
module->ant.num = 2;
- module->ant.isolation = 10;
- module->ant.diversity = 0;
- module->ant.single_pos = RF_PATH_A;
- module->ant.btg_pos = RF_PATH_B;
+ module->ant.single_pos = BTC_RF_S0; /* WL 1ss+1Ant 0:s0(A)/ 1:s1(B) */
- if (module->kt_ver <= 1)
- module->wa_type |= BTC_WA_HFP_ZB;
+ /* set default antenna isolation */
+ cx->bt0.ant_iso_to_wl = module->ant.isolation;
+ cx->bt1.ant_iso_to_wl = module->ant.isolation;
- rtwdev->btc.cx.bt_ext.func_type = BTC_3CX_NONE;
+ module->ant.stream_cnt = 2;
+ module->ant.btg_pos = BTC_RF_S1; /* BTG0 at WL-S1 */
+ module->ant.btg1_pos = BTC_RF_S0; /* BTG1 at WL-S0 if Dual-BTGA */
- if (module->rfe_type == 0) {
- rtwdev->btc.dm.error.map.rfe_type0 = true;
- return;
+ cx->bt0.band_56G_support = 1;
+ cx->bt1.band_56G_support = 1;
+ cx->bt0.func_type = BTC_BTF_BT;
+ cx->bt1.func_type = BTC_BTF_BT;
+
+ efuse_bt_func = rtwdev->efuse.bt_setting_2;
+
+ switch ((efuse_bt_func & 0xe0) >> 5) { /* 0xcd[7:5] */
+ default:
+ case 0:
+ case 1:
+ bt_sw_gpio_pos = 5;
+ break;
+ case 2:
+ bt_sw_gpio_pos = 11;
+ break;
+ case 3:
+ bt_sw_gpio_pos = 15;
+ break;
+ case 4:
+ bt_sw_gpio_pos = 20;
+ break;
}
- module->ant.num = (module->rfe_type % 2) ? 2 : 3;
+ efuse_bt_func &= 0x1f; /* 0xcd[4:0] */
+ efuse_ant_info = rtwdev->efuse.bt_setting_3;
+ module->ant.num = (efuse_ant_info & 0xe0) >> 5; /* 0xCE[7:5] */
+ is_combo = (efuse_ant_info & 0xe) >> 1; /* 0xCE[3:1] */
+ is_bt_share = efuse_ant_info & BIT(0); /* 0xCE[0] */
- if (module->kt_ver == 0)
- module->ant.num = 2;
+ memset(dm->ant_xmap, 0, sizeof(dm->ant_xmap));
- if (module->ant.num == 3) {
- module->ant.type = BTC_ANT_DEDICATED;
- module->bt_pos = BTC_BT_ALONE;
- } else {
+ /* To-Do: "RFE_TYpe" to "ant.num" translation */
+ switch (module->ant.num) {
+ case 1: /* 1-Ant WL-S0 only & BT0 only */
module->ant.type = BTC_ANT_SHARED;
- module->bt_pos = BTC_BT_BTG;
+ module->bt0_pos = BTC_BT_BTG;
+ module->bt0_sw_type = BTC_SWITCH_INTERNAL;
+ module->ant.btg_pos = BTC_RF_S0; /* BTG0 at WL-S0 */
+ module->ant.stream_cnt = 1;
+ module->ant.func[0] = BTC_EFMAP_BT0;
+ dm->ant_xmap[BTC_RF_S0][BTC_BT_1ST] = 1; /* BT0 shared with S0*/
+ dm->ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 0; /* WL 1T1R no RF-S1 */
+ break;
+ case 2: /* 2-Ant */
+ default:
+ if (is_combo) {
+ if (efuse_bt_func == (BTC_EFMAP_BT0 | BTC_EFMAP_BT1))
+ module->ant.func[0] = BTC_EFMAP_BT1;
+
+ module->ant.func[1] = BTC_EFMAP_BT0;
+ } else {
+ module->ant.func[0] = BTC_EFMAP_NONE;
+ module->ant.func[1] = BTC_EFMAP_NONE;
+ }
+
+ if (is_bt_share) { /* WL-S0 + (WL-S1 & BT0-S1) */
+ module->ant.type = BTC_ANT_SHARED;
+ module->bt0_pos = BTC_BT_BTG;
+ module->bt0_sw_type = BTC_SWITCH_INTERNAL;
+ dm->ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 1;
+ } else { /* WL-S0 + BT0-S1 */
+ module->ant.type = BTC_ANT_DEDICATED;
+ module->bt0_pos = BTC_BT_ALONE;
+ module->bt0_sw_type = BTC_SWITCH_V1_NONE;
+ }
+
+ if (module->ant.func[0] == BTC_EFMAP_BT1) { /* if 2nd BT exist */
+ dm->ant_xmap[BTC_RF_S0][BTC_BT_2ND] = 1;
+ if (module->rfe_type == 12) { /* WL-S0 & BT1 by SPDT */
+ module->bt1_pos = BTC_BT_ALONE;
+ /* Todo: set SPDT GPIO-ctrl */
+ module->bt1_sw_type = bt_sw_gpio_pos;
+ } else { /* WL-S0 & BT1-S1 by BTGA */
+ module->bt1_pos = BTC_BT_BTG;
+ module->bt1_sw_type = BTC_SWITCH_INTERNAL;
+ }
+ }
+
+ dm->wl_trx_nss_en = 1; /* 1ss MIMO-PS capability if 1-BT */
+ break;
+ case 3: /* 3-Ant, 3 different BT-configuration */
+ if (is_bt_share) {
+ module->ant.func[0] = BTC_EFMAP_NONE;
+ module->ant.func[1] = BTC_EFMAP_BT0;
+ module->ant.func[2] = efuse_bt_func & (~BTC_EFMAP_BT0);
+ module->ant.type = BTC_ANT_SHARED;
+ module->bt0_pos = BTC_BT_BTG;
+ module->bt0_sw_type = BTC_SWITCH_INTERNAL;
+ dm->ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 1;
+ dm->wl_trx_nss_en = 1; /* 1ss MIMO-PS capability */
+ } else {
+ module->ant.func[0] = BTC_EFMAP_NONE;
+ module->ant.func[1] = BTC_EFMAP_NONE;
+ module->ant.func[2] = efuse_bt_func;
+ module->ant.type = BTC_ANT_DEDICATED;
+ module->bt0_pos = BTC_BT_ALONE;
+ module->bt0_sw_type = BTC_SWITCH_V1_NONE;
+ }
+
+ module->bt1_pos = BTC_BT_ALONE; /* BT1 may exist or not */
+ module->bt1_sw_type = BTC_SWITCH_V1_NONE;
+ break;
+ case 4: /* 4-Ant, WL-S0 + WL-S1 + BT0 + BT1 */
+ module->ant.func[0] = BTC_EFMAP_NONE;
+ module->ant.func[1] = BTC_EFMAP_NONE;
+ module->ant.func[2] = BTC_EFMAP_BT0;
+ module->ant.func[3] = efuse_bt_func & (~BTC_EFMAP_BT0);
+ module->ant.type = BTC_ANT_DEDICATED;
+ module->bt0_pos = BTC_BT_ALONE;
+ module->bt0_sw_type = BTC_SWITCH_V1_NONE;
+ module->bt1_pos = BTC_BT_ALONE;
+ module->bt1_sw_type = BTC_SWITCH_V1_NONE;
+ break;
+ case 5:
+ module->ant.func[0] = BTC_EFMAP_NONE;
+ module->ant.func[1] = BTC_EFMAP_NONE;
+ module->ant.func[2] = BTC_EFMAP_BT0;
+ module->ant.func[3] = BTC_EFMAP_BT1;
+ module->ant.func[4] = BTC_EFMAP_ZB;
+ module->ant.type = BTC_ANT_DEDICATED;
+ module->bt0_pos = BTC_BT_ALONE;
+ module->bt0_sw_type = BTC_SWITCH_V1_NONE;
+ module->bt1_pos = BTC_BT_ALONE;
+ module->bt1_sw_type = BTC_SWITCH_V1_NONE;
+ break;
}
- rtwdev->btc.btg_pos = module->ant.btg_pos;
- rtwdev->btc.ant_type = module->ant.type;
+
+ /*
+ * if only BT0 at BTGA: 2-Ant, 3-Ant(BT1 used dedicated-ant)
+ * can setup dm->wl_trx_nss_en = 1, WL MIMO-PS to 1T1R
+ * (WL at WL-S0 only, BT0 at WL-S1)
+ * tx_limit/rx_limit is decided by _set_trx_nss()
+ */
+ if (dm->wl_trx_nss_en &&
+ (dm->wl_trx_nss.tx_limit && dm->wl_trx_nss.rx_limit)) {
+ module->ant.type = BTC_ANT_DEDICATED;
+ module->ant.stream_cnt = 1;
+ dm->ant_xmap[BTC_RF_S0][BTC_BT_1ST] = 0; /* wl 1ss-> RF-S0 */
+ dm->ant_xmap[BTC_RF_S1][BTC_BT_1ST] = 0; /* BT0-> RF-S1 */
+ dm->ant_xmap[BTC_RF_S0][BTC_BT_2ND] = 0;
+ dm->ant_xmap[BTC_RF_S1][BTC_BT_2ND] = 0; /* BT1 -> 3rd Ant */
+ }
+
+ /*
+ * Todo: call HALBB API to set BT0/1 at WL_S0 or WL_S1
+ * r_sel_gnt_bt_rx_path0[1:0], r_sel_gnt_bt_rx_path1[1:0]
+ * WL_S0 with BT1 -> r_sel_gnt_bt_rx_path0[1:0]= 2b'10
+ * WL_S1 with BT0 -> r_sel_gnt_bt_rx_path1[1:0]= 2b'01
+ */
+
+ /* To Do: setup ext-SOC coex if exist */
+ switch (cx->bt_ext.chip_id) {
+ default:
+ case BTC_ESOC_NONE:
+ memset(&cx->bt_ext, 0, sizeof(struct rtw89_btc_extsoc_info));
+ cx->bt_ext.max_tx_pwr = RTW89_BTC_BT_DEF_LE_TX_PWR;
+ cx->bt_ext.ant_iso_to_wl = RTW89_BTC_DEFAULT_ANISO;
+ break;
+ case BTC_ESOC_8771:
+ cx->bt_ext.func_type = BTC_BTF_THREAD;
+ cx->bt_ext.hw_coex = BTC_EXTSOC_INTF_PTA;
+ cx->bt_ext.rf_band_map = 0x1; /* 2.4GHz only */
+ cx->bt_ext.link_weight[BTC_BT_B2G] = 10;
+ cx->bt_ext.profile_map[BTC_BT_B2G] |= BTC_BT_THREAD;
+ /* use GPIO 12~15 for Ext-4-wire-PTA */
+ cx->bt_ext.hpta_cfg = BIT(12) | BIT(13) | BIT(14) | BIT(15);
+ /* for Ext-SOC locate at Ant-2 */
+ if (module->ant.num >= 5)
+ module->ant.func[4] = BTC_EFMAP_ZB;
+ else
+ module->ant.func[module->ant.num - 1] = BTC_EFMAP_ZB;
+ break;
+ }
+
+ dm->ant_xmap[BTC_RF_S0][BTC_BT_EXT] = 0;
+ dm->ant_xmap[BTC_RF_S1][BTC_BT_EXT] = 0;
}
static void rtw8922d_btc_init_cfg(struct rtw89_dev *rtwdev)
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 09/11] wifi: rtw89: coex: Add firmware report control report v11
From: Ping-Ke Shih @ 2026-07-12 3:05 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260712030506.43438-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
In the version 11 report control report, firmware will report firmware
build date, version. And Bluetooth to Wi-Fi scoreboard value will be
read at Wi-Fi firmware and update to Wi-Fi driver.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 218 +++++++++++++++++++++-
drivers/net/wireless/realtek/rtw89/core.h | 26 +++
2 files changed, 243 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index 17290b2cb2c8..c2356d6d9811 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -1417,6 +1417,40 @@ static void _chk_btc_err(struct rtw89_dev *rtwdev, u8 type, u32 cnt)
dm->error.map.bt_slot_drift = false;
break;
+ case BTC_DCNT_WL_STA_NTFY:
+ cnt = dm->cnt_notify[BTC_NCNT_WL_STA] -
+ dm->cnt_notify[BTC_NCNT_WL_STA_LAST];
+
+ dm->cnt_notify[BTC_NCNT_WL_STA_LAST] =
+ dm->cnt_notify[BTC_NCNT_WL_STA];
+
+ if (cnt == 0 &&
+ (dm->tdd_bind.wl_link_mode != BTC_WLINK_NOLINK ||
+ dm->fdd_bind.wl_link_mode != BTC_WLINK_NOLINK))
+ dm->cnt_dm[BTC_DCNT_WL_STA_NTFY]++;
+ else
+ dm->cnt_dm[BTC_DCNT_WL_STA_NTFY] = 0;
+
+ if (dm->cnt_dm[BTC_DCNT_WL_STA_NTFY] >= BTC_CHK_HANG_MAX)
+ dm->error.map.wl_no_sta_ntfy = true;
+ else
+ dm->error.map.wl_no_sta_ntfy = false;
+ break;
+ case BTC_DCNT_W2B_SCBD_NOSYNC:
+ if (!(rtwdev->chip->para_ver & BTC_FEAT_MULTI_PTA))
+ return; /* return if no-support W2B scbd readback */
+
+ if (wl->scbd_rb[BTC_BT_1ST] != wl->scbd[BTC_BT_1ST] ||
+ wl->scbd_rb[BTC_BT_2ND] != wl->scbd[BTC_BT_2ND])
+ dm->cnt_dm[BTC_DCNT_W2B_SCBD_NOSYNC]++;
+ else
+ dm->cnt_dm[BTC_DCNT_W2B_SCBD_NOSYNC] = 0;
+
+ if (dm->cnt_dm[BTC_DCNT_W2B_SCBD_NOSYNC] >= BTC_CHK_HANG_MAX)
+ dm->error.map.w2b_scbd_no_sync = true;
+ else
+ dm->error.map.w2b_scbd_no_sync = false;
+ break;
}
}
@@ -1564,6 +1598,7 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
const struct rtw89_btc_ver *ver = btc->ver;
struct rtw89_btc_dm *dm = &btc->dm;
struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
+ struct rtw89_btc_cx *cx = &btc->cx;
struct rtw89_btc_wl_info *wl = &btc->cx.wl;
struct rtw89_btc_bt_info *bt = &btc->cx.bt0;
union rtw89_btc_fbtc_rpt_ctrl_ver_info *prpt = NULL;
@@ -1574,7 +1609,8 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
u16 wl_slot_set = 0, wl_slot_real = 0, val16;
u32 trace_step = 0, rpt_len = 0, diff_t = 0;
u32 cnt_leak_slot, bt_slot_real, bt_slot_set, cnt_rx_imr;
- u8 i, val = 0, val1, val2;
+ u8 i, j, val = 0, val1, val2;
+ u32 *bt_cnt, start_idx;
rtw89_debug(rtwdev, RTW89_DBG_BTC,
"[BTC], %s(): index:%d\n",
@@ -1626,6 +1662,10 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
pfinfo = &pfwinfo->rpt_ctrl.finfo.v7;
pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v7);
fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v7.fver;
+ } else if (ver->fcxbtcrpt == 11) {
+ pfinfo = &pfwinfo->rpt_ctrl.finfo.v11;
+ pcinfo->req_len = sizeof(pfwinfo->rpt_ctrl.finfo.v11);
+ fwsubver->fcxbtcrpt = pfwinfo->rpt_ctrl.finfo.v11.fver;
} else {
goto err;
}
@@ -2031,6 +2071,70 @@ static u32 _chk_btc_report(struct rtw89_dev *rtwdev,
_chk_btc_err(rtwdev, BTC_DCNT_RPT_HANG, val1);
_chk_btc_err(rtwdev, BTC_DCNT_WL_FW_VER_MATCH, 0);
_chk_btc_err(rtwdev, BTC_DCNT_BTTX_HANG, 0);
+ } else if (ver->fcxbtcrpt == 11) {
+ prpt->v11 = pfwinfo->rpt_ctrl.finfo.v11;
+ pfwinfo->rpt_en_map = le32_to_cpu(prpt->v11.rpt_info.en);
+ wl->ver_info.fw_coex = le32_to_cpu(prpt->v11.rpt_info.cx_ver);
+ wl->ver_info.fw = le32_to_cpu(prpt->v11.rpt_info.fw_ver);
+
+ memset(wl->ver_info.build_time, 0,
+ sizeof(wl->ver_info.build_time));
+ memcpy(wl->ver_info.build_time,
+ prpt->v11.build_time,
+ sizeof(wl->ver_info.build_time));
+
+ memset(wl->ver_info.build_date, 0,
+ sizeof(wl->ver_info.build_date));
+ memcpy(wl->ver_info.build_date,
+ prpt->v11.build_date,
+ sizeof(wl->ver_info.build_date));
+
+ for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++)
+ memcpy(&dm->gnt_set[i], &prpt->v11.gnt_val[i][0],
+ sizeof(dm->gnt_set[i]));
+
+ for (i = BTC_BT_1ST; i <= BTC_BT_EXT; i++) {
+ if (i == BTC_BT_EXT) {
+ if (cx->bt_ext.func_type == BTC_BTF_NONE)
+ continue;
+ bt_cnt = cx->bt_ext.bcnt;
+ } else if (i == BTC_BT_2ND) {
+ if (!(rtwdev->chip->para_ver & BTC_FEAT_DUAL_BT))
+ continue;
+ bt_cnt = cx->bt1.bcnt;
+ wl->scbd_rb[i] = le32_to_cpu(prpt->v11.scbd_w2b[i]);
+ cx->bt1.scbd_rb = le32_to_cpu(prpt->v11.scbd_b2w[i]);
+ } else {
+ bt_cnt = cx->bt0.bcnt;
+ wl->scbd_rb[i] = le32_to_cpu(prpt->v11.scbd_w2b[i]);
+ cx->bt0.scbd_rb = le32_to_cpu(prpt->v11.scbd_b2w[i]);
+ }
+
+ start_idx = BTC_BCNT_HIPRI_TX;
+ for (j = BTC_BCNT_HI_TX_V105; j <= BTC_BCNT_LO_RX_V105 ; j++)
+ bt_cnt[start_idx++] = le16_to_cpu(prpt->v11.bt_cnt[i][j]);
+
+ /* check if polut counter increase */
+ val1 = le16_to_cpu(prpt->v11.bt_cnt[i][BTC_BCNT_POLLUTED_V105]);
+ if (val1 > bt_cnt[BTC_BCNT_POLUT_NOW]) /* cnt increase*/
+ val2 = val1 - bt_cnt[BTC_BCNT_POLUT_NOW];
+ else
+ val2 = val1; /* overflow */
+
+ bt_cnt[BTC_BCNT_POLUT_DIFF] = val2;
+ bt_cnt[BTC_BCNT_POLUT_NOW] = val1;
+
+ if (i <= BTC_BT_2ND)
+ bt_cnt[BTC_BCNT_SCBDREAD]++;
+ }
+ dm->scbd_w2b_update = true;
+ dm->scbd_b2w_update = true;
+
+ _chk_btc_err(rtwdev, BTC_DCNT_BTCNT_HANG, 0);
+ _chk_btc_err(rtwdev, BTC_DCNT_WL_FW_VER_MATCH, 0);
+ _chk_btc_err(rtwdev, BTC_DCNT_BTTX_HANG, 0);
+ _chk_btc_err(rtwdev, BTC_DCNT_WL_STA_NTFY, 0);
+ _chk_btc_err(rtwdev, BTC_DCNT_W2B_SCBD_NOSYNC, 0);
} else {
goto err;
}
@@ -11953,6 +12057,116 @@ static int _show_summary_v8(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
return p - buf;
}
+static int _show_summary_v11(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
+{
+ struct rtw89_btc_btf_fwinfo *pfwinfo = &rtwdev->btc.fwinfo;
+ struct rtw89_btc_rpt_cmn_info *pcinfo = NULL;
+ struct rtw89_btc_fbtc_rpt_ctrl_v11 *prptctrl = NULL;
+ struct rtw89_btc_cx *cx = &rtwdev->btc.cx;
+ struct rtw89_btc_dm *dm = &rtwdev->btc.dm;
+ struct rtw89_btc_wl_info *wl = &cx->wl;
+ u32 *cnt = rtwdev->btc.dm.cnt_notify;
+ char *p = buf, *end = buf + bufsz;
+ u32 cnt_sum = 0;
+ u8 i;
+
+ if (!(dm->coex_info_map & BTC_COEX_INFO_SUMMARY))
+ return 0;
+
+ p += scnprintf(p, end - p, "%s",
+ "\n\r========== [Statistics] ==========");
+
+ pcinfo = &pfwinfo->rpt_ctrl.cinfo;
+ if (pcinfo->valid && wl->status.map.lps != BTC_LPS_RF_OFF &&
+ !wl->status.map.rf_off) {
+ prptctrl = &pfwinfo->rpt_ctrl.finfo.v11;
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : h2c_cnt=%d(fail:%d, fw_recv:%d), c2h_cnt=%d(fw_send:%d, len:%d, max:fw-%d/drv-%d), ",
+ "[summary]", pfwinfo->cnt_h2c,
+ pfwinfo->cnt_h2c_fail,
+ le16_to_cpu(prptctrl->rpt_info.cnt_h2c),
+ pfwinfo->cnt_c2h,
+ le16_to_cpu(prptctrl->rpt_info.cnt_c2h),
+ le16_to_cpu(prptctrl->rpt_info.len_c2h),
+ (prptctrl->rpt_len_max_h << 8) + prptctrl->rpt_len_max_l,
+ rtwdev->btc.ver->info_buf);
+
+ p += scnprintf(p, end - p,
+ "rpt_cnt=%d(fw_send:%d), rpt_map=0x%x",
+ pfwinfo->event[BTF_EVNT_RPT],
+ le16_to_cpu(prptctrl->rpt_info.cnt),
+ le32_to_cpu(prptctrl->rpt_info.en));
+
+ if (dm->error.map.wl_fw_hang)
+ p += scnprintf(p, end - p, " (WL FW Hang!!)");
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : send_ok:%d, send_fail:%d, recv:%d, ",
+ "[mailbox]",
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_ok),
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_send_fail),
+ le32_to_cpu(prptctrl->bt_mbx_info.cnt_recv));
+
+ p += scnprintf(p, end - p,
+ "A2DP_empty:%d(stop:%d/tx:%d/ack:%d/nack:%d)",
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_empty),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_flowctrl),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_tx),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_ack),
+ le32_to_cpu(prptctrl->bt_mbx_info.a2dp.cnt_nack));
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : wl_rfk[req:%d/go:%d/reject:%d/tout:%d/time:%dms]",
+ "[RFK/LPS]", wl->wcnt[BTC_WCNT_RFK_REQ],
+ wl->wcnt[BTC_WCNT_RFK_GO],
+ wl->wcnt[BTC_WCNT_RFK_REJECT],
+ wl->wcnt[BTC_WCNT_RFK_TIMEOUT],
+ wl->rfk_info.proc_time);
+
+ p += scnprintf(p, end - p, ", AOAC[RF_on:%d/RF_off:%d]",
+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_on),
+ le16_to_cpu(prptctrl->rpt_info.cnt_aoac_rf_off));
+ } else {
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : h2c_cnt=%d(fail:%d), c2h_cnt=%d (lps=%d/rf_off=%d)",
+ "[summary]",
+ pfwinfo->cnt_h2c, pfwinfo->cnt_h2c_fail,
+ pfwinfo->cnt_c2h,
+ wl->status.map.lps, wl->status.map.rf_off);
+ }
+
+ for (i = 0; i < BTC_NCNT_NUM; i++)
+ cnt_sum += dm->cnt_notify[i];
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : total=%d, show_coex_info=%d, power_on=%d, init_coex=%d, ",
+ "[notify_cnt]",
+ cnt_sum, cnt[BTC_NCNT_SHOW_COEX_INFO],
+ cnt[BTC_NCNT_POWER_ON], cnt[BTC_NCNT_INIT_COEX]);
+
+ p += scnprintf(p, end - p,
+ "power_off=%d, radio_state=%d, role_info=%d, wl_rfk=%d, wl_sta=%d",
+ cnt[BTC_NCNT_POWER_OFF], cnt[BTC_NCNT_RADIO_STATE],
+ cnt[BTC_NCNT_ROLE_INFO], cnt[BTC_NCNT_WL_RFK],
+ cnt[BTC_NCNT_WL_STA]);
+
+ p += scnprintf(p, end - p,
+ "\n\r %-15s : scan_start=%d, scan_finish=%d, switch_band=%d, switch_chbw=%d, special_pkt=%d, ",
+ "[notify_cnt]",
+ cnt[BTC_NCNT_SCAN_START], cnt[BTC_NCNT_SCAN_FINISH],
+ cnt[BTC_NCNT_SWITCH_BAND], cnt[BTC_NCNT_SWITCH_CHBW],
+ cnt[BTC_NCNT_SPECIAL_PACKET]);
+
+ p += scnprintf(p, end - p,
+ "timer=%d, customerize=%d, hub_msg=%d, chg_fw=%d, send_cc=%d",
+ cnt[BTC_NCNT_TIMER], cnt[BTC_NCNT_CUSTOMERIZE],
+ rtwdev->btc.hubmsg_cnt, cnt[BTC_NCNT_RESUME_DL_FW],
+ cnt[BTC_NCNT_COUNTRYCODE]);
+
+ return p - buf;
+}
+
ssize_t rtw89_btc_dump_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
{
struct rtw89_btc *btc = &rtwdev->btc;
@@ -12016,6 +12230,8 @@ ssize_t rtw89_btc_dump_info(struct rtw89_dev *rtwdev, char *buf, size_t bufsz)
p += _show_summary_v7(rtwdev, p, end - p);
else if (ver->fcxbtcrpt == 8)
p += _show_summary_v8(rtwdev, p, end - p);
+ else if (ver->fcxbtcrpt == 11)
+ p += _show_summary_v11(rtwdev, p, end - p);
return p - buf;
}
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index d876de21482f..e7e72f742847 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -1406,6 +1406,7 @@ enum rtw89_btc_dcnt {
BTC_DCNT_WL_FW_VER_MATCH,
BTC_DCNT_NULL_TX_FAIL,
BTC_DCNT_WL_STA_NTFY,
+ BTC_DCNT_W2B_SCBD_NOSYNC,
BTC_DCNT_NUM,
};
@@ -2058,6 +2059,8 @@ struct rtw89_btc_wl_role_info { /* Logic dynamic using */
};
struct rtw89_btc_wl_ver_info {
+ char build_time[12];
+ char build_date[12];
u32 fw_coex; /* match with which coex_ver */
u32 fw;
u32 mac;
@@ -2245,6 +2248,7 @@ struct rtw89_btc_dm_emap {
u32 h2c_buffer_over: 1;
u32 bt_tx_hang: 1; /* for SNR too low bug, BT has no Tx req*/
u32 wl_no_sta_ntfy: 1;
+ u32 w2b_scbd_no_sync: 1;
u32 h2c_bmap_mismatch: 1;
u32 c2h_bmap_mismatch: 1;
@@ -2784,6 +2788,26 @@ struct rtw89_btc_fbtc_rpt_ctrl_v8 {
struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info;
} __packed;
+struct rtw89_btc_fbtc_rpt_ctrl_v11 {
+ u8 fver;
+ u8 rsvd0;
+ u8 rpt_len_max_l; /* BTC_RPT_MAX bit0~7 */
+ u8 rpt_len_max_h; /* BTC_RPT_MAX bit8~15 */
+
+ u8 build_time[12];
+ u8 build_date[12];
+
+ u8 gnt_val[RTW89_PHY_NUM][8]; /* gwl/gbt012 refer to struct btc_gnt_ctrl */
+ __le16 bt_cnt[BTC_ALL_BT_EZL][BTC_BCNT_STA_MAX_V105];
+
+ struct rtw89_btc_fbtc_rpt_ctrl_info_v8 rpt_info;
+ struct rtw89_btc_fbtc_rpt_ctrl_bt_mailbox bt_mbx_info;
+
+ __le32 error_code;
+ __le32 scbd_w2b[2];
+ __le32 scbd_b2w[2];
+} __packed;
+
union rtw89_btc_fbtc_rpt_ctrl_ver_info {
struct rtw89_btc_fbtc_rpt_ctrl_v1 v1;
struct rtw89_btc_fbtc_rpt_ctrl_v4 v4;
@@ -2791,6 +2815,7 @@ union rtw89_btc_fbtc_rpt_ctrl_ver_info {
struct rtw89_btc_fbtc_rpt_ctrl_v105 v105;
struct rtw89_btc_fbtc_rpt_ctrl_v7 v7;
struct rtw89_btc_fbtc_rpt_ctrl_v8 v8;
+ struct rtw89_btc_fbtc_rpt_ctrl_v11 v11;
};
enum rtw89_fbtc_ext_ctrl_type {
@@ -3691,6 +3716,7 @@ struct rtw89_btc_dm {
u8 lps_ctrl_change: 1;
u8 scbd_write_instant;
bool scbd_b2w_update;
+ bool scbd_w2b_update;
bool pre_agc_chg;
};
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 10/11] wifi: rtw89: coex: update external control length by case
From: Ping-Ke Shih @ 2026-07-12 3:05 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260712030506.43438-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
Update recommend external control slot length to driver. Some of the
Wi-Fi feature has its time slot requirement can not be simply controlled
by coexistence firmware TDMA timer. For example: Wi-Fi scan/MCC etc.
In the same time, coexistence need to tell driver the recommend Bluetooth
slot length to make sure Bluetooth can still has enough time slot to
traffic.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 70 +++++++++++++++++++++++
drivers/net/wireless/realtek/rtw89/core.c | 11 ++--
drivers/net/wireless/realtek/rtw89/core.h | 4 +-
3 files changed, 80 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index c2356d6d9811..a6b1aa2cb24e 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -526,6 +526,14 @@ enum btc_cx_poicy_main_type {
BTC_CXP_MAIN_MAX
};
+enum btc_bslot_length {
+ BTC_BSLOT_A2DP_HID = 60,
+ BTC_BSLOT_A2DP = 50,
+ BTC_BSLOT_A2DP_2 = 40,
+ BTC_BSLOT_INQ = 30,
+ BTC_BSLOT_IDLE = 20,
+};
+
enum btc_cx_poicy_type {
/* TDMA off + pri: BT > WL */
BTC_CXP_OFF_BT = (BTC_CXP_OFF << 8) | 0,
@@ -5989,6 +5997,67 @@ static void _set_wl_tx_limit(struct rtw89_dev *rtwdev)
&data);
}
+static void _set_phl_bt_slot_req(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_btc *btc = &rtwdev->btc;
+ struct rtw89_btc_cx *cx = &btc->cx;
+ struct rtw89_btc_wl_info *wl = &cx->wl;
+ struct rtw89_btc_dm *dm = &btc->dm;
+ u8 len = 0;
+ u8 i;
+
+ /* don't change bt slot req state during RFK for p2p/mcc case */
+ if (dm->run_reason == BTC_RSN_NTFY_WL_RFK ||
+ wl->status.map.transacting)
+ return;
+
+ /* enable bt-slot req if ext-slot-control */
+ if (dm->tdma_now.type == CXTDMA_OFF &&
+ dm->tdma_now.ext_ctrl == CXECTL_EXT &&
+ dm->tdd_bind.bt_sel != 0) {
+ if (btc->cx.wl.status.val & btc_scanning_map.val)
+ btc->bt_req_en = false;
+ else
+ btc->bt_req_en = true;
+ } else {
+ btc->bt_req_en = false;
+ }
+
+ if (dm->slot_req_more) {
+ len = BTC_BSLOT_A2DP_HID;
+ } else {
+ if (dm->tdd_bind.bt_link_weight >= BTC_BSLOT_A2DP_HID)
+ len = BTC_BSLOT_A2DP_HID;
+ else if (dm->tdd_bind.bt_link_weight <= BTC_BSLOT_IDLE)
+ len = BTC_BSLOT_IDLE;
+ else
+ len = dm->tdd_bind.bt_link_weight;
+ }
+
+ if (dm->tdd_bind.rf_band == BIT(RTW89_BAND_5G))
+ len = 100 - len;
+
+ if (!btc->bt_req_en)
+ len = 0;
+
+ for (i = RTW89_PHY_0; i < RTW89_PHY_NUM; i++) {
+ if (!(dm->tdd_bind.wl_hwb_sel & BIT(i)))
+ continue;
+
+ if (len == btc->bt_req_len[i])
+ continue;
+
+ btc->bt_req_len[i] = len;
+
+ rtw89_core_ntfy_btc_event(rtwdev,
+ RTW89_BTC_HMSG_SET_BT_REQ_SLOT, i);
+
+ rtw89_debug(rtwdev, RTW89_DBG_BTC,
+ "[BTC], %s(): HWB%d bt_req_len = %d\n",
+ __func__, i, btc->bt_req_len[i]);
+ }
+}
+
static void _set_bt_rx_agc(struct rtw89_dev *rtwdev)
{
struct rtw89_btc *btc = &rtwdev->btc;
@@ -6148,6 +6217,7 @@ static void _action_common(struct rtw89_dev *rtwdev)
_set_btg_ctrl(rtwdev);
_set_wl_preagc_ctrl(rtwdev);
_set_wl_tx_limit(rtwdev);
+ _set_phl_bt_slot_req(rtwdev);
_set_bt_afh_info(rtwdev);
_set_bt_rx_agc(rtwdev);
_set_rf_trx_para(rtwdev);
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 0343cd1a0ee1..30a8e337498e 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -6539,15 +6539,18 @@ void rtw89_complete_cond(struct rtw89_wait_info *wait, unsigned int cond,
rtw89_complete_cond_resp(resp, data);
}
-void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg event)
+void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev,
+ enum rtw89_btc_hmsg event,
+ enum rtw89_phy_idx phy_idx)
{
- u16 bt_req_len;
+ u16 bt_slot_req[RTW89_PHY_NUM];
switch (event) {
case RTW89_BTC_HMSG_SET_BT_REQ_SLOT:
- bt_req_len = rtw89_coex_query_bt_req_len(rtwdev, RTW89_PHY_0);
+ bt_slot_req[phy_idx] = rtw89_coex_query_bt_req_len(rtwdev, phy_idx);
rtw89_debug(rtwdev, RTW89_DBG_BTC,
- "coex updates BT req len to %d TU\n", bt_req_len);
+ "coex updates PHY-%d BT req len to %d TU\n",
+ phy_idx, bt_slot_req[phy_idx]);
rtw89_queue_chanctx_change(rtwdev, RTW89_CHANCTX_BT_SLOT_CHANGE);
break;
default:
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index e7e72f742847..c8b5c9ed55be 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -8866,7 +8866,9 @@ int rtw89_reg_6ghz_recalc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvi
void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link,
struct ieee80211_bss_conf *bss_conf);
-void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev, enum rtw89_btc_hmsg event);
+void rtw89_core_ntfy_btc_event(struct rtw89_dev *rtwdev,
+ enum rtw89_btc_hmsg event,
+ enum rtw89_phy_idx phy_idx);
int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
unsigned int link_id);
void rtw89_core_dm_disable_cfg(struct rtw89_dev *rtwdev, u32 new);
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 11/11] wifi: rtw89: coex: Update coexistence version to 9.24.0
From: Ping-Ke Shih @ 2026-07-12 3:05 UTC (permalink / raw)
To: linux-wireless; +Cc: ku920601
In-Reply-To: <20260712030506.43438-1-pkshih@realtek.com>
From: Ching-Te Ku <ku920601@realtek.com>
RTL8922D first release, add related feature support.
Signed-off-by: Ching-Te Ku <ku920601@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/coex.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/realtek/rtw89/coex.c b/drivers/net/wireless/realtek/rtw89/coex.c
index a6b1aa2cb24e..b044b25aeade 100644
--- a/drivers/net/wireless/realtek/rtw89/coex.c
+++ b/drivers/net/wireless/realtek/rtw89/coex.c
@@ -11,7 +11,7 @@
#include "ps.h"
#include "reg.h"
-#define RTW89_COEX_VERSION 0x09000113
+#define RTW89_COEX_VERSION 0x09180013
#define FCXDEF_STEP 50 /* MUST <= FCXMAX_STEP and match with wl fw*/
#define BTC_E2G_LIMIT_DEF 80
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 0/8] wifi: rtw89: add RF diagnosis and update random patches
From: Ping-Ke Shih @ 2026-07-12 3:44 UTC (permalink / raw)
To: linux-wireless; +Cc: echuang, kevin_yang
First patch is to reduce IO time for USB device, which is addressed by real
time measurement.
The second patch is to abstract a register for WiFi 6 and 7 chips to read
firmware state for boot debugging.
Patch 3/8 is to resolve RTL8922DE interoperability issue operating in 2GHz
channels. Limit the TX time to prevent peer can't receive packets properly.
Patch 4-6/8 are to extend TX shape per 2/5/6 GHz bands to satisfy
regulation for each bands.
Patch 7/8 is to properly co-work with BB registers access in firmware, so
driver should power-on BB circuit to ensure possibly accessing.
The last patch is to add RF diagnosis assisting in debugging.
Eric Huang (1):
wifi: rtw89: pack I/O during bb_sethw to reduce API execution time
Ping-Ke Shih (3):
wifi: rtw89: mac: abstract register definition of firmware boot debug
wifi: rtw89: 8922d: add TX time limit for 2GHz band
wifi: rtw89: fw: do bb_preinit before downloading firmware
Zong-Zhe Yang (4):
wifi: rtw89: introduce helper to get tx shape index
wifi: rtw89: add tx shape v0 to keep built-in arrays compatible during
transitions
wifi: rtw89: extend tx shape format for regulatory 6 GHz power type
wifi: rtw89: debug: add diagnosis for RF
drivers/net/wireless/realtek/rtw89/core.c | 83 ++++++++++++-
drivers/net/wireless/realtek/rtw89/core.h | 74 ++++++++++-
drivers/net/wireless/realtek/rtw89/debug.c | 115 ++++++++++++++++++
drivers/net/wireless/realtek/rtw89/fw.c | 21 +++-
drivers/net/wireless/realtek/rtw89/fw.h | 2 +
drivers/net/wireless/realtek/rtw89/mac.c | 28 ++++-
drivers/net/wireless/realtek/rtw89/mac.h | 4 +-
drivers/net/wireless/realtek/rtw89/mac_be.c | 1 +
drivers/net/wireless/realtek/rtw89/phy.c | 62 ++++++++--
drivers/net/wireless/realtek/rtw89/phy.h | 3 +
drivers/net/wireless/realtek/rtw89/reg.h | 1 +
drivers/net/wireless/realtek/rtw89/rtw8851b.c | 7 +-
.../wireless/realtek/rtw89/rtw8851b_table.c | 8 +-
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 +
.../wireless/realtek/rtw89/rtw8852b_common.c | 6 +-
.../wireless/realtek/rtw89/rtw8852b_table.c | 4 +-
.../net/wireless/realtek/rtw89/rtw8852bt.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 7 +-
.../wireless/realtek/rtw89/rtw8852c_table.c | 4 +-
drivers/net/wireless/realtek/rtw89/rtw8922a.c | 10 +-
drivers/net/wireless/realtek/rtw89/rtw8922d.c | 18 +--
22 files changed, 400 insertions(+), 61 deletions(-)
base-commit: 56d32cdc6040440b08edfd5d7262250a721233f8
--
2.25.1
^ permalink raw reply
* [PATCH rtw-next 1/8] wifi: rtw89: pack I/O during bb_sethw to reduce API execution time
From: Ping-Ke Shih @ 2026-07-12 3:44 UTC (permalink / raw)
To: linux-wireless; +Cc: echuang, kevin_yang
In-Reply-To: <20260712034506.53209-1-pkshih@realtek.com>
From: Eric Huang <echuang@realtek.com>
Wrap rtw89_chip_bb_sethw() with rtw89_io_pack/unpack so all register
writes during baseband hardware initialization are batched into a single
bus transaction. This reduces API execution time from ~11000 us to
~4000 us on affected platforms.
Signed-off-by: Eric Huang <echuang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 174349c6bc58..0f6d4ad66fe2 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -7810,8 +7810,12 @@ static inline void rtw89_chip_bb_sethw(struct rtw89_dev *rtwdev)
{
const struct rtw89_chip_info *chip = rtwdev->chip;
+ rtw89_io_pack(rtwdev);
+
if (chip->ops->bb_sethw)
chip->ops->bb_sethw(rtwdev);
+
+ rtw89_io_unpack(rtwdev);
}
static inline void rtw89_chip_rfk_init(struct rtw89_dev *rtwdev)
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 2/8] wifi: rtw89: mac: abstract register definition of firmware boot debug
From: Ping-Ke Shih @ 2026-07-12 3:45 UTC (permalink / raw)
To: linux-wireless; +Cc: echuang, kevin_yang
In-Reply-To: <20260712034506.53209-1-pkshih@realtek.com>
The registers of firmware boot debug are different between WiFi 6 and 7
chips. Add field to abstract it accordingly.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/fw.c | 5 +++--
drivers/net/wireless/realtek/rtw89/mac.c | 1 +
drivers/net/wireless/realtek/rtw89/mac.h | 1 +
drivers/net/wireless/realtek/rtw89/mac_be.c | 1 +
4 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 0e7168605850..01770a6a1f6f 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -1939,13 +1939,14 @@ static void rtw89_fw_prog_cnt_dump(struct rtw89_dev *rtwdev)
static void rtw89_fw_dl_fail_dump(struct rtw89_dev *rtwdev)
{
+ const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
u32 val32;
val32 = rtw89_read32(rtwdev, R_AX_WCPU_FW_CTRL);
rtw89_err(rtwdev, "[ERR]fwdl 0x1E0 = 0x%x\n", val32);
- val32 = rtw89_read32(rtwdev, R_AX_BOOT_DBG);
- rtw89_err(rtwdev, "[ERR]fwdl 0x83F0 = 0x%x\n", val32);
+ val32 = rtw89_read32(rtwdev, mac->boot_dbg);
+ rtw89_err(rtwdev, "[ERR]fwdl 0x%x = 0x%x\n", mac->boot_dbg, val32);
rtw89_fw_prog_cnt_dump(rtwdev);
}
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index 6e3da5e4a1b3..b58d9439ee6d 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -7442,6 +7442,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_ax = {
.agg_len_ht = R_AX_AGG_LEN_HT_0,
.ps_status = R_AX_PPWRBIT_SETTING,
.mu_gid = &rtw89_mac_mu_gid_addr_ax,
+ .boot_dbg = R_AX_BOOT_DBG,
.muedca_ctrl = {
.addr = R_AX_MUEDCA_EN,
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index a5f1694af91a..c05f5ee0d2fd 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -1067,6 +1067,7 @@ struct rtw89_mac_gen_def {
u32 agg_len_ht;
u32 ps_status;
const struct rtw89_mac_mu_gid_addr *mu_gid;
+ u32 boot_dbg;
struct rtw89_reg_def muedca_ctrl;
struct rtw89_reg_def bfee_ctrl;
diff --git a/drivers/net/wireless/realtek/rtw89/mac_be.c b/drivers/net/wireless/realtek/rtw89/mac_be.c
index 4bdf20b7ba6d..46aea7f6a4a1 100644
--- a/drivers/net/wireless/realtek/rtw89/mac_be.c
+++ b/drivers/net/wireless/realtek/rtw89/mac_be.c
@@ -3287,6 +3287,7 @@ const struct rtw89_mac_gen_def rtw89_mac_gen_be = {
.agg_len_ht = R_BE_AGG_LEN_HT_0,
.ps_status = R_BE_WMTX_POWER_BE_BIT_CTL,
.mu_gid = &rtw89_mac_mu_gid_addr_be,
+ .boot_dbg = R_BE_BOOT_DBG,
.muedca_ctrl = {
.addr = R_BE_MUEDCA_EN,
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 3/8] wifi: rtw89: 8922d: add TX time limit for 2GHz band
From: Ping-Ke Shih @ 2026-07-12 3:45 UTC (permalink / raw)
To: linux-wireless; +Cc: echuang, kevin_yang
In-Reply-To: <20260712034506.53209-1-pkshih@realtek.com>
Fix 2.4GHz specific L-SIG length TX issue, causing interoperability problem
with certain APs. Limit the A-MPDU duration to be workaround.
For 8922DE, the MAC limit is 164 ticks, and BB limit is 4608 us. The
conversion is 32.768us / tick. Since smaller limit should be adopted,
BB limit is filled into newly added field.
The units of register and CCTL table are tick and us/512 respectively.
Convert to target unit when filling values.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 1 +
drivers/net/wireless/realtek/rtw89/mac.c | 20 +++++++++++++++++--
drivers/net/wireless/realtek/rtw89/rtw8851b.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852b.c | 1 +
.../net/wireless/realtek/rtw89/rtw8852bt.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8922a.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8922d.c | 9 +++++++++
9 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 0f6d4ad66fe2..b7536288c084 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -5012,6 +5012,7 @@ struct rtw89_chip_info {
const struct wiphy_wowlan_support *wowlan_stub;
const struct rtw89_xtal_info *xtal_info;
unsigned long default_quirks; /* bitmap of rtw89_quirks */
+ u16 txtime_limit_2ghz;
};
struct rtw89_chip_variant {
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index b58d9439ee6d..a63f34440554 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -7047,11 +7047,23 @@ __rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_
{
#define MAC_AX_DFLT_TX_TIME 5280
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
u8 mac_idx = rtwsta_link->rtwvif_link->mac_idx;
u32 max_tx_time = tx_time == 0 ? MAC_AX_DFLT_TX_TIME : tx_time;
+ struct rtw89_entity_conf conf;
+ const struct rtw89_chan *chan;
u32 reg;
int ret = 0;
+ if (chip->txtime_limit_2ghz) {
+ rtw89_entity_get_conf(rtwdev, &conf);
+ chan = conf.chans[mac_idx];
+
+ if (chan->band_type == RTW89_BAND_2G)
+ max_tx_time = min_t(u32, max_tx_time,
+ chip->txtime_limit_2ghz);
+ }
+
if (rtwsta_link->cctl_tx_time) {
rtwsta_link->ampdu_max_time = (max_tx_time - 512) >> 9;
ret = rtw89_chip_h2c_txtime_cmac_tbl(rtwdev, rtwsta_link);
@@ -7062,9 +7074,13 @@ __rtw89_mac_set_tx_time(struct rtw89_dev *rtwdev, struct rtw89_sta_link *rtwsta_
return ret;
}
+ if (chip->chip_gen == RTW89_CHIP_AX)
+ max_tx_time >>= 5;
+ else
+ max_tx_time = max_tx_time * 1000 >> 15;
+
reg = rtw89_mac_reg_by_idx(rtwdev, mac->agg_limit.addr, mac_idx);
- rtw89_write32_mask(rtwdev, reg, mac->agg_limit.mask,
- max_tx_time >> 5);
+ rtw89_write32_mask(rtwdev, reg, mac->agg_limit.mask, max_tx_time);
}
return ret;
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
index 50480f72c96d..8dd909fc4754 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
@@ -2779,6 +2779,7 @@ const struct rtw89_chip_info rtw8851b_chip_info = {
#endif
.xtal_info = &rtw8851b_xtal_info,
.default_quirks = 0,
+ .txtime_limit_2ghz = 0,
};
EXPORT_SYMBOL(rtw8851b_chip_info);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852a.c b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
index 0c7794742650..66e8035703a6 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852a.c
@@ -2517,6 +2517,7 @@ const struct rtw89_chip_info rtw8852a_chip_info = {
#endif
.xtal_info = &rtw8852a_xtal_info,
.default_quirks = 0,
+ .txtime_limit_2ghz = 0,
};
EXPORT_SYMBOL(rtw8852a_chip_info);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b.c b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
index 5904127cc836..19f35b87d42e 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b.c
@@ -1115,6 +1115,7 @@ const struct rtw89_chip_info rtw8852b_chip_info = {
#endif
.xtal_info = NULL,
.default_quirks = 0,
+ .txtime_limit_2ghz = 0,
};
EXPORT_SYMBOL(rtw8852b_chip_info);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
index e68f73827fa5..3da95beddc1f 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852bt.c
@@ -951,6 +951,7 @@ const struct rtw89_chip_info rtw8852bt_chip_info = {
#endif
.xtal_info = NULL,
.default_quirks = 0,
+ .txtime_limit_2ghz = 0,
};
EXPORT_SYMBOL(rtw8852bt_chip_info);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index 968666280c89..54425d707bc6 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -3320,6 +3320,7 @@ const struct rtw89_chip_info rtw8852c_chip_info = {
#endif
.xtal_info = NULL,
.default_quirks = 0,
+ .txtime_limit_2ghz = 0,
};
EXPORT_SYMBOL(rtw8852c_chip_info);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
index fe87b4929ddc..900aa20cf6ac 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
@@ -3302,6 +3302,7 @@ const struct rtw89_chip_info rtw8922a_chip_info = {
#endif
.xtal_info = NULL,
.default_quirks = 0,
+ .txtime_limit_2ghz = 0,
};
EXPORT_SYMBOL(rtw8922a_chip_info);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index 768434db14c6..27e148b4213a 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -1173,8 +1173,10 @@ static void rtw8922d_set_channel_mac(struct rtw89_dev *rtwdev,
u32 sub_carr = rtw89_mac_reg_by_idx(rtwdev, R_BE_TX_SUB_BAND_VALUE, mac_idx);
u32 chk_rate = rtw89_mac_reg_by_idx(rtwdev, R_BE_TXRATE_CHK, mac_idx);
u32 rf_mod = rtw89_mac_reg_by_idx(rtwdev, R_BE_WMAC_RFMOD, mac_idx);
+ const struct rtw89_chip_info *chip = rtwdev->chip;
u8 txsb20 = 0, txsb40 = 0, txsb80 = 0;
u8 rf_mod_val, chk_rate_mask, sifs;
+ u16 tx_time = AMPDU_MAX_TIME_V1;
u32 txsb;
u32 reg;
@@ -1255,6 +1257,12 @@ static void rtw8922d_set_channel_mac(struct rtw89_dev *rtwdev,
reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_MUEDCA_EN, mac_idx);
rtw89_write32_mask(rtwdev, reg, B_BE_SIFS_MACTXEN_TB_T1_DOT05US_MASK, sifs);
+
+ if (chan->band_type == RTW89_BAND_2G && chip->txtime_limit_2ghz)
+ tx_time = min_t(u32, tx_time, chip->txtime_limit_2ghz * 1000 >> 15);
+
+ reg = rtw89_mac_reg_by_idx(rtwdev, R_BE_AMPDU_AGG_LIMIT, mac_idx);
+ rtw89_write32_mask(rtwdev, reg, B_BE_AMPDU_MAX_TIME_MASK, tx_time);
}
static const u32 rtw8922d_sco_barker_threshold[14] = {
@@ -3591,6 +3599,7 @@ const struct rtw89_chip_info rtw8922d_chip_info = {
#endif
.xtal_info = NULL,
.default_quirks = BIT(RTW89_QUIRK_THERMAL_PROT_120C),
+ .txtime_limit_2ghz = 4608,
};
EXPORT_SYMBOL(rtw8922d_chip_info);
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 4/8] wifi: rtw89: introduce helper to get tx shape index
From: Ping-Ke Shih @ 2026-07-12 3:45 UTC (permalink / raw)
To: linux-wireless; +Cc: echuang, kevin_yang
In-Reply-To: <20260712034506.53209-1-pkshih@realtek.com>
From: Zong-Zhe Yang <kevin_yang@realtek.com>
TX shape has a set of parameters inside RFE (RF Front End) parameters.
It also depends on regulation and even will depend on regulatory 6 GHz
power type afterwards. Introduce a helper to encapsulate the access to
TX shape index.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 13 +++++++++++++
drivers/net/wireless/realtek/rtw89/rtw8851b.c | 6 ++----
.../net/wireless/realtek/rtw89/rtw8852b_common.c | 6 ++----
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 6 ++----
drivers/net/wireless/realtek/rtw89/rtw8922a.c | 9 ++-------
drivers/net/wireless/realtek/rtw89/rtw8922d.c | 9 ++-------
6 files changed, 23 insertions(+), 26 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index b7536288c084..1e323007421c 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -8042,6 +8042,19 @@ static inline u8 rtw89_regd_get(struct rtw89_dev *rtwdev, u8 band)
return txpwr_regd;
}
+static inline u8 rtw89_get_tx_shape_idx(struct rtw89_dev *rtwdev, u8 band,
+ enum rtw89_rate_section rs)
+{
+ const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
+ const struct rtw89_tx_shape *tx_shape = &rfe_parms->tx_shape;
+ u8 regd = rtw89_regd_get(rtwdev, band);
+
+ if (unlikely(rs >= RTW89_RS_TX_SHAPE_NUM))
+ rs = RTW89_RS_OFDM;
+
+ return (*tx_shape->lmt)[band][rs][regd];
+}
+
static inline void rtw89_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
enum rtw89_phy_idx phy_idx)
{
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b.c b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
index 8dd909fc4754..38592504b4d0 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b.c
@@ -1918,11 +1918,9 @@ static void rtw8851b_set_tx_shape(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
- const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
u8 band = chan->band_type;
- u8 regd = rtw89_regd_get(rtwdev, band);
- u8 tx_shape_cck = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_CCK][regd];
- u8 tx_shape_ofdm = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_OFDM][regd];
+ u8 tx_shape_cck = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_CCK);
+ u8 tx_shape_ofdm = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_OFDM);
if (band == RTW89_BAND_2G)
rtw8851b_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c
index 7d409a64869f..7c68260dce70 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_common.c
@@ -1321,11 +1321,9 @@ static void rtw8852bx_set_tx_shape(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
- const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
u8 band = chan->band_type;
- u8 regd = rtw89_regd_get(rtwdev, band);
- u8 tx_shape_cck = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_CCK][regd];
- u8 tx_shape_ofdm = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_OFDM][regd];
+ u8 tx_shape_cck = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_CCK);
+ u8 tx_shape_ofdm = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_OFDM);
if (band == RTW89_BAND_2G)
rtw8852bx_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c.c b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
index 54425d707bc6..c7d64fe9c2bc 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c.c
@@ -2193,11 +2193,9 @@ static void rtw8852c_set_tx_shape(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
- const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
u8 band = chan->band_type;
- u8 regd = rtw89_regd_get(rtwdev, band);
- u8 tx_shape_cck = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_CCK][regd];
- u8 tx_shape_ofdm = (*rfe_parms->tx_shape.lmt)[band][RTW89_RS_OFDM][regd];
+ u8 tx_shape_cck = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_CCK);
+ u8 tx_shape_ofdm = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_OFDM);
if (band == RTW89_BAND_2G)
rtw8852c_bb_set_tx_shape_dfir(rtwdev, chan, tx_shape_cck, phy_idx);
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922a.c b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
index 900aa20cf6ac..86a756f51026 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922a.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922a.c
@@ -2502,15 +2502,10 @@ static void rtw8922a_set_tx_shape(struct rtw89_dev *rtwdev,
const struct rtw89_chan *chan,
enum rtw89_phy_idx phy_idx)
{
- const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
- const struct rtw89_tx_shape *tx_shape = &rfe_parms->tx_shape;
+ u8 band = chan->band_type;
u8 tx_shape_idx;
- u8 band, regd;
-
- band = chan->band_type;
- regd = rtw89_regd_get(rtwdev, band);
- tx_shape_idx = (*tx_shape->lmt)[band][RTW89_RS_OFDM][regd];
+ tx_shape_idx = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_OFDM);
if (tx_shape_idx == 0)
rtw8922a_bb_tx_triangular(rtwdev, false, phy_idx);
else
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8922d.c b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
index 27e148b4213a..462165bc2485 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8922d.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8922d.c
@@ -2854,16 +2854,11 @@ static void rtw8922d_set_tx_shape(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx)
{
const struct rtw89_bb_wrap_data *d = rtwdev->phy_info.bb_wrap_data;
- const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
- const struct rtw89_tx_shape *tx_shape = &rfe_parms->tx_shape;
+ u8 band = chan->band_type;
u8 tx_shape_idx;
- u8 band, regd;
const u16 *th;
- band = chan->band_type;
- regd = rtw89_regd_get(rtwdev, band);
- tx_shape_idx = (*tx_shape->lmt)[band][RTW89_RS_OFDM][regd];
-
+ tx_shape_idx = rtw89_get_tx_shape_idx(rtwdev, band, RTW89_RS_OFDM);
if (tx_shape_idx == 0)
goto disable;
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 5/8] wifi: rtw89: add tx shape v0 to keep built-in arrays compatible during transitions
From: Ping-Ke Shih @ 2026-07-12 3:45 UTC (permalink / raw)
To: linux-wireless; +Cc: echuang, kevin_yang
In-Reply-To: <20260712034506.53209-1-pkshih@realtek.com>
From: Zong-Zhe Yang <kevin_yang@realtek.com>
TX shape parameters can come from (old way) built-in arrays or (new way)
FW elements. The built-in arrays will no longer be updated, but will be
retained during a certain transition period. However, the format of newer
TX shape parameters are going to be expanded. It will only be applied to
FW elements. To keep built-in arrays compatible during transition period,
add tx shape v0 for old format.
The v0 fields can be removed along with built-in arrays once transition
period ends.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 9 +++++++++
drivers/net/wireless/realtek/rtw89/rtw8851b_table.c | 8 ++++----
drivers/net/wireless/realtek/rtw89/rtw8852b_table.c | 4 ++--
drivers/net/wireless/realtek/rtw89/rtw8852c_table.c | 4 ++--
4 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 1e323007421c..94ba7e368880 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4518,6 +4518,9 @@ struct rtw89_txpwr_rule_6ghz {
struct rtw89_tx_shape {
const u8 (*lmt)[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM][RTW89_REGD_NUM];
const u8 (*lmt_ru)[RTW89_BAND_NUM][RTW89_REGD_NUM];
+
+ const u8 (*lmt_v0)[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM][RTW89_REGD_NUM];
+ const u8 (*lmt_ru_v0)[RTW89_BAND_NUM][RTW89_REGD_NUM];
};
struct rtw89_rfe_parms {
@@ -8052,7 +8055,13 @@ static inline u8 rtw89_get_tx_shape_idx(struct rtw89_dev *rtwdev, u8 band,
if (unlikely(rs >= RTW89_RS_TX_SHAPE_NUM))
rs = RTW89_RS_OFDM;
+ if (!tx_shape->lmt)
+ goto v0;
+
return (*tx_shape->lmt)[band][rs][regd];
+
+v0:
+ return (*tx_shape->lmt_v0)[band][rs][regd];
}
static inline void rtw89_ctrl_btg_bt_rx(struct rtw89_dev *rtwdev, bool en,
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c
index b8105f6e94f1..f875beaec555 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8851b_table.c
@@ -14887,8 +14887,8 @@ const struct rtw89_rfe_parms rtw89_8851b_dflt_parms = {
.lmt_ru = &rtw89_8851b_txpwr_lmt_ru_5g,
},
.tx_shape = {
- .lmt = &rtw89_8851b_tx_shape_lmt,
- .lmt_ru = &rtw89_8851b_tx_shape_lmt_ru,
+ .lmt_v0 = &rtw89_8851b_tx_shape_lmt,
+ .lmt_ru_v0 = &rtw89_8851b_tx_shape_lmt_ru,
},
};
@@ -14903,8 +14903,8 @@ static const struct rtw89_rfe_parms rtw89_8851b_rfe_parms_type2 = {
.lmt_ru = &rtw89_8851b_txpwr_lmt_ru_5g_type2,
},
.tx_shape = {
- .lmt = &rtw89_8851b_tx_shape_lmt,
- .lmt_ru = &rtw89_8851b_tx_shape_lmt_ru,
+ .lmt_v0 = &rtw89_8851b_tx_shape_lmt,
+ .lmt_ru_v0 = &rtw89_8851b_tx_shape_lmt_ru,
},
};
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c
index 96b18e9095b3..1485a8fc4bde 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852b_table.c
@@ -22922,7 +22922,7 @@ const struct rtw89_rfe_parms rtw89_8852b_dflt_parms = {
.lmt_ru = &rtw89_8852b_txpwr_lmt_ru_5g,
},
.tx_shape = {
- .lmt = &rtw89_8852b_tx_shape_lmt,
- .lmt_ru = &rtw89_8852b_tx_shape_lmt_ru,
+ .lmt_v0 = &rtw89_8852b_tx_shape_lmt,
+ .lmt_ru_v0 = &rtw89_8852b_tx_shape_lmt_ru,
},
};
diff --git a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c
index b4cf497e8524..c5ede63e7e23 100644
--- a/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c
+++ b/drivers/net/wireless/realtek/rtw89/rtw8852c_table.c
@@ -57154,7 +57154,7 @@ const struct rtw89_rfe_parms rtw89_8852c_dflt_parms = {
.lmt_ru = &rtw89_8852c_txpwr_lmt_ru_6g,
},
.tx_shape = {
- .lmt = &rtw89_8852c_tx_shape_lmt,
- .lmt_ru = &rtw89_8852c_tx_shape_lmt_ru,
+ .lmt_v0 = &rtw89_8852c_tx_shape_lmt,
+ .lmt_ru_v0 = &rtw89_8852c_tx_shape_lmt_ru,
},
};
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 6/8] wifi: rtw89: extend tx shape format for regulatory 6 GHz power type
From: Ping-Ke Shih @ 2026-07-12 3:45 UTC (permalink / raw)
To: linux-wireless; +Cc: echuang, kevin_yang
In-Reply-To: <20260712034506.53209-1-pkshih@realtek.com>
From: Zong-Zhe Yang <kevin_yang@realtek.com>
Even under the same regulation, TX shape may need different settings for
different 6 GHz power types. So, add one more dimension for that. Because
TX shape parameters are not quite large, the 2/5/6 GHz sections are not
divided into different structures. So, the 2/5 GHz sections will also get
the new dimension. To 2/5 GHz sections, fill the TX shape settings with
RTW89_REG_6GHZ_POWER_DFLT (0) field.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.h | 17 ++++++++++++-----
drivers/net/wireless/realtek/rtw89/fw.c | 16 ++++++++++++++--
drivers/net/wireless/realtek/rtw89/fw.h | 2 ++
3 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 94ba7e368880..4ba6452a7123 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -4516,8 +4516,9 @@ struct rtw89_txpwr_rule_6ghz {
};
struct rtw89_tx_shape {
- const u8 (*lmt)[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM][RTW89_REGD_NUM];
- const u8 (*lmt_ru)[RTW89_BAND_NUM][RTW89_REGD_NUM];
+ const u8 (*lmt)[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM][RTW89_REGD_NUM]
+ [NUM_OF_RTW89_REG_6GHZ_POWER];
+ const u8 (*lmt_ru)[RTW89_BAND_NUM][RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER];
const u8 (*lmt_v0)[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM][RTW89_REGD_NUM];
const u8 (*lmt_ru_v0)[RTW89_BAND_NUM][RTW89_REGD_NUM];
@@ -4614,12 +4615,13 @@ struct rtw89_txpwr_lmt_ru_6ghz_data {
struct rtw89_tx_shape_lmt_data {
struct rtw89_txpwr_conf conf;
- u8 v[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM][RTW89_REGD_NUM];
+ u8 v[RTW89_BAND_NUM][RTW89_RS_TX_SHAPE_NUM][RTW89_REGD_NUM]
+ [NUM_OF_RTW89_REG_6GHZ_POWER];
};
struct rtw89_tx_shape_lmt_ru_data {
struct rtw89_txpwr_conf conf;
- u8 v[RTW89_BAND_NUM][RTW89_REGD_NUM];
+ u8 v[RTW89_BAND_NUM][RTW89_REGD_NUM][NUM_OF_RTW89_REG_6GHZ_POWER];
};
struct rtw89_rfe_data {
@@ -8048,8 +8050,10 @@ static inline u8 rtw89_regd_get(struct rtw89_dev *rtwdev, u8 band)
static inline u8 rtw89_get_tx_shape_idx(struct rtw89_dev *rtwdev, u8 band,
enum rtw89_rate_section rs)
{
+ struct rtw89_regulatory_info *regulatory = &rtwdev->regulatory;
const struct rtw89_rfe_parms *rfe_parms = rtwdev->rfe_parms;
const struct rtw89_tx_shape *tx_shape = &rfe_parms->tx_shape;
+ u8 reg6_pwr = regulatory->reg_6ghz_power;
u8 regd = rtw89_regd_get(rtwdev, band);
if (unlikely(rs >= RTW89_RS_TX_SHAPE_NUM))
@@ -8058,7 +8062,10 @@ static inline u8 rtw89_get_tx_shape_idx(struct rtw89_dev *rtwdev, u8 band,
if (!tx_shape->lmt)
goto v0;
- return (*tx_shape->lmt)[band][rs][regd];
+ if (band != RTW89_BAND_6G)
+ reg6_pwr = RTW89_REG_6GHZ_POWER_DFLT;
+
+ return (*tx_shape->lmt)[band][rs][regd][reg6_pwr];
v0:
return (*tx_shape->lmt_v0)[band][rs][regd];
diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c
index 01770a6a1f6f..95acf7caf08e 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.c
+++ b/drivers/net/wireless/realtek/rtw89/fw.c
@@ -11626,6 +11626,12 @@ fw_tx_shape_lmt_entry_valid(const struct rtw89_fw_tx_shape_lmt_entry *e,
if (e->regd >= RTW89_REGD_NUM)
return false;
+ /* ensure compatibility work with 2/5 GHz */
+ static_assert(RTW89_REG_6GHZ_POWER_DFLT == 0);
+
+ if (e->reg6_pwr >= NUM_OF_RTW89_REG_6GHZ_POWER)
+ return false;
+
return true;
}
@@ -11640,7 +11646,7 @@ void rtw89_fw_load_tx_shape_lmt(struct rtw89_tx_shape_lmt_data *data)
if (!fw_tx_shape_lmt_entry_valid(&entry, cursor, conf))
continue;
- data->v[entry.band][entry.tx_shape_rs][entry.regd] = entry.v;
+ data->v[entry.band][entry.tx_shape_rs][entry.regd][entry.reg6_pwr] = entry.v;
}
}
@@ -11657,6 +11663,12 @@ fw_tx_shape_lmt_ru_entry_valid(const struct rtw89_fw_tx_shape_lmt_ru_entry *e,
if (e->regd >= RTW89_REGD_NUM)
return false;
+ /* ensure compatibility work with 2/5 GHz */
+ static_assert(RTW89_REG_6GHZ_POWER_DFLT == 0);
+
+ if (e->reg6_pwr >= NUM_OF_RTW89_REG_6GHZ_POWER)
+ return false;
+
return true;
}
@@ -11671,7 +11683,7 @@ void rtw89_fw_load_tx_shape_lmt_ru(struct rtw89_tx_shape_lmt_ru_data *data)
if (!fw_tx_shape_lmt_ru_entry_valid(&entry, cursor, conf))
continue;
- data->v[entry.band][entry.regd] = entry.v;
+ data->v[entry.band][entry.regd][entry.reg6_pwr] = entry.v;
}
}
diff --git a/drivers/net/wireless/realtek/rtw89/fw.h b/drivers/net/wireless/realtek/rtw89/fw.h
index af126d15a1fb..5efa75f8c392 100644
--- a/drivers/net/wireless/realtek/rtw89/fw.h
+++ b/drivers/net/wireless/realtek/rtw89/fw.h
@@ -5834,6 +5834,7 @@ struct rtw89_fw_tx_shape_lmt_entry {
u8 tx_shape_rs;
u8 regd;
u8 v;
+ u8 reg6_pwr;
} __packed;
/* must consider compatibility; don't insert new in the mid */
@@ -5841,6 +5842,7 @@ struct rtw89_fw_tx_shape_lmt_ru_entry {
u8 band;
u8 regd;
u8 v;
+ u8 reg6_pwr;
} __packed;
const struct rtw89_rfe_parms *
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 7/8] wifi: rtw89: fw: do bb_preinit before downloading firmware
From: Ping-Ke Shih @ 2026-07-12 3:45 UTC (permalink / raw)
To: linux-wireless; +Cc: echuang, kevin_yang
In-Reply-To: <20260712034506.53209-1-pkshih@realtek.com>
The firmware access BB registers while initialization, so driver should
do bb_preinit before downloading firmware. Otherwise, it might get BB IO
stuck and throw error.
rtw89_8922de 0000:04:00.0: loaded firmware rtw89/rtw8922d_fw.bin
rtw89_8922de 0000:04:00.0: Firmware version 0.35.111.7 (51c56e7b), cmd version 1, type 14
rtw89_8922de 0000:04:00.0: Firmware version 0.35.111.7 (51c56e7b), cmd version 1, type 15
rtw89_8922de 0000:04:00.0: fw unexpected status 6
rtw89_8922de 0000:04:00.0: download firmware fail
rtw89_8922de 0000:04:00.0: [ERR]fwdl 0x1E0 = 0x8000012
rtw89_8922de 0000:04:00.0: [ERR]fwdl 0x78F0 = 0x290900
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]fw PC = 0x201445f2
rtw89_8922de 0000:04:00.0: [ERR]H2C path ready
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.c | 12 +++++++++++-
drivers/net/wireless/realtek/rtw89/mac.c | 7 ++++---
drivers/net/wireless/realtek/rtw89/mac.h | 3 ++-
3 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 0343cd1a0ee1..3950792651c1 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -7197,9 +7197,19 @@ int rtw89_core_mlsr_switch(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
static int rtw89_chip_efuse_info_setup(struct rtw89_dev *rtwdev)
{
const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def;
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ bool bb_preinit = false;
int ret;
- ret = rtw89_mac_partial_init(rtwdev, false);
+ /*
+ * Normally in probe stage, we don't need to do BB pre-initialization.
+ * However, RTL8922D firmware can access BB registers at firmware
+ * initial state, so initialize it to avoid BB IO stuck in firmware.
+ */
+ if (chip->chip_id == RTL8922D)
+ bb_preinit = true;
+
+ ret = rtw89_mac_partial_init(rtwdev, false, bb_preinit);
if (ret)
return ret;
diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c
index a63f34440554..accc5cdfaa3d 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.c
+++ b/drivers/net/wireless/realtek/rtw89/mac.c
@@ -4308,13 +4308,14 @@ int rtw89_mac_disable_bb_rf(struct rtw89_dev *rtwdev)
}
EXPORT_SYMBOL(rtw89_mac_disable_bb_rf);
-int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb)
+int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb,
+ bool bb_preinit)
{
int ret;
rtw89_mac_ctrl_hci_dma_trx(rtwdev, true);
- if (include_bb) {
+ if (include_bb || bb_preinit) {
/* Only call BB preinit including configuration of BB MCU for
* the chips which need to download BB MCU firmware. Otherwise,
* calling preinit later to prevent touching registers affecting
@@ -4367,7 +4368,7 @@ int rtw89_mac_init(struct rtw89_dev *rtwdev)
bool include_bb = !!chip->bbmcu_nr;
int ret;
- ret = rtw89_mac_partial_init(rtwdev, include_bb);
+ ret = rtw89_mac_partial_init(rtwdev, include_bb, include_bb);
if (ret)
goto fail;
diff --git a/drivers/net/wireless/realtek/rtw89/mac.h b/drivers/net/wireless/realtek/rtw89/mac.h
index c05f5ee0d2fd..493d2b9626a6 100644
--- a/drivers/net/wireless/realtek/rtw89/mac.h
+++ b/drivers/net/wireless/realtek/rtw89/mac.h
@@ -1302,7 +1302,8 @@ rtw89_write32_port_set(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_l
int rtw89_mac_pwr_on(struct rtw89_dev *rtwdev);
void rtw89_mac_pwr_off(struct rtw89_dev *rtwdev);
-int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb);
+int rtw89_mac_partial_init(struct rtw89_dev *rtwdev, bool include_bb,
+ bool bb_preinit);
int rtw89_mac_preinit(struct rtw89_dev *rtwdev);
int rtw89_mac_init(struct rtw89_dev *rtwdev);
int rtw89_mac_dle_init(struct rtw89_dev *rtwdev, enum rtw89_qta_mode mode,
--
2.25.1
^ permalink raw reply related
* [PATCH rtw-next 8/8] wifi: rtw89: debug: add diagnosis for RF
From: Ping-Ke Shih @ 2026-07-12 3:45 UTC (permalink / raw)
To: linux-wireless; +Cc: echuang, kevin_yang
In-Reply-To: <20260712034506.53209-1-pkshih@realtek.com>
From: Zong-Zhe Yang <kevin_yang@realtek.com>
Add debugfs diag_rf and show RFK (RF calibration) diagnosis things for
now. Record channel related info before triggering RFK, and then record
state of each kind of RFK from C2H event report. Besides, in track work,
monitor TSSI status too. Both support history up to 10, and show records
via debugfs.
The following is an example of output.
RFK (next index: 2)
PHY-X = 0 0 0 0 0 0 0 0 0 0
S0-CH = 0012a 0012a 00000 00000 00000 00000 00000 00000 00000 00000
S0-CV = 0032c 0032c 00000 00000 00000 00000 00000 00000 00000 00000
S0-C5 = 10000 10000 00000 00000 00000 00000 00000 00000 00000 00000
S1-CH = 0012a 0012a 00000 00000 00000 00000 00000 00000 00000 00000
S1-CV = 0032d 0032d 00000 00000 00000 00000 00000 00000 00000 00000
S1-C5 = 00000 00000 00000 00000 00000 00000 00000 00000 00000 00000
PRE_NTFY = 0 0 0 0 0 0 0 0 0 0
TSSI = 1 1 0 0 0 0 0 0 0 0
IQK = 1 1 0 0 0 0 0 0 0 0
DPK = 1 1 0 0 0 0 0 0 0 0
TXGAPK = 1 1 0 0 0 0 0 0 0 0
DACK = 0 0 0 0 0 0 0 0 0 0
RX_DCK = 1 1 0 0 0 0 0 0 0 0
TX_IQK = 1 1 0 0 0 0 0 0 0 0
CIM3k = 1 1 0 0 0 0 0 0 0 0
TSSI-track (next index: 6)
S0 = 00e 00e 00c 00d 00d 00e 00d 00d 00d 00e
S1 = 00a 00b 009 00a 00a 00a 009 009 009 00a
Debugfs diag_rf can also be used to manually trigger RFK when written by 1.
Signed-off-by: Zong-Zhe Yang <kevin_yang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
---
drivers/net/wireless/realtek/rtw89/core.c | 71 ++++++++++++-
drivers/net/wireless/realtek/rtw89/core.h | 32 ++++++
drivers/net/wireless/realtek/rtw89/debug.c | 115 +++++++++++++++++++++
drivers/net/wireless/realtek/rtw89/phy.c | 62 +++++++++--
drivers/net/wireless/realtek/rtw89/phy.h | 3 +
drivers/net/wireless/realtek/rtw89/reg.h | 1 +
6 files changed, 272 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c
index 3950792651c1..5c58ce311c1b 100644
--- a/drivers/net/wireless/realtek/rtw89/core.c
+++ b/drivers/net/wireless/realtek/rtw89/core.c
@@ -486,6 +486,37 @@ void rtw89_core_set_chip_txpwr(struct rtw89_dev *rtwdev)
__rtw89_core_set_chip_txpwr(rtwdev, conf.chans[1], RTW89_PHY_1);
}
+static void rtw89_core_rfk_record(struct rtw89_dev *rtwdev,
+ struct rtw89_vif_link *rtwvif_link,
+ bool start)
+{
+ struct rtw89_rfk_wait_info *info = &rtwdev->rfk_wait;
+ struct rtw89_rfk_record *record = &info->records[info->record_idx];
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ u8 path_num = min(chip->rf_path_num, RTW89_RFK_RECORD_PATH_NR);
+ int path;
+
+ if (!start)
+ goto end;
+
+ info->record_ptr = record;
+ record->phy_idx = rtwvif_link->phy_idx;
+
+ for (path = 0; path < path_num; path++) {
+ record->ch[path] = rtw89_read_rf(rtwdev, path, RR_CFGCH,
+ RR_CFGCH_BAND0 | RR_CFGCH_CH);
+ record->cv[path] = rtw89_read_rf(rtwdev, path, RR_VCO,
+ RR_VCO_SEL | RR_VCO_STS);
+ record->c5[path] = rtw89_read_rf(rtwdev, path, RR_SYNFB, RFREG_MASK);
+ }
+
+ return;
+
+end:
+ info->record_idx = (info->record_idx + 1) % RTW89_RFK_RECORD_HISTORY_NR;
+ info->record_ptr = NULL;
+}
+
void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev,
struct rtw89_vif_link *rtwvif_link)
{
@@ -503,9 +534,14 @@ void rtw89_chip_rfk_channel(struct rtw89_dev *rtwdev,
rtw89_set_channel(rtwdev);
}
- if (chip->ops->rfk_channel)
+ if (chip->ops->rfk_channel) {
+ rtw89_core_rfk_record(rtwdev, rtwvif_link, true);
+
chip->ops->rfk_channel(rtwdev, rtwvif_link);
+ rtw89_core_rfk_record(rtwdev, rtwvif_link, false);
+ }
+
if (prehdl_link) {
rtw89_entity_force_hw(rtwdev, RTW89_PHY_NUM);
rtw89_set_channel(rtwdev);
@@ -5274,6 +5310,37 @@ static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev,
}
}
+static void rtw89_core_rfk_tssi_record(struct rtw89_dev *rtwdev)
+{
+ const struct rtw89_chip_info *chip = rtwdev->chip;
+ u8 path_num = min(chip->rf_path_num, RTW89_RFK_RECORD_PATH_NR);
+ struct rtw89_rfk_wait_info *info = &rtwdev->rfk_wait;
+ int i = info->record_tssi_idx;
+ u32 base;
+ u32 mask;
+ int path;
+
+ if (chip->chip_gen == RTW89_CHIP_AX)
+ return;
+
+ info->record_tssi_idx = (info->record_tssi_idx + 1) %
+ RTW89_RFK_RECORD_HISTORY_NR;
+
+ if (chip->chip_id == RTL8922A) {
+ base = 0x2ee10;
+ mask = 0x7fc00;
+ } else {
+ base = 0x2f918;
+ mask = 0x000001ff;
+ }
+
+ for (path = 0; path < path_num; path++) {
+ u32 addr = base + 0x100 * path;
+
+ info->tssi_code[i][path] = rtw89_read32_mask(rtwdev, addr, mask);
+ }
+}
+
static void rtw89_core_rfk_track(struct rtw89_dev *rtwdev)
{
enum rtw89_entity_mode mode;
@@ -5283,6 +5350,8 @@ static void rtw89_core_rfk_track(struct rtw89_dev *rtwdev)
return;
rtw89_chip_rfk_track(rtwdev);
+
+ rtw89_core_rfk_tssi_record(rtwdev);
}
void rtw89_core_update_p2p_ps(struct rtw89_dev *rtwdev,
diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h
index 4ba6452a7123..6fec9ce59f7a 100644
--- a/drivers/net/wireless/realtek/rtw89/core.h
+++ b/drivers/net/wireless/realtek/rtw89/core.h
@@ -5728,11 +5728,43 @@ enum rtw89_rfk_report_state {
RTW89_RFK_STATE_H2C_CMD_ERR = 0x4,
};
+enum rtw89_rfk_report_types {
+ RTW89_RFK_REPORT_PRE_NTFY,
+ RTW89_RFK_REPORT_TSSI,
+ RTW89_RFK_REPORT_IQK,
+ RTW89_RFK_REPORT_DPK,
+ RTW89_RFK_REPORT_TXGAPK,
+ RTW89_RFK_REPORT_DACK,
+ RTW89_RFK_REPORT_RX_DCK,
+ RTW89_RFK_REPORT_TX_IQK,
+ RTW89_RFK_REPORT_CIM3k,
+
+ NUM_OF_RTW89_RFK_REPORT_TYPES,
+};
+
+#define RTW89_RFK_RECORD_PATH_NR 2
+#define RTW89_RFK_RECORD_HISTORY_NR 10
+
+struct rtw89_rfk_record {
+ u32 ch[RTW89_RFK_RECORD_PATH_NR];
+ u32 cv[RTW89_RFK_RECORD_PATH_NR];
+ u32 c5[RTW89_RFK_RECORD_PATH_NR];
+ enum rtw89_phy_idx phy_idx;
+ enum rtw89_rfk_report_state states[NUM_OF_RTW89_RFK_REPORT_TYPES];
+};
+
struct rtw89_rfk_wait_info {
struct completion completion;
ktime_t start_time;
enum rtw89_rfk_report_state state;
u8 version;
+
+ int record_idx;
+ struct rtw89_rfk_record *record_ptr;
+ struct rtw89_rfk_record records[RTW89_RFK_RECORD_HISTORY_NR];
+
+ int record_tssi_idx;
+ u32 tssi_code[RTW89_RFK_RECORD_HISTORY_NR][RTW89_RFK_RECORD_PATH_NR];
};
#define RTW89_DACK_PATH_NR 2
diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c
index e42dc5707576..ccfd69271f90 100644
--- a/drivers/net/wireless/realtek/rtw89/debug.c
+++ b/drivers/net/wireless/realtek/rtw89/debug.c
@@ -93,6 +93,7 @@ struct rtw89_debugfs {
struct rtw89_debugfs_priv beacon_info;
struct rtw89_debugfs_priv diag_mac;
struct rtw89_debugfs_priv diag_bb;
+ struct rtw89_debugfs_priv diag_rf;
struct rtw89_debugfs_priv monitor_opts;
};
@@ -5397,6 +5398,118 @@ rtw89_debug_priv_diag_bb_get(struct rtw89_dev *rtwdev,
return p - buf;
}
+static ssize_t
+rtw89_debug_priv_diag_rf_get(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ char *buf, size_t bufsz)
+{
+ struct rtw89_rfk_wait_info *info = &rtwdev->rfk_wait;
+ char *p = buf, *end = buf + bufsz;
+ int i, j;
+
+ p += scnprintf(p, end - p, "RFK (next index: %d)\n", info->record_idx);
+
+ p += scnprintf(p, end - p, " PHY-X =");
+ for (i = 0; i < RTW89_RFK_RECORD_HISTORY_NR; i++) {
+ struct rtw89_rfk_record *record = &info->records[i];
+
+ p += scnprintf(p, end - p, " %4d ", record->phy_idx);
+ }
+ p += scnprintf(p, end - p, "\n");
+
+ for (j = 0; j < RTW89_RFK_RECORD_PATH_NR; j++) {
+ p += scnprintf(p, end - p, " S%d-CH =", j);
+ for (i = 0; i < RTW89_RFK_RECORD_HISTORY_NR; i++) {
+ struct rtw89_rfk_record *record = &info->records[i];
+
+ p += scnprintf(p, end - p, " %05x", record->ch[j]);
+ }
+ p += scnprintf(p, end - p, "\n");
+
+ p += scnprintf(p, end - p, " S%d-CV =", j);
+ for (i = 0; i < RTW89_RFK_RECORD_HISTORY_NR; i++) {
+ struct rtw89_rfk_record *record = &info->records[i];
+
+ p += scnprintf(p, end - p, " %05x", record->cv[j]);
+ }
+ p += scnprintf(p, end - p, "\n");
+
+ p += scnprintf(p, end - p, " S%d-C5 =", j);
+ for (i = 0; i < RTW89_RFK_RECORD_HISTORY_NR; i++) {
+ struct rtw89_rfk_record *record = &info->records[i];
+
+ p += scnprintf(p, end - p, " %05x", record->c5[j]);
+ }
+ p += scnprintf(p, end - p, "\n");
+ }
+
+ for (j = 0; j < NUM_OF_RTW89_RFK_REPORT_TYPES; j++) {
+ p += scnprintf(p, end - p, " %-8s =", rtw89_rfk_report_names[j]);
+ for (i = 0; i < RTW89_RFK_RECORD_HISTORY_NR; i++) {
+ struct rtw89_rfk_record *record = &info->records[i];
+
+ p += scnprintf(p, end - p, " %4d ", record->states[j]);
+ }
+ p += scnprintf(p, end - p, "\n");
+ }
+
+ p += scnprintf(p, end - p, "TSSI-track (next index: %d)\n", info->record_tssi_idx);
+
+ for (j = 0; j < RTW89_RFK_RECORD_PATH_NR; j++) {
+ p += scnprintf(p, end - p, " S%d =", j);
+ for (i = 0; i < RTW89_RFK_RECORD_HISTORY_NR; i++)
+ p += scnprintf(p, end - p, " %03x", info->tssi_code[i][j]);
+ p += scnprintf(p, end - p, "\n");
+ }
+
+ return p - buf;
+}
+
+static void rtw89_dbg_diag_rf_set_rfk(struct rtw89_dev *rtwdev)
+{
+ struct rtw89_entity_mgnt *mgnt = &rtwdev->hal.entity_mgnt;
+ struct rtw89_vif_link *rtwvif_link;
+ struct rtw89_vif *rtwvif;
+ unsigned int link_id;
+
+ list_for_each_entry(rtwvif, &mgnt->active_list, mgnt_entry)
+ rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
+ rtw89_chip_rfk_channel(rtwdev, rtwvif_link);
+}
+
+enum rtw89_dbg_diag_rf_type {
+ RTW89_DBG_DIAG_RF_RSVD = 0,
+ RTW89_DBG_DIAG_RF_RFK = 1,
+};
+
+static ssize_t
+rtw89_debug_priv_diag_rf_set(struct rtw89_dev *rtwdev,
+ struct rtw89_debugfs_priv *debugfs_priv,
+ const char *buf, size_t count)
+{
+ u8 type;
+ int ret;
+
+ ret = kstrtou8(buf, 0, &type);
+ if (ret)
+ return -EINVAL;
+
+ if (rtwdev->scanning)
+ rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif);
+
+ rtw89_leave_ps_mode(rtwdev);
+
+ switch (type) {
+ case RTW89_DBG_DIAG_RF_RFK:
+ rtw89_dbg_diag_rf_set_rfk(rtwdev);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return count;
+}
+
static ssize_t
rtw89_debug_priv_monitor_opts_get(struct rtw89_dev *rtwdev,
struct rtw89_debugfs_priv *debugfs_priv,
@@ -5509,6 +5622,7 @@ static const struct rtw89_debugfs rtw89_debugfs_templ = {
.beacon_info = rtw89_debug_priv_get(beacon_info),
.diag_mac = rtw89_debug_priv_get(diag_mac, RSIZE_16K, RLOCK),
.diag_bb = rtw89_debug_priv_get(diag_bb, RSIZE_8K, RLOCK),
+ .diag_rf = rtw89_debug_priv_set_and_get(diag_rf, RWLOCK),
.monitor_opts = rtw89_debug_priv_set_and_get(monitor_opts, RWLOCK),
};
@@ -5566,6 +5680,7 @@ void rtw89_debugfs_add_sec2(struct rtw89_dev *rtwdev, struct dentry *debugfs_top
rtw89_debugfs_add_r(beacon_info);
rtw89_debugfs_add_r(diag_mac);
rtw89_debugfs_add_r(diag_bb);
+ rtw89_debugfs_add_rw(diag_rf);
rtw89_debugfs_add_rw(monitor_opts);
}
diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c
index 30d5741da87e..c78107e92206 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.c
+++ b/drivers/net/wireless/realtek/rtw89/phy.c
@@ -3968,6 +3968,23 @@ void (* const rtw89_phy_c2h_rfk_log_handler[])(struct rtw89_dev *rtwdev,
[RTW89_PHY_C2H_RFK_LOG_FUNC_CIM3K] = rtw89_phy_c2h_rfk_log_cim3k,
};
+#define NAME_RTW89_RFK_REPORT(type) \
+ [RTW89_RFK_REPORT_ ## type] = #type
+
+const char * const rtw89_rfk_report_names[] = {
+ NAME_RTW89_RFK_REPORT(PRE_NTFY),
+ NAME_RTW89_RFK_REPORT(TSSI),
+ NAME_RTW89_RFK_REPORT(IQK),
+ NAME_RTW89_RFK_REPORT(DPK),
+ NAME_RTW89_RFK_REPORT(TXGAPK),
+ NAME_RTW89_RFK_REPORT(DACK),
+ NAME_RTW89_RFK_REPORT(RX_DCK),
+ NAME_RTW89_RFK_REPORT(TX_IQK),
+ NAME_RTW89_RFK_REPORT(CIM3k),
+};
+
+static_assert(ARRAY_SIZE(rtw89_rfk_report_names) == NUM_OF_RTW89_RFK_REPORT_TYPES);
+
static
void rtw89_phy_rfk_report_prep(struct rtw89_dev *rtwdev)
{
@@ -3979,8 +3996,8 @@ void rtw89_phy_rfk_report_prep(struct rtw89_dev *rtwdev)
}
static
-int rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev, const char *rfk_name,
- unsigned int ms)
+int ____rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev, const char *rfk_name,
+ unsigned int ms)
{
struct rtw89_rfk_wait_info *wait = &rtwdev->rfk_wait;
unsigned long time_left;
@@ -4017,6 +4034,29 @@ int rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev, const char *rfk_name,
return 0;
}
+static
+int __rtw89_phy_rfk_report_wait(struct rtw89_dev *rtwdev,
+ enum rtw89_rfk_report_types rfk_type,
+ enum rtw89_phy_idx phy_idx,
+ const struct rtw89_chan *chan,
+ unsigned int ms)
+{
+ const char *rfk_name = rtw89_rfk_report_names[rfk_type];
+ struct rtw89_rfk_wait_info *wait = &rtwdev->rfk_wait;
+ struct rtw89_rfk_record *record = wait->record_ptr;
+ int ret;
+
+ ret = ____rtw89_phy_rfk_report_wait(rtwdev, rfk_name, ms);
+
+ if (record)
+ record->states[rfk_type] = wait->state;
+
+ return ret;
+}
+
+#define rtw89_phy_rfk_report_wait(rtwdev, type, phy_idx, chan, ms) \
+ __rtw89_phy_rfk_report_wait(rtwdev, RTW89_RFK_REPORT_ ## type, phy_idx, chan, ms)
+
static void
rtw89_phy_c2h_rfk_report_state(struct rtw89_dev *rtwdev, struct sk_buff *c2h, u32 len)
{
@@ -4122,7 +4162,7 @@ int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev,
if (RTW89_CHK_FW_FEATURE_GROUP(WITH_RFK_PRE_NOTIFY, &rtwdev->fw)) {
rtw89_phy_rfk_report_prep(rtwdev);
rtw89_fw_h2c_rf_pre_ntfy(rtwdev, phy_idx);
- ret = rtw89_phy_rfk_report_wait(rtwdev, "PRE_NTFY", ms);
+ ret = rtw89_phy_rfk_report_wait(rtwdev, PRE_NTFY, phy_idx, NULL, ms);
if (ret)
return ret;
}
@@ -4152,7 +4192,7 @@ int rtw89_phy_rfk_tssi_and_wait(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- return rtw89_phy_rfk_report_wait(rtwdev, "TSSI", ms);
+ return rtw89_phy_rfk_report_wait(rtwdev, TSSI, phy_idx, chan, ms);
}
EXPORT_SYMBOL(rtw89_phy_rfk_tssi_and_wait);
@@ -4169,7 +4209,7 @@ int rtw89_phy_rfk_iqk_and_wait(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- return rtw89_phy_rfk_report_wait(rtwdev, "IQK", ms);
+ return rtw89_phy_rfk_report_wait(rtwdev, IQK, phy_idx, chan, ms);
}
EXPORT_SYMBOL(rtw89_phy_rfk_iqk_and_wait);
@@ -4186,7 +4226,7 @@ int rtw89_phy_rfk_dpk_and_wait(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- return rtw89_phy_rfk_report_wait(rtwdev, "DPK", ms);
+ return rtw89_phy_rfk_report_wait(rtwdev, DPK, phy_idx, chan, ms);
}
EXPORT_SYMBOL(rtw89_phy_rfk_dpk_and_wait);
@@ -4203,7 +4243,7 @@ int rtw89_phy_rfk_txgapk_and_wait(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- return rtw89_phy_rfk_report_wait(rtwdev, "TXGAPK", ms);
+ return rtw89_phy_rfk_report_wait(rtwdev, TXGAPK, phy_idx, chan, ms);
}
EXPORT_SYMBOL(rtw89_phy_rfk_txgapk_and_wait);
@@ -4220,7 +4260,7 @@ int rtw89_phy_rfk_dack_and_wait(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- return rtw89_phy_rfk_report_wait(rtwdev, "DACK", ms);
+ return rtw89_phy_rfk_report_wait(rtwdev, DACK, phy_idx, chan, ms);
}
EXPORT_SYMBOL(rtw89_phy_rfk_dack_and_wait);
@@ -4237,7 +4277,7 @@ int rtw89_phy_rfk_rxdck_and_wait(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- return rtw89_phy_rfk_report_wait(rtwdev, "RX_DCK", ms);
+ return rtw89_phy_rfk_report_wait(rtwdev, RX_DCK, phy_idx, chan, ms);
}
EXPORT_SYMBOL(rtw89_phy_rfk_rxdck_and_wait);
@@ -4254,7 +4294,7 @@ int rtw89_phy_rfk_txiqk_and_wait(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- return rtw89_phy_rfk_report_wait(rtwdev, "TX_IQK", ms);
+ return rtw89_phy_rfk_report_wait(rtwdev, TX_IQK, phy_idx, chan, ms);
}
EXPORT_SYMBOL(rtw89_phy_rfk_txiqk_and_wait);
@@ -4271,7 +4311,7 @@ int rtw89_phy_rfk_cim3k_and_wait(struct rtw89_dev *rtwdev,
if (ret)
return ret;
- return rtw89_phy_rfk_report_wait(rtwdev, "CIM3k", ms);
+ return rtw89_phy_rfk_report_wait(rtwdev, CIM3k, phy_idx, chan, ms);
}
EXPORT_SYMBOL(rtw89_phy_rfk_cim3k_and_wait);
diff --git a/drivers/net/wireless/realtek/rtw89/phy.h b/drivers/net/wireless/realtek/rtw89/phy.h
index b0c82bac72f0..0963cdfb1594 100644
--- a/drivers/net/wireless/realtek/rtw89/phy.h
+++ b/drivers/net/wireless/realtek/rtw89/phy.h
@@ -1150,6 +1150,9 @@ void rtw89_phy_rate_pattern_vif(struct rtw89_dev *rtwdev,
bool rtw89_phy_c2h_chk_atomic(struct rtw89_dev *rtwdev, u8 class, u8 func);
void rtw89_phy_c2h_handle(struct rtw89_dev *rtwdev, struct sk_buff *skb,
u32 len, u8 class, u8 func);
+
+extern const char * const rtw89_rfk_report_names[];
+
int rtw89_phy_rfk_pre_ntfy_and_wait(struct rtw89_dev *rtwdev,
enum rtw89_phy_idx phy_idx,
unsigned int ms);
diff --git a/drivers/net/wireless/realtek/rtw89/reg.h b/drivers/net/wireless/realtek/rtw89/reg.h
index 4d2117de798b..3bf2865b81ab 100644
--- a/drivers/net/wireless/realtek/rtw89/reg.h
+++ b/drivers/net/wireless/realtek/rtw89/reg.h
@@ -8763,6 +8763,7 @@
#define RR_VCO 0xb2
#define RR_VCO_VAL GENMASK(18, 14)
#define RR_VCO_SEL GENMASK(9, 8)
+#define RR_VCO_STS GENMASK(7, 0)
#define RR_VCI 0xb3
#define RR_VCI_ON BIT(7)
#define RR_LPF 0xb7
--
2.25.1
^ permalink raw reply related
* RE: [PATCH] rtlwifi: rtl8192d: remove dead SMPS rate mask code
From: Ping-Ke Shih @ 2026-07-12 3:58 UTC (permalink / raw)
To: Chelsy Ratnawat
Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20260709194315.157030-1-chelsyratnawat2001@gmail.com>
Chelsy Ratnawat <chelsyratnawat2001@gmail.com> wrote:
> mimo_ps is initialized to IEEE80211_SMPS_OFF and never modified in
> rtl92d_update_hal_rate_table(). Therefore, the IEEE80211_SMPS_STATIC
> case is unreachable.
> Remove the unused mimo_ps variable and the dead branch.
>
> Signed-off-by: Chelsy Ratnawat <chelsyratnawat2001@gmail.com>
Acked-by: Ping-Ke Shih <pkshih@realtek.com>
I'd use "wifi: rtlwifi: ..." as prefix while merging this patch.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox