* [PATCH v7 3/3] PCI: Disable broken bus reset on Qualcomm devices
From: Jose Ignacio Tornos Martinez @ 2026-06-03 10:58 UTC (permalink / raw)
To: bhelgaas, alex
Cc: jjohnson, mani, linux-pci, linux-wireless, ath11k, ath12k, mhi,
linux-kernel, Jose Ignacio Tornos Martinez
In-Reply-To: <20260603105853.326290-1-jtornosm@redhat.com>
Some Qualcomm PCIe devices (WCN6855/WCN7850 WiFi cards, SDX62/SDX65 modems)
do not properly support Secondary Bus Reset (SBR).
Testing confirms this is device-specific, not deployment-specific:
MediaTek MT7925e successfully uses bus reset through the same passive
M.2-to-PCIe adapters where Qualcomm devices fail, proving PERST# is
properly wired through the adapters.
This quirk acts as a safety net, preventing the broken bus reset from being
attempted if users override reset methods (device_specific or d3cold when
available) via sysfs.
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v7: Address the comments from Jeff Johnson: the problem was detected for
the specific devices WCN6855 and WCN7850, use the name of the devices
instead of the related drivers ath11k and ath12k, which support a large
number of devices
v6: https://lore.kernel.org/all/20260602160024.1171949-4-jtornosm@redhat.com/
drivers/pci/quirks.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 000000000000..111111111111 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -3789,6 +3789,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0033, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0034, quirk_no_bus_reset);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003e, quirk_no_bus_reset);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_QCOM, 0x1103, quirk_no_bus_reset); /* WCN6855 */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_QCOM, 0x1107, quirk_no_bus_reset); /* WCN7850 */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_QCOM, 0x0308, quirk_no_bus_reset); /* SDX62/SDX65 */
/*
* Root port on some Cavium CN8xxx chips do not successfully complete a bus
--
2.53.0
^ permalink raw reply related
* [PATCH v6 2/3] PCI: Add device-specific reset for Qualcomm devices
From: Jose Ignacio Tornos Martinez @ 2026-06-03 10:58 UTC (permalink / raw)
To: bhelgaas, alex
Cc: jjohnson, mani, linux-pci, linux-wireless, ath11k, ath12k, mhi,
linux-kernel, Jose Ignacio Tornos Martinez
In-Reply-To: <20260603105853.326290-1-jtornosm@redhat.com>
Some Qualcomm PCIe devices (WCN6855/WCN7850 WiFi cards, SDX62/SDX65 modems)
lack working reset methods for VFIO passthrough scenarios. These devices
have no FLR capability, advertise NoSoftRst+ (blocking PM reset), and have
broken bus reset.
The problem manifests in VFIO passthrough scenarios:
- WCN6855 WiFi card (17cb:1103): Normal VM operation works fine, including
clean shutdown/reboot. However, when the VM terminates uncleanly
(crash, force-off), VFIO attempts to reset the device before it can
be assigned to another VM. Without a working reset method, the device
remains in an undefined state, preventing reuse.
- WCN7850 WiFi card (17cb:1107): Same behavior as WCN6855.
- SDX62/SDX65 5G modems (17cb:0308): Never successfully initialize even
on first VM assignment without proper reset capability.
Add device-specific reset entries for these Qualcomm devices using D3cold
power cycling with automatic D3hot fallback. The implementation uses
pci_set_power_state(D3cold) which automatically falls back to D3hot on
platforms without ACPI _PR3 power resources. While not a complete reset
(BARs preserved), testing shows D3hot transition provides sufficient reset
for VFIO reuse.
Extract a shared pci_dev_d3cold_d0_cycle() helper function to avoid code
duplication between pci_d3cold_reset() (strict _PR3 requirement) and the
new reset_d3cold_d3hot() device-specific reset (automaticfallback). The
helper handles IOMMU preparation, performs the power cycle via
pci_set_power_state(), and cleans up IOMMU state.
Device-specific reset is position #1 in the reset hierarchy, so these
Qualcomm devices will use power cycling as their primary reset method,
with the general d3cold method (position #8) available as a fallback on
_PR3-capable platforms if users override via sysfs.
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v7: Address the comments from Jeff Johnson: the problem was detected for
the specific devices WCN6855 and WCN7850, use the name of the devices
instead of the related drivers ath11k and ath12k, which support a large
number of devices
v6: https://lore.kernel.org/all/20260602160024.1171949-3-jtornosm@redhat.com/
drivers/pci/pci.c | 37 +++++++++++++++++++++++++++----------
drivers/pci/pci.h | 1 +
drivers/pci/quirks.c | 19 +++++++++++++++++++
3 files changed, 47 insertions(+), 10 deletions(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 096868f80cd4..f7a7443287fd 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4491,6 +4491,32 @@ static int pci_pm_reset(struct pci_dev *dev, bool probe)
return ret;
}
+/**
+ * pci_dev_d3cold_d0_cycle - Perform D3cold->D0 power cycle
+ * @dev: Device to power cycle
+ *
+ * Common helper to perform D3cold->D0 power cycle for reset methods.
+ * Attempts D3cold transition with automatic fallback to D3hot on platforms
+ * without ACPI _PR3 power resources.
+ *
+ * Caller must handle IOMMU preparation/cleanup if needed.
+ *
+ * Returns 0 on success, negative error code on failure.
+ */
+int pci_dev_d3cold_d0_cycle(struct pci_dev *dev)
+{
+ int ret;
+
+ if (dev->current_state != PCI_D0)
+ return -EINVAL;
+
+ ret = pci_set_power_state(dev, PCI_D3cold);
+ if (ret)
+ return ret;
+
+ return pci_set_power_state(dev, PCI_D0);
+}
+
/**
* pci_d3cold_reset - Put device into D3cold and back to D0 for reset
* @dev: PCI device to reset
@@ -4520,22 +4546,13 @@ static int pci_d3cold_reset(struct pci_dev *dev, bool probe)
if (probe)
return 0;
- if (dev->current_state != PCI_D0)
- return -EINVAL;
-
ret = pci_dev_reset_iommu_prepare(dev);
if (ret) {
pci_err(dev, "failed to stop IOMMU for a PCI reset: %d\n", ret);
return ret;
}
- ret = pci_set_power_state(dev, PCI_D3cold);
- if (ret)
- goto done;
-
- ret = pci_set_power_state(dev, PCI_D0);
-
-done:
+ ret = pci_dev_d3cold_d0_cycle(dev);
pci_dev_reset_iommu_done(dev);
return ret;
}
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 4a14f88e543a..a9942787de9e 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -234,6 +234,7 @@ void pci_init_reset_methods(struct pci_dev *dev);
int pci_bridge_secondary_bus_reset(struct pci_dev *dev);
int pci_bus_error_reset(struct pci_dev *dev);
int pci_try_reset_bridge(struct pci_dev *bridge);
+int pci_dev_d3cold_d0_cycle(struct pci_dev *dev);
struct pci_cap_saved_data {
u16 cap_nr;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index e49136ac5dbf..70f3b0f26799 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -4237,6 +4237,22 @@ static int reset_hinic_vf_dev(struct pci_dev *pdev, bool probe)
return 0;
}
+/*
+ * Device-specific reset method via D3cold/D3hot power cycle.
+ *
+ * Some devices lack working FLR, advertise NoSoftRst+ (blocking PM reset),
+ * and have broken bus reset. This function provides device-specific reset via
+ * power cycling, attempting D3cold with automatic fallback to D3hot on platforms
+ * without ACPI _PR3 power resources.
+ */
+static int reset_d3cold_d3hot(struct pci_dev *dev, bool probe)
+{
+ if (probe)
+ return 0;
+
+ return pci_dev_d3cold_d0_cycle(dev);
+}
+
static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF,
reset_intel_82599_sfp_virtfn },
@@ -4252,6 +4268,9 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = {
reset_chelsio_generic_dev },
{ PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HINIC_VF,
reset_hinic_vf_dev },
+ { PCI_VENDOR_ID_QCOM, 0x1103, reset_d3cold_d3hot }, /* WCN6855 */
+ { PCI_VENDOR_ID_QCOM, 0x1107, reset_d3cold_d3hot }, /* WCN7850 */
+ { PCI_VENDOR_ID_QCOM, 0x0308, reset_d3cold_d3hot }, /* SDX62/SDX65 */
{ 0 }
};
--
2.54.0
^ permalink raw reply related
* [PATCH v7 1/3] PCI: Add d3cold as general reset method
From: Jose Ignacio Tornos Martinez @ 2026-06-03 10:58 UTC (permalink / raw)
To: bhelgaas, alex
Cc: jjohnson, mani, linux-pci, linux-wireless, ath11k, ath12k, mhi,
linux-kernel, Jose Ignacio Tornos Martinez
In-Reply-To: <20260603105853.326290-1-jtornosm@redhat.com>
Add D3cold power cycle as a general PCI reset method for single-function
devices on platforms with ACPI _PR3 power resources. This provides true
power cycle reset capability when the platform can physically cut power
to the device.
The implementation strictly requires _PR3 to be present - the platform
must be able to control device power. This ensures d3cold only attempts
true power cycling, not falling back to D3hot transitions.
D3cold reset is placed at the end of the reset hierarchy since it requires
specific platform support and should be tried after standard methods.
Reset hierarchy with this change:
1. device_specific
2. acpi
3. flr
4. af_flr
5. pm (D3hot via config space, checks NoSoftRst)
6. bus (SBR)
7. cxl_bus
8. d3cold (NEW - true power cycle, requires _PR3)
This benefits:
- Platforms with _PR3 support
- Single-function devices needing true power cycle
- VFIO passthrough scenarios where FLR/PM unavailable
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v7: code unchanged from v6
v6: https://lore.kernel.org/all/20260602160024.1171949-2-jtornosm@redhat.com/
drivers/pci/pci.c | 50 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/pci.h | 2 +-
2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 8f7cfcc00090..096868f80cd4 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -4491,6 +4491,55 @@ static int pci_pm_reset(struct pci_dev *dev, bool probe)
return ret;
}
+/**
+ * pci_d3cold_reset - Put device into D3cold and back to D0 for reset
+ * @dev: PCI device to reset
+ * @probe: if true, check if D3cold reset is supported; if false, perform reset
+ *
+ * Reset the device by transitioning through D3cold (actual power removal via
+ * platform power control) and back to D0. This requires ACPI _PR3 power
+ * resources to be present - the platform must be able to physically cut power
+ * to the device.
+ *
+ * Only available for single-function devices to avoid affecting other
+ * functions in multi-function devices.
+ *
+ * Returns 0 if device can be/was reset this way, -ENOTTY if not supported,
+ * or other negative error code on failure.
+ */
+static int pci_d3cold_reset(struct pci_dev *dev, bool probe)
+{
+ int ret;
+
+ if (dev->multifunction)
+ return -ENOTTY;
+
+ if (!pci_pr3_present(dev))
+ return -ENOTTY;
+
+ if (probe)
+ return 0;
+
+ if (dev->current_state != PCI_D0)
+ return -EINVAL;
+
+ ret = pci_dev_reset_iommu_prepare(dev);
+ if (ret) {
+ pci_err(dev, "failed to stop IOMMU for a PCI reset: %d\n", ret);
+ return ret;
+ }
+
+ ret = pci_set_power_state(dev, PCI_D3cold);
+ if (ret)
+ goto done;
+
+ ret = pci_set_power_state(dev, PCI_D0);
+
+done:
+ pci_dev_reset_iommu_done(dev);
+ return ret;
+}
+
/**
* pcie_wait_for_link_status - Wait for link status change
* @pdev: Device whose link to wait for.
@@ -5065,6 +5114,7 @@ const struct pci_reset_fn_method pci_reset_fn_methods[] = {
{ pci_pm_reset, .name = "pm" },
{ pci_reset_bus_function, .name = "bus" },
{ cxl_reset_bus_function, .name = "cxl_bus" },
+ { pci_d3cold_reset, .name = "d3cold" },
};
/**
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2c4454583c11..1ca7b880ead7 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -51,7 +51,7 @@
PCI_STATUS_PARITY)
/* Number of reset methods used in pci_reset_fn_methods array in pci.c */
-#define PCI_NUM_RESET_METHODS 8
+#define PCI_NUM_RESET_METHODS 9
#define PCI_RESET_PROBE true
#define PCI_RESET_DO_RESET false
--
2.54.0
^ permalink raw reply related
* [PATCH v7 0/3] PCI: Add d3cold and device-specific reset for Qualcomm devices
From: Jose Ignacio Tornos Martinez @ 2026-06-03 10:58 UTC (permalink / raw)
To: bhelgaas, alex
Cc: jjohnson, mani, linux-pci, linux-wireless, ath11k, ath12k, mhi,
linux-kernel, Jose Ignacio Tornos Martinez
Some PCIe devices lack working reset methods for VFIO passthrough scenarios.
These devices typically have no FLR, advertise NoSoftRst+ (blocking PM reset),
and have broken or unavailable bus reset. When a VM crashes, VFIO cannot reset
the device for reuse without a working reset method.
This series addresses the problem by adding general d3cold infrastructure and
device-specific reset for Qualcomm devices:
**Patch 1/3: d3cold reset method**
Adds D3cold as a general reset method with strict _PR3 requirement. Only
attempts true power cycling via platform control (ACPI _PR3), never falls
back to D3hot. This provides genuine power-off reset on platforms that
support it.
**Patch 2/3: device-specific reset for Qualcomm devices**
Adds device-specific reset entries for Qualcomm WCN6855/WCN7850 WiFi cards and
SDX62/SDX65 modems using D3cold power cycling with automatic D3hot fallback.
Uses pci_set_power_state(D3cold) which automatically falls back to D3hot on
platforms without _PR3. Extracts shared pci_dev_d3cold_d0_cycle() helper to
avoid code duplication with general d3cold method. Device-specific reset is
position #1 in reset hierarchy, providing immediate working reset for these
Qualcomm devices.
**Patch 3/3: Qualcomm quirk_no_bus_reset**
Disables broken bus reset for Qualcomm devices. Testing proves this is
device-specific: MediaTek MT7925e works correctly with bus reset using the
same passive M.2-to-PCIe adapters where Qualcomm devices fail, confirming
PERST# is properly wired and the issue is not deployment-specific. Acts as
safety net to prevent broken SBR if users override via sysfs.
v7: Address the comments from Jeff Johnson: the problem was detected for
the specific devices WCN6855 and WCN7850, use the name of the devices
instead of the related drivers ath11k and ath12k, which support a large
number of devices (patches 2/3 and 3/3).
v6: https://lore.kernel.org/all/20260602160024.1171949-1-jtornosm@redhat.com/
Jose Ignacio Tornos Martinez (3):
PCI: Add d3cold as general reset method
PCI: Add device-specific reset for Qualcomm devices
PCI: Disable broken bus reset on Qualcomm devices
--
2.53.0
^ permalink raw reply
* Re: [PATCH wireless-next 11/16] wifi: Update UHR PHY capabilities to D1.4
From: Raja Mani @ 2026-06-03 9:51 UTC (permalink / raw)
To: Johannes Berg, linux-wireless; +Cc: Johannes Berg
In-Reply-To: <20260529102644.f146932b21e2.I12bad84157bf809fbe285b79420143b3c456d9d2@changeid>
On 5/29/2026 1:55 PM, Johannes Berg wrote:
> From: Johannes Berg <johannes.berg@intel.com>
>
> There are new capabilities in D1.4, and some reserved
> bits. Update the code accordingly.
>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> ---
> .../wireless/intel/iwlwifi/iwl-nvm-parse.c | 10 +++--
> drivers/net/wireless/intel/iwlwifi/mld/tlc.c | 4 +-
> .../wireless/virtual/mac80211_hwsim_main.c | 24 +++++------
> include/linux/ieee80211-uhr.h | 40 ++++++++++++++-----
> 4 files changed, 49 insertions(+), 29 deletions(-)
>
[..]
> diff --git a/include/linux/ieee80211-uhr.h b/include/linux/ieee80211-uhr.h
> index 71faf4a6825e..120993897490 100644
> --- a/include/linux/ieee80211-uhr.h
> +++ b/include/linux/ieee80211-uhr.h
> @@ -401,17 +401,39 @@ struct ieee80211_uhr_cap_mac {
> u8 mac_cap[5];
> } __packed;
>
> -#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 0x01
> -#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 0x02
> -#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 0x04
> -#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_160 0x08
> -#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_320 0x10
> -#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_320 0x20
> -#define IEEE80211_UHR_PHY_CAP_ELR_RX 0x40
> -#define IEEE80211_UHR_PHY_CAP_ELR_TX 0x80
> +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_LE80 0x00000001
> +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_LE80 0x00000002
> +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_160 0x00000004
> +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_160 0x00000008
> +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_SND_NDP_320 0x00000010
> +#define IEEE80211_UHR_PHY_CAP_MAX_NSS_RX_DL_MU_320 0x00000020
> +#define IEEE80211_UHR_PHY_CAP_ELR_RX 0x00000040
> +#define IEEE80211_UHR_PHY_CAP_ELR_TX 0x00000080
In D1.4, bit 6 is assigned to ELR TX, bit 7 is for ELR RX.
> +#define IEEE80211_UHR_PHY_CAP_PART_BW_DL_MUMIMO 0x00000100
> +#define IEEE80211_UHR_PHY_CAP_PART_BW_UL_MUMIMO 0x00000200
> +#define IEEE80211_UHR_PHY_CAP_MCS15 0x00000400
> +#define IEEE80211_UHR_PHY_CAP_2XLDPC_TX 0x00000800
> +#define IEEE80211_UHR_PHY_CAP_2XLDPC_RX 0x00001000
> +#define IEEE80211_UHR_PHY_CAP_UEQM_TX_MAX_NSS 0x00006000
> +#define IEEE80211_UHR_PHY_CAP_UEQM_RX_MAX_NSS 0x00018000
> +#define IEEE80211_UHR_PHY_CAP_CO_BF_JOINT_SOUNDING 0x00040000
> +#define IEEE80211_UHR_PHY_CAP_IM_TX 0x00080000
> +#define IEEE80211_UHR_PHY_CAP_IM_RX 0x00100000
> +#define IEEE80211_UHR_PHY_CAP_CO_SR_MODE_1 0x00200000
> +#define IEEE80211_UHR_PHY_CAP_CO_SR_MODE_2 0x00400000
> +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_20_IN_PBW_20 0x00800000
> +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_40_IN_PBW_40 0x01000000
> +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_80_IN_PBW_80 0x02000000
> +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_80_IN_PBW_160 0x04000000
> +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_80_IN_PBW_320 0x08000000
> +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_20_IN_PBW_GE80 0x10000000
> +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_40_IN_PBW_GE80 0x20000000
> +#define IEEE80211_UHR_PHY_CAP_DRU_DBW_60_IN_PBW_GE80 0x40000000
> +#define IEEE80211_UHR_PHY_CAP_DRU_RRU_HYBRID_MODE 0x80000000
>
> struct ieee80211_uhr_cap_phy {
> - u8 cap;
> + __le32 cap;
> + u8 reserved;
> } __packed;
>
> struct ieee80211_uhr_cap {
^ permalink raw reply
* Re: [PATCH 3/4] dt-bindings: bus: add brcm,bcm6362-wlan
From: Philipp Zabel @ 2026-06-03 9:29 UTC (permalink / raw)
To: Alessio Ferri, Rafał Miłecki, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli
Cc: linux-kernel, linux-wireless, devicetree
In-Reply-To: <20260529-add-bcm6362-wlan-v1-3-722242777f58@gmail.com>
On Fr, 2026-05-29 at 02:06 +0200, Alessio Ferri wrote:
> Document the binding for the SHIM bridge that gates the on-chip
> 2.4 GHz WLAN block of the Broadcom BCM6362 SoC. The bridge owns the
> SHIM peephole, a single clock for the macro, and two resets (the
> SHIM macro itself and its ubus side). It is also a bus: it carries
> one brcm,bus-axi child describing the bcma backplane behind the
> SHIM, with a standard interrupt-map routing the d11 core's IRQ to
> the SoC interrupt controller.
>
> Assisted-by: Claude:claude-4.8-opus
> Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
> ---
> .../devicetree/bindings/bus/brcm,bcm6362-wlan.yaml | 106 +++++++++++++++++++++
> 1 file changed, 106 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml b/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml
> new file mode 100644
> index 000000000000..c8d49ccdd2c1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml
> @@ -0,0 +1,106 @@
[...]
> + resets:
> + items:
> + - description: SHIM macro reset
> + - description: SHIM ubus reset
> +
> + reset-names:
> + items:
> + - const: shim
> + - const: shim-ubus
The "shim" prefix is superfluous. Why not call them "macro" and "ubus"
and match the description?
regards
Philipp
^ permalink raw reply
* Re: [PATCH 4/4] bus: add BCM6362 on-chip WLAN SHIM bridge driver
From: Philipp Zabel @ 2026-06-03 9:28 UTC (permalink / raw)
To: Alessio Ferri, Rafał Miłecki, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Florian Fainelli
Cc: linux-kernel, linux-wireless, devicetree
In-Reply-To: <20260529-add-bcm6362-wlan-v1-4-722242777f58@gmail.com>
On Fr, 2026-05-29 at 02:06 +0200, Alessio Ferri wrote:
> Add the bridge driver that brings up the BCM6362 on-chip WLAN SHIM
> and then populates a brcm,bus-axi child whose backplane is
> enumerated by drivers/bcma/host_soc.c.
>
> Add myself as MANTAINER for this shim.
>
[...]
>
> Assisted-by: Claude:claude-4.8-opus
> Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
> ---
> MAINTAINERS | 7 ++
> drivers/bus/Kconfig | 13 +++
> drivers/bus/Makefile | 1 +
> drivers/bus/bcm6362-wlan-shim.c | 252 ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 273 insertions(+)
>
[...]
> diff --git a/drivers/bus/bcm6362-wlan-shim.c b/drivers/bus/bcm6362-wlan-shim.c
> new file mode 100644
> index 000000000000..a2de03cf8ff7
> --- /dev/null
> +++ b/drivers/bus/bcm6362-wlan-shim.c
> @@ -0,0 +1,252 @@
[...]
> +static int bcm6362_wlan_bringup(struct bcm6362_wlan *priv)
> +{
> + int ret;
> +
> + dev_info(priv->dev, "bring-up: start\n");
Too verbose.
> +
> + ret = clk_prepare_enable(priv->clk);
> + if (ret) {
> + dev_err(priv->dev, "clk_prepare_enable failed: %d\n", ret);
> + return ret;
> + }
> + dev_info(priv->dev, "bring-up: clock enabled, rate=%lu Hz\n",
> + clk_get_rate(priv->clk));
> + mdelay(10);
Why is this a delay instead of a sleep? Why is it there at all?
Prefer using msleep() or fsleep() if possible.
> +
> + /* Reset toggle (brcm,bcm6345-reset hides the active-low softResetB
> + * encoding, so assert/deassert read naturally here).
> + */
> + reset_control_assert(priv->rst_shim_ubus);
> + reset_control_assert(priv->rst_shim);
> + mdelay(1);
> + reset_control_deassert(priv->rst_shim_ubus);
> + reset_control_deassert(priv->rst_shim);
Switch deassert order for consistency with teardown, if possible.
Or use reset_control_bulk_(de)assert() API.
[...]
> +static int bcm6362_wlan_probe(struct platform_device *pdev)
> +{
> + struct device *dev = &pdev->dev;
> + struct of_dev_auxdata auxdata[2];
> + struct bcm6362_wlan *priv;
> + int ret;
> +
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> + priv->dev = dev;
> +
> + priv->shim = devm_platform_ioremap_resource_byname(pdev, "shim");
> + if (IS_ERR(priv->shim))
> + return PTR_ERR(priv->shim);
> +
> + priv->clk = devm_clk_get(dev, NULL);
> + if (IS_ERR(priv->clk))
> + return PTR_ERR(priv->clk);
> +
> + priv->rst_shim = devm_reset_control_get_exclusive(dev, "shim");
> + if (IS_ERR(priv->rst_shim))
> + return PTR_ERR(priv->rst_shim);
> +
> + priv->rst_shim_ubus = devm_reset_control_get_exclusive(dev,
> + "shim-ubus");
> + if (IS_ERR(priv->rst_shim_ubus))
> + return PTR_ERR(priv->rst_shim_ubus);
Consider using devm_reset_control_bulk_get_exclusive().
regards
Philipp
^ permalink raw reply
* [PATCH] wifi: cfg80211: enforce HE/EHT cap/oper consistency
From: Johannes Berg @ 2026-06-03 9:18 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg, Xiang Mei
From: Johannes Berg <johannes.berg@intel.com>
Xiang Mei reports that mac80211 could crash if eht_cap is set
but eht_oper isn't. Rather than fixing that for the individual
user(s), enforce that both HE/EHT have consistent elements.
Reported-by: Xiang Mei <xmei5@asu.edu>
Fixes: 22c64f37e1d4 ("wifi: mac80211: Update MCS15 support in link_conf")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/wireless/nl80211.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index dac2e8643c49..76c537a6e8b5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6714,6 +6714,12 @@ static int nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
return -EINVAL;
}
+ if (!!params->he_cap != !!params->he_oper)
+ return -EINVAL;
+
+ if (!!params->eht_cap != !!params->eht_oper)
+ return -EINVAL;
+
return 0;
}
--
2.53.0
^ permalink raw reply related
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
From: Arnd Bergmann @ 2026-06-03 8:41 UTC (permalink / raw)
To: Rasmus Villemoes
Cc: Andy Shevchenko, Arnd Bergmann, Steven Rostedt, Masami Hiramatsu,
Andrew Morton, Petr Mladek, Nathan Chancellor, Dennis Dalessandro,
Jason Gunthorpe, Leon Romanovsky, Arend van Spriel,
Miri Korenblit, Mathieu Desnoyers, Sergey Senozhatsky,
Nick Desaulniers, Bill Wendling, Justin Stitt,
Vlastimil Babka (SUSE), linux-rdma, linux-kernel, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-trace-kernel, llvm
In-Reply-To: <875x40hz7k.fsf@prevas.dk>
On Wed, Jun 3, 2026, at 09:15, Rasmus Villemoes wrote:
> On Tue, Jun 02 2026, "Arnd Bergmann" <arnd@arndb.de> wrote:
>> On Tue, Jun 2, 2026, at 20:59, Andy Shevchenko wrote:
>>> On Tue, Jun 02, 2026 at 05:07:05PM +0200, Arnd Bergmann wrote:
>
> May I suggest a different approach, that avoids having that extra
> function emitted (which presumably compiles to a single jump
> instruction, but still, with retpoline and CFI and all that it all adds
> up): Keep the declaration of __vsnprintf() in the header without the
> __print() attribute, but then do
>
> int __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> __alias(vsnprintf);
>
> in vsprintf.c. Aside from reusing the same entry point, I could well
> imagine a compiler some day complaining about seeing the printf
> attribute applied in a local extra declaration but not having it in the
> header file.
>
> Presumably it will need its own EXPORT_SYMBOL if any of the intended
> users are modular, and it certainly still needs a comment.
I had tried that earlier but given up because the attributes have to
match exactly.
This definition works with all currently supported versions of gcc,
but may have to change when the there is a new version that adds
even more attributes:
int
__printf(3, 0)
__attribute__((nothrow))
__attribute__((nonnull(1)))
__vsnprintf(char *__restrict buf, size_t size,
const char * __restrict fmt_str, va_list args)
__alias(vsnprintf);
We'd probably want to also add __nothrow and __nonnull macros
in linux/compiler-attributes.h if we do this.
For reference, see below for the alternative idea I had
that avoids adding the __vsnprintf() alias altogether by
passing down the va_format using "%pV".
I don't think I actually got this one right in the end
since I only build-tested it, but I expect it could be done
if someone is able to test and fix all the corner cases
properly.
Arnd
diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
index 4715330c7b6b..8e44fc3e60b0 100644
--- a/include/linux/trace_events.h
+++ b/include/linux/trace_events.h
@@ -956,14 +956,11 @@ perf_trace_buf_submit(void *raw_data, int size, int rctx, u16 type,
* gcc warns that you can not use a va_list in an inlined
* function. But lets me make it into a macro :-/
*/
-#define __trace_event_vstr_len(fmt, va) \
+#define __trace_event_vstr_len(vf) \
({ \
- va_list __ap; \
int __ret; \
\
- va_copy(__ap, *(va)); \
- __ret = __vsnprintf(NULL, 0, fmt, __ap) + 1; \
- va_end(__ap); \
+ __ret = snprintf(NULL, 0, "%pV", vf) + 1; \
\
min(__ret, TRACE_EVENT_STR_MAX); \
})
diff --git a/samples/trace_events/trace-events-sample.h b/samples/trace_events/trace-events-sample.h
index 1a05fc153353..2f3ee3632e77 100644
--- a/samples/trace_events/trace-events-sample.h
+++ b/samples/trace_events/trace-events-sample.h
@@ -143,20 +143,20 @@
* saved string into the "foo" field.
*
* __vstring: This is similar to __string() but instead of taking a
- * dynamic length, it takes a variable list va_list 'va' variable.
+ * dynamic length, it takes a variable list va_format 'vaf' variable.
* Some event callers already have a message from parameters saved
- * in a va_list. Passing in the format and the va_list variable
- * will save just enough on the ring buffer for that string.
- * Note, the va variable used is a pointer to a va_list, not
- * to the va_list directly.
+ * in a va_format. Passing in the va_format variable will save just
+ * enough on the ring buffer for that string.
*
- * (va_list *va)
+ * (va_format *vaf)
*
- * __vstring(foo, fmt, va) is similar to: vsnprintf(foo, fmt, va)
+ * __vstring(foo, vaf) is similar to:
+ *
+ * vsnprintf(foo, "%pV", vaf)
*
* To assign the string, use the helper macro __assign_vstr().
*
- * __assign_vstr(foo, fmt, va);
+ * __assign_vstr(foo, vaf);
*
* In most cases, the __assign_vstr() macro will take the same
* parameters as the __vstring() macro had to declare the string.
@@ -292,9 +292,9 @@ TRACE_EVENT(foo_bar,
TP_PROTO(const char *foo, int bar, const int *lst,
const char *string, const struct cpumask *mask,
- const char *fmt, va_list *va),
+ struct va_format *vaf),
- TP_ARGS(foo, bar, lst, string, mask, fmt, va),
+ TP_ARGS(foo, bar, lst, string, mask, vaf),
TP_STRUCT__entry(
__array( char, foo, 10 )
@@ -303,7 +303,7 @@ TRACE_EVENT(foo_bar,
__string( str, string )
__bitmask( cpus, num_possible_cpus() )
__cpumask( cpum )
- __vstring( vstr, fmt, va )
+ __vstring( vstr, vaf )
__string_len( lstr, foo, bar / 2 < strlen(foo) ? bar / 2 : strlen(foo) )
),
@@ -314,7 +314,7 @@ TRACE_EVENT(foo_bar,
__length_of(lst) * sizeof(int));
__assign_str(str);
__assign_str(lstr);
- __assign_vstr(vstr, fmt, va);
+ __assign_vstr(vstr, vaf);
__assign_bitmask(cpus, cpumask_bits(mask), num_possible_cpus());
__assign_cpumask(cpum, cpumask_bits(mask));
),
diff --git a/include/trace/stages/stage6_event_callback.h b/include/trace/stages/stage6_event_callback.h
index 7d6a6ca6e779..2a4611b20afa 100644
--- a/include/trace/stages/stage6_event_callback.h
+++ b/include/trace/stages/stage6_event_callback.h
@@ -28,7 +28,7 @@
#define __string_len(item, src, len) __dynamic_array(char, item, -1)
#undef __vstring
-#define __vstring(item, fmt, ap) __dynamic_array(char, item, -1)
+#define __vstring(item, vf) __dynamic_array(char, item, -1)
#undef __assign_str
#define __assign_str(dst) \
@@ -41,13 +41,8 @@
} while (0)
#undef __assign_vstr
-#define __assign_vstr(dst, fmt, va) \
- do { \
- va_list __cp_va; \
- va_copy(__cp_va, *(va)); \
- __vsnprintf(__get_str(dst), TRACE_EVENT_STR_MAX, fmt, __cp_va); \
- va_end(__cp_va); \
- } while (0)
+#define __assign_vstr(dst, vf) \
+ snprintf(__get_str(dst), TRACE_EVENT_STR_MAX, "%pV", vf);
#undef __bitmask
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
diff --git a/drivers/infiniband/hw/hfi1/trace_dbg.h b/drivers/infiniband/hw/hfi1/trace_dbg.h
index 05c4f1354269..c96144d516db 100644
--- a/drivers/infiniband/hw/hfi1/trace_dbg.h
+++ b/drivers/infiniband/hw/hfi1/trace_dbg.h
@@ -26,10 +26,10 @@ DECLARE_EVENT_CLASS(hfi1_trace_template,
TP_PROTO(const char *function, struct va_format *vaf),
TP_ARGS(function, vaf),
TP_STRUCT__entry(__string(function, function)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(__assign_str(function);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("(%s) %s",
__get_str(function),
diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h
index 68b78ca17eaa..c258ad7de79e 100644
--- a/drivers/net/wireless/ath/ath10k/trace.h
+++ b/drivers/net/wireless/ath/ath10k/trace.h
@@ -52,12 +52,12 @@ DECLARE_EVENT_CLASS(ath10k_log_event,
TP_STRUCT__entry(
__string(device, dev_name(ar->dev))
__string(driver, dev_driver_string(ar->dev))
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(device);
__assign_str(driver);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk(
"%s %s %s",
@@ -89,13 +89,13 @@ TRACE_EVENT(ath10k_log_dbg,
__string(device, dev_name(ar->dev))
__string(driver, dev_driver_string(ar->dev))
__field(unsigned int, level)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(device);
__assign_str(driver);
__entry->level = level;
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk(
"%s %s %s",
diff --git a/drivers/net/wireless/ath/ath11k/trace.h b/drivers/net/wireless/ath/ath11k/trace.h
index 75246b0a82e3..0ac14b72deac 100644
--- a/drivers/net/wireless/ath/ath11k/trace.h
+++ b/drivers/net/wireless/ath/ath11k/trace.h
@@ -127,12 +127,12 @@ DECLARE_EVENT_CLASS(ath11k_log_event,
TP_STRUCT__entry(
__string(device, dev_name(ab->dev))
__string(driver, dev_driver_string(ab->dev))
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(device);
__assign_str(driver);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk(
"%s %s %s",
diff --git a/drivers/net/wireless/ath/ath6kl/trace.h b/drivers/net/wireless/ath/ath6kl/trace.h
index 8577aa459c58..d46fe6b675f9 100644
--- a/drivers/net/wireless/ath/ath6kl/trace.h
+++ b/drivers/net/wireless/ath/ath6kl/trace.h
@@ -253,10 +253,10 @@ DECLARE_EVENT_CLASS(ath6kl_log_event,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf),
TP_STRUCT__entry(
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
@@ -281,11 +281,11 @@ TRACE_EVENT(ath6kl_log_dbg,
TP_ARGS(level, vaf),
TP_STRUCT__entry(
__field(unsigned int, level)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__entry->level = level;
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
diff --git a/drivers/net/wireless/ath/trace.h b/drivers/net/wireless/ath/trace.h
index 82aac0a4baff..298a56349ea7 100644
--- a/drivers/net/wireless/ath/trace.h
+++ b/drivers/net/wireless/ath/trace.h
@@ -40,13 +40,13 @@ TRACE_EVENT(ath_log,
TP_STRUCT__entry(
__string(device, wiphy_name(wiphy))
__string(driver, KBUILD_MODNAME)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(device);
__assign_str(driver);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk(
diff --git a/drivers/net/wireless/ath/wil6210/trace.h b/drivers/net/wireless/ath/wil6210/trace.h
index 201f44612c31..7eb6ca2b0cb6 100644
--- a/drivers/net/wireless/ath/wil6210/trace.h
+++ b/drivers/net/wireless/ath/wil6210/trace.h
@@ -70,10 +70,10 @@ DECLARE_EVENT_CLASS(wil6210_log_event,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf),
TP_STRUCT__entry(
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h
index 6c4e00e9ccd1..66b179adb80c 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.h
@@ -33,11 +33,11 @@ TRACE_EVENT(brcmf_err,
TP_ARGS(func, vaf),
TP_STRUCT__entry(
__string(func, func)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(func);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s", __get_str(func), __get_str(msg))
);
@@ -48,12 +48,12 @@ TRACE_EVENT(brcmf_dbg,
TP_STRUCT__entry(
__field(u32, level)
__string(func, func)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__entry->level = level;
__assign_str(func);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s", __get_str(func), __get_str(msg))
);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h
index dc296d8bf775..369171af1a30 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h
@@ -28,10 +28,10 @@ DECLARE_EVENT_CLASS(brcms_msg_event,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf),
TP_STRUCT__entry(
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
@@ -62,12 +62,12 @@ TRACE_EVENT(brcms_dbg,
TP_STRUCT__entry(
__field(u32, level)
__string(func, func)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__entry->level = level;
__assign_str(func);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s", __get_str(func), __get_str(msg))
);
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h
index 0db1fa5477af..80cfb9fc8ad8 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-devtrace-msg.h
@@ -18,10 +18,10 @@ DECLARE_EVENT_CLASS(iwlwifi_msg_event,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf),
TP_STRUCT__entry(
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
@@ -53,12 +53,12 @@ TRACE_EVENT(iwlwifi_dbg,
TP_STRUCT__entry(
__field(u32, level)
__string(function, function)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__entry->level = level;
__assign_str(function);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
diff --git a/drivers/usb/chipidea/trace.h b/drivers/usb/chipidea/trace.h
index 1875419cd17f..9ec0df074872 100644
--- a/drivers/usb/chipidea/trace.h
+++ b/drivers/usb/chipidea/trace.h
@@ -28,11 +28,11 @@ TRACE_EVENT(ci_log,
TP_ARGS(ci, vaf),
TP_STRUCT__entry(
__string(name, dev_name(ci->dev))
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(name);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s", __get_str(name), __get_str(msg))
);
diff --git a/drivers/usb/host/xhci-trace.h b/drivers/usb/host/xhci-trace.h
index 724cba2dbb78..575c02109b4b 100644
--- a/drivers/usb/host/xhci-trace.h
+++ b/drivers/usb/host/xhci-trace.h
@@ -28,9 +28,9 @@
DECLARE_EVENT_CLASS(xhci_log_msg,
TP_PROTO(struct va_format *vaf),
TP_ARGS(vaf),
- TP_STRUCT__entry(__vstring(msg, vaf->fmt, vaf->va)),
+ TP_STRUCT__entry(__vstring(msg, vaf)),
TP_fast_assign(
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
);
diff --git a/drivers/usb/mtu3/mtu3_trace.h b/drivers/usb/mtu3/mtu3_trace.h
index 89870175d635..56c9263a99d8 100644
--- a/drivers/usb/mtu3/mtu3_trace.h
+++ b/drivers/usb/mtu3/mtu3_trace.h
@@ -23,11 +23,11 @@ TRACE_EVENT(mtu3_log,
TP_ARGS(dev, vaf),
TP_STRUCT__entry(
__string(name, dev_name(dev))
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(name);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s", __get_str(name), __get_str(msg))
);
diff --git a/drivers/usb/musb/musb_trace.h b/drivers/usb/musb/musb_trace.h
index 726e6697d475..7dba44b0496d 100644
--- a/drivers/usb/musb/musb_trace.h
+++ b/drivers/usb/musb/musb_trace.h
@@ -28,11 +28,11 @@ TRACE_EVENT(musb_log,
TP_ARGS(musb, vaf),
TP_STRUCT__entry(
__string(name, dev_name(musb->controller))
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(name);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s", __get_str(name), __get_str(msg))
);
diff --git a/include/trace/events/iscsi.h b/include/trace/events/iscsi.h
index 990fd154f586..2e2667658b51 100644
--- a/include/trace/events/iscsi.h
+++ b/include/trace/events/iscsi.h
@@ -26,12 +26,12 @@ DECLARE_EVENT_CLASS(iscsi_log_msg,
TP_STRUCT__entry(
__string(dname, dev_name(dev) )
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(dname);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s: %s",__get_str(dname), __get_str(msg)
diff --git a/include/trace/events/qla.h b/include/trace/events/qla.h
index 74a7534b99b6..554ae9a623c6 100644
--- a/include/trace/events/qla.h
+++ b/include/trace/events/qla.h
@@ -17,11 +17,11 @@ DECLARE_EVENT_CLASS(qla_log_event,
TP_STRUCT__entry(
__string(buf, buf)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(buf);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s %s", __get_str(buf), __get_str(msg))
diff --git a/include/trace/stages/stage1_struct_define.h b/include/trace/stages/stage1_struct_define.h
index 69e0dae453bf..0ae49a935d16 100644
--- a/include/trace/stages/stage1_struct_define.h
+++ b/include/trace/stages/stage1_struct_define.h
@@ -27,7 +27,7 @@
#define __string_len(item, src, len) __dynamic_array(char, item, -1)
#undef __vstring
-#define __vstring(item, fmt, ap) __dynamic_array(char, item, -1)
+#define __vstring(item, vf) __dynamic_array(char, item, -1)
#undef __bitmask
#define __bitmask(item, nr_bits) __dynamic_array(char, item, -1)
diff --git a/include/trace/stages/stage2_data_offsets.h b/include/trace/stages/stage2_data_offsets.h
index 8b0cff06d346..5c6dc3092e07 100644
--- a/include/trace/stages/stage2_data_offsets.h
+++ b/include/trace/stages/stage2_data_offsets.h
@@ -33,7 +33,7 @@
#define __string_len(item, src, len) __dynamic_array(char, item, -1)
#undef __vstring
-#define __vstring(item, fmt, ap) __dynamic_array(char, item, -1)
+#define __vstring(item, vf) __dynamic_array(char, item, -1)
#undef __bitmask
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
diff --git a/include/trace/stages/stage4_event_fields.h b/include/trace/stages/stage4_event_fields.h
index b6f679ae21aa..77f74d509760 100644
--- a/include/trace/stages/stage4_event_fields.h
+++ b/include/trace/stages/stage4_event_fields.h
@@ -42,7 +42,7 @@
#define __string_len(item, src, len) __dynamic_array(char, item, -1)
#undef __vstring
-#define __vstring(item, fmt, ap) __dynamic_array(char, item, -1)
+#define __vstring(item, vf) __dynamic_array(char, item, -1)
#undef __bitmask
#define __bitmask(item, nr_bits) __dynamic_array(unsigned long, item, -1)
diff --git a/include/trace/stages/stage5_get_offsets.h b/include/trace/stages/stage5_get_offsets.h
index c6a62dfb18ef..1ce5ca15a8ed 100644
--- a/include/trace/stages/stage5_get_offsets.h
+++ b/include/trace/stages/stage5_get_offsets.h
@@ -65,8 +65,8 @@ static inline const char *__string_src(const char *str)
__data_offsets->item##_ptr_ = src;
#undef __vstring
-#define __vstring(item, fmt, ap) __dynamic_array(char, item, \
- __trace_event_vstr_len(fmt, ap))
+#define __vstring(item, vf) __dynamic_array(char, item, \
+ __trace_event_vstr_len(vf))
#undef __rel_dynamic_array
#define __rel_dynamic_array(type, item, len) \
diff --git a/net/batman-adv/trace.h b/net/batman-adv/trace.h
index 7da692ec38e9..ac88789330a3 100644
--- a/net/batman-adv/trace.h
+++ b/net/batman-adv/trace.h
@@ -36,13 +36,13 @@ TRACE_EVENT(batadv_dbg,
TP_STRUCT__entry(
__string(device, bat_priv->mesh_iface->name)
__string(driver, KBUILD_MODNAME)
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
__assign_str(device);
__assign_str(driver);
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk(
diff --git a/net/mac80211/trace_msg.h b/net/mac80211/trace_msg.h
index aea4ce55c5ac..0de50dfa13ed 100644
--- a/net/mac80211/trace_msg.h
+++ b/net/mac80211/trace_msg.h
@@ -22,11 +22,11 @@ DECLARE_EVENT_CLASS(mac80211_msg_event,
TP_ARGS(vaf),
TP_STRUCT__entry(
- __vstring(msg, vaf->fmt, vaf->va)
+ __vstring(msg, vaf)
),
TP_fast_assign(
- __assign_vstr(msg, vaf->fmt, vaf->va);
+ __assign_vstr(msg, vaf);
),
TP_printk("%s", __get_str(msg))
diff --git a/samples/trace_events/trace-events-sample.c b/samples/trace_events/trace-events-sample.c
index ecc7db237f2e..07096eadfb7b 100644
--- a/samples/trace_events/trace-events-sample.c
+++ b/samples/trace_events/trace-events-sample.c
@@ -23,6 +23,7 @@ static void do_simple_thread_func(int cnt, const char *fmt, ...)
{
unsigned long bitmask[1] = {0xdeadbeefUL};
va_list va;
+ struct va_format vf = { .fmt = fmt };
int array[6];
int len = cnt % 5;
int i;
@@ -35,10 +36,11 @@ static void do_simple_thread_func(int cnt, const char *fmt, ...)
array[i] = 0;
va_start(va, fmt);
+ vf.va = &va;
/* Silly tracepoints */
trace_foo_bar("hello", cnt, array, random_strings[len],
- current->cpus_ptr, fmt, &va);
+ current->cpus_ptr, &vf);
va_end(va);
^ permalink raw reply related
* [PATCH] wifi: mt76: mt7921: add regulatory wiphy self manager support
From: JB Tsai @ 2026-06-03 7:53 UTC (permalink / raw)
To: nbd, lorenzo
Cc: linux-wireless, linux-mediatek, Deren.Wu, Sean.Wang, Quan.Zhou,
Ryder.Lee, Leon.Yen, litien.chang, Charlie-cy.Wu, jb.tsai
From: Charlie-cy Wu <Charlie-cy.Wu@mediatek.com>
Introduce regulatory wiphy self-managed mode support for MT7921,
allowing the driver to manage its own regulatory domain independently
from the kernel's regulatory framework.
Signed-off-by: Charlie-cy Wu <Charlie-cy.Wu@mediatek.com>
---
.../wireless/mediatek/mt76/mt76_connac_mcu.h | 1 +
.../net/wireless/mediatek/mt76/mt7921/mcu.c | 3 +
.../net/wireless/mediatek/mt76/mt7921/regd.c | 209 ++++++++++++++++--
.../net/wireless/mediatek/mt76/mt7921/regd.h | 55 ++++-
4 files changed, 245 insertions(+), 23 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index ed5c441748d8..c10a2c4e7ee2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -1363,6 +1363,7 @@ enum {
MCU_CE_CMD_FWLOG_2_HOST = 0xc5,
MCU_CE_CMD_GET_WTBL = 0xcd,
MCU_CE_CMD_GET_TXPWR = 0xd0,
+ MCU_CE_CMD_SET_REGD_CH = 0xd1,
};
enum {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index 25b9437250f7..2e0769d18f87 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -1403,6 +1403,9 @@ int mt7921_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,
/* submit all clc config */
for (i = 0; i < ARRAY_SIZE(phy->clc); i++) {
+ if (i == MT792x_CLC_REGD)
+ continue;
+
ret = __mt7921_mcu_set_clc(dev, alpha2, env_cap,
phy->clc[i], i);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/regd.c b/drivers/net/wireless/mediatek/mt76/mt7921/regd.c
index f122e418d825..e52191776f97 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/regd.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/regd.c
@@ -10,6 +10,15 @@ static bool mt7921_disable_clc;
module_param_named(disable_clc, mt7921_disable_clc, bool, 0644);
MODULE_PARM_DESC(disable_clc, "disable CLC support");
+static const struct ieee80211_regdomain mt7921_regd_ww = {
+ .n_reg_rules = 1,
+ .alpha2 = "00",
+ .reg_rules = {
+ /* IEEE 802.11b/g, channels 1..11 */
+ REG_RULE(2412 - 10, 2462 + 10, 40, 6, 20, 0),
+ }
+};
+
bool mt7921_regd_clc_supported(struct mt792x_dev *dev)
{
if (mt7921_disable_clc ||
@@ -33,6 +42,9 @@ mt7921_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev)
np = mt76_find_power_limits_node(mdev);
sband = wiphy->bands[NL80211_BAND_5GHZ];
+ if (!sband)
+ return;
+
band_np = np ? of_get_child_by_name(np, "txpower-5g") : NULL;
for (i = 0; i < sband->n_channels; i++) {
ch = &sband->channels[i];
@@ -71,35 +83,36 @@ mt7921_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev)
}
}
-int mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,
- enum environment_cap country_ie_env)
+static int mt7921_mcu_apply_regd(struct mt792x_dev *dev, u8 *alpha2,
+ enum environment_cap env)
{
- struct mt76_dev *mdev = &dev->mt76;
- struct ieee80211_hw *hw = mdev->hw;
+ struct ieee80211_hw *hw = mt76_hw(dev);
struct wiphy *wiphy = hw->wiphy;
- int ret = 0;
-
- dev->regd_in_progress = true;
-
- mt792x_mutex_acquire(dev);
- if (!dev->regd_change)
- goto err;
+ int ret;
- ret = mt7921_mcu_set_clc(dev, alpha2, country_ie_env);
+ ret = mt7921_mcu_set_clc(dev, alpha2, env);
if (ret < 0)
- goto err;
+ return ret;
mt7921_regd_channel_update(wiphy, dev);
ret = mt76_connac_mcu_set_channel_domain(hw->priv);
if (ret < 0)
- goto err;
+ return ret;
- ret = mt7921_set_tx_sar_pwr(hw, NULL);
- if (ret < 0)
- goto err;
+ return mt7921_set_tx_sar_pwr(hw, NULL);
+}
-err:
+int mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,
+ enum environment_cap country_ie_env)
+{
+ int ret = 0;
+
+ dev->regd_in_progress = true;
+
+ mt792x_mutex_acquire(dev);
+ if (dev->regd_change)
+ ret = mt7921_mcu_apply_regd(dev, alpha2, country_ie_env);
mt792x_mutex_release(dev);
dev->regd_change = false;
dev->regd_in_progress = false;
@@ -142,10 +155,160 @@ void mt7921_regd_notifier(struct wiphy *wiphy,
if (pm->suspended)
return;
+ if (MT7921_REGD_SUPPORTED(&dev->phy)) {
+ mt7921_regd_update(&dev->phy, req->alpha2);
+
+ return;
+ }
+
mt7921_mcu_regd_update(dev, req->alpha2,
req->country_ie_env);
}
+static struct sk_buff *
+mt7921_regd_query_regdb(struct mt792x_phy *phy, char *alpha2)
+{
+ struct wiphy *wiphy = phy->mt76->hw->wiphy;
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct mt792x_dev *dev = mt792x_hw_dev(hw);
+ struct mt7921_clc *clc = phy->clc[MT792x_CLC_REGD];
+ struct mt7921_regd_query_req *req;
+ struct mt7921_regd_cc *regd_cc;
+ struct sk_buff *ret_skb = NULL;
+ u8 *pos, *last_pos;
+ int ret = 0;
+
+ if (!clc)
+ return NULL;
+
+ pos = clc->data;
+ last_pos = pos + le32_to_cpu(clc->len) - sizeof(struct mt7921_clc);
+ while (pos < last_pos) {
+ u32 req_len = 0;
+ u32 rules_len = 0;
+ u32 sign_len = 4;
+
+ if (pos + sizeof(*regd_cc) > last_pos)
+ break;
+
+ regd_cc = (struct mt7921_regd_cc *)pos;
+ rules_len = sizeof(struct mt7921_regd_rule_header) +
+ sizeof(struct mt7921_regd_rule) *
+ le32_to_cpu(regd_cc->n_reg_rules);
+
+ if (pos + sizeof(*regd_cc) + rules_len + sign_len > last_pos)
+ break;
+
+ pos += sizeof(*regd_cc) + rules_len + sign_len;
+ if (memcmp(regd_cc->alpha2, alpha2, 2))
+ continue;
+
+ req_len = sizeof(*req) + rules_len + sign_len;
+ req = devm_kmalloc(dev->mt76.dev, req_len, GFP_KERNEL);
+
+ if (!req)
+ return NULL;
+
+ req->ver = regd_cc->ver;
+ req->sign_type = regd_cc->sign_type;
+ req->size = cpu_to_le32(rules_len + sign_len);
+ req->n_reg_rules = regd_cc->n_reg_rules;
+
+ memcpy(req->alpha2, regd_cc->alpha2, 2);
+ memcpy(req->data, regd_cc->data, rules_len + sign_len);
+
+ ret = mt76_mcu_send_and_get_msg(&dev->mt76,
+ MCU_CE_CMD(SET_REGD_CH),
+ req, req_len, true, &ret_skb);
+
+ devm_kfree(dev->mt76.dev, req);
+
+ return ret < 0 ? NULL : ret_skb;
+ }
+
+ return NULL;
+}
+
+int mt7921_regd_update(struct mt792x_phy *phy, char *alpha2)
+{
+ struct wiphy *wiphy = phy->mt76->hw->wiphy;
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct mt792x_dev *dev = mt792x_hw_dev(hw);
+ struct mt7921_regd_rule *mt7921_rule;
+ struct mt76_dev *mdev = &dev->mt76;
+ struct ieee80211_regdomain *regd;
+ struct ieee80211_reg_rule *rule;
+ struct mt7921_regd_rule_ev *ev;
+ int i, num_of_rules = 0;
+ struct sk_buff *skb;
+ int ret = 0;
+
+ if (dev->hw_full_reset)
+ return 0;
+
+ if (!MT7921_REGD_SUPPORTED(phy))
+ return -EOPNOTSUPP;
+
+ mt792x_mutex_acquire(dev);
+ skb = mt7921_regd_query_regdb(phy, alpha2);
+ mt792x_mutex_release(dev);
+
+ if (!skb)
+ return -EINVAL;
+
+ ev = (struct mt7921_regd_rule_ev *)(skb->data + 4);
+ num_of_rules = le32_to_cpu(ev->n_reg_rules);
+
+ if (!num_of_rules ||
+ WARN_ON_ONCE(num_of_rules > NL80211_MAX_SUPP_REG_RULES)) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ regd = kzalloc(struct_size(regd, reg_rules, num_of_rules), GFP_KERNEL);
+ if (!regd) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ for (i = 0; i < num_of_rules; i++) {
+ mt7921_rule = &ev->reg_rule[i];
+ rule = ®d->reg_rules[i];
+
+ rule->freq_range.start_freq_khz =
+ MHZ_TO_KHZ(mt7921_rule->start_freq);
+ rule->freq_range.end_freq_khz =
+ MHZ_TO_KHZ(mt7921_rule->end_freq);
+ rule->freq_range.max_bandwidth_khz =
+ MHZ_TO_KHZ(mt7921_rule->max_bw);
+ /* not used by fw */
+ rule->power_rule.max_antenna_gain = DBI_TO_MBI(6);
+ rule->power_rule.max_eirp = DBM_TO_MBM(22);
+ rule->flags = mt7921_rule->flags;
+ }
+
+ regd->n_reg_rules = num_of_rules;
+ regd->dfs_region = ev->dfs_region;
+
+ memcpy(regd->alpha2, alpha2, 2);
+ memcpy(mdev->alpha2, alpha2, 2);
+
+ dev->regd_change = true;
+ mt7921_mcu_regd_update(dev, alpha2, ENVIRON_ANY);
+
+ ret = regulatory_set_wiphy_regd(wiphy, regd);
+
+ kfree(regd);
+err:
+ dev_kfree_skb(skb);
+
+ if (ret < 0)
+ return regulatory_set_wiphy_regd(wiphy, &mt7921_regd_ww);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mt7921_regd_update);
+
static bool
mt7921_regd_is_valid_alpha2(const char *alpha2)
{
@@ -183,7 +346,9 @@ int mt7921_regd_change(struct mt792x_phy *phy, char *alpha2)
if (!memcmp(alpha2, mdev->alpha2, 2))
return 0;
- if (phy->chip_cap & MT792x_CHIP_CAP_11D_EN)
+ if (MT7921_REGD_SUPPORTED(phy))
+ return mt7921_regd_update(phy, alpha2);
+ else if (phy->chip_cap & MT792x_CHIP_CAP_11D_EN)
return regulatory_hint(wiphy, alpha2);
else
return mt7921_mcu_set_clc(dev, alpha2, ENVIRON_INDOOR);
@@ -197,7 +362,11 @@ int mt7921_regd_init(struct mt792x_phy *phy)
struct mt792x_dev *dev = mt792x_hw_dev(hw);
struct mt76_dev *mdev = &dev->mt76;
- if (phy->chip_cap & MT792x_CHIP_CAP_11D_EN)
+ if (MT7921_REGD_SUPPORTED(phy)) {
+ wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED |
+ REGULATORY_DISABLE_BEACON_HINTS;
+ return mt7921_regd_update(phy, "00");
+ } else if (phy->chip_cap & MT792x_CHIP_CAP_11D_EN)
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE |
REGULATORY_DISABLE_BEACON_HINTS;
else
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/regd.h b/drivers/net/wireless/mediatek/mt76/mt7921/regd.h
index 571f31629e9e..c1e94cd4c958 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/regd.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/regd.h
@@ -4,9 +4,57 @@
#ifndef __MT7921_REGD_H
#define __MT7921_REGD_H
-struct mt792x_dev;
-struct wiphy;
-struct regulatory_request;
+#include "mt7921.h"
+
+struct mt7921_regd_rule_header {
+ u8 alpha2[2];
+ u8 dfs_region;
+ u8 rsv[13];
+};
+
+struct mt7921_regd_rule {
+ u32 start_freq;
+ u32 end_freq;
+ u32 max_bw;
+ u32 eirp;
+ u32 flags;
+ u8 rsv[12];
+};
+
+struct mt7921_regd_cc {
+ u8 alpha2[2];
+ u8 ver;
+ u8 rsv;
+ __le32 n_reg_rules;
+ u8 sign_type;
+ u8 rsv1[7];
+ u8 data[];
+};
+
+struct mt7921_regd_rule_ev {
+ __le16 tag;
+ __le16 len;
+ __le32 n_reg_rules;
+ u8 dfs_region;
+ u8 rsv[15];
+ struct mt7921_regd_rule reg_rule[];
+};
+
+struct mt7921_regd_query_req {
+ u8 ver;
+ u8 sign_type;
+ u8 rsv1[2];
+ __le32 size;
+ u8 alpha2[2];
+ u8 rsv2[2];
+ __le32 n_reg_rules;
+ u8 rsv3[64];
+ u8 data[];
+};
+
+#define MT7921_REGD_SUPPORTED(phy) \
+ (((phy)->chip_cap & MT792x_CHIP_CAP_REGD_EN) && \
+ (phy)->clc[MT792x_CLC_REGD])
int mt7921_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,
enum environment_cap country_ie_env);
@@ -15,5 +63,6 @@ void mt7921_regd_notifier(struct wiphy *wiphy,
bool mt7921_regd_clc_supported(struct mt792x_dev *dev);
int mt7921_regd_change(struct mt792x_phy *phy, char *alpha2);
int mt7921_regd_init(struct mt792x_phy *phy);
+int mt7921_regd_update(struct mt792x_phy *phy, char *alpha2);
#endif
--
2.18.0
^ permalink raw reply related
* [PATCH] wifi: mt76: mt7925: add regulatory wiphy self manager support
From: JB Tsai @ 2026-06-03 7:53 UTC (permalink / raw)
To: nbd, lorenzo
Cc: linux-wireless, linux-mediatek, Deren.Wu, Sean.Wang, Quan.Zhou,
Ryder.Lee, Leon.Yen, litien.chang, Charlie-cy.Wu, jb.tsai
From: Charlie-cy Wu <Charlie-cy.Wu@mediatek.com>
Introduce regulatory wiphy self-managed mode support for MT7925,
allowing the driver to manage its own regulatory domain independently
from the kernel's regulatory framework.
Signed-off-by: Charlie-cy Wu <Charlie-cy.Wu@mediatek.com>
---
.../net/wireless/mediatek/mt76/mt7925/mcu.c | 3 +-
.../net/wireless/mediatek/mt76/mt7925/regd.c | 204 ++++++++++++++++--
.../net/wireless/mediatek/mt76/mt7925/regd.h | 54 +++++
drivers/net/wireless/mediatek/mt76/mt792x.h | 2 +
4 files changed, 244 insertions(+), 19 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
index 37cdf3e8a067..56b265602faa 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
@@ -3457,7 +3457,8 @@ int mt7925_mcu_set_clc(struct mt792x_dev *dev, u8 *alpha2,
/* submit all clc config */
for (i = 0; i < ARRAY_SIZE(phy->clc); i++) {
- if (i == MT792x_CLC_BE_CTRL)
+ if (i == MT792x_CLC_BE_CTRL ||
+ i == MT792x_CLC_REGD)
continue;
ret = __mt7925_mcu_set_clc(dev, alpha2, env_cap,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c
index 16f56ee879d4..bbd8f2d008c0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/regd.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/regd.c
@@ -9,6 +9,15 @@ static bool mt7925_disable_clc;
module_param_named(disable_clc, mt7925_disable_clc, bool, 0644);
MODULE_PARM_DESC(disable_clc, "disable CLC support");
+static const struct ieee80211_regdomain mt7925_regd_ww = {
+ .n_reg_rules = 1,
+ .alpha2 = "00",
+ .reg_rules = {
+ /* IEEE 802.11b/g, channels 1..11 */
+ REG_RULE(2412 - 10, 2462 + 10, 40, 6, 20, 0),
+ }
+};
+
bool mt7925_regd_clc_supported(struct mt792x_dev *dev)
{
if (mt7925_disable_clc ||
@@ -128,35 +137,37 @@ mt7925_regd_channel_update(struct wiphy *wiphy, struct mt792x_dev *dev)
}
}
-int mt7925_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,
- enum environment_cap country_ie_env)
+static int mt7925_mcu_apply_regd(struct mt792x_dev *dev, u8 *alpha2,
+ enum environment_cap env)
{
struct ieee80211_hw *hw = mt76_hw(dev);
struct wiphy *wiphy = hw->wiphy;
- int ret = 0;
-
- dev->regd_in_progress = true;
-
- mt792x_mutex_acquire(dev);
- if (!dev->regd_change)
- goto err;
+ int ret;
- ret = mt7925_mcu_set_clc(dev, alpha2, country_ie_env);
+ ret = mt7925_mcu_set_clc(dev, alpha2, env);
if (ret < 0)
- goto err;
+ return ret;
mt7925_regd_be_ctrl(dev, alpha2);
mt7925_regd_channel_update(wiphy, dev);
ret = mt7925_mcu_set_channel_domain(hw->priv);
if (ret < 0)
- goto err;
+ return ret;
- ret = mt7925_set_tx_sar_pwr(hw, NULL);
- if (ret < 0)
- goto err;
+ return mt7925_set_tx_sar_pwr(hw, NULL);
+}
-err:
+int mt7925_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,
+ enum environment_cap country_ie_env)
+{
+ int ret = 0;
+
+ dev->regd_in_progress = true;
+
+ mt792x_mutex_acquire(dev);
+ if (dev->regd_change)
+ ret = mt7925_mcu_apply_regd(dev, alpha2, country_ie_env);
mt792x_mutex_release(dev);
dev->regd_change = false;
dev->regd_in_progress = false;
@@ -197,11 +208,162 @@ void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req)
/* postpone the mcu update to resume */
return;
+ if (MT7925_REGD_SUPPORTED(&dev->phy)) {
+ mt7925_regd_update(&dev->phy, req->alpha2);
+
+ return;
+ }
+
mt7925_mcu_regd_update(dev, req->alpha2,
req->country_ie_env);
return;
}
+static struct sk_buff *
+mt7925_regd_query_regdb(struct mt792x_phy *phy, char *alpha2)
+{
+ struct wiphy *wiphy = phy->mt76->hw->wiphy;
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct mt792x_dev *dev = mt792x_hw_dev(hw);
+ struct mt7925_clc *clc = phy->clc[MT792x_CLC_REGD];
+ struct mt7925_regd_query_req *req;
+ struct mt7925_regd_cc *regd_cc;
+ struct sk_buff *ret_skb = NULL;
+ u8 *pos, *last_pos;
+ int ret = 0;
+
+ if (!clc)
+ return NULL;
+
+ pos = clc->data;
+ last_pos = pos + le32_to_cpu(clc->len) - sizeof(struct mt7925_clc);
+ while (pos < last_pos) {
+ u32 req_len = 0;
+ u32 rules_len = 0;
+ u32 sign_len = 4;
+
+ if (pos + sizeof(*regd_cc) > last_pos)
+ break;
+
+ regd_cc = (struct mt7925_regd_cc *)pos;
+ rules_len = sizeof(struct mt7925_regd_rule_header) +
+ sizeof(struct mt7925_regd_rule) *
+ le32_to_cpu(regd_cc->n_reg_rules);
+
+ if (pos + sizeof(*regd_cc) + rules_len + sign_len > last_pos)
+ break;
+
+ pos += sizeof(*regd_cc) + rules_len + sign_len;
+ if (memcmp(regd_cc->alpha2, alpha2, 2))
+ continue;
+
+ req_len = sizeof(*req) + rules_len + sign_len;
+ req = devm_kmalloc(dev->mt76.dev, req_len, GFP_KERNEL);
+
+ if (!req)
+ return NULL;
+
+ req->tag = cpu_to_le16(0x6);
+ req->len = cpu_to_le16(req_len - 4);
+ req->ver = regd_cc->ver;
+ req->sign_type = regd_cc->sign_type;
+ req->size = cpu_to_le32(rules_len + sign_len);
+ req->n_reg_rules = regd_cc->n_reg_rules;
+
+ memcpy(req->alpha2, regd_cc->alpha2, 2);
+ memcpy(req->data, regd_cc->data, rules_len + sign_len);
+
+ ret = mt76_mcu_send_and_get_msg(&dev->mt76,
+ MCU_UNI_CMD(SET_POWER_LIMIT),
+ req, req_len, true, &ret_skb);
+ devm_kfree(dev->mt76.dev, req);
+
+ return ret < 0 ? NULL : ret_skb;
+ }
+
+ return NULL;
+}
+
+int mt7925_regd_update(struct mt792x_phy *phy, char *alpha2)
+{
+ struct wiphy *wiphy = phy->mt76->hw->wiphy;
+ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+ struct mt792x_dev *dev = mt792x_hw_dev(hw);
+ struct mt7925_regd_rule *mt7925_rule;
+ struct mt76_dev *mdev = &dev->mt76;
+ struct ieee80211_regdomain *regd;
+ struct ieee80211_reg_rule *rule;
+ struct mt7925_regd_rule_ev *ev;
+ int i, num_of_rules = 0;
+ struct sk_buff *skb;
+ int ret = 0;
+
+ if (dev->hw_full_reset)
+ return 0;
+
+ if (!MT7925_REGD_SUPPORTED(phy))
+ return -EOPNOTSUPP;
+
+ mt792x_mutex_acquire(dev);
+ skb = mt7925_regd_query_regdb(phy, alpha2);
+ mt792x_mutex_release(dev);
+
+ if (!skb)
+ return -EINVAL;
+
+ ev = (struct mt7925_regd_rule_ev *)(skb->data + 4);
+ num_of_rules = le32_to_cpu(ev->n_reg_rules);
+
+ if (!num_of_rules ||
+ WARN_ON_ONCE(num_of_rules > NL80211_MAX_SUPP_REG_RULES)) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ regd = kzalloc(struct_size(regd, reg_rules, num_of_rules), GFP_KERNEL);
+ if (!regd) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ for (i = 0; i < num_of_rules; i++) {
+ mt7925_rule = &ev->reg_rule[i];
+ rule = ®d->reg_rules[i];
+
+ rule->freq_range.start_freq_khz =
+ MHZ_TO_KHZ(mt7925_rule->start_freq);
+ rule->freq_range.end_freq_khz =
+ MHZ_TO_KHZ(mt7925_rule->end_freq);
+ rule->freq_range.max_bandwidth_khz =
+ MHZ_TO_KHZ(mt7925_rule->max_bw);
+ /* not used by fw */
+ rule->power_rule.max_antenna_gain = DBI_TO_MBI(6);
+ rule->power_rule.max_eirp = DBM_TO_MBM(22);
+ rule->flags = mt7925_rule->flags;
+ }
+
+ regd->n_reg_rules = num_of_rules;
+ regd->dfs_region = ev->dfs_region;
+
+ memcpy(regd->alpha2, alpha2, 2);
+ memcpy(mdev->alpha2, alpha2, 2);
+
+ dev->regd_change = true;
+ mt7925_mcu_regd_update(dev, alpha2, ENVIRON_ANY);
+
+ ret = regulatory_set_wiphy_regd(wiphy, regd);
+
+ kfree(regd);
+err:
+ dev_kfree_skb(skb);
+
+ if (ret < 0)
+ return regulatory_set_wiphy_regd(wiphy, &mt7925_regd_ww);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(mt7925_regd_update);
+
static bool
mt7925_regd_is_valid_alpha2(const char *alpha2)
{
@@ -240,7 +402,9 @@ int mt7925_regd_change(struct mt792x_phy *phy, char *alpha2)
if (!memcmp(alpha2, mdev->alpha2, 2))
return 0;
- if (phy->chip_cap & MT792x_CHIP_CAP_11D_EN) {
+ if (MT7925_REGD_SUPPORTED(phy)) {
+ return mt7925_regd_update(phy, alpha2);
+ } else if (phy->chip_cap & MT792x_CHIP_CAP_11D_EN) {
return regulatory_hint(wiphy, alpha2);
} else {
return mt7925_mcu_set_clc(dev, alpha2, ENVIRON_INDOOR);
@@ -255,7 +419,11 @@ int mt7925_regd_init(struct mt792x_phy *phy)
struct mt792x_dev *dev = mt792x_hw_dev(hw);
struct mt76_dev *mdev = &dev->mt76;
- if (phy->chip_cap & MT792x_CHIP_CAP_11D_EN) {
+ if (MT7925_REGD_SUPPORTED(phy)) {
+ wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED |
+ REGULATORY_DISABLE_BEACON_HINTS;
+ return mt7925_regd_update(phy, "00");
+ } else if (phy->chip_cap & MT792x_CHIP_CAP_11D_EN) {
wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE |
REGULATORY_DISABLE_BEACON_HINTS;
} else {
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/regd.h b/drivers/net/wireless/mediatek/mt76/mt7925/regd.h
index 0767f078862e..2feacf42dc22 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/regd.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/regd.h
@@ -6,12 +6,66 @@
#include "mt7925.h"
+struct mt7925_regd_rule_header {
+ u8 alpha2[2];
+ u8 dfs_region;
+ u8 rsv[13];
+};
+
+struct mt7925_regd_rule {
+ u32 start_freq;
+ u32 end_freq;
+ u32 max_bw;
+ u32 eirp;
+ u32 flags;
+ u8 rsv[12];
+};
+
+struct mt7925_regd_cc {
+ u8 alpha2[2];
+ u8 ver;
+ u8 rsv;
+ __le32 n_reg_rules;
+ u8 sign_type;
+ u8 rsv1[7];
+ u8 data[];
+};
+
+struct mt7925_regd_rule_ev {
+ __le16 tag;
+ __le16 len;
+ __le32 n_reg_rules;
+ u8 dfs_region;
+ u8 rsv[15];
+ struct mt7925_regd_rule reg_rule[];
+};
+
+struct mt7925_regd_query_req {
+ u8 rsv[4];
+ __le16 tag;
+ __le16 len;
+ u8 ver;
+ u8 sign_type;
+ u8 rsv1[2];
+ __le32 size;
+ u8 alpha2[2];
+ u8 rsv2[2];
+ __le32 n_reg_rules;
+ u8 rsv3[64];
+ u8 data[];
+};
+
+#define MT7925_REGD_SUPPORTED(phy) \
+ (((phy)->chip_cap & MT792x_CHIP_CAP_REGD_EN) && \
+ (phy)->clc[MT792x_CLC_REGD])
+
int mt7925_mcu_regd_update(struct mt792x_dev *dev, u8 *alpha2,
enum environment_cap country_ie_env);
void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2);
void mt7925_regd_notifier(struct wiphy *wiphy, struct regulatory_request *req);
bool mt7925_regd_clc_supported(struct mt792x_dev *dev);
+int mt7925_regd_update(struct mt792x_phy *phy, char *alpha2);
int mt7925_regd_change(struct mt792x_phy *phy, char *alpha2);
int mt7925_regd_init(struct mt792x_phy *phy);
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x.h b/drivers/net/wireless/mediatek/mt76/mt792x.h
index 4ff93f2cd624..cd81cc519ef4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x.h
+++ b/drivers/net/wireless/mediatek/mt76/mt792x.h
@@ -29,6 +29,7 @@
#define MT792x_CHIP_CAP_RSSI_NOTIFY_EVT_EN BIT(1)
#define MT792x_CHIP_CAP_WF_RF_PIN_CTRL_EVT_EN BIT(3)
#define MT792x_CHIP_CAP_11D_EN BIT(4)
+#define MT792x_CHIP_CAP_REGD_EN BIT(5)
#define MT792x_CHIP_CAP_MLO_EN BIT(8)
#define MT792x_CHIP_CAP_MLO_EML_EN BIT(9)
@@ -75,6 +76,7 @@ enum {
MT792x_CLC_POWER,
MT792x_CLC_POWER_EXT,
MT792x_CLC_BE_CTRL,
+ MT792x_CLC_REGD,
MT792x_CLC_MAX_NUM,
};
--
2.18.0
^ permalink raw reply related
* pull-request: rtw-next-2026-06-03
From: Ping-Ke Shih @ 2026-06-03 7:45 UTC (permalink / raw)
To: linux-wireless
Hi,
A pull-request of rtw-next to wireless-next tree, more info below. Please
let me know if any problems.
Thanks
Ping-Ke
---
The following changes since commit 7baf5857e15d722776898510a10546d6b2f18645:
wifi: brcmsmac: phy_lcn: Remove dead code in wlc_lcnphy_radio_2064_channel_tune_4313() (2026-04-28 10:43:27 +0200)
are available in the Git repository at:
https://github.com/pkshih/rtw.git tags/rtw-next-2026-06-03
for you to fetch changes up to 384cc80f30977d2ff095615f2241b21904499255:
wifi: rtw89: usb: add serial_number and uuid sysfs attributes for 0x28de:0x2432 (2026-06-03 14:48:22 +0800)
----------------------------------------------------------------
rtw-next patches for -next
Pull-request includes many random fixes and new features.
Major changes are listed below:
rtl8xxxu:
* declare supported channel width by firmware report
rtw88:
* validate RX descriptor to avoid malformed data causing warnings
rtw89:
* support USB devices RTL8922AU
* add sysfs entry to show SN and UUID for specific USB devices
* support to switch USB 3.0 mode for higher performance
* add more fields (mainly SIG-A/SIG-B) to radiotap in monitor mode
* offload packed IO to firmware to reduce IO time (for USB devices)
* add debugfs to diagnose BB healthy
* more preparations for RTL8922DE
----------------------------------------------------------------
Bitterblue Smith (16):
wifi: rtw89: usb: Support 2 bulk in endpoints
wifi: rtw89: Fix rtw89_usb_ops_mac_lv1_rcvy() for RTL8922AU
wifi: rtw89: Fix rtw89_usb_ops_mac_pre_init() for RTL8922AU
wifi: rtw89: Fix rtw89_usb_ops_mac_post_init() for RTL8922AU
wifi: rtw89: usb: Enable RX aggregation for RTL8922AU
wifi: rtw89: Fix rtw8922a_pwr_{on,off}_func() for USB
wifi: rtw89: Let hfc_param_ini have separate settings for USB 2/3
wifi: rtw89: Add rtw8922a_hfc_param_ini_usb{2,3}
wifi: rtw89: Add rtw8922a_dle_mem_usb{2,3}
wifi: rtw89: Add rtw8922au.c
wifi: rtw89: Enable the new rtw89_8922au module
wifi: rtlwifi: rtl8821ae: Fix C2H bit location in RX descriptor
wifi: rtl8xxxu: Detect the maximum supported channel width
wifi: rtw89: Add missing TX queue mappings for RTL8922AU
wifi: rtw88: Add more validation for the RX descriptor
wifi: rtw89: usb: Support switching to USB 3 mode
Chelsy Ratnawat (1):
wifi: rtlwifi: rtl8821ae: Remove dead code in rtl8821ae_update_hal_rate_table()
Chia-Yuan Li (2):
wifi: rtw89: add IO offload support via firmware
wifi: rtw89: offload DMAC and CMAC init IO to firmware
Chih-Kang Chang (3):
wifi: rtw89: use struct to fill C2H recv ack
wifi: rtw89: check scan C2H event recv ack instead of C2H event done ack
wifi: rtw89: suspend DIG when remain-on-channel
Chin-Yen Lee (2):
wifi: rtw88: fix wrong pci_get_drvdata type in AER handlers
wifi: rtw89: wow: send ARP reply packets instead of Null packets to keep alive
Christos Longros (1):
wifi: rtw89: fix wrong pci_get_drvdata type in AER handlers
David Lee (1):
wifi: rtw89: usb: skip ACPI capability check for USB devices
Dian-Syuan Yang (3):
wifi: rtw89: disable HTC field in AP mode
wifi: rtw89: disable CSI STBC for VHT 160MHz
wifi: rtw89: pci: enable LTR based on pcie control register
Eric Huang (2):
wifi: rtw89: phy: support static PD level setting
wifi: rtw89: use firmware offload for PHY and RF batch register writes
Hugo Villeneuve (1):
wifi: rtlwifi: fix typos in comments in rtl8821ae_card_disable()
Johnson Tsai (5):
wifi: rtw89: debug: disable hw_scan for latency-sensitive scenarios
wifi: rtw89: debug: disable inactive power save to reduce bus overhead
wifi: rtw89: 8832cu: Add ID 2c7c:8206 for RTL8832CU
wifi: rtw89: add dev_id_quirks to driver_info for per-device quirk control
wifi: rtw89: usb: add serial_number and uuid sysfs attributes for 0x28de:0x2432
Kuan-Chung Chen (7):
wifi: rtw89: mlo: rearrange MLSR link decision flow
wifi: rtw89: phy: support per PHY RX statistics
wifi: rtw89: debug: bb_info entry including TX rate count for WiFi 7 chips
wifi: rtw89: debug: add PMAC counter in bb_info
wifi: rtw89: debug: extend bb_info with TX status and PER
wifi: rtw89: debug: add RX statistics in bb_info
wifi: rtw89: debug: add BB diagnose
Louis Kotze (1):
wifi: rtw89: phy: increase RF calibration timeouts for USB transport
Luka Gejak (2):
wifi: rtw88: increase TX report timeout to fix race condition
wifi: rtw88: usb: fix memory leaks on USB write failures
Martin Kaiser (1):
wifi: rtw88: remove rtw_txq_dequeue
Panagiotis Petrakopoulos (1):
wifi: rtw88: Add NULL check for chip->edcca_th in rtw_fw_adaptivity_result()
Ping-Ke Shih (41):
wifi: rtl8xxxu: validate action frame size before using in rtl8xxxu_dump_action()
wifi: rtlwifi: validate action frame size in rtl_action_proc()
wifi: rtlwifi: validate action frame size before using in _rtl_pci_tx_isr()
wifi: rtw89: 8922d: fix typo rx_freq_frome_ie
wifi: rtw89: pci: no need to wait CLK ready for RTL8922DE
wifi: rtw89: add AMPDU to radiotap
wifi: rtw89: add VHT beamformed to radiotap
wifi: rtw89: SNIFFER_MODE bit along IEEE80211_CONF_MONITOR
wifi: rtw89: phy: define PHY status IE length for generations
wifi: rtw89: phy: enable IE-09/IE-10 PHY status report for monitor mode
wifi: rtw89: move HE radiotap to an individual function
wifi: rtw89: fill VHT radiotap
wifi: rtw89: fill HE-SU/HE-TB/HE-MU/HE-EXT_SU radiotap
wifi: rtw89: debug: make implementation of beacon_info entry in order
wifi: rtw89: add debugfs entry of monitor mode options to capture HE-MU packets
wifi: rtw89: phy: check length before parsing PHY status IE
wifi: rtw89: phy: skip trailing 8-byte zeros of PHY status IE for RTL8922D
wifi: rtw89: phy: support PHY status IE-09 GEN2 for RTL8922D
wifi: rtw89: check skb headroom before adding radiotap
wifi: rtw89: phy: define BB wrap data for RTL8922D variants
wifi: rtw89: phy: set BB wrap of out-of-band DPD
wifi: rtw89: phy: set BB wrap of DPD by bandwidth
wifi: rtw89: phy: set BB wrap of control options
wifi: rtw89: phy: set BB wrap of QAM threshold
wifi: rtw89: phy: set BB wrap of QAM options
wifi: rtw89: phy: set BB wrap of trigger-base partial band
wifi: rtw89: phy: set BB wrap of CIM3K
wifi: rtw89: phy: change order to align register order
wifi: rtw89: phy: configure control options of BB wrapper by RFSI band
wifi: rtw89: phy: add BB wrapper generation 3 for RTL8922D variant
wifi: rtw89: pci: not disable PCI completion timeout control for a variant of RTL8922DE
wifi: rtw89: pci: disable PCI PHY error flag 8
wifi: rtw89: clear auto K delay value before downloading firmware
wifi: rtw89: 8922d: change naming number and update values for WDE/PLE quota
wifi: rtw89: mac: add field of release report size to DLE quota
wifi: rtw89: mac: consolidate quota into a struct for variant chips
wifi: rtw89: 8922d: add quota for RTL8922DE variant
wifi: rtw89: 8922d: refactor digital power compensation to support new format
wifi: rtw89: 8922d: support new digital power compensation format
wifi: rtw89: fw: load TX compensation element by RFE type
wifi: rtw89: 8851bu: add Mercusys MA60XNB (2c4e:0128)
Po-Hao Huang (2):
wifi: rtw89: 8852a: refine power save to lower latency
wifi: rtw89: correct drop logic for malformed AMPDU frames
Shin-Yi Lin (1):
wifi: rtw89: Correct data type for scan index to avoid infinite loop
Tristan Madani (2):
wifi: rtw88: fix OOB read from firmware RX descriptor exceeding DMA buffer
wifi: rtw89: add bounds check on firmware mac_id in link lookup
Zong-Zhe Yang (10):
wifi: rtw89: 8852bt: configure support_noise field explicitly
wifi: rtw89: chan: introduce new helper to get entity current configuration
wifi: rtw89: 8922d: update RF calibration flow for MLD
wifi: rtw89: debug: Wi-Fi 7 show count of SER L0 simulation
wifi: rtw89: debug: Wi-Fi 7 update simulation of SER L0/L1 by halt H2C command
wifi: rtw89: fw: dump status of H2C command and C2H event for SER
wifi: rtw89: fw: load TX power track element according to AID
wifi: rtw89: Wi-Fi 7 configure TX power limit for large MRU
wifi: rtw89: debug: show large MRU in txpwr_table dbgfs
wifi: rtw89: 8922d: configure TX shape settings
.../ABI/testing/sysfs-class-ieee80211-rtw89 | 24 +
drivers/net/wireless/realtek/rtl8xxxu/8188e.c | 1 +
drivers/net/wireless/realtek/rtl8xxxu/8188f.c | 1 +
drivers/net/wireless/realtek/rtl8xxxu/8192c.c | 1 +
drivers/net/wireless/realtek/rtl8xxxu/8192e.c | 1 +
drivers/net/wireless/realtek/rtl8xxxu/8192f.c | 1 +
drivers/net/wireless/realtek/rtl8xxxu/8710b.c | 1 +
drivers/net/wireless/realtek/rtl8xxxu/8723a.c | 1 +
drivers/net/wireless/realtek/rtl8xxxu/8723b.c | 1 +
drivers/net/wireless/realtek/rtl8xxxu/core.c | 77 +-
drivers/net/wireless/realtek/rtl8xxxu/regs.h | 2 +
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h | 7 +
drivers/net/wireless/realtek/rtlwifi/base.c | 17 +-
drivers/net/wireless/realtek/rtlwifi/pci.c | 7 +-
.../net/wireless/realtek/rtlwifi/rtl8821ae/hw.c | 21 +-
.../net/wireless/realtek/rtlwifi/rtl8821ae/trx.h | 2 +-
drivers/net/wireless/realtek/rtw88/fw.c | 3 +
drivers/net/wireless/realtek/rtw88/pci.c | 29 +-
drivers/net/wireless/realtek/rtw88/rx.c | 31 +-
drivers/net/wireless/realtek/rtw88/rx.h | 6 +-
drivers/net/wireless/realtek/rtw88/sdio.c | 8 +-
drivers/net/wireless/realtek/rtw88/tx.c | 25 +-
drivers/net/wireless/realtek/rtw88/usb.c | 22 +-
drivers/net/wireless/realtek/rtw89/Kconfig | 12 +
drivers/net/wireless/realtek/rtw89/Makefile | 3 +
drivers/net/wireless/realtek/rtw89/chan.c | 92 ++-
drivers/net/wireless/realtek/rtw89/chan.h | 21 +-
drivers/net/wireless/realtek/rtw89/core.c | 815 +++++++++++++++++--
drivers/net/wireless/realtek/rtw89/core.h | 347 +++++++-
drivers/net/wireless/realtek/rtw89/debug.c | 892 ++++++++++++++++++---
drivers/net/wireless/realtek/rtw89/fw.c | 500 +++++++++++-
drivers/net/wireless/realtek/rtw89/fw.h | 115 ++-
drivers/net/wireless/realtek/rtw89/mac.c | 153 +++-
drivers/net/wireless/realtek/rtw89/mac.h | 52 +-
drivers/net/wireless/realtek/rtw89/mac80211.c | 29 +-
drivers/net/wireless/realtek/rtw89/mac_be.c | 68 +-
drivers/net/wireless/realtek/rtw89/pci.c | 41 +-
drivers/net/wireless/realtek/rtw89/pci.h | 6 +-
drivers/net/wireless/realtek/rtw89/pci_be.c | 15 +
drivers/net/wireless/realtek/rtw89/phy.c | 622 +++++++++++++-
drivers/net/wireless/realtek/rtw89/phy.h | 164 +++-
drivers/net/wireless/realtek/rtw89/phy_be.c | 744 +++++++++++++----
drivers/net/wireless/realtek/rtw89/ps.c | 6 +
drivers/net/wireless/realtek/rtw89/reg.h | 289 +++++++
drivers/net/wireless/realtek/rtw89/regd.c | 24 +
drivers/net/wireless/realtek/rtw89/rtw8851b.c | 58 +-
drivers/net/wireless/realtek/rtw89/rtw8851be.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8851bu.c | 4 +
drivers/net/wireless/realtek/rtw89/rtw8852a.c | 63 +-
drivers/net/wireless/realtek/rtw89/rtw8852ae.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852au.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852b.c | 58 +-
drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c | 6 +-
drivers/net/wireless/realtek/rtw89/rtw8852be.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852bt.c | 58 +-
drivers/net/wireless/realtek/rtw89/rtw8852bt_rfk.c | 6 +-
drivers/net/wireless/realtek/rtw89/rtw8852bte.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852bu.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852c.c | 68 +-
drivers/net/wireless/realtek/rtw89/rtw8852c.h | 6 +-
drivers/net/wireless/realtek/rtw89/rtw8852ce.c | 1 +
drivers/net/wireless/realtek/rtw89/rtw8852cu.c | 13 +
drivers/net/wireless/realtek/rtw89/rtw8922a.c | 335 ++++++--
drivers/net/wireless/realtek/rtw89/rtw8922a_rfk.c | 22 +-
drivers/net/wireless/realtek/rtw89/rtw8922ae.c | 2 +
drivers/net/wireless/realtek/rtw89/rtw8922au.c | 86 ++
drivers/net/wireless/realtek/rtw89/rtw8922d.c | 445 +++++++++-
drivers/net/wireless/realtek/rtw89/rtw8922d_rfk.c | 92 ++-
drivers/net/wireless/realtek/rtw89/rtw8922d_rfk.h | 1 +
drivers/net/wireless/realtek/rtw89/rtw8922de.c | 2 +
drivers/net/wireless/realtek/rtw89/sar.c | 4 +
drivers/net/wireless/realtek/rtw89/txrx.h | 110 +++
drivers/net/wireless/realtek/rtw89/usb.c | 199 ++++-
drivers/net/wireless/realtek/rtw89/usb.h | 11 +-
74 files changed, 6188 insertions(+), 767 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-class-ieee80211-rtw89
create mode 100644 drivers/net/wireless/realtek/rtw89/rtw8922au.c
^ permalink raw reply
* ⚠️ wireless tree rebased
From: Johannes Berg @ 2026-06-03 7:36 UTC (permalink / raw)
To: Wireless
To drop a commit that didn't have proper S-o-b, I just rebased the
wireless tree.
Sorry for the mess.
johannes
^ permalink raw reply
* Missing signoff in the wireless tree
From: Mark Brown @ 2026-06-03 7:16 UTC (permalink / raw)
To: Johannes Berg, Wireless; +Cc: linux-kernel, linux-next
[-- Attachment #1: Type: text/plain, Size: 145 bytes --]
Commit
1b659e979685b ("wifi: mac80211: fix NULL dereference of eht_oper in ieee80211_start_ap()")
is missing a Signed-off-by from its author
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v6 2/3] PCI: Add device-specific reset for Qualcomm devices
From: Jose Ignacio Tornos Martinez @ 2026-06-03 7:15 UTC (permalink / raw)
To: jeff.johnson
Cc: alex, ath11k, ath12k, bhelgaas, jjohnson, jtornosm, linux-kernel,
linux-pci, linux-wireless, mani, mhi
In-Reply-To: <dc836218-2f18-4465-882c-c41b5289c379@oss.qualcomm.com>
Hello Jeff,
Thank you for the feedback.
I incorrectly referred to the drivers instead of the actual device names.
I'll send v7 with the corrections.
Thanks
Best regards
José Ignacio
^ permalink raw reply
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
From: Rasmus Villemoes @ 2026-06-03 7:15 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andy Shevchenko, Arnd Bergmann, Steven Rostedt, Masami Hiramatsu,
Andrew Morton, Petr Mladek, Nathan Chancellor, Dennis Dalessandro,
Jason Gunthorpe, Leon Romanovsky, Arend van Spriel,
Miri Korenblit, Mathieu Desnoyers, Sergey Senozhatsky,
Nick Desaulniers, Bill Wendling, Justin Stitt,
Vlastimil Babka (SUSE), linux-rdma, linux-kernel, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-trace-kernel, llvm
In-Reply-To: <35c1ba62-e74d-4abc-aa73-ccd35968ff89@app.fastmail.com>
On Tue, Jun 02 2026, "Arnd Bergmann" <arnd@arndb.de> wrote:
> On Tue, Jun 2, 2026, at 20:59, Andy Shevchenko wrote:
>> On Tue, Jun 02, 2026 at 05:07:05PM +0200, Arnd Bergmann wrote:
>>>
>>> A number of tracing headers turn off -Wsuggest-attribute=format for
>>> gcc, but they don't turn it off for clang, so the same warning still
>>> happens on new versions of clang that support the format attribute.
>>>
>>> To avoid duplicating the same thing in each tracing header, as well
>>> as changing all of them to also turn it off for clang, add a new
>>> __vsnprintf() helper that is not annotated this way in linux/sprintf.h
>>> but is defined to work the same way as the regular vsprintf.
>>
>> vsprintf()
>
> Fixed now
>
>> Why the __printf() annotation is in the C file and not here?
>> Is this all about headers as the second paragraph in the commit message
>> explains?
>> I would add a comment to explain it here, otherwise we might see false
>> patches to "make things consistent" in a wrong way.
>
> I've tried to come up with a kerneldoc comment now, similar to
> the one for the vsnprintf() function, and added a separate prototype
> in the header. Does this address your concern?
>
> Arnd
>
> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index 3caf0796f54d..7c696aea2ed3 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -2975,7 +2975,23 @@ int vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> }
> EXPORT_SYMBOL(vsnprintf);
>
> -int __printf(3, 0) __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> +/**
> + * __vsnprintf - vsnprintf() wrapper without __printf() attribute
> + * @buf: The buffer to place the result into
> + * @size: The size of the buffer, including the trailing null space
> + * @fmt_str: The format string to use
> + * @args: Arguments for the format string
> + *
> + * This has the exact same behavior as vsnprintf() but can be used in call
> + * sites that are missing a __printf() annotation, e.g. because they
> + * get a 'va_format' argument instead of format and varargs.
> + *
> + * For this to work, the attribute is added to the declaration here but
> + * not in the header.
> + */
> +int __printf(3, 0) __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args);
> +
> +int __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
> {
> return vsnprintf(buf, size, fmt_str, args);
> }
May I suggest a different approach, that avoids having that extra
function emitted (which presumably compiles to a single jump
instruction, but still, with retpoline and CFI and all that it all adds
up): Keep the declaration of __vsnprintf() in the header without the
__print() attribute, but then do
int __vsnprintf(char *buf, size_t size, const char *fmt_str, va_list args)
__alias(vsnprintf);
in vsprintf.c. Aside from reusing the same entry point, I could well
imagine a compiler some day complaining about seeing the printf
attribute applied in a local extra declaration but not having it in the
header file.
Presumably it will need its own EXPORT_SYMBOL if any of the intended
users are modular, and it certainly still needs a comment.
Rasmus
^ permalink raw reply
* Re: [PATCH] wifi: mt76: mt7996: Fix possible token leak in mt7996_tx_prepare_skb()
From: Lorenzo Bianconi @ 2026-06-03 7:09 UTC (permalink / raw)
To: Dylan Eskew
Cc: Felix Fietkau, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno, linux-wireless,
linux-arm-kernel, linux-mediatek
In-Reply-To: <80ff2108-dce3-4060-a8d0-59740979a99a@candelatech.com>
[-- Attachment #1: Type: text/plain, Size: 2978 bytes --]
> Hi Lore,
Hi Dylan,
>
> We have been seeing the token memory leak in our custom kernel. After
> pulling your patch in, we are still getting the leak (validated with
> kmemleak). How did you figure out where this potential leak was? I want to
> determine if we are leaking because of our changes or if there's more areas
> for token leakage.
Can you please try to run kmemleak on Felix's tree to check if there are any
leftover leaks not fixed yet?
Regards,
Lorenzo
>
> -- Dylan
>
> On 5/31/26 2:10 AM, Lorenzo Bianconi wrote:
> > If link_conf or link_sta lookup fails in mt7996_tx_prepare_skb routine,
> > mt7996 driver leaks an already allocated tx token. Fix the issue
> > releasing the token in case of error.
> >
> > Fixes: 7ef0c7ad735b0 ("wifi: mt76: mt7996: Implement MLD address translation for EAPOL")
> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
> > ---
> > drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 8 ++++++--
> > drivers/net/wireless/mediatek/mt76/tx.c | 2 +-
> > 2 files changed, 7 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
> > index c98446057282..8c56344d211b 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
> > @@ -1067,11 +1067,11 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
> > link_conf = rcu_dereference(vif->link_conf[wcid->link_id]);
> > if (!link_conf)
> > - return -EINVAL;
> > + goto error_relase_token;
> > link_sta = rcu_dereference(sta->link[wcid->link_id]);
> > if (!link_sta)
> > - return -EINVAL;
> > + goto error_relase_token;
> > dma_sync_single_for_cpu(mdev->dma_dev, tx_info->buf[1].addr,
> > tx_info->buf[1].len, DMA_TO_DEVICE);
> > @@ -1176,6 +1176,10 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
> > tx_info->nbuf = MT_CT_DMA_BUF_NUM;
> > return 0;
> > +
> > +error_relase_token:
> > + mt76_token_release(mdev, id, NULL);
> > + return -EINVAL;
> > }
> > u32 mt7996_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
> > diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
> > index 22f9690634c9..f96d9c471853 100644
> > --- a/drivers/net/wireless/mediatek/mt76/tx.c
> > +++ b/drivers/net/wireless/mediatek/mt76/tx.c
> > @@ -933,7 +933,7 @@ mt76_token_release(struct mt76_dev *dev, int token, bool *wake)
> > #endif
> > }
> > - if (dev->token_count < dev->token_size - MT76_TOKEN_FREE_THR &&
> > + if (wake && dev->token_count < dev->token_size - MT76_TOKEN_FREE_THR &&
> > dev->phy.q_tx[0]->blocked)
> > *wake = true;
> >
> > ---
> > base-commit: 4913f44167cf35a9536e9eec7352e15b2de0c573
> > change-id: 20260531-mt7996_tx_prepare_skb-token-leack-82e240d8c66f
> >
> > Best regards,
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH v3 rtw-next 1/2] wifi: rtw89: add dev_id_quirks to driver_info for per-device quirk control
From: Ping-Ke Shih @ 2026-06-03 6:59 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless
Cc: driver-core, johannes, mh_chen, wenjie.tsai, charlesl, sabae
In-Reply-To: <20260529075032.16807-2-pkshih@realtek.com>
Ping-Ke Shih <pkshih@realtek.com> wrote:
> From: Johnson Tsai <wenjie.tsai@realtek.com>
>
> Add a dev_id_quirks field to rtw89_driver_info so that per-device
> (VID/PID) quirks can be expressed independently of chip-level
> default_quirks. Apply the bitmap in rtw89_alloc_ieee80211_hw() so
> both USB and PCI probes benefit automatically.
>
> All existing driver_info structs initialize dev_id_quirks to 0;
> no behavior change.
>
> Signed-off-by: Johnson Tsai <wenjie.tsai@realtek.com>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
2 patch(es) applied to rtw-next branch of rtw.git, thanks.
7554f6602a80 wifi: rtw89: add dev_id_quirks to driver_info for per-device quirk control
384cc80f3097 wifi: rtw89: usb: add serial_number and uuid sysfs attributes for 0x28de:0x2432
---
https://github.com/pkshih/rtw.git
^ permalink raw reply
* Re: [PATCH rtw-next] wifi: rtw89: usb: skip ACPI capability check for USB devices
From: Ping-Ke Shih @ 2026-06-03 6:45 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless; +Cc: sc.lee
In-Reply-To: <20260525082636.31105-1-pkshih@realtek.com>
Ping-Ke Shih <pkshih@realtek.com> wrote:
> From: David Lee <sc.lee@realtek.com>
>
> Skip the ACPI capability check for all USB devices by default,
> allowing them to use their default configurations.
>
> For USB dongles, customers will manage their own compliance and
> certification. This initial patch focuses on the generic USB skip
> infrastructure; specific customer certifications and localized
> configurations will be handled by quirks afterward.
>
> Signed-off-by: David Lee <sc.lee@realtek.com>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
1 patch(es) applied to rtw-next branch of rtw.git, thanks.
bf4a37f516f0 wifi: rtw89: usb: skip ACPI capability check for USB devices
---
https://github.com/pkshih/rtw.git
^ permalink raw reply
* Re: [PATCH rtw-next] wifi: rtw89: 8851bu: add Mercusys MA60XNB (2c4e:0128)
From: Ping-Ke Shih @ 2026-06-03 6:43 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless; +Cc: guillem
In-Reply-To: <20260525011728.6836-1-pkshih@realtek.com>
Ping-Ke Shih <pkshih@realtek.com> wrote:
> Add the specific USB device ID which adapter tested fully functional on
> Fedora 44 with kernel 7.0.8-200.fc44.x86_64 and linux-firmware
> 20260410-1.fc44.
>
> Reported-by: Guillermo Servera Negre <guillem@gservera.com>
> Tested-by: Guillermo Servera Negre <guillem@gservera.com>
> Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
1 patch(es) applied to rtw-next branch of rtw.git, thanks.
575e6a72bd68 wifi: rtw89: 8851bu: add Mercusys MA60XNB (2c4e:0128)
---
https://github.com/pkshih/rtw.git
^ permalink raw reply
* RE: [PATCH v2 0/3] wifi: iwlwifi: add Device Tree hardware integration information
From: Bhatt, Avinash @ 2026-06-03 6:39 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: devicetree@vger.kernel.org, linux-wireless@vger.kernel.org,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
johannes@sipsolutions.net, Korenblit, Miriam Rachel,
linux-kernel@vger.kernel.org, Guetta, Kobi, Grumbach, Emmanuel
In-Reply-To: <a51ba34d-92db-46a5-a87d-15cea72af833@kernel.org>
> If you are not willing to post DTS, then you are not helping us to
> understand the completeness of this binding and hardware description.
> IOW, the bigger picture is missing, so IMO I would remove most of the
> properties.
Apologies for the delay in getting back on this. This is not a matter
of willingness — we have a dependency on our OEM partners to provide an
upstream DTS user, as this binding is intended for use on their
platforms.
We reached out to them, and they have confirmed that they are unable to
upstream their DTS at this time. Given this constraint, we will hold
off on pushing this binding upstream for now. We will reassess and
return to this thread if and when the situation changes.
Best regards,
Avinash
-----Original Message-----
From: Krzysztof Kozlowski <krzk@kernel.org>
Sent: 13 May 2026 23:49
To: Bhatt, Avinash <avinash.bhatt@intel.com>
Cc: devicetree@vger.kernel.org; linux-wireless@vger.kernel.org; robh@kernel.org; krzk+dt@kernel.org; conor+dt@kernel.org; johannes@sipsolutions.net; Korenblit, Miriam Rachel <miriam.rachel.korenblit@intel.com>; linux-kernel@vger.kernel.org; Guetta, Kobi <kobi.guetta@intel.com>; Grumbach, Emmanuel <emmanuel.grumbach@intel.com>
Subject: Re: [PATCH v2 0/3] wifi: iwlwifi: add Device Tree hardware integration information
On 12/05/2026 12:07, Bhatt, Avinash wrote:
> Hi Krzysztof,
>
> Thank you for the review. Please find our response inline below.
>
> On Mon, May 04, 2026 at 12:53:24PM +0300, Krzysztof Kozlowski wrote:
>> Please provide link to any upstream DTS user of this binding, either
>> complete or work in progress.
>
> We have OEM partners waiting for this binding layout to be finalized
> before they proceed with their DTS work. Our intent is to have the
> schema reviewed and accepted by the DT maintainers first — sharing a
> binding that may still undergo structural changes with OEMs would
> create unnecessary churn on their side.
>
> OEM partners are targeting platforms that depend on this binding. They
> are waiting for the schema to be finalized before proceeding with
> their DTS work, and whether they upstream that DTS is ultimately their
> decision.
>
> If a DTS user is strictly required for the binding to be merged, we
> understand and accept that requirement — however, since OEM
> upstreaming is outside our control, we would greatly appreciate an
> early indication of whether the schema direction is acceptable before
> we distribute it further. Any feedback or provisional acceptance at
> this stage would be very helpful.
>
> We are actively addressing all the review comments from v2 and plan to
> send v3 shortly.
>
> Best Regards,
> Avinash
>
> -----Original Message-----
> From: Krzysztof Kozlowski <krzk@kernel.org>
> Sent: 05 May 2026 14:50
> To: Bhatt, Avinash <avinash.bhatt@intel.com>
> Cc: devicetree@vger.kernel.org; linux-wireless@vger.kernel.org;
> robh@kernel.org; krzk+dt@kernel.org; conor+dt@kernel.org;
> johannes@sipsolutions.net; Korenblit, Miriam Rachel
> <miriam.rachel.korenblit@intel.com>; linux-kernel@vger.kernel.org;
> Guetta, Kobi <kobi.guetta@intel.com>; Grumbach, Emmanuel
> <emmanuel.grumbach@intel.com>
> Subject: Re: [PATCH v2 0/3] wifi: iwlwifi: add Device Tree hardware
> integration information
>
> On Mon, May 04, 2026 at 12:53:24PM +0300, Avinash Bhatt wrote:
>> Add Device Tree support for Intel Wi-Fi hardware integration
>> information on platforms that do not provide UEFI variables or ACPI methods.
>>
>> Patch 1/3 adds the DT binding schema for the Intel iwlwifi compatible
>> node. Patches 2/3 and 3/3 add the driver infrastructure and integrate
>> DT as the lowest-priority fallback after UEFI and ACPI.
>
> Please provide link to any upstream DTS user of this binding, either complete or work in progress.
>
> Best regards,
> Krzysztof
Do not top post.
If you are not willing to post DTS, then you are not helping us to understand the completeness of this binding and hardware description.
IOW, the bigger picture is missing, so IMO I would remove most of the properties.
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
From: Andy Shevchenko @ 2026-06-03 5:46 UTC (permalink / raw)
To: Masami Hiramatsu
Cc: Arnd Bergmann, Steven Rostedt, Andrew Morton, Petr Mladek,
Nathan Chancellor, Arnd Bergmann, Dennis Dalessandro,
Jason Gunthorpe, Leon Romanovsky, Arend van Spriel,
Miri Korenblit, Mathieu Desnoyers, Rasmus Villemoes,
Sergey Senozhatsky, Nick Desaulniers, Bill Wendling, Justin Stitt,
Vlastimil Babka, linux-rdma, linux-kernel, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-trace-kernel, llvm
In-Reply-To: <20260603105842.1e0ef8cb4a55cb776d6a4971@kernel.org>
On Wed, Jun 03, 2026 at 10:58:42AM +0900, Masami Hiramatsu wrote:
> On Tue, 2 Jun 2026 17:07:05 +0200
> Arnd Bergmann <arnd@kernel.org> wrote:
...
> I think this is a slightly confusing name. What about vsnprintf_nocheck()?
What check? If you want to be more precise: vsnprintf_no_printf_attr() or
vsnprintf_no_format_check(). But they also seem to me not the good choices.
(Just slight preference to the latter one no_format_check.)
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH] wifi: brcmfmac: add DPP support and fix fw-supplicant/P2P interop
From: Jason Huang @ 2026-06-03 3:57 UTC (permalink / raw)
To: linux-wireless; +Cc: wlan-kernel-dev-list, Johannes Berg, Kurt Lee, Jason Huang
From: Kurt Lee <kurt.lee@cypress.com>
Add DPP support in brcmfmac and include follow-up fixes needed for reliable operation with mixed security setups.
Main changes:
- add DPP AKM handling in key-mgmt and RSN parsing
- map DPP to WFA_AUTH_DPP and allow it in MFP-required checks
- recognize DPP public action frames in the P2P TX path
- pass the transmitting vif explicitly for action frame TX
- track the correct ROC wdev for remain-on-channel expiry
- gate sup_wpa iovar usage by firmware FWSUP capability
- avoid stale fw supplicant state that can break DPP/EAPOL handling
- add missing NULL checks in P2P abort/search-channel paths
Together these changes enable DPP while preventing regressions when
switching between DPP and non-DPP encrypted connections.
Signed-off-by: Kurt Lee <kurt.lee@cypress.com>
Signed-off-by: Jason Huang <jason.huang2@infineon.com>
---
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 151 ++++++++++--------
.../broadcom/brcm80211/brcmfmac/p2p.c | 58 ++++++-
.../broadcom/brcm80211/brcmfmac/p2p.h | 1 +
.../broadcom/brcm80211/include/brcmu_wifi.h | 5 +
4 files changed, 148 insertions(+), 67 deletions(-)
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
index 0b55d445895f..482abee11987 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -65,6 +65,9 @@
#define RSN_CAP_MFPC_MASK BIT(7)
#define RSN_PMKID_COUNT_LEN 2
+#define DPP_AKM_SUITE_TYPE 2
+#define WLAN_AKM_SUITE_DPP SUITE(WLAN_OUI_WFA, DPP_AKM_SUITE_TYPE)
+
#define VNDR_IE_CMD_LEN 4 /* length of the set command
* string :"add", "del" (+ NUL)
*/
@@ -2174,6 +2177,9 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
val = WPA2_AUTH_PSK | WPA2_AUTH_FT;
profile->is_ft = true;
break;
+ case WLAN_AKM_SUITE_DPP:
+ val = WFA_AUTH_DPP;
+ break;
default:
bphy_err(drvr, "invalid akm suite (%d)\n",
sme->crypto.akm_suites[0]);
@@ -2483,43 +2489,47 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
goto done;
}
- if (sme->crypto.psk &&
- profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) {
- if (WARN_ON(profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE)) {
- err = -EINVAL;
- goto done;
- }
- brcmf_dbg(INFO, "using PSK offload\n");
- profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
- }
-
- if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
- /* enable firmware supplicant for this interface */
- err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
- if (err < 0) {
- bphy_err(drvr, "failed to enable fw supplicant\n");
- goto done;
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) {
+ if (sme->crypto.psk) {
+ if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) {
+ if (WARN_ON(profile->use_fwsup !=
+ BRCMF_PROFILE_FWSUP_NONE)) {
+ err = -EINVAL;
+ goto done;
+ }
+ brcmf_dbg(INFO, "using PSK offload\n");
+ profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
+ }
+ } else {
+ profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
}
- }
-
- if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK)
- err = brcmf_set_pmk(ifp, sme->crypto.psk,
- BRCMF_WSEC_MAX_PSK_LEN);
- else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) {
- /* clean up user-space RSNE */
- err = brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0);
- if (err) {
- bphy_err(drvr, "failed to clean up user-space RSNE\n");
- goto done;
+ if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
+ /* enable firmware supplicant for this interface */
+ err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
+ if (err < 0) {
+ bphy_err(drvr, "failed to enable fw supplicant\n");
+ goto done;
+ }
+ } else {
+ err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 0);
}
- err = brcmf_fwvid_set_sae_password(ifp, &sme->crypto);
- if (!err && sme->crypto.psk)
+ if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK)
err = brcmf_set_pmk(ifp, sme->crypto.psk,
BRCMF_WSEC_MAX_PSK_LEN);
+ else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) {
+ /* clean up user-space RSNE */
+ if (brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0)) {
+ bphy_err(drvr, "failed to clean up user-space RSNE\n");
+ goto done;
+ }
+ err = brcmf_fwvid_set_sae_password(ifp, &sme->crypto);
+ if (!err && sme->crypto.psk)
+ err = brcmf_set_pmk(ifp, sme->crypto.psk,
+ BRCMF_WSEC_MAX_PSK_LEN);
+ }
+ if (err)
+ goto done;
}
- if (err)
- goto done;
-
/* Join with specific BSSID and cached SSID
* If SSID is zero join based on BSSID only
*/
@@ -4538,6 +4548,12 @@ static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
}
+static bool brcmf_valid_dpp_suite(u8 *oui)
+{
+ return (memcmp(oui, WFA_OUI, TLV_OUI_LEN) == 0 &&
+ *(oui + TLV_OUI_LEN) == DPP_AKM_SUITE_TYPE);
+}
+
static s32
brcmf_configure_wpaie(struct brcmf_if *ifp,
const struct brcmf_vs_tlv *wpa_ie,
@@ -4651,42 +4667,47 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
goto exit;
}
for (i = 0; i < count; i++) {
- if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
+ if (brcmf_valid_dpp_suite(&data[offset])) {
+ wpa_auth |= WFA_AUTH_DPP;
+ offset += TLV_OUI_LEN;
+ } else if (brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
+ offset += TLV_OUI_LEN;
+ switch (data[offset]) {
+ case RSN_AKM_NONE:
+ brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
+ wpa_auth |= WPA_AUTH_NONE;
+ break;
+ case RSN_AKM_UNSPECIFIED:
+ brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
+ is_rsn_ie ?
+ (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
+ (wpa_auth |= WPA_AUTH_UNSPECIFIED);
+ break;
+ case RSN_AKM_PSK:
+ brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
+ is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
+ (wpa_auth |= WPA_AUTH_PSK);
+ break;
+ case RSN_AKM_SHA256_PSK:
+ brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
+ wpa_auth |= WPA2_AUTH_PSK_SHA256;
+ break;
+ case RSN_AKM_SHA256_1X:
+ brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
+ wpa_auth |= WPA2_AUTH_1X_SHA256;
+ break;
+ case RSN_AKM_SAE:
+ brcmf_dbg(TRACE, "RSN_AKM_SAE\n");
+ wpa_auth |= WPA3_AUTH_SAE_PSK;
+ break;
+ default:
+ bphy_err(drvr, "Invalid key mgmt info\n");
+ }
+ } else {
err = -EINVAL;
bphy_err(drvr, "invalid OUI\n");
goto exit;
}
- offset += TLV_OUI_LEN;
- switch (data[offset]) {
- case RSN_AKM_NONE:
- brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
- wpa_auth |= WPA_AUTH_NONE;
- break;
- case RSN_AKM_UNSPECIFIED:
- brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
- is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
- (wpa_auth |= WPA_AUTH_UNSPECIFIED);
- break;
- case RSN_AKM_PSK:
- brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
- is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
- (wpa_auth |= WPA_AUTH_PSK);
- break;
- case RSN_AKM_SHA256_PSK:
- brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
- wpa_auth |= WPA2_AUTH_PSK_SHA256;
- break;
- case RSN_AKM_SHA256_1X:
- brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
- wpa_auth |= WPA2_AUTH_1X_SHA256;
- break;
- case RSN_AKM_SAE:
- brcmf_dbg(TRACE, "RSN_AKM_SAE\n");
- wpa_auth |= WPA3_AUTH_SAE_PSK;
- break;
- default:
- bphy_err(drvr, "Invalid key mgmt info\n");
- }
offset++;
}
@@ -4706,10 +4727,12 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
*/
if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
WPA2_AUTH_1X_SHA256 |
+ WFA_AUTH_DPP |
WPA3_AUTH_SAE_PSK))) {
err = -EINVAL;
goto exit;
}
+
/* Firmware has requirement that WPA2_AUTH_PSK/
* WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
* is to be included in the rsn ie.
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
index e1752a513c73..72869219dd6b 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
@@ -231,7 +231,35 @@ static bool brcmf_p2p_is_pub_action(void *frame, u32 frame_len)
if (pact_frm->category == P2P_PUB_AF_CATEGORY &&
pact_frm->action == P2P_PUB_AF_ACTION &&
pact_frm->oui_type == P2P_VER &&
- memcmp(pact_frm->oui, P2P_OUI, P2P_OUI_LEN) == 0)
+ memcmp(pact_frm->oui, WFA_OUI, P2P_OUI_LEN) == 0)
+ return true;
+
+ return false;
+}
+
+/**
+ * brcmf_p2p_is_dpp_pub_action() - true if dpp public type frame.
+ *
+ * @frame: action frame data.
+ * @frame_len: length of action frame data.
+ *
+ * Determine if action frame is dpp public action type
+ */
+static bool brcmf_p2p_is_dpp_pub_action(void *frame, u32 frame_len)
+{
+ struct brcmf_p2p_pub_act_frame *pact_frm;
+
+ if (!frame)
+ return false;
+
+ pact_frm = (struct brcmf_p2p_pub_act_frame *)frame;
+ if (frame_len < sizeof(struct brcmf_p2p_pub_act_frame) - 1)
+ return false;
+
+ if (pact_frm->category == WLAN_CATEGORY_PUBLIC &&
+ pact_frm->action == WLAN_PUB_ACTION_VENDOR_SPECIFIC &&
+ pact_frm->oui_type == DPP_VER &&
+ memcmp(pact_frm->oui, WFA_OUI, TLV_OUI_LEN) == 0)
return true;
return false;
@@ -991,6 +1019,8 @@ int brcmf_p2p_remain_on_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
if (err)
goto exit;
+ p2p->remin_on_channel_wdev = wdev;
+
memcpy(&p2p->remain_on_channel, channel, sizeof(*channel));
*cookie = p2p->remain_on_channel_cookie;
cfg80211_ready_on_channel(wdev, *cookie, channel, duration, GFP_KERNEL);
@@ -1014,6 +1044,7 @@ int brcmf_p2p_notify_listen_complete(struct brcmf_if *ifp,
{
struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
struct brcmf_p2p_info *p2p = &cfg->p2p;
+ struct wireless_dev *wdev = p2p->remin_on_channel_wdev;
brcmf_dbg(TRACE, "Enter\n");
if (test_and_clear_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN,
@@ -1026,10 +1057,16 @@ int brcmf_p2p_notify_listen_complete(struct brcmf_if *ifp,
complete(&p2p->wait_next_af);
}
- cfg80211_remain_on_channel_expired(&ifp->vif->wdev,
+ wdev = p2p->remin_on_channel_wdev ?
+ p2p->remin_on_channel_wdev :
+ &ifp->vif->wdev;
+
+ cfg80211_remain_on_channel_expired(wdev,
p2p->remain_on_channel_cookie,
&p2p->remain_on_channel,
GFP_KERNEL);
+ p2p->remin_on_channel_wdev = NULL;
+
}
return 0;
}
@@ -1281,6 +1318,10 @@ static s32 brcmf_p2p_abort_action_frame(struct brcmf_cfg80211_info *cfg)
brcmf_dbg(TRACE, "Enter\n");
vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
+
+ if (!vif)
+ vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
+
err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe_abort", &int_val,
sizeof(s32));
if (err)
@@ -1532,6 +1573,7 @@ int brcmf_p2p_notify_action_tx_complete(struct brcmf_if *ifp,
* @ifp: interface to transmit on.
* @p2p: p2p info struct for vif.
* @af_params: action frame data/info.
+ * @vif: vif to send
*
* Send an action frame immediately without doing channel synchronization.
*
@@ -1545,6 +1587,11 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_if *ifp,
{
struct brcmf_pub *drvr = p2p->cfg->pub;
s32 err = 0;
+ struct brcmf_fil_action_frame_le *action_frame;
+ u16 action_frame_len;
+
+ action_frame = &af_params->action_frame;
+ action_frame_len = le16_to_cpu(action_frame->len);
brcmf_dbg(TRACE, "Enter\n");
@@ -1706,6 +1753,7 @@ static bool brcmf_p2p_check_dwell_overflow(u32 requested_dwell,
*
* @ifp: interface to transmit on.
* @af_params: configuration data for action frame.
+ * @vif: virtual interface to send
*/
bool brcmf_p2p_send_action_frame(struct brcmf_if *ifp,
struct brcmf_fil_af_params_le *af_params)
@@ -1780,7 +1828,9 @@ bool brcmf_p2p_send_action_frame(struct brcmf_if *ifp,
goto exit;
}
} else if (brcmf_p2p_is_p2p_action(action_frame->data,
- action_frame_len)) {
+ action_frame_len) ||
+ brcmf_p2p_is_dpp_pub_action(action_frame->data,
+ action_frame_len)) {
/* do not configure anything. it will be */
/* sent with a default configuration */
} else {
@@ -1817,6 +1867,7 @@ bool brcmf_p2p_send_action_frame(struct brcmf_if *ifp,
/* validate channel and p2p ies */
if (config_af_params.search_channel &&
IS_P2P_SOCIAL_CHANNEL(le32_to_cpu(af_params->channel)) &&
+ p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif &&
p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif->saved_ie.probe_req_ie_len) {
afx_hdl = &p2p->afx_hdl;
afx_hdl->peer_listen_chan = le32_to_cpu(af_params->channel);
@@ -2502,6 +2553,7 @@ s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced)
pri_ifp = brcmf_get_ifp(cfg->pub, 0);
p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif;
+ init_completion(&p2p->send_af_done);
init_completion(&p2p->send_af_done);
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
index d3137ebd7158..2a74e3036ce3 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
@@ -138,6 +138,7 @@ struct brcmf_p2p_info {
bool block_gon_req_tx;
bool p2pdev_dynamically;
bool wait_for_offchan_complete;
+ struct wireless_dev *remin_on_channel_wdev;
};
s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced);
diff --git a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
index 7552bdb91991..3a9cad3730b8 100644
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h
@@ -233,6 +233,11 @@ static inline bool ac_bitmap_tst(u8 bitmap, int prec)
#define WPA3_AUTH_SAE_PSK 0x40000 /* SAE with 4-way handshake */
+#define WFA_AUTH_DPP 0x200000 /* WFA DPP AUTH */
+
+#define WFA_OUI "\x50\x6F\x9A" /* WFA OUI */
+#define DPP_VER 0x1A /* WFA DPP v1.0 */
+
#define DOT11_DEFAULT_RTS_LEN 2347
#define DOT11_DEFAULT_FRAG_LEN 2346
--
2.25.1
^ permalink raw reply related
* Re: [PATCH 1/2] tracing: work around -Wmissing-format-attribute warning
From: Masami Hiramatsu @ 2026-06-03 1:58 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Steven Rostedt, Andrew Morton, Petr Mladek, Nathan Chancellor,
Arnd Bergmann, Dennis Dalessandro, Jason Gunthorpe,
Leon Romanovsky, Arend van Spriel, Miri Korenblit,
Mathieu Desnoyers, Andy Shevchenko, Rasmus Villemoes,
Sergey Senozhatsky, Nick Desaulniers, Bill Wendling, Justin Stitt,
Vlastimil Babka, linux-rdma, linux-kernel, linux-wireless,
brcm80211, brcm80211-dev-list.pdl, linux-trace-kernel, llvm
In-Reply-To: <20260602150904.2258624-1-arnd@kernel.org>
On Tue, 2 Jun 2026 17:07:05 +0200
Arnd Bergmann <arnd@kernel.org> wrote:
> diff --git a/include/linux/sprintf.h b/include/linux/sprintf.h
> index f06f7b785091..036a247b7c1e 100644
> --- a/include/linux/sprintf.h
> +++ b/include/linux/sprintf.h
> @@ -12,6 +12,7 @@ __printf(2, 3) int sprintf(char *buf, const char * fmt, ...);
> __printf(2, 0) int vsprintf(char *buf, const char *, va_list);
> __printf(3, 4) int snprintf(char *buf, size_t size, const char *fmt, ...);
> __printf(3, 0) int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
> +int __vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
> __printf(3, 4) int scnprintf(char *buf, size_t size, const char *fmt, ...);
> __printf(3, 0) int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
> __printf(2, 3) __malloc char *kasprintf(gfp_t gfp, const char *fmt, ...);
> diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
> index d49338c44014..4715330c7b6b 100644
> --- a/include/linux/trace_events.h
> +++ b/include/linux/trace_events.h
> @@ -962,7 +962,7 @@ perf_trace_buf_submit(void *raw_data, int size, int rctx, u16 type,
> int __ret; \
> \
> va_copy(__ap, *(va)); \
> - __ret = vsnprintf(NULL, 0, fmt, __ap) + 1; \
> + __ret = __vsnprintf(NULL, 0, fmt, __ap) + 1; \
> va_end(__ap); \
> \
> min(__ret, TRACE_EVENT_STR_MAX); \
I think this is a slightly confusing name. What about vsnprintf_nocheck()?
Thanks,
--
Masami Hiramatsu (Google) <mhiramat@kernel.org>
^ permalink raw reply
* Re: [PATCH 3/4] dt-bindings: bus: add brcm,bcm6362-wlan
From: Alessio Ferri @ 2026-06-02 22:18 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Rafał Miłecki, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, Florian Fainelli, linux-kernel,
linux-wireless, devicetree
In-Reply-To: <20260530-psychedelic-cyber-seagull-140adf@quoll>
Il 30/05/2026 13:50, Krzysztof Kozlowski ha scritto:
> On Fri, May 29, 2026 at 02:06:01AM +0200, Alessio Ferri wrote:
>> Document the binding for the SHIM bridge that gates the on-chip
>> 2.4 GHz WLAN block of the Broadcom BCM6362 SoC. The bridge owns the
>> SHIM peephole, a single clock for the macro, and two resets (the
>> SHIM macro itself and its ubus side). It is also a bus: it carries
>> one brcm,bus-axi child describing the bcma backplane behind the
>> SHIM, with a standard interrupt-map routing the d11 core's IRQ to
>> the SoC interrupt controller.
>>
>> Assisted-by: Claude:claude-4.8-opus
>> Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
>> ---
>> .../devicetree/bindings/bus/brcm,bcm6362-wlan.yaml | 106 +++++++++++++++++++++
>> 1 file changed, 106 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml b/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml
>> new file mode 100644
>> index 000000000000..c8d49ccdd2c1
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml
>> @@ -0,0 +1,106 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/bus/brcm,bcm6362-wlan.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Broadcom BCM6362 on-chip WLAN SHIM bridge
>> +
>> +maintainers:
>> + - Alessio Ferri <alessio.ferri@mythread.it>
>> +
>> +description: |
>> + The BCM6362 SoC integrates a 2.4 GHz Broadcom WLAN block whose
>> + register backplane uses the Broadcom AMBA (bcma) architecture. The
>> + backplane is gated by a small SHIM bridge that holds the WLAN macro
>> + in reset and disables its clocks until released by software. CFE
>> + does not release this block, so software bring-up is required
>> + before bcma can enumerate the backplane.
>> +
>> + This binding describes the SHIM bridge node. The SHIM driver brings
>
> Do not describe binding. Do not describe driver.
> Describe hardware.
>
>> + the macro up and then populates the brcm,bus-axi child node, which
>> + describes the bcma backplane behind the SHIM and is bound by the
>> + bcma-host-soc driver. The SoC-specific configuration (big-endian
>> + accessors, SHIM-attached topology, SHIM Control register peephole
>> + pointer) is delivered to bcma via platform_data injected at
>> + populate time, so the brcm,bus-axi child stays SoC-agnostic.
>
> How is it relevant?
>
>> +
>> +properties:
>> + compatible:
>> + const: brcm,bcm6362-wlan
>> +
>> + reg:
>> + maxItems: 1
>> + description: SHIM peephole registers.
>
> What is SHIM?
>
>> +
>> + reg-names:
>> + items:
>> + - const: shim
>> +
>> + clocks:
>> + maxItems: 1
>> +
>> + resets:
>> + items:
>> + - description: SHIM macro reset
>> + - description: SHIM ubus reset
>> +
>> + reset-names:
>> + items:
>> + - const: shim
>> + - const: shim-ubus
>> +
>> + '#address-cells':
>> + const: 1
>> +
>> + '#size-cells':
>> + const: 1
>> +
>> + ranges: true
>> +
>> +patternProperties:
>> + "^axi@[0-9a-f]+$":
>
> Use consistent quotes.
>
>> + type: object
>> + description: The bcma AXI backplane behind the SHIM.
>> + $ref: /schemas/types.yaml#
>
> Need proper ref. You could easily check instead of sending Claude slop -
> is there any binding with above syntax?
>
> You don't get subnodes for buses for devices not being the actual
> buses.
>
> Best regards,
> Krzysztof
>
Sorry for letting AI-slop pass through in this patch and excessive
descriptions.
SHIM is just the control block for the integrated wlan. Copied verbatim
from the original broadcom 96362 code.
For the last sentence, how should i map it? At the very least I need to
tell bcma that this is big-endian before it touches anything, otherwise
it will read/write garbage or even cause a panic. If necessary i can
pick up the quirks after reading the chip-id from the bus, skipping the
new driver and the new bindings.
^ 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