* Re: [PATCH v1 0/3] regulator: Use named initializers for platform_device_id arrays
From: Mark Brown @ 2026-06-02 15:09 UTC (permalink / raw)
To: Liam Girdwood, Uwe Kleine-König (The Capable Hub)
Cc: Chanwoo Choi, Krzysztof Kozlowski, Javier Martinez Canillas,
Matthias Brugger, AngeloGioacchino Del Regno, André Draszik,
linux-kernel, linux-arm-kernel, linux-mediatek, linux-samsung-soc,
Karel Balej, Matti Vaittinen, Marek Vasut, Samuel Kayode,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, linux-renesas-soc, imx, linux-arm-msm, linux-omap
In-Reply-To: <cover.1779878004.git.u.kleine-koenig@baylibre.com>
On Wed, 27 May 2026 12:47:43 +0200, Uwe Kleine-König (The Capable Hub) wrote:
> regulator: Use named initializers for platform_device_id arrays
>
> Hello,
>
> this series targets to use named initializers for platform_device_id
> arrays. In general these are better readable for humans and more robust
> to changes in the respective struct definition.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git for-7.2
Thanks!
[1/3] regulator: Drop unused assignment of platform_device_id driver data
https://git.kernel.org/broonie/regulator/c/4079e9d91b40
[2/3] regulator: Use named initializers for platform_device_id arrays
https://git.kernel.org/broonie/regulator/c/d35028340d75
[3/3] regulator: Unify usage of space and comma in platform_device_id arrays
https://git.kernel.org/broonie/regulator/c/0eb17367814a
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply
* Re: [PATCH 0/2] ASoC: mediatek: mt8192 probe cleanup
From: Mark Brown @ 2026-06-02 15:13 UTC (permalink / raw)
To: Liam Girdwood, Takashi Iwai, Jaroslav Kysela, Matthias Brugger,
AngeloGioacchino Del Regno, Chen-Yu Tsai, Jiaxin Yu,
Cássio Gabriel
Cc: linux-sound, linux-kernel, linux-arm-kernel, linux-mediatek,
notify, stable
In-Reply-To: <20260527-asoc-mt8192-probe-cleanup-v1-0-1bb834d05b72@gmail.com>
On Wed, 27 May 2026 10:55:45 -0300, Cássio Gabriel wrote:
> ASoC: mediatek: mt8192 probe cleanup
>
> Fix two MT8192 AFE probe cleanup issues that mirror the recently fixed
> MT8189 and MT8196 paths.
>
> The first patch registers a devm cleanup action for a successful
> reserved-memory assignment so later probe failures and driver unbind
> release it.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-7.2
Thanks!
[1/2] ASoC: mediatek: mt8192: Release reserved memory on cleanup
https://git.kernel.org/broonie/sound/c/965e17ae6751
[2/2] ASoC: mediatek: mt8192: Check runtime resume during probe
https://git.kernel.org/broonie/sound/c/e24d5dde56a5
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply
* Re: [PATCH 0/2] ASoC: mediatek: mt8183: Fix probe resource cleanup
From: Mark Brown @ 2026-06-02 15:11 UTC (permalink / raw)
To: Liam Girdwood, Takashi Iwai, Jaroslav Kysela, Matthias Brugger,
AngeloGioacchino Del Regno, Chen-Yu Tsai, Shunli Wang,
Cássio Gabriel
Cc: linux-sound, linux-kernel, linux-arm-kernel, linux-mediatek,
notify, stable
In-Reply-To: <20260527-asoc-mt8183-probe-cleanup-v1-0-4f4f5593c8d1@gmail.com>
On Wed, 27 May 2026 10:41:47 -0300, Cássio Gabriel wrote:
> ASoC: mediatek: mt8183: Fix probe resource cleanup
>
> The MT8183 AFE probe has two cleanup gaps that match issues
> recently fixed in newer MediaTek AFE drivers.
>
> First, reserved memory assigned with of_reserved_mem_device_init()
> is never released on driver removal or later probe failures.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-7.2
Thanks!
[1/2] ASoC: mediatek: mt8183: Release reserved memory on cleanup
https://git.kernel.org/broonie/sound/c/bee65e00c092
[2/2] ASoC: mediatek: mt8183: Check runtime resume during probe
https://git.kernel.org/broonie/sound/c/f0334fbfd107
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply
* Re: [PATCH RFC 00/12] arm64: mediatek: Add M.2 E-key slot on Chromebooks
From: Chen-Yu Tsai @ 2026-06-03 6:55 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, linux-pm, linux-usb, devicetree,
linux-mediatek, linux-arm-kernel, linux-kernel,
Greg Kroah-Hartman, Manivannan Sadhasivam
In-Reply-To: <CAMRc=McADm0F4bwhj5qoigfUT-AV6CVpo+FAaqoBnZ3PrjBc7Q@mail.gmail.com>
On Thu, May 28, 2026 at 4:33 PM Bartosz Golaszewski <brgl@kernel.org> wrote:
>
> On Wed, 27 May 2026 18:21:00 +0200, Chen-Yu Tsai <wenst@chromium.org> said:
> > On Tue, May 26, 2026 at 11:48 AM Bartosz Golaszewski <brgl@kernel.org> wrote:
> >>
> >> On Sun, May 24, 2026 at 10:06 AM Chen-Yu Tsai <wenst@chromium.org> wrote:
> >> >
> >> > > >
> >> > > > I expect some discussion on this patch, because a) it adds some
> >> > > > OF-specific code into an otherwise generic (core) driver, and
> >> > > > b) it doesn't yet handle USB 2.0 / 3.x shared ports; it ends up powering
> >> > > > on the port twice, which negates the port reset part.
> >> > > >
> >> > >
> >> > > I understand that you do this because the port device has no OF node
> >> > > assigned. If we wanted to call pwrseq_get() for the port device, is
> >> > > there really no other way to associate it with the correct pwrseq
> >> > > provider?
> >> >
> >> > I suppose we could tie the "port@X" node to the usb port device, but
> >> > AFAIK no other subsystem does this so we would be introducing a new
> >> > pattern.
> >> >
> >> > In the M.2 pwrseq driver, we would have to match by port node instead
> >> > of its parent device node. We may end up with different behavior for
> >> > the USB target vs the other targets.
> >> >
> >>
> >> I imagine, we can check the bus type of the parent device to know if
> >> this is USB?
> >
> > The "bus type" type is probably not exported. However since the DT binding
> > explicitly says which port on the M.2 slot is for which connection type,
> > I think the matching can do a special case check for the USB port.
> > The next obstacle is that the target string is not given to the provider
> > match function.
> >
> >> > Also, the "port@X" nodes only exist for the OF graph connections to
> >> > connectors and/or muxes (this series doesn't deal with the latter).
> >> > For directly connected devices, there is a "device@X" child node
> >> > directly under the USB hub node. That node is what gets tied to the
> >> > the USB device.
> >> >
> >>
> >> Is this a problem? I don't think I understand what you're saying here.
> >
> > It shouldn't be. I'm just saying there would be different behavior on
> > the USB side for connectors vs onboard devices (like hubs) device nodes.
> >
> > I talked to Greg earlier, and he said not to touch the hub driver; the
> > hub driver should only deal with features from the USB spec. The
> > "onboard USB devices" driver is what should be used. And this would
> > be a proper case of adding an auxiliary device to the M.2 slot driver.
> >
>
> The onboard USB device is what initially inspired the PCI pwrctl code so it
> doesn't surprise me we circle back to it.
>
> > However this seems to completely decouple the power sequencing from the
> > USB core. Take the USB A connector for example, it was recently added to
> > the onboard USB devices driver. However the connector has a device node
> > that is not a child node of any USB host controller or hub; it is connected
> > through OF graph. At the same time, since it typically sits at the top
> > level of the device tree, a platform device is directly created and the
> > driver subsequently binds to that device. This is totally different from
> > how the hub and other directly connected onboard USB devices work. In
> > the onboard device case, the device node is a child node of the USB hub
> > or controller, and the corresponding platform device only gets created
> > when the USB hub driver probes, thereby sort of tying it into the USB
> > device topology.
> >
>
> Which is precisely what we do for PCI pwrctl. Though I'm not sure how we could
> replicate this behavior without touching the hub driver.
>
> > If the power sequencing ends up not connected to the USB subsystem, then
> > maybe the M.2 slot driver could just check if the USB port (port@3) was
> > used, and just enable the USB / BT pwrseq target at probe time? That
> > would mean less changes needed.
> >
>
> That sounds sane to me.
Mani seems to be against this idea though, since as I mentioned it decouples
the timing of the power sequencing from the USB subsystem completely.
Ideally we want them to be linked.
So I will take a stab at option one for now, incorporating changes you
requested:
- Drop the pwrseq API change
- Use the firmware node API instead of the OF API
- Tie the usb_port device to the "port@N" node
And we'll see how the USB folks like or dislike it.
Thanks
ChenYu
^ permalink raw reply
* [PATCH net-next v9 6/6] net: airoha: Support multiple LAN/WAN interfaces for hw MAC address configuration
From: Lorenzo Bianconi @ 2026-06-03 6:00 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, Benjamin Larsson, linux-arm-kernel,
linux-mediatek, netdev, devicetree, Madhur Agrawal
In-Reply-To: <20260603-airoha-eth-multi-serdes-v9-0-5d476bc2f426@kernel.org>
The EN7581 and AN7583 SoCs provide registers to configure hardware LAN/WAN
MAC addresses. These registers are used during FE hw acceleration to
determine whether received traffic is destined to this host (L3 traffic)
or should be switched to another device (L2 traffic).
The SoC hardware design assumes all interfaces configured as LAN (or WAN)
share the MAC address MSBs, which are programmed into the
REG_FE_{LAN,WAN}_MAC_H register. The LSBs of 'local' mac addresses can be
expressed as a range via the REG_FE_MAC_LMIN and REG_FE_MAC_LMAX
registers. In order to properly accelerate the traffic, FE module requires
the user to configure the REG_FE_{LAN,WAN}_MAC_H register respecting this
limitation. Please note a misconfiguration in REG_FE_{LAN,WAN}_MAC_H
will still allow the user to log into the device for debugging.
Previously, only a single interface was considered when programming these
registers. Extend the logic to derive the correct minimum and maximum
values for REG_FE_MAC_LMIN/REG_FE_MAC_LMAX when two or more interfaces are
configured as LAN or WAN. Since this functionality was not available
before this series, no regression is introduced.
Tested-by: Madhur Agrawal <madhur.agrawal@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 77 ++++++++++++++++++++++++++++----
drivers/net/ethernet/airoha/airoha_eth.h | 2 +-
drivers/net/ethernet/airoha/airoha_ppe.c | 4 +-
3 files changed, 71 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 64ee526da241..8f2608293bb7 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -71,20 +71,76 @@ static void airoha_qdma_irq_disable(struct airoha_irq_bank *irq_bank,
airoha_qdma_set_irqmask(irq_bank, index, mask, 0);
}
-static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
+static int airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
{
+ u8 ref_addr[ETH_ALEN] __aligned(2);
struct airoha_eth *eth = dev->eth;
- u32 val, reg;
+ u32 reg, val, lmin, lmax;
+ int i;
+
+ eth_zero_addr(ref_addr);
+ lmin = (addr[3] << 16) | (addr[4] << 8) | addr[5];
+ lmax = lmin;
+
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
+ struct airoha_gdm_port *port = eth->ports[i];
+ int j;
+
+ if (!port)
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
+ struct airoha_gdm_dev *iter_dev;
+ struct net_device *netdev;
+
+ iter_dev = port->devs[j];
+ if (!iter_dev || iter_dev == dev)
+ continue;
+
+ if (airoha_is_lan_gdm_dev(iter_dev) !=
+ airoha_is_lan_gdm_dev(dev))
+ continue;
+
+ netdev = netdev_from_priv(iter_dev);
+ if (netdev->reg_state != NETREG_REGISTERED)
+ continue;
+
+ ether_addr_copy(ref_addr, netdev->dev_addr);
+ val = (netdev->dev_addr[3] << 16) |
+ (netdev->dev_addr[4] << 8) | netdev->dev_addr[5];
+ if (val < lmin)
+ lmin = val;
+ if (val > lmax)
+ lmax = val;
+ }
+ }
+
+ if (!is_zero_ether_addr(ref_addr) && memcmp(ref_addr, addr, 3)) {
+ /* According to the HW design, hw mac address MSBs must be
+ * the same for each net_device with the same LAN/WAN
+ * configuration.
+ */
+ struct net_device *netdev = netdev_from_priv(dev);
+
+ dev_warn(eth->dev,
+ "%s: wrong mac addr, MSBs must be %02x:%02x:%02x\n",
+ netdev->name, ref_addr[0], ref_addr[1],
+ ref_addr[2]);
+ dev_warn(eth->dev, "FE hw forwarding won't work properly\n");
+
+ return -EINVAL;
+ }
reg = airoha_is_lan_gdm_dev(dev) ? REG_FE_LAN_MAC_H : REG_FE_WAN_MAC_H;
val = (addr[0] << 16) | (addr[1] << 8) | addr[2];
airoha_fe_wr(eth, reg, val);
- val = (addr[3] << 16) | (addr[4] << 8) | addr[5];
- airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val);
- airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val);
+ airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), lmin);
+ airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), lmax);
- airoha_ppe_init_upd_mem(dev);
+ airoha_ppe_init_upd_mem(dev, addr);
+
+ return 0;
}
static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,
@@ -1826,13 +1882,18 @@ static int airoha_dev_stop(struct net_device *netdev)
static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct sockaddr *addr = p;
int err;
- err = eth_mac_addr(netdev, p);
+ err = eth_prepare_mac_addr_change(netdev, p);
if (err)
return err;
- airoha_set_macaddr(dev, netdev->dev_addr);
+ err = airoha_set_macaddr(dev, addr->sa_data);
+ if (err)
+ return err;
+
+ eth_commit_mac_addr_change(netdev, p);
return 0;
}
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 3e8262f583a7..8f42973f9cf5 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -683,7 +683,7 @@ void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
int airoha_ppe_setup_tc_block_cb(struct airoha_ppe_dev *dev, void *type_data);
int airoha_ppe_init(struct airoha_eth *eth);
void airoha_ppe_deinit(struct airoha_eth *eth);
-void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev);
+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev, const u8 *addr);
u32 airoha_ppe_get_total_num_entries(struct airoha_ppe *ppe);
struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe,
u32 hash);
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index f54622904733..91bcc55a6ac6 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -1487,12 +1487,10 @@ void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
airoha_ppe_foe_insert_entry(ppe, skb, hash, rx_wlan);
}
-void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev)
+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev, const u8 *addr)
{
- struct net_device *netdev = netdev_from_priv(dev);
struct airoha_gdm_port *port = dev->port;
struct airoha_eth *eth = dev->eth;
- const u8 *addr = netdev->dev_addr;
u32 val;
val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v9 5/6] net: airoha: Introduce WAN device flag
From: Lorenzo Bianconi @ 2026-06-03 6:00 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, Benjamin Larsson, linux-arm-kernel,
linux-mediatek, netdev, devicetree, Xuegang Lu
In-Reply-To: <20260603-airoha-eth-multi-serdes-v9-0-5d476bc2f426@kernel.org>
Introduce WAN flag to specify if a given device is used to transmit/receive
WAN or LAN traffic. Current codebase supports specifying LAN/WAN device
configuration in ndo_init() callback during device bootstrap.
In order to consider setups where LAN configuration is used even for
GDM3/GDM4 devices, check airoha_is_lan_gdm_dev() to select pse_port in
airoha_ppe_foe_entry_prepare().
Please note after this patch, it will be possible to specify multiple LAN
devices but just a single WAN one. Please note this change is not visible
to the user since airoha_eth driver currently supports just the internal
phy available via the MT7530 DSA switch and there are no WAN interfaces
officially supported since PCS/external phy is not merged mainline yet
(it will be posted with following patches).
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 73 ++++++++++++++++++++++++++------
drivers/net/ethernet/airoha/airoha_eth.h | 13 +++---
drivers/net/ethernet/airoha/airoha_ppe.c | 2 +-
3 files changed, 66 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 44b77a5cc4c5..64ee526da241 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1899,36 +1899,81 @@ static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev)
return 0;
}
-static int airoha_dev_init(struct net_device *netdev)
+static struct airoha_gdm_dev *
+airoha_get_wan_gdm_dev(struct airoha_eth *eth)
{
- struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
+ struct airoha_gdm_port *port = eth->ports[i];
+ int j;
+
+ if (!port)
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
+ struct airoha_gdm_dev *dev = port->devs[j];
+
+ if (dev && !airoha_is_lan_gdm_dev(dev))
+ return dev;
+ }
+ }
+
+ return NULL;
+}
+
+static void airoha_dev_set_qdma(struct airoha_gdm_dev *dev)
+{
+ struct net_device *netdev = netdev_from_priv(dev);
struct airoha_eth *eth = dev->eth;
int ppe_id;
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)];
netdev->irq = dev->qdma->irq_banks[0].irq;
- airoha_set_macaddr(dev, netdev->dev_addr);
+
+ ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1);
+ airoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev));
+}
+
+static int airoha_dev_init(struct net_device *netdev)
+{
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
switch (port->id) {
case AIROHA_GDM3_IDX:
- case AIROHA_GDM4_IDX:
- /* If GDM2 is active we can't enable loopback */
- if (!eth->ports[1]) {
- int err;
+ case AIROHA_GDM4_IDX: {
+ struct airoha_eth *eth = dev->eth;
- err = airoha_enable_gdm2_loopback(dev);
- if (err)
- return err;
- }
+ /* GDM2 supports a single net_device */
+ if (eth->ports[1] && eth->ports[1]->devs[0])
+ break;
+
+ if (airoha_get_wan_gdm_dev(eth))
+ break;
+
+ fallthrough;
+ }
+ case AIROHA_GDM2_IDX:
+ /* GDM2 is always used as wan */
+ dev->flags |= AIROHA_PRIV_F_WAN;
break;
default:
break;
}
- ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1);
- airoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev));
+ airoha_dev_set_qdma(dev);
+ airoha_set_macaddr(dev, netdev->dev_addr);
+
+ if (!airoha_is_lan_gdm_dev(dev) &&
+ (port->id == AIROHA_GDM3_IDX || port->id == AIROHA_GDM4_IDX)) {
+ int err;
+
+ err = airoha_enable_gdm2_loopback(dev);
+ if (err)
+ return err;
+ }
return 0;
}
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 666e9246e70e..3e8262f583a7 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -538,6 +538,10 @@ struct airoha_qdma {
DECLARE_BITMAP(qos_channel_map, AIROHA_NUM_QOS_CHANNELS);
};
+enum airoha_priv_flags {
+ AIROHA_PRIV_F_WAN = BIT(0),
+};
+
struct airoha_gdm_dev {
struct airoha_gdm_port *port;
struct airoha_qdma *qdma;
@@ -548,6 +552,7 @@ struct airoha_gdm_dev {
u64 cpu_tx_packets;
u64 fwd_tx_packets;
+ u32 flags;
int nbq;
};
@@ -654,13 +659,7 @@ static inline u16 airoha_qdma_get_txq(struct airoha_qdma *qdma, u16 qid)
static inline bool airoha_is_lan_gdm_dev(struct airoha_gdm_dev *dev)
{
- struct airoha_gdm_port *port = dev->port;
-
- /* GDM1 port on EN7581 SoC is connected to the lan dsa switch.
- * GDM{2,3,4} can be used as wan port connected to an external
- * phy module.
- */
- return port->id == 1;
+ return !(dev->flags & AIROHA_PRIV_F_WAN);
}
static inline bool airoha_is_7581(struct airoha_eth *eth)
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 96abf451fdac..f54622904733 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -355,7 +355,7 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
return -EINVAL;
port = dev->port;
- if (dsa_port >= 0 || eth->ports[1])
+ if (dsa_port >= 0 || airoha_is_lan_gdm_dev(dev))
pse_port = port->id == 4 ? FE_PSE_PORT_GDM4
: port->id;
else
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v9 4/6] net: airoha: Do not stop GDM port if it is shared
From: Lorenzo Bianconi @ 2026-06-03 6:00 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, Benjamin Larsson, linux-arm-kernel,
linux-mediatek, netdev, devicetree, Xuegang Lu
In-Reply-To: <20260603-airoha-eth-multi-serdes-v9-0-5d476bc2f426@kernel.org>
Theoretically, in the current codebase, two independent net_devices can
be connected to the same GDM port so we need to check the GDM port is not
used by any other running net_device before setting the forward
configuration to FE_PSE_PORT_DROP.
Moreover, always set in GDM_LONG_LEN_MASK field of REG_GDM_LEN_CFG
register the maximum MTU of all running net_devices connected to the same
GDM port.
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 59 +++++++++++++++++++++++++-------
drivers/net/ethernet/airoha/airoha_eth.h | 1 +
2 files changed, 48 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 1d088d95d5fb..44b77a5cc4c5 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1720,8 +1720,8 @@ static int airoha_dev_open(struct net_device *netdev)
int err, len = ETH_HLEN + netdev->mtu + ETH_FCS_LEN;
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_gdm_port *port = dev->port;
+ u32 cur_len, pse_port = FE_PSE_PORT_PPE1;
struct airoha_qdma *qdma = dev->qdma;
- u32 pse_port = FE_PSE_PORT_PPE1;
netif_tx_start_all_queues(netdev);
err = airoha_set_vip_for_gdm_port(dev, true);
@@ -1735,10 +1735,20 @@ static int airoha_dev_open(struct net_device *netdev)
airoha_fe_clear(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
GDM_STAG_EN_MASK);
- airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id),
- GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
- FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
- FIELD_PREP(GDM_LONG_LEN_MASK, len));
+ cur_len = airoha_fe_get(qdma->eth, REG_GDM_LEN_CFG(port->id),
+ GDM_LONG_LEN_MASK);
+ if (!port->users || len > cur_len) {
+ /* Opening a sibling net_device with a larger MTU updates the
+ * MTU of already running devices. This is required to allow
+ * multiple net_devices with different MTUs to share the same
+ * GDM port.
+ */
+ airoha_fe_rmw(qdma->eth, REG_GDM_LEN_CFG(port->id),
+ GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
+ FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
+ FIELD_PREP(GDM_LONG_LEN_MASK, len));
+ }
+ port->users++;
airoha_qdma_set(qdma, REG_QDMA_GLOBAL_CFG,
GLOBAL_CFG_TX_DMA_EN_MASK |
@@ -1754,6 +1764,30 @@ static int airoha_dev_open(struct net_device *netdev)
return 0;
}
+static void airoha_set_port_mtu(struct airoha_eth *eth,
+ struct airoha_gdm_port *port)
+{
+ u32 len = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(port->devs); i++) {
+ struct airoha_gdm_dev *dev = port->devs[i];
+ struct net_device *netdev;
+
+ if (!dev)
+ continue;
+
+ netdev = netdev_from_priv(dev);
+ if (netif_running(netdev))
+ len = max_t(u32, len, netdev->mtu);
+ }
+ len += ETH_HLEN + ETH_FCS_LEN;
+
+ airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
+ GDM_LONG_LEN_MASK,
+ FIELD_PREP(GDM_LONG_LEN_MASK, len));
+}
+
static int airoha_dev_stop(struct net_device *netdev)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
@@ -1766,8 +1800,12 @@ static int airoha_dev_stop(struct net_device *netdev)
for (i = 0; i < netdev->num_tx_queues; i++)
netdev_tx_reset_subqueue(netdev, i);
- airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
- FE_PSE_PORT_DROP);
+ if (--port->users)
+ airoha_set_port_mtu(dev->eth, port);
+ else
+ airoha_set_gdm_port_fwd_cfg(qdma->eth,
+ REG_GDM_FWD_CFG(port->id),
+ FE_PSE_PORT_DROP);
if (atomic_dec_and_test(&qdma->users)) {
airoha_qdma_clear(qdma, REG_QDMA_GLOBAL_CFG,
@@ -1922,13 +1960,10 @@ static int airoha_dev_change_mtu(struct net_device *netdev, int mtu)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_gdm_port *port = dev->port;
- u32 len = ETH_HLEN + mtu + ETH_FCS_LEN;
- struct airoha_eth *eth = dev->eth;
- airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
- GDM_LONG_LEN_MASK,
- FIELD_PREP(GDM_LONG_LEN_MASK, len));
WRITE_ONCE(netdev->mtu, mtu);
+ if (port->users)
+ airoha_set_port_mtu(dev->eth, port);
return 0;
}
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 92fd81bb9269..666e9246e70e 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -554,6 +554,7 @@ struct airoha_gdm_dev {
struct airoha_gdm_port {
struct airoha_gdm_dev *devs[AIROHA_MAX_NUM_GDM_DEVS];
int id;
+ int users;
struct airoha_hw_stats stats;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v9 3/6] net: airoha: Support multiple net_devices for a single FE GDM port
From: Lorenzo Bianconi @ 2026-06-03 6:00 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, Benjamin Larsson, linux-arm-kernel,
linux-mediatek, netdev, devicetree, Xuegang Lu
In-Reply-To: <20260603-airoha-eth-multi-serdes-v9-0-5d476bc2f426@kernel.org>
EN7581 or AN7583 SoCs support connecting multiple external SerDes (e.g.
Ethernet or USB SerDes) to GDM3 or GDM4 ports via a hw arbiter that
manages the traffic in a TDM manner. As a result multiple net_devices can
connect to the same GDM{3,4} port and there is a theoretical "1:n"
relation between GDM ports and net_devices.
┌─────────────────────────────────┐
│ │ ┌──────┐
│ P1 GDM1 ├────►MT7530│
│ │ └──────┘
│ │ ETH0 (DSA conduit)
│ │
│ PSE/FE │
│ │
│ │
│ │ ┌─────┐
│ P0 CDM1 ├────►QDMA0│
│ P4 P9 GDM4 │ └─────┘
└──┬─────────────────────────┬────┘
│ │
┌──▼──┐ ┌────▼────┐
│ PPE │ │ ARB │
└─────┘ └─┬─────┬─┘
│ │
┌──▼──┐┌─▼───┐
│ ETH ││ USB │
└─────┘└─────┘
ETH1 ETH2
Introduce support for multiple net_devices connected to the same Frame
Engine (FE) GDM port (GDM3 or GDM4) via an external hw arbiter.
Please note GDM1 or GDM2 does not support the connection with the external
arbiter.
Add get_dev_from_sport callback since EN7581 and AN7583 have different
logics for the net_device type connected to GDM3 or GDM4.
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 280 +++++++++++++++++++++++--------
drivers/net/ethernet/airoha/airoha_eth.h | 8 +-
drivers/net/ethernet/airoha/airoha_ppe.c | 26 ++-
3 files changed, 237 insertions(+), 77 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 57a16de0a2ec..1d088d95d5fb 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -106,7 +106,7 @@ static int airoha_set_vip_for_gdm_port(struct airoha_gdm_dev *dev, bool enable)
struct airoha_eth *eth = dev->eth;
u32 vip_port;
- vip_port = eth->soc->ops.get_vip_port(port, port->nbq);
+ vip_port = eth->soc->ops.get_vip_port(port, dev->nbq);
if (enable) {
airoha_fe_set(eth, REG_FE_VIP_PORT_EN, vip_port);
airoha_fe_set(eth, REG_FE_IFC_PORT_EN, vip_port);
@@ -566,24 +566,26 @@ static int airoha_qdma_fill_rx_queue(struct airoha_queue *q)
return nframes;
}
-static int airoha_qdma_get_gdm_port(struct airoha_eth *eth,
- struct airoha_qdma_desc *desc)
+static struct airoha_gdm_dev *
+airoha_qdma_get_gdm_dev(struct airoha_eth *eth, struct airoha_qdma_desc *desc)
{
- u32 port, sport, msg1 = le32_to_cpu(READ_ONCE(desc->msg1));
+ struct airoha_gdm_port *port;
+ u16 p, d;
- sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK, msg1);
- switch (sport) {
- case 0x10 ... 0x14:
- port = 0;
- break;
- case 0x2 ... 0x4:
- port = sport - 1;
- break;
- default:
- return -EINVAL;
- }
+ if (eth->soc->ops.get_dev_from_sport(desc, &p, &d))
+ return ERR_PTR(-ENODEV);
- return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port;
+ if (p >= ARRAY_SIZE(eth->ports))
+ return ERR_PTR(-ENODEV);
+
+ port = eth->ports[p];
+ if (!port)
+ return ERR_PTR(-ENODEV);
+
+ if (d >= ARRAY_SIZE(port->devs))
+ return ERR_PTR(-ENODEV);
+
+ return port->devs[d] ? port->devs[d] : ERR_PTR(-ENODEV);
}
static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
@@ -598,9 +600,9 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
struct airoha_queue_entry *e = &q->entry[q->tail];
struct airoha_qdma_desc *desc = &q->desc[q->tail];
u32 hash, reason, msg1, desc_ctrl;
- struct airoha_gdm_port *port;
+ struct airoha_gdm_dev *dev;
struct net_device *netdev;
- int data_len, len, p;
+ int data_len, len;
struct page *page;
desc_ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
@@ -621,15 +623,11 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
if (!len || data_len < len)
goto free_frag;
- p = airoha_qdma_get_gdm_port(eth, desc);
- if (p < 0 || !eth->ports[p])
+ dev = airoha_qdma_get_gdm_dev(eth, desc);
+ if (IS_ERR(dev))
goto free_frag;
- port = eth->ports[p];
- if (!port->dev)
- goto free_frag;
-
- netdev = netdev_from_priv(port->dev);
+ netdev = netdev_from_priv(dev);
if (!q->skb) { /* first buffer */
q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM,
q->buf_size);
@@ -659,6 +657,8 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
continue;
if (netdev_uses_dsa(netdev)) {
+ struct airoha_gdm_port *port = dev->port;
+
/* PPE module requires untagged packets to work
* properly and it provides DSA port index via the
* DMA descriptor. Report DSA tag to the DSA stack
@@ -852,26 +852,29 @@ static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
- struct airoha_gdm_dev *dev;
- struct net_device *netdev;
- int j;
+ int d;
if (!port)
continue;
- dev = port->dev;
- if (!dev)
- continue;
+ for (d = 0; d < ARRAY_SIZE(port->devs); d++) {
+ struct airoha_gdm_dev *dev = port->devs[d];
+ struct net_device *netdev;
+ int j;
- if (dev->qdma != qdma)
- continue;
+ if (!dev)
+ continue;
- netdev = netdev_from_priv(dev);
- for (j = 0; j < netdev->num_tx_queues; j++) {
- if (airoha_qdma_get_txq(qdma, j) != qid)
+ if (dev->qdma != qdma)
continue;
- netif_wake_subqueue(netdev, j);
+ netdev = netdev_from_priv(dev);
+ for (j = 0; j < netdev->num_tx_queues; j++) {
+ if (airoha_qdma_get_txq(qdma, j) != qid)
+ continue;
+
+ netif_wake_subqueue(netdev, j);
+ }
}
}
q->txq_stopped = false;
@@ -1742,11 +1745,9 @@ static int airoha_dev_open(struct net_device *netdev)
GLOBAL_CFG_RX_DMA_EN_MASK);
atomic_inc(&qdma->users);
- if (port->id == AIROHA_GDM2_IDX &&
- airoha_ppe_is_enabled(qdma->eth, 1)) {
- /* For PPE2 always use secondary cpu port. */
+ if (!airoha_is_lan_gdm_dev(dev) &&
+ airoha_ppe_is_enabled(qdma->eth, 1))
pse_port = FE_PSE_PORT_PPE2;
- }
airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
pse_port);
@@ -1834,7 +1835,7 @@ static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev)
airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(AIROHA_GDM2_IDX));
airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(AIROHA_GDM2_IDX));
- src_port = eth->soc->ops.get_sport(port, port->nbq);
+ src_port = eth->soc->ops.get_sport(port, dev->nbq);
if (src_port < 0)
return src_port;
@@ -1851,7 +1852,7 @@ static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev)
airoha_ppe_set_cpu_port(dev, i, AIROHA_GDM2_IDX);
if (port->id == AIROHA_GDM4_IDX && airoha_is_7581(eth)) {
- u32 mask = FC_ID_OF_SRC_PORT_MASK(port->nbq);
+ u32 mask = FC_ID_OF_SRC_PORT_MASK(dev->nbq);
airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, mask,
__field_prep(mask, AIROHA_GDM2_IDX));
@@ -1865,7 +1866,7 @@ static int airoha_dev_init(struct net_device *netdev)
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_gdm_port *port = dev->port;
struct airoha_eth *eth = dev->eth;
- int i;
+ int ppe_id;
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)];
@@ -1888,8 +1889,8 @@ static int airoha_dev_init(struct net_device *netdev)
break;
}
- for (i = 0; i < eth->soc->num_ppe; i++)
- airoha_ppe_set_cpu_port(dev, i, airoha_get_fe_port(dev));
+ ppe_id = !airoha_is_lan_gdm_dev(dev) && airoha_ppe_is_enabled(eth, 1);
+ airoha_ppe_set_cpu_port(dev, ppe_id, airoha_get_fe_port(dev));
return 0;
}
@@ -2055,7 +2056,8 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
}
fport = airoha_get_fe_port(dev);
- msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
+ msg1 = FIELD_PREP(QDMA_ETH_TXMSG_NBOQ_MASK, dev->nbq) |
+ FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
q = &qdma->q_tx[qid];
@@ -2985,12 +2987,15 @@ bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
+ int j;
if (!port)
continue;
- if (port->dev == dev)
- return true;
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
+ if (port->devs[j] == dev)
+ return true;
+ }
}
return false;
@@ -2998,10 +3003,11 @@ bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
static int airoha_alloc_gdm_device(struct airoha_eth *eth,
struct airoha_gdm_port *port,
- struct device_node *np)
+ int nbq, struct device_node *np)
{
- struct airoha_gdm_dev *dev;
struct net_device *netdev;
+ struct airoha_gdm_dev *dev;
+ u8 index;
int err;
netdev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*dev),
@@ -3021,7 +3027,6 @@ static int airoha_alloc_gdm_device(struct airoha_eth *eth,
NETIF_F_HW_TC;
netdev->features |= netdev->hw_features;
netdev->vlan_features = netdev->hw_features;
- netdev->dev.of_node = np;
SET_NETDEV_DEV(netdev, eth->dev);
/* reserve hw queues for HTB offloading */
@@ -3039,10 +3044,24 @@ static int airoha_alloc_gdm_device(struct airoha_eth *eth,
netdev->dev_addr);
}
+ /* Allowed nbq for EN7581 on GDM3 port are 4 and 5 for PCIE0
+ * and PCIE1 respectively.
+ */
+ index = nbq;
+ if (index && airoha_is_7581(eth) && port->id == AIROHA_GDM3_IDX)
+ index -= 4;
+
+ if (index >= ARRAY_SIZE(port->devs) || port->devs[index]) {
+ dev_err(eth->dev, "invalid nbq id: %d\n", nbq);
+ return -EINVAL;
+ }
+
+ netdev->dev.of_node = of_node_get(np);
dev = netdev_priv(netdev);
dev->port = port;
- port->dev = dev;
dev->eth = eth;
+ dev->nbq = nbq;
+ port->devs[index] = dev;
return 0;
}
@@ -3052,7 +3071,8 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
{
const __be32 *id_ptr = of_get_property(np, "reg", NULL);
struct airoha_gdm_port *port;
- int err, p;
+ struct device_node *node;
+ int err, nbq, p, d = 0;
u32 id;
if (!id_ptr) {
@@ -3080,15 +3100,51 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
u64_stats_init(&port->stats.syncp);
spin_lock_init(&port->stats.lock);
port->id = id;
- /* XXX: Read nbq from DTS */
- port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
eth->ports[p] = port;
err = airoha_metadata_dst_alloc(port);
if (err)
return err;
- return airoha_alloc_gdm_device(eth, port, np);
+ /* Default nbq value to ensure backward compatibility */
+ nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
+
+ for_each_child_of_node(np, node) {
+ /* Multiple external serdes connected to the FE GDM port via an
+ * external arbiter.
+ */
+ const __be32 *nbq_ptr;
+
+ if (!of_device_is_compatible(node, "airoha,eth-port"))
+ continue;
+
+ d++;
+ if (!of_device_is_available(node))
+ continue;
+
+ nbq_ptr = of_get_property(node, "reg", NULL);
+ if (!nbq_ptr) {
+ dev_err(eth->dev, "missing nbq id\n");
+ of_node_put(node);
+ return -EINVAL;
+ }
+
+ /* Verify the provided nbq parameter is valid */
+ nbq = be32_to_cpup(nbq_ptr);
+ err = eth->soc->ops.get_sport(port, nbq);
+ if (err < 0) {
+ of_node_put(node);
+ return err;
+ }
+
+ err = airoha_alloc_gdm_device(eth, port, nbq, node);
+ if (err) {
+ of_node_put(node);
+ return err;
+ }
+ }
+
+ return !d ? airoha_alloc_gdm_device(eth, port, nbq, np) : 0;
}
static int airoha_register_gdm_devices(struct airoha_eth *eth)
@@ -3097,14 +3153,22 @@ static int airoha_register_gdm_devices(struct airoha_eth *eth)
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
- int err;
+ int j;
if (!port)
continue;
- err = register_netdev(netdev_from_priv(port->dev));
- if (err)
- return err;
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
+ struct airoha_gdm_dev *dev = port->devs[j];
+ int err;
+
+ if (!dev)
+ continue;
+
+ err = register_netdev(netdev_from_priv(dev));
+ if (err)
+ return err;
+ }
}
set_bit(DEV_STATE_REGISTERED, ð->state);
@@ -3211,17 +3275,22 @@ static int airoha_probe(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
- struct airoha_gdm_dev *dev;
+ int j;
if (!port)
continue;
- dev = port->dev;
- if (dev) {
- struct net_device *netdev = netdev_from_priv(dev);
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
+ struct airoha_gdm_dev *dev = port->devs[j];
+ struct net_device *netdev;
+
+ if (!dev)
+ continue;
+ netdev = netdev_from_priv(dev);
if (netdev->reg_state == NETREG_REGISTERED)
unregister_netdev(netdev);
+ of_node_put(netdev->dev.of_node);
}
airoha_metadata_dst_free(port);
}
@@ -3243,14 +3312,22 @@ static void airoha_remove(struct platform_device *pdev)
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
- struct airoha_gdm_dev *dev;
+ int j;
if (!port)
continue;
- dev = port->dev;
- if (dev)
- unregister_netdev(netdev_from_priv(dev));
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
+ struct airoha_gdm_dev *dev = port->devs[j];
+ struct net_device *netdev;
+
+ if (!dev)
+ continue;
+
+ netdev = netdev_from_priv(dev);
+ unregister_netdev(netdev);
+ of_node_put(netdev->dev.of_node);
+ }
airoha_metadata_dst_free(port);
}
airoha_hw_cleanup(eth);
@@ -3313,6 +3390,39 @@ static u32 airoha_en7581_get_vip_port(struct airoha_gdm_port *port, int nbq)
return 0;
}
+static int airoha_en7581_get_dev_from_sport(struct airoha_qdma_desc *desc,
+ u16 *port, u16 *dev)
+{
+ u32 sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK,
+ le32_to_cpu(READ_ONCE(desc->msg1)));
+
+ *dev = 0;
+ switch (sport) {
+ case 0x10 ... 0x14:
+ *port = 0; /* GDM1 */
+ break;
+ case 0x2 ... 0x4:
+ *port = sport - 1;
+ break;
+ case HSGMII_LAN_7581_PCIE1_SRCPORT:
+ *dev = 1;
+ fallthrough;
+ case HSGMII_LAN_7581_PCIE0_SRCPORT:
+ *port = 2; /* GDM3 */
+ break;
+ case HSGMII_LAN_7581_USB_SRCPORT:
+ *dev = 1;
+ fallthrough;
+ case HSGMII_LAN_7581_ETH_SRCPORT:
+ *port = 3; /* GDM4 */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const char * const an7583_xsi_rsts_names[] = {
"xsi-mac",
"hsi0-mac",
@@ -3362,6 +3472,36 @@ static u32 airoha_an7583_get_vip_port(struct airoha_gdm_port *port, int nbq)
return 0;
}
+static int airoha_an7583_get_dev_from_sport(struct airoha_qdma_desc *desc,
+ u16 *port, u16 *dev)
+{
+ u32 sport = FIELD_GET(QDMA_ETH_RXMSG_SPORT_MASK,
+ le32_to_cpu(READ_ONCE(desc->msg1)));
+
+ *dev = 0;
+ switch (sport) {
+ case 0x10 ... 0x14:
+ *port = 0; /* GDM1 */
+ break;
+ case 0x2 ... 0x4:
+ *port = sport - 1;
+ break;
+ case HSGMII_LAN_7583_ETH_SRCPORT:
+ *port = 2; /* GDM3 */
+ break;
+ case HSGMII_LAN_7583_USB_SRCPORT:
+ *dev = 1;
+ fallthrough;
+ case HSGMII_LAN_7583_PCIE_SRCPORT:
+ *port = 3; /* GDM4 */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const struct airoha_eth_soc_data en7581_soc_data = {
.version = 0x7581,
.xsi_rsts_names = en7581_xsi_rsts_names,
@@ -3370,6 +3510,7 @@ static const struct airoha_eth_soc_data en7581_soc_data = {
.ops = {
.get_sport = airoha_en7581_get_sport,
.get_vip_port = airoha_en7581_get_vip_port,
+ .get_dev_from_sport = airoha_en7581_get_dev_from_sport,
},
};
@@ -3381,6 +3522,7 @@ static const struct airoha_eth_soc_data an7583_soc_data = {
.ops = {
.get_sport = airoha_an7583_get_sport,
.get_vip_port = airoha_an7583_get_vip_port,
+ .get_dev_from_sport = airoha_an7583_get_dev_from_sport,
},
};
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index 1f162fa1405e..92fd81bb9269 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -17,6 +17,7 @@
#include <net/dsa.h>
#define AIROHA_MAX_NUM_GDM_PORTS 4
+#define AIROHA_MAX_NUM_GDM_DEVS 2
#define AIROHA_MAX_NUM_QDMA 2
#define AIROHA_MAX_NUM_IRQ_BANKS 4
#define AIROHA_MAX_DSA_PORTS 7
@@ -546,12 +547,13 @@ struct airoha_gdm_dev {
/* qos stats counters */
u64 cpu_tx_packets;
u64 fwd_tx_packets;
+
+ int nbq;
};
struct airoha_gdm_port {
- struct airoha_gdm_dev *dev;
+ struct airoha_gdm_dev *devs[AIROHA_MAX_NUM_GDM_DEVS];
int id;
- int nbq;
struct airoha_hw_stats stats;
@@ -587,6 +589,8 @@ struct airoha_eth_soc_data {
struct {
int (*get_sport)(struct airoha_gdm_port *port, int nbq);
u32 (*get_vip_port)(struct airoha_gdm_port *port, int nbq);
+ int (*get_dev_from_sport)(struct airoha_qdma_desc *desc,
+ u16 *port, u16 *dev);
} ops;
};
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index c9711bb7ef1c..96abf451fdac 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -167,9 +167,7 @@ static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
airoha_fe_clear(eth, REG_PPE_PPE_FLOW_CFG(i),
PPE_FLOW_CFG_IP6_6RD_MASK);
- for (p = 0; p < ARRAY_SIZE(eth->ports); p++) {
- struct airoha_gdm_port *port = eth->ports[p];
-
+ for (p = 0; p < ARRAY_SIZE(eth->ports); p++)
airoha_fe_rmw(eth, REG_PPE_MTU(i, p),
FP0_EGRESS_MTU_MASK |
FP1_EGRESS_MTU_MASK,
@@ -177,11 +175,27 @@ static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
AIROHA_MAX_MTU) |
FIELD_PREP(FP1_EGRESS_MTU_MASK,
AIROHA_MAX_MTU));
- if (!port)
+ }
+
+ for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
+ struct airoha_gdm_port *port = eth->ports[i];
+ int j;
+
+ if (!port)
+ continue;
+
+ for (j = 0; j < ARRAY_SIZE(port->devs); j++) {
+ struct airoha_gdm_dev *dev = port->devs[j];
+ int ppe_id;
+ u8 fport;
+
+ if (!dev)
continue;
- airoha_ppe_set_cpu_port(port->dev, i,
- airoha_get_fe_port(port->dev));
+ ppe_id = !airoha_is_lan_gdm_dev(dev) &&
+ airoha_ppe_is_enabled(eth, 1);
+ fport = airoha_get_fe_port(dev);
+ airoha_ppe_set_cpu_port(dev, ppe_id, fport);
}
}
}
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v9 2/6] net: airoha: Remove private net_device pointer in airoha_gdm_dev struct
From: Lorenzo Bianconi @ 2026-06-03 6:00 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, Benjamin Larsson, linux-arm-kernel,
linux-mediatek, netdev, devicetree
In-Reply-To: <20260603-airoha-eth-multi-serdes-v9-0-5d476bc2f426@kernel.org>
Remove redundant net_device pointer inside airoha_gdm_dev struct and
rely on netdev_from_priv routine instead. Please note this patch does
not introduce any logical change, just code refactoring.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 23 ++++++++++++++---------
drivers/net/ethernet/airoha/airoha_eth.h | 1 -
drivers/net/ethernet/airoha/airoha_ppe.c | 2 +-
3 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 6574901ebd19..57a16de0a2ec 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -629,7 +629,7 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
if (!port->dev)
goto free_frag;
- netdev = port->dev->dev;
+ netdev = netdev_from_priv(port->dev);
if (!q->skb) { /* first buffer */
q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM,
q->buf_size);
@@ -853,6 +853,7 @@ static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
struct airoha_gdm_port *port = eth->ports[i];
struct airoha_gdm_dev *dev;
+ struct net_device *netdev;
int j;
if (!port)
@@ -865,11 +866,12 @@ static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)
if (dev->qdma != qdma)
continue;
- for (j = 0; j < dev->dev->num_tx_queues; j++) {
+ netdev = netdev_from_priv(dev);
+ for (j = 0; j < netdev->num_tx_queues; j++) {
if (airoha_qdma_get_txq(qdma, j) != qid)
continue;
- netif_wake_subqueue(dev->dev, j);
+ netif_wake_subqueue(netdev, j);
}
}
q->txq_stopped = false;
@@ -1867,7 +1869,7 @@ static int airoha_dev_init(struct net_device *netdev)
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)];
- dev->dev->irq = dev->qdma->irq_banks[0].irq;
+ netdev->irq = dev->qdma->irq_banks[0].irq;
airoha_set_macaddr(dev, netdev->dev_addr);
switch (port->id) {
@@ -3038,7 +3040,6 @@ static int airoha_alloc_gdm_device(struct airoha_eth *eth,
}
dev = netdev_priv(netdev);
- dev->dev = netdev;
dev->port = port;
port->dev = dev;
dev->eth = eth;
@@ -3101,7 +3102,7 @@ static int airoha_register_gdm_devices(struct airoha_eth *eth)
if (!port)
continue;
- err = register_netdev(port->dev->dev);
+ err = register_netdev(netdev_from_priv(port->dev));
if (err)
return err;
}
@@ -3216,8 +3217,12 @@ static int airoha_probe(struct platform_device *pdev)
continue;
dev = port->dev;
- if (dev && dev->dev->reg_state == NETREG_REGISTERED)
- unregister_netdev(dev->dev);
+ if (dev) {
+ struct net_device *netdev = netdev_from_priv(dev);
+
+ if (netdev->reg_state == NETREG_REGISTERED)
+ unregister_netdev(netdev);
+ }
airoha_metadata_dst_free(port);
}
airoha_hw_cleanup(eth);
@@ -3245,7 +3250,7 @@ static void airoha_remove(struct platform_device *pdev)
dev = port->dev;
if (dev)
- unregister_netdev(dev->dev);
+ unregister_netdev(netdev_from_priv(dev));
airoha_metadata_dst_free(port);
}
airoha_hw_cleanup(eth);
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index fbb50dc73af8..1f162fa1405e 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -540,7 +540,6 @@ struct airoha_qdma {
struct airoha_gdm_dev {
struct airoha_gdm_port *port;
struct airoha_qdma *qdma;
- struct net_device *dev;
struct airoha_eth *eth;
DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 047141b2d6d8..c9711bb7ef1c 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -1475,8 +1475,8 @@ void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev)
{
+ struct net_device *netdev = netdev_from_priv(dev);
struct airoha_gdm_port *port = dev->port;
- struct net_device *netdev = dev->dev;
struct airoha_eth *eth = dev->eth;
const u8 *addr = netdev->dev_addr;
u32 val;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v9 1/6] dt-bindings: net: airoha: Add GDM port ethernet child node
From: Lorenzo Bianconi @ 2026-06-03 6:00 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, Benjamin Larsson, linux-arm-kernel,
linux-mediatek, netdev, devicetree
In-Reply-To: <20260603-airoha-eth-multi-serdes-v9-0-5d476bc2f426@kernel.org>
EN7581 and AN7583 SoCs support connecting multiple external SerDes to GDM3
or GDM4 ports via a hw arbiter that manages the traffic in a TDM manner.
As a result multiple net_devices can connect to the same GDM{3,4} port
and there is a theoretical "1:n" relation between GDM ports and
net_devices.
Introduce the ethernet node child of a specific GDM port in order to model
a given net_device that is connected via the external arbiter to the
GDM{3,4} port. This new ethernet node is defined by the "airoha,eth-port"
compatible string. Please note GDM1 and GDM2 does not support the
connection with the external arbiter and they are represented by an
ethernet node defined by the "airoha,eth-mac" compatible string.
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
.../devicetree/bindings/net/airoha,en7581-eth.yaml | 56 +++++++++++++++++++++-
1 file changed, 55 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml b/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
index fbe2ddcdd909..17fe2edf4886 100644
--- a/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
+++ b/Documentation/devicetree/bindings/net/airoha,en7581-eth.yaml
@@ -130,6 +130,42 @@ patternProperties:
maximum: 4
description: GMAC port identifier
+ allOf:
+ - if:
+ properties:
+ reg:
+ contains:
+ items:
+ - enum:
+ - 3
+ - 4
+ then:
+ properties:
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ patternProperties:
+ "^ethernet@[0-5]$":
+ type: object
+ unevaluatedProperties: false
+ $ref: ethernet-controller.yaml#
+ description: External ethernet port ID available on the GDM port
+
+ properties:
+ compatible:
+ const: airoha,eth-port
+
+ reg:
+ maximum: 5
+ description: External ethernet port identifier
+
+ required:
+ - reg
+ - compatible
+
required:
- reg
- compatible
@@ -191,9 +227,27 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
- mac: ethernet@1 {
+ ethernet@1 {
compatible = "airoha,eth-mac";
reg = <1>;
};
+
+ ethernet@4 {
+ compatible = "airoha,eth-mac";
+ reg = <4>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet@0 {
+ compatible = "airoha,eth-port";
+ reg = <0>;
+ };
+
+ ethernet@1 {
+ compatible = "airoha,eth-port";
+ reg = <1>;
+ };
+ };
};
};
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v9 0/6] net: airoha: Support multiple net_devices connected to the same GDM port
From: Lorenzo Bianconi @ 2026-06-03 6:00 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Lorenzo Bianconi
Cc: Christian Marangi, Benjamin Larsson, linux-arm-kernel,
linux-mediatek, netdev, devicetree, Xuegang Lu, Madhur Agrawal
EN7581 or AN7583 SoCs support connecting multiple external SerDes (e.g.
Ethernet or USB SerDes) to GDM3 or GDM4 ports via a hw arbiter that
manages the traffic in a TDM manner. As a result multiple net_devices can
connect to the same GDM{3,4} port and there is a theoretical "1:n"
relation between GDM ports and net_devices.
┌─────────────────────────────────┐
│ │ ┌──────┐
│ P1 GDM1 ├────►MT7530│
│ │ └──────┘
│ │ ETH0 (DSA conduit)
│ │
│ PSE/FE │
│ │
│ │
│ │ ┌─────┐
│ P0 CDM1 ├────►QDMA0│
│ P4 P9 GDM4 │ └─────┘
└──┬─────────────────────────┬────┘
│ │
┌──▼──┐ ┌────▼────┐
│ PPE │ │ ARB │
└─────┘ └─┬─────┬─┘
│ │
┌──▼──┐┌─▼───┐
│ ETH ││ USB │
└─────┘└─────┘
ETH1 ETH2
This series introduces support for multiple net_devices connected to the
same Frame Engine (FE) GDM port (GDM3 or GDM4) via an external hw
arbiter. Please note GDM1 or GDM2 does not support the connection with
the external arbiter.
---
Changes in v9:
- Do not stop device probe if mac address are misconfigured but just
report the warning
- Rebase on top of net-next main branch
- Remove redundant net_device pointer inside airoha_gdm_dev struct.
- Link to v8: https://lore.kernel.org/r/20260519-airoha-eth-multi-serdes-v8-0-6bd70e329df6@kernel.org
Changes in v8:
- Fix dts schema issues reported by sashiko.
- Fix possible NULL-pointer dereference in patch 2/10.
- Fix max mtu computation in airoha_dev_change_mtu().
- Link to v7: https://lore.kernel.org/r/20260516-airoha-eth-multi-serdes-v7-0-99e0093303e2@kernel.org
Changes in v7:
- Fix dma_sync_single_for_cpu() size in airoha_qdma_rx_process().
- Fix hw stats reset.
- Fix typos.
- Add fix for airoha_tc_remove_htb_queue queue index.
- Fix dts schema issues.
- Remove hw stats patch from the series.
- Link to v6: https://lore.kernel.org/r/20260511-airoha-eth-multi-serdes-v6-0-c899462c4f75@kernel.org
Changes in v6:
- Reconfigure REG_GDM_LEN_CFG() whit max 'running' MTU in
airoha_dev_stop().
- Fix port staring MIB counters in airoha_update_hw_stats().
- Fix regression in TC_HTB_NODE_MODIFY command.
- Fix length check in airoha_qdma_rx_process().
- Fix dts schema.
- Link to v5: https://lore.kernel.org/r/20260509-airoha-eth-multi-serdes-v5-0-805e38edc2aa@kernel.org
Changes in v5:
- Move qos_sq_bmap bitmap in airoha_gdm_dev struct.
- Unregister netdevice before running of_node_put().
- Move stat MIB counters in airoha_gdm_dev struct.
- Fix airoha_ppe_init_upd_mem() mac address configuration.
- Do not return -EBUSY if we try to decrease configured MTU of a shared
GDM port, just skip hw configuration.
- use int instead of atomic_t for GDM port users.
- Add patch "net: airoha: Reserve RX headroom to avoid skb reallocation"
- Fix typos.
- Link to v4: https://lore.kernel.org/r/20260507-airoha-eth-multi-serdes-v4-0-af613b61ae02@kernel.org
Changes in v4:
- Make ethernet-port property available just for GDM3 and GDM4 in DTS
specification
- Move cpu_tx_packets, fwd_tx_packets qos_sq_bmap fields in airoha_qdma
struct
- Fix of_node leak removing the net_device in airoha_remove() or
airoha_probe() error path
- Fix nbq backward compatibility
- Link to v3: https://lore.kernel.org/r/20260406-airoha-eth-multi-serdes-v3-0-ab6ea49d59ff@kernel.org
Changes in v3:
- Fix MTU and VIP configuration when the GDM port is shared between
multiple net_devices.
- Add sanity check for nbq parameter.
- Add missing of_node_get() for net_device np node.
- Check if GDM port is shared before decresing device MTU.
- Move port forward configuration in airoha_dev_stop() before
configuring DMA tx/rx engine.
- Introduce PRIV_FLAG_WAN parameter.
- Link to v2: https://lore.kernel.org/r/20260401-airoha-eth-multi-serdes-v2-0-ac427ae4beeb@kernel.org
Changes in v2:
- Rename multiplexer in arbiter in the commit logs.
- Rebase on top of net-next main branch.
- Add missing PPE cpu port configuration for GDM2 when loopback is
enabled.
- Link to v1: https://lore.kernel.org/r/20260329-airoha-eth-multi-serdes-v1-0-00f52dc360ca@kernel.org
---
Lorenzo Bianconi (6):
dt-bindings: net: airoha: Add GDM port ethernet child node
net: airoha: Remove private net_device pointer in airoha_gdm_dev struct
net: airoha: Support multiple net_devices for a single FE GDM port
net: airoha: Do not stop GDM port if it is shared
net: airoha: Introduce WAN device flag
net: airoha: Support multiple LAN/WAN interfaces for hw MAC address configuration
.../devicetree/bindings/net/airoha,en7581-eth.yaml | 56 ++-
drivers/net/ethernet/airoha/airoha_eth.c | 490 ++++++++++++++++-----
drivers/net/ethernet/airoha/airoha_eth.h | 25 +-
drivers/net/ethernet/airoha/airoha_ppe.c | 32 +-
4 files changed, 480 insertions(+), 123 deletions(-)
---
base-commit: dfcc2ff12925d99e858eaf539eaa4aaaf81fe2a6
change-id: 20260324-airoha-eth-multi-serdes-fb4b556ee756
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply
* Re: [PATCH 2/4] iio: adc: mt6323-auxadc: add mt6323 PMIC AUXADC driver
From: Andy Shevchenko @ 2026-06-03 5:51 UTC (permalink / raw)
To: Sanjay Chitroda
Cc: rva333, Roman Vivchar via B4 Relay, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Lee Jones, linux-iio, devicetree,
linux-kernel, linux-arm-kernel, linux-mediatek, Ben Grisdale
In-Reply-To: <1F6728A6-BD73-4159-AAC9-82370212EF04@gmail.com>
On Wed, Jun 03, 2026 at 06:41:43AM +0530, Sanjay Chitroda wrote:
> On 2 June 2026 6:16:55 pm IST, Roman Vivchar via B4 Relay <devnull+rva333.protonmail.com@kernel.org> wrote:
...
> >+MEDIATEK MT6323 PMIC AUXADC DRIVER
> >+M: Roman Vivchar <rva333@protonmail.com>
> >+L: linux-iio@vger.kernel.org
>
> No need to add explicit iio list for driver.
> Top level entry covers this driver.
While that's true, if person wants to commit to maintain the code, it is always
being appreciated.
> >+L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
This line might be questionable (or at least needs an Ack from MediaTek
maintainers / senior developers.
> >+S: Maintained
> >+F: drivers/iio/adc/mt6323-auxadc.c
> >+F: include/dt-bindings/iio/adc/mediatek,mt6323-auxadc.h
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply
* [PATCH 0/2] pmdomain: mediatek: Enable module support for mtk-scpsys
From: Justin Yeh @ 2026-06-03 5:11 UTC (permalink / raw)
To: Ulf Hansson, Matthias Brugger, AngeloGioacchino Del Regno
Cc: Project_Global_Chrome_Upstream_Group, linux-pm, linux-kernel,
linux-arm-kernel, linux-mediatek, Justin Yeh
This series enables the MTK_SCPSYS driver to be built as a loadable
module for GKI (Generic Kernel Image) compliance.
This series depends on the following patches currently under review:
- soc: mediatek: Allow MTK_INFRACFG to be built as module
- soc: mediatek: mtk-infracfg: Export symbols for DDK modules
The MTK_SCPSYS driver depends on MTK_INFRACFG being available as a
module, which is enabled by these prerequisite patches.
Patch 1 converts the Kconfig option from bool to tristate, allowing
the driver to be built as either built-in or as a module.
Patch 2 adds MODULE_DESCRIPTION() and converts to module_platform_driver()
to complete the modularization and silence modpost warnings.
Together these changes allow the MediaTek SCPSYS power domain driver
to support modern Android GKI/vendor_dlkm module loading requirements
while maintaining backward compatibility with the traditional built-in
configuration.
Justin Yeh (2):
pmdomain: mediatek: Convert MTK_SCPSYS to tristate
pmdomain: mediatek: Add MODULE_DESCRIPTION to mtk-scpsys
drivers/pmdomain/mediatek/Kconfig | 2 +-
drivers/pmdomain/mediatek/mtk-scpsys.c | 5 ++++-
2 files changed, 5 insertions(+), 2 deletions(-)
--
2.45.2
^ permalink raw reply
* [PATCH 1/2] pmdomain: mediatek: Convert MTK_SCPSYS to tristate
From: Justin Yeh @ 2026-06-03 5:11 UTC (permalink / raw)
To: Ulf Hansson, Matthias Brugger, AngeloGioacchino Del Regno
Cc: Project_Global_Chrome_Upstream_Group, linux-pm, linux-kernel,
linux-arm-kernel, linux-mediatek, Justin Yeh
In-Reply-To: <20260603051200.1163226-1-justin.yeh@mediatek.com>
Convert CONFIG_MTK_SCPSYS from bool to tristate to support building
as a loadable module for GKI compliance.
This change allows MTK_SCPSYS to be built as:
- CONFIG_MTK_SCPSYS=y: built-in (traditional approach)
- CONFIG_MTK_SCPSYS=m: module (GKI/vendor_dlkm approach)
- CONFIG_MTK_SCPSYS is not set: disabled
The tristate option is the standard kernel pattern for drivers that
need to support both built-in and modular configurations without
requiring separate Kconfig options.
This aligns common/staging with the equivalent change in
private/desktop-google, ensuring consistent configuration across
both kernel trees.
Signed-off-by: Justin Yeh <justin.yeh@mediatek.com>
---
drivers/pmdomain/mediatek/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pmdomain/mediatek/Kconfig b/drivers/pmdomain/mediatek/Kconfig
index 8923e6516441..bf5108ba360a 100644
--- a/drivers/pmdomain/mediatek/Kconfig
+++ b/drivers/pmdomain/mediatek/Kconfig
@@ -4,7 +4,7 @@ menu "MediaTek PM Domains"
depends on ARCH_MEDIATEK || COMPILE_TEST
config MTK_SCPSYS
- bool "MediaTek SCPSYS Support"
+ tristate "MediaTek SCPSYS Support"
default ARCH_MEDIATEK
depends on OF
select REGMAP
--
2.45.2
^ permalink raw reply related
* [PATCH 2/2] pmdomain: mediatek: Add MODULE_DESCRIPTION to mtk-scpsys
From: Justin Yeh @ 2026-06-03 5:11 UTC (permalink / raw)
To: Ulf Hansson, Matthias Brugger, AngeloGioacchino Del Regno
Cc: Project_Global_Chrome_Upstream_Group, linux-pm, linux-kernel,
linux-arm-kernel, linux-mediatek, Justin Yeh
In-Reply-To: <20260603051200.1163226-1-justin.yeh@mediatek.com>
Kernel modpost in v6.x emits a warning when a module is missing
MODULE_DESCRIPTION():
WARNING: modpost: missing MODULE_DESCRIPTION() in mtk-scpsys.o
Add MODULE_DESCRIPTION() to mtk-scpsys.c to silence the warning.
Signed-off-by: Justin Yeh <justin.yeh@mediatek.com>
---
drivers/pmdomain/mediatek/mtk-scpsys.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/pmdomain/mediatek/mtk-scpsys.c b/drivers/pmdomain/mediatek/mtk-scpsys.c
index efc8f276ffce..bfaa6c8f88dc 100644
--- a/drivers/pmdomain/mediatek/mtk-scpsys.c
+++ b/drivers/pmdomain/mediatek/mtk-scpsys.c
@@ -1151,4 +1151,7 @@ static struct platform_driver scpsys_drv = {
.of_match_table = of_scpsys_match_tbl,
},
};
-builtin_platform_driver(scpsys_drv);
+
+module_platform_driver(scpsys_drv);
+MODULE_DESCRIPTION("MediaTek SCPSYS power domain driver");
+MODULE_LICENSE("GPL");
--
2.45.2
^ permalink raw reply related
* Re: [PATCH 2/4] iio: adc: mt6323-auxadc: add mt6323 PMIC AUXADC driver
From: Sanjay Chitroda @ 2026-06-03 1:11 UTC (permalink / raw)
To: rva333, Roman Vivchar via B4 Relay, Jonathan Cameron,
David Lechner, Nuno Sá, Andy Shevchenko, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Ben Grisdale, Roman Vivchar
In-Reply-To: <20260602-mt6323-adc-v1-2-68ec737508ee@protonmail.com>
On 2 June 2026 6:16:55 pm IST, Roman Vivchar via B4 Relay <devnull+rva333.protonmail.com@kernel.org> wrote:
>From: Roman Vivchar <rva333@protonmail.com>
>
>The mt6323 AUXADC is a 15-bit ADC used for system monitoring. This driver
>provides support for reading various channels including battery and
>charger voltages, battery and chip temperature, current sensing and
>accessory detection.
>
>Add a driver for the AUXADC found in the MediaTek mt6323 PMIC.
>
>Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd Generation)
>Signed-off-by: Roman Vivchar <rva333@protonmail.com>
Hi Roman,
Thank you for the patch.
>---
> MAINTAINERS | 8 ++
> drivers/iio/adc/Kconfig | 11 ++
> drivers/iio/adc/Makefile | 1 +
> drivers/iio/adc/mt6323-auxadc.c | 299 ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 319 insertions(+)
>
>diff --git a/MAINTAINERS b/MAINTAINERS
>index d1cc0e12fe1f..c9ad2417a3ef 100644
>--- a/MAINTAINERS
>+++ b/MAINTAINERS
>@@ -16256,6 +16256,14 @@ S: Maintained
> F: Documentation/devicetree/bindings/mmc/mtk-sd.yaml
> F: drivers/mmc/host/mtk-sd.c
>
>+MEDIATEK MT6323 PMIC AUXADC DRIVER
>+M: Roman Vivchar <rva333@protonmail.com>
>+L: linux-iio@vger.kernel.org
No need to add explicit iio list for driver.
Top level entry covers this driver.
>+L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
>+S: Maintained
>+F: drivers/iio/adc/mt6323-auxadc.c
>+F: include/dt-bindings/iio/adc/mediatek,mt6323-auxadc.h
>+
> MEDIATEK MT6735 CLOCK & RESET DRIVERS
> M: Yassine Oudjana <y.oudjana@protonmail.com>
> L: linux-clk@vger.kernel.org
...
Thanks, Sanjay
>+MODULE_DESCRIPTION("MediaTek MT6323 PMIC AUXADC Driver");
>
^ permalink raw reply
* Re: [PATCH 00/11] net: wwan: t9xx: Add MediaTek T9XX WWAN driver
From: Sergey Ryazanov @ 2026-06-02 20:46 UTC (permalink / raw)
To: Wu. JackBB (GSM), Jakub Kicinski, Jack Wu via B4 Relay
Cc: Loic Poulain, Johannes Berg, Andrew Lunn, David S. Miller,
Eric Dumazet, Paolo Abeni, Wen-Zhi Huang, Shi-Wei Yeh,
Minano Tseng, Matthias Brugger, AngeloGioacchino Del Regno,
Simon Horman, Jonathan Corbet, Shuah Khan,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org, linux-doc@vger.kernel.org
In-Reply-To: <c279aea41ecf41c6aca4314a2f4e306b@compal.com>
Hi,
let me join the discussion and put my 2c.
On 6/2/26 13:58, Wu. JackBB (GSM) wrote:
> Hi Jakub,
>
>> On Fri, 29 May 2026 18:31:39 +0800 Jack Wu via B4 Relay wrote:
>>> 43 files changed, 14761 insertions(+)
>>
>> Please try to cut this down to ~5kLoC for the initial submission.
>> Whatever the absolute minimum sensible chunk of code is.
>>
>> Each patch must build cleanly with W=1
>
> We've already reduced this significantly from the original 41k LoC
> down to ~14.7k by stripping out non-essential features such as
> exception handling, memory logging, devlink, statistics, debug
> tracing, and others.
>
> We even removed some arguably necessary features (PM, mdlog,
> throughput optimizations) that we plan to submit as follow-up
> series.
Great work. Highly appreciate!
> Note that the line count may slightly increase in v2, as we plan
> to add missing kdoc comments based on review feedback.
>
> For reference, the t7xx driver (two generations older, simpler HW)
> had an initial submission of ~11.3k LoC [1]. The t9xx hardware is
> more complex, so we believe being in a similar range is reasonable.
Let me elaborate a bit here. The size problem is not due to a git or a
mailbox limitation. It arise due to the human limitation. The T7xx
submission review took something about 4 months and 8 iterations. And it
was 'only' 11.3k lines. Let's do some extrapolation assuming that
function is linear. 14.7k is 30% bigger, thus, estimated reviewing time
should be 5 months and 2 weeks. And this looks optimistic.
Recommendation, shared by Jakub, is practical. 5k lines might be
reviewed in a reasonable time and merged with the full confidence of the
quality.
> We'd like to keep the driver functional and reviewable in its
> current scope. Do you have any suggestions on how we could further
> reduce the size while maintaining a working initial submission?
Off the top of my head, I would suggest joining T7xx and T9xx code
bases. It could be done through factoring out a core functionality of
T7xx into a library, or through making the driver layered.
I am not pretending being an expert in any of these drivers, but
generally divide-n-conqueror together with code reuse work reliable. As
an alternative, I could spend a couple of weeks reviewing the new
submission and will come with more specific ideas on what can be thrown
away or reused.
> [1] https://patchwork.kernel.org/project/netdevbpf/cover/20220506181310.2183829-1-ricardo.martinez@linux.intel.com/
>
> Thanks.
>
>
> ================================================================================================================================================================
> This message may contain information which is private, privileged or confidential of Compal Electronics, Inc. If you are not the intended recipient of this message, please notify the sender and destroy/delete the message. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon this information, by persons or entities other than the intended recipient is prohibited.
> ================================================================================================================================================================
And this disclaimer does not facilitate the review. Am I 'intended'
recipient or should I destroy the message ASAP?
--
Sergey
^ permalink raw reply
* Re: [PATCH net-next 0/6] net: airoha: Preliminary patches to support multiple net_devices connected to the same GDM port
From: patchwork-bot+netdevbpf @ 2026-06-02 20:30 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, horms,
linux-arm-kernel, linux-mediatek, netdev, xuegang.lu
In-Reply-To: <20260527-airoha-eth-multi-serdes-preliminary-v1-0-ec6ed73ef7fc@kernel.org>
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Wed, 27 May 2026 12:21:14 +0200 you wrote:
> EN7581 or AN7583 SoCs support connecting multiple external SerDes (e.g.
> Ethernet or USB SerDes) to GDM3 or GDM4 ports via a hw arbiter that
> manages the traffic in a TDM manner. As a result multiple net_devices can
> connect to the same GDM{3,4} port and there is a theoretical "1:n"
> relation between GDM ports and net_devices.
>
> ┌─────────────────────────────────┐
> │ │ ┌──────┐
> │ P1 GDM1 ├────►MT7530│
> │ │ └──────┘
> │ │ ETH0 (DSA conduit)
> │ │
> │ PSE/FE │
> │ │
> │ │
> │ │ ┌─────┐
> │ P0 CDM1 ├────►QDMA0│
> │ P4 P9 GDM4 │ └─────┘
> └──┬─────────────────────────┬────┘
> │ │
> ┌──▼──┐ ┌────▼────┐
> │ PPE │ │ ARB │
> └─────┘ └─┬─────┬─┘
> │ │
> ┌──▼──┐┌─▼───┐
> │ ETH ││ USB │
> └─────┘└─────┘
> ETH1 ETH2
>
> [...]
Here is the summary with links:
- [net-next,1/6] net: airoha: Introduce airoha_gdm_dev struct
https://git.kernel.org/netdev/net-next/c/ec6c391bcca7
- [net-next,2/6] net: airoha: Move airoha_qdma pointer in airoha_gdm_dev struct
https://git.kernel.org/netdev/net-next/c/528c5153a557
- [net-next,3/6] net: airoha: Rely on airoha_gdm_dev pointer in airoha_is_lan_gdm_port()
https://git.kernel.org/netdev/net-next/c/eca4f59b5367
- [net-next,4/6] net: airoha: Move qos_sq_bmap in airoha_gdm_dev struct
https://git.kernel.org/netdev/net-next/c/069626af6dfa
- [net-next,5/6] net: airoha: Move {cpu,fwd}_tx_packets in airoha_gdm_dev struct
https://git.kernel.org/netdev/net-next/c/962c17dd2878
- [net-next,6/6] net: airoha: Rename airoha_set_gdm2_loopback in airoha_enable_gdm2_loopback
https://git.kernel.org/netdev/net-next/c/842a7ee50d68
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH 0/9] MT6365 PMIC support cleanup
From: Rob Herring @ 2026-06-02 19:58 UTC (permalink / raw)
To: Louis-Alexis Eyraud
Cc: Sen Chu, Sean Wang, Macpaul Lin, Lee Jones, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Dmitry Torokhov, Chen Zhong, Jonathan Cameron, David Lechner,
Nuno Sá, Andy Shevchenko, kernel, linux-pm, devicetree,
linux-kernel, linux-arm-kernel, linux-mediatek, linux-input,
linux-iio
In-Reply-To: <20260429-mediatek-genio-mt6365-cleanup-v1-0-6f43838be92f@collabora.com>
On Wed, Apr 29, 2026 at 11:44:13AM +0200, Louis-Alexis Eyraud wrote:
> Several Mediatek and Radxa boards, based on MT8370, MT8390 or MT8395
> SoC, integrate the MT6365 PMIC, that is a MT6359P variant:
> - Mediatek Genio 1200-EVK
> - Mediatek Genio 700-EVK
> - Mediatek Genio 510-EVK
> - Radxa NIO-12L
> It is compatible with the MT6359 PMIC.
>
> But both MT6365 PMIC support and compatibility were never expressed in
> the dt-bindings and there is no MT6365 include file as well.
> So, since these board support was introduced, their devicetrees use the
> mt6359 include file to enable this PMIC support.
>
> The goal of this series is to clean this support by adding the missing
> compatible strings for this MFD main and subdevices in the dt-bindings,
> and add a include for MT6365 definitions to replace the MT6359 include
> in these board devicetrees and for future ones (like Genio 520/720
> EVKs).
>
> The series is based on linux-next tree (tag: next-20260428) and has
> been tested on Mediatek Genio 510, 700 and 1200-EVK boards.
>
> ---
> Louis-Alexis Eyraud (9):
> dt-bindings: mfd: mediatek: mt6397: Add rtc for MT6359
> dt-bindings: mfd: mediatek: mt6397: Add MT6365 PMIC support
> dt-bindings: input: mediatek,pmic-keys: Add MT6365 support
> dt-bindings: iio: adc: mt6359: Add MT6365 PMIC AuxADC
Applied these 2 to fix warnings in linux-next.
Angelo, Apply the binding changes along with the .dts changes if they
haven't been picked up yet.
Once again, Mediatek warnings are moving in the wrong direction. :(
Rob
> arm64: dts: mediatek: mt6359: use proper compatible for rtc
> arm64: dts: mediatek: add MT6365 PMIC include
> arm64: dts: mediatek: mt8390-genio-common: use MT6365 PMIC definitions
> arm64: dts: mediatek: mt8395-genio-common: use MT6365 PMIC definitions
> arm64: dts: mediatek: mt8395-radxa-nio-12l: use MT6365 PMIC definitions
^ permalink raw reply
* Re: [PATCH] wifi: mt76: mt7996: Fix possible token leak in mt7996_tx_prepare_skb()
From: Dylan Eskew @ 2026-06-02 18:58 UTC (permalink / raw)
To: Lorenzo Bianconi, Felix Fietkau, Ryder Lee, Shayne Chen,
Sean Wang, Matthias Brugger, AngeloGioacchino Del Regno
Cc: linux-wireless, linux-arm-kernel, linux-mediatek
In-Reply-To: <20260531-mt7996_tx_prepare_skb-token-leack-v1-1-2b9c9f59ceb1@kernel.org>
Hi Lore,
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.
-- 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,
^ permalink raw reply
* [PATCH] Bluetooth: btmtk: Disable remote wakeup for MT7922/MT7925
From: Rong Zhang @ 2026-06-02 18:38 UTC (permalink / raw)
To: Marcel Holtmann, Luiz Augusto von Dentz, Matthias Brugger,
AngeloGioacchino Del Regno
Cc: linux-bluetooth, linux-kernel, linux-arm-kernel, linux-mediatek,
Rong Zhang
These NICs are often reported to lose their Bluetooth interfaces, i.e,
their USB interfaces suddenly become completely unresponsive, causing
the USB core to reset them, only to find that they are no longer
accessible. A power cycle is required to make the Bluetooth interfaces
recover.
After some investigations, I found that their USB autosuspend remote
wakeup capabilities are so broken that they are precisely the culprit
behind the issue:
[27452.608056] hub 3-0:1.0: state 7 ports 5 chg 0000 evt 0020
[27452.702018] usb 3-5: usb wakeup-resume
[27452.716038] usb 3-5: Waited 0ms for CONNECT
[27452.716642] usb 3-5: finish resume
/* usbmon showed that the device was completely unresponsive to any
URBs after the remote wakeup */
[27457.836030] usb 3-5: retry with reset-resume
[27457.956046] usb 3-5: reset high-speed USB device number 4 using xhci_hcd
[27463.332047] usb 3-5: device descriptor read/64, error -110
[27478.948117] usb 3-5: device descriptor read/64, error -110
[27479.172430] usb 3-5: reset high-speed USB device number 4 using xhci_hcd
[27484.332035] usb 3-5: device descriptor read/64, error -110
[27499.940039] usb 3-5: device descriptor read/64, error -110
[27500.164060] usb 3-5: reset high-speed USB device number 4 using xhci_hcd
[27505.196142] xhci_hcd 0000:67:00.0: Timeout while waiting for setup device command
[27510.576045] xhci_hcd 0000:67:00.0: Timeout while waiting for setup device command
[27510.784038] usb 3-5: device not accepting address 4, error -62
[27510.912215] usb 3-5: reset high-speed USB device number 4 using xhci_hcd
[27515.948307] xhci_hcd 0000:67:00.0: Timeout while waiting for setup device command
[27521.324380] xhci_hcd 0000:67:00.0: Timeout while waiting for setup device command
[27521.525107] usb 3-5: device not accepting address 4, error -62
[27521.525928] usb usb3-port5: logical disconnect
[27521.525996] usb 3-5: gone after usb resume? status -19
[27521.526230] usb 3-5: can't resume, status -19
[27521.526434] usb usb3-port5: logical disconnect
[27521.526469] usb usb3-port5: resume, status -19
[27521.526493] usb usb3-port5: status 0503, change 0004, 480 Mb/s
[27521.526528] usb 3-5: USB disconnect, device number 4
[27521.526736] usb 3-5: unregistering device
[27521.804029] usb 3-5: new high-speed USB device number 5 using xhci_hcd
[27527.076067] usb 3-5: device descriptor read/64, error -110
[27542.692027] usb 3-5: device descriptor read/64, error -110
[27542.916047] usb 3-5: new high-speed USB device number 6 using xhci_hcd
[27548.068043] usb 3-5: device descriptor read/64, error -110
[27563.684073] usb 3-5: device descriptor read/64, error -110
[27563.792133] usb usb3-port5: attempt power cycle
[27563.924381] hub 3-0:1.0: port_wait_reset: err = -11
[27563.925213] usb usb3-port5: not enabled, trying reset again...
[27564.184398] usb 3-5: new high-speed USB device number 7 using xhci_hcd
[27569.196322] xhci_hcd 0000:67:00.0: Timeout while waiting for setup device command
[27574.572040] xhci_hcd 0000:67:00.0: Timeout while waiting for setup device command
[27574.776053] usb 3-5: device not accepting address 7, error -62
[27574.900165] usb 3-5: new high-speed USB device number 8 using xhci_hcd
[27579.948039] xhci_hcd 0000:67:00.0: Timeout while waiting for setup device command
[27585.324331] xhci_hcd 0000:67:00.0: Timeout while waiting for setup device command
[27585.528040] usb 3-5: device not accepting address 8, error -62
[27585.528389] usb usb3-port5: unable to enumerate USB device
[27585.528424] hub 3-0:1.0: state 7 ports 5 chg 0000 evt 0020
To reproduce the issue, these conditions must be met:
- a noisy radio environment (cafe or office) to cause frequent remote
wakeup events
- no Bluetooth device is connected, so autosuspend is not prohibited
- the Bluetooth interface is opened, so remote wakeup is enabled when
the device runs into autosuspend
Then I can reproduce the issue within sereval hours each time.
Increasing TRSMRCY or setting USB_QUIRK_RESET doesn't help at all.
Since the remote wakeup capability is super broken, just disable it to
get rid of the troubles. The device can still be autosuspended when
the bluetooth interface is closed, which won't break the device as
remote wakeup is unneeded in this case.
Link: https://bbs.archlinux.org/viewtopic.php?id=308169
Link: https://bbs.bee-link.com/d/7694-gtr9-pro-ai-max-395-usb-issues
Signed-off-by: Rong Zhang <i@rong.moe>
---
drivers/bluetooth/btmtk.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 8ff66b276af0..3d2a8598892b 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -1379,6 +1379,16 @@ int btmtk_usb_setup(struct hci_dev *hdev)
break;
case 0x7922:
case 0x7925:
+ /*
+ * A remote wakeup could cause the device completely unresponsive, and
+ * recovering from such a state needs a power cycle.
+ *
+ * Since the remote wakeup capability is super broken, just disable it
+ * to get rid of the troubles. The device can still be autosuspended
+ * when the bluetooth interface is closed.
+ */
+ device_set_wakeup_capable(&btmtk_data->udev->dev, false);
+ fallthrough;
case 0x7961:
case 0x7902:
case 0x6639:
---
base-commit: e43ffb69e0438cddd72aaa30898b4dc446f664f8
change-id: a4222333-btmtk-remote-wakeup-494f4c97af88
Thanks,
Rong
^ permalink raw reply related
* Re: [PATCH] dt-bindings: pinctrl: mediatek: mt6795: document the slew-rate property
From: Conor Dooley @ 2026-06-02 16:42 UTC (permalink / raw)
To: Luca Leonardo Scorcia
Cc: linux-mediatek, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Matthias Brugger, AngeloGioacchino Del Regno,
Sean Wang, linux-gpio, devicetree, linux-kernel, linux-arm-kernel
In-Reply-To: <20260601152707.29039-1-l.scorcia@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH 2/4] iio: adc: mt6323-auxadc: add mt6323 PMIC AUXADC driver
From: Nuno Sá @ 2026-06-02 16:43 UTC (permalink / raw)
To: rva333, Jonathan Cameron, David Lechner, Nuno Sá,
Andy Shevchenko, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Matthias Brugger, AngeloGioacchino Del Regno, Lee Jones
Cc: linux-iio, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, Ben Grisdale
In-Reply-To: <20260602-mt6323-adc-v1-2-68ec737508ee@protonmail.com>
On Tue, 2026-06-02 at 15:46 +0300, Roman Vivchar via B4 Relay wrote:
> From: Roman Vivchar <rva333@protonmail.com>
>
> The mt6323 AUXADC is a 15-bit ADC used for system monitoring. This driver
> provides support for reading various channels including battery and
> charger voltages, battery and chip temperature, current sensing and
> accessory detection.
>
> Add a driver for the AUXADC found in the MediaTek mt6323 PMIC.
>
> Tested-by: Ben Grisdale <bengris32@protonmail.ch> # Amazon Echo Dot (2nd
> Generation)
> Signed-off-by: Roman Vivchar <rva333@protonmail.com>
> ---
> MAINTAINERS | 8 ++
> drivers/iio/adc/Kconfig | 11 ++
> drivers/iio/adc/Makefile | 1 +
> drivers/iio/adc/mt6323-auxadc.c | 299 ++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 319 insertions(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d1cc0e12fe1f..c9ad2417a3ef 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16256,6 +16256,14 @@ S: Maintained
> F: Documentation/devicetree/bindings/mmc/mtk-sd.yaml
> F: drivers/mmc/host/mtk-sd.c
>
> +MEDIATEK MT6323 PMIC AUXADC DRIVER
> +M: Roman Vivchar <rva333@protonmail.com>
> +L: linux-iio@vger.kernel.org
> +L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
> +S: Maintained
> +F: drivers/iio/adc/mt6323-auxadc.c
> +F: include/dt-bindings/iio/adc/mediatek,mt6323-auxadc.h
The above file was not added in this patch
...
> +
> +static const struct iio_chan_spec mt6323_auxadc_channels[] = {
> + MTK_PMIC_IIO_CHAN(baton2, MT6323_AUXADC_BATON2, MT6323_AUXADC_ADC6,
> IIO_VOLTAGE),
> + MTK_PMIC_IIO_CHAN(ch6, MT6323_AUXADC_CH6, MT6323_AUXADC_ADC11,
> IIO_VOLTAGE),
> + MTK_PMIC_IIO_CHAN(bat_temp, MT6323_AUXADC_BAT_TEMP, MT6323_AUXADC_ADC5,
> IIO_VOLTAGE),
> + MTK_PMIC_IIO_CHAN(chip_temp, MT6323_AUXADC_CHIP_TEMP, MT6323_AUXADC_ADC4,
> IIO_VOLTAGE),
> + MTK_PMIC_IIO_CHAN(vcdt, MT6323_AUXADC_VCDT, MT6323_AUXADC_ADC2,
> IIO_VOLTAGE),
> + MTK_PMIC_IIO_CHAN(baton1, MT6323_AUXADC_BATON1, MT6323_AUXADC_ADC3,
> IIO_VOLTAGE),
> + MTK_PMIC_IIO_CHAN(isense, MT6323_AUXADC_ISENSE, MT6323_AUXADC_ADC1,
> IIO_VOLTAGE),
> + MTK_PMIC_IIO_CHAN(batsns, MT6323_AUXADC_BATSNS, MT6323_AUXADC_ADC0,
> IIO_VOLTAGE),
> + MTK_PMIC_IIO_CHAN(accdet, MT6323_AUXADC_ACCDET, MT6323_AUXADC_ADC7,
> IIO_VOLTAGE),
> +};
All of the above are IIO_VOLTAGE. Just remove _ch_type then.
> +
> +/**
> + * struct mt6323_auxadc - Main driver structure
> + * @regmap: Regmap from PWRAP
> + * @lock: Mutex to serialize AUXADC reading vs configuration
> + *
> + * The MediaTek MT6323 (as well as a lot of other PMICs) has the following
> hierarchy:
> + * PMIC AUXADC <- PMIC MFD <- SoC PWRAP (wrapper for PWRAP FSM)
> + *
> + * Therefore, PWRAP regmap should be obtained using dev->parent->parent.
> + */
The above kerneldoc seems unnecessary to me.
> +struct mt6323_auxadc {
> + struct regmap *regmap;
> + struct mutex lock;
> +};
...
>
> +
> +static int mt6323_auxadc_read_raw(struct iio_dev *indio_dev,
> + const struct iio_chan_spec *chan,
> + int *val, int *val2, long mask)
> +{
> + struct mt6323_auxadc *auxadc = iio_priv(indio_dev);
> + int ret, mult;
> +
> + switch (mask) {
> + case IIO_CHAN_INFO_SCALE:
> + if (chan->channel == MT6323_AUXADC_ISENSE ||
> + chan->channel == MT6323_AUXADC_BATSNS)
> + mult = 4;
> + else
> + mult = 1;
> +
> + /* 1800mV full range with 15-bit resolution. */
> + *val = mult * 1800;
> + *val2 = 15;
> +
> + return IIO_VAL_FRACTIONAL_LOG2;
> + case IIO_CHAN_INFO_RAW:
> + scoped_guard(mutex, &auxadc->lock) {
> + ret = mt6323_auxadc_prepare_channel(auxadc);
> + if (ret)
> + return ret;
> +
> + ret = mt6323_auxadc_request(auxadc, chan->channel);
> + if (ret)
> + return ret;
> +
> + /* Hardware limitation: the AUXADC needs a delay to become
> ready. */
> + fsleep(300);
> +
> + ret = mt6323_auxadc_read(auxadc, chan, val);
> + if (ret)
> + return ret;
Could be return mt6323_auxadc_read(...)
- Nuno Sá
>
> +
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("MediaTek MT6323 PMIC AUXADC Driver");
^ permalink raw reply
* Re: [PATCH 1/4] dt-bindings: iio: adc: mediatek,mt6359-auxadc: add mt6323 PMIC AUXADC
From: Conor Dooley @ 2026-06-02 16:21 UTC (permalink / raw)
To: rva333
Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Lee Jones, linux-iio, devicetree,
linux-kernel, linux-arm-kernel, linux-mediatek, Ben Grisdale
In-Reply-To: <20260602-mt6323-adc-v1-1-68ec737508ee@protonmail.com>
[-- Attachment #1: Type: text/plain, Size: 75 bytes --]
Acked-by: Conor Dooley <conor.dooley@microchip.com>
pw-bot: not-applicable
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* Re: [PATCH] dt-bindings: Consolidate "sram" property definition
From: Heiko Stuebner @ 2026-06-02 15:06 UTC (permalink / raw)
To: Liu Ying, Philipp Zabel, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter,
Krzysztof Kozlowski, Conor Dooley, Frank Li, Sascha Hauer,
Pengutronix Kernel Team, Fabio Estevam, Rob Clark, Sean Paul,
Konrad Dybcio, Akhil P Oommen, Dmitry Baryshkov, Abhinav Kumar,
Jessica Zhang, Marijn Suijten, Vinod Koul, Nas Chung, Jackson Lee,
Mauro Carvalho Chehab, Mirela Rabulea, Detlev Casanova,
Ezequiel Garcia, Hugues Fruchet, Alain Volmat, Maxime Coquelin,
Alexandre Torgue, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, MD Danish Anwar, Roger Quadros,
Parvathi Pudi, Mohan Reddy Putluru, Bjorn Andersson,
Mathieu Poirier, Neil Armstrong, Kevin Hilman, Jerome Brunet,
Martin Blumenstingl, Michal Simek, Mark Brown, Matthias Brugger,
AngeloGioacchino Del Regno, Linus Walleij, Lorenzo Bianconi,
Felix Fietkau, Andrew F. Davis, Hussain Khaja, Suman Anna,
Ben Levinsky, Tanmay Shah, Erwan Leray, Fabrice Gasnier,
Rob Herring (Arm)
Cc: Roger Quadros, dri-devel, devicetree, imx, linux-arm-kernel,
linux-kernel, linux-arm-msm, freedreno, dmaengine, linux-media,
linux-rockchip, linux-stm32, netdev, linux-remoteproc,
linux-amlogic, linux-spi, linux-mediatek
In-Reply-To: <20260511165942.2774868-1-robh@kernel.org>
Am Montag, 11. Mai 2026, 18:59:36 Mitteleuropäische Sommerzeit schrieb Rob Herring (Arm):
> The "sram" property has become a de facto standard property, so create a
> common schema for it and drop all the duplicated definitions.
>
> Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
> ---
> .../bindings/media/rockchip,vdec.yaml | 5 ++--
Acked-by: Heiko Stuebner <heiko@sntech.de>
^ 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