* Re: [RFC PATCH net] netfilter: flowtable: fix offloaded ct timeout never being extended
From: Florian Westphal @ 2026-05-27 7:34 UTC (permalink / raw)
To: Adrian Bente
Cc: pablo, netfilter-devel, phil, nbd, sean.wang, lorenzo,
andrew+netdev, matthias.bgg, angelogioacchino.delregno, daniel,
coreteam, linux-mediatek
In-Reply-To: <20260526060138.3924-1-adibente@gmail.com>
Adrian Bente <adibente@gmail.com> wrote:
[ trimming CCs .. ]
> OpenWrt has recently migrated many platforms to kernel 6.18. On the
> MediaTek platform, which supports hardware network offloading, WiFi
> connections accelerated via the WED path were observed to drop after
> roughly 300 seconds.
>
> After several debugging sessions, assisted by the Claude LLM, the
> problem was narrowed down as follows:
>
> nf_flow_table_extend_ct_timeout() extends ct->timeout for offloaded
> flows using:
>
> cmpxchg(&ct->timeout, expires, new_timeout);
>
> 'expires' comes from nf_ct_expires(ct) and is a relative value, while
> ct->timeout holds an absolute timestamp. The two are never equal, so
> the cmpxchg always fails and the timeout is never extended.
>
> This goes unnoticed for most flows, but a long-lived hardware (WED)
> offloaded flow on MediaTek MT7986 eventually has ct->timeout decay to
> zero, the conntrack entry is reaped and the connection breaks.
>
> Compare against the current ct->timeout value instead.
>
> This patch is sent as RFC: the diagnosis is verified on hardware and
> the fix resolves the drop, but review of the chosen approach is
> welcome.
I guess we need to open-code expires, something like this (not even
compile tested). Also see https://sashiko.dev/#/patchset/20260526060138.3924-1-adibente%40gmail.com
diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c
--- a/net/netfilter/nf_flow_table_core.c
+++ b/net/netfilter/nf_flow_table_core.c
@@ -506,7 +506,12 @@ static u32 nf_flow_table_tcp_timeout(const struct nf_conn *ct)
static void nf_flow_table_extend_ct_timeout(struct nf_conn *ct)
{
static const u32 min_timeout = 5 * 60 * HZ;
- u32 expires = nf_ct_expires(ct);
+ u32 ct_timeout = READ_ONCE(ct->timeout);
+ s32 expires;
+
+ expires = ct_timeout - nfct_time_stamp;
+ if (expires <= 0) /* already expired */
+ return;
/* normal case: large enough timeout, nothing to do. */
if (likely(expires >= min_timeout))
@@ -524,7 +529,7 @@ static void nf_flow_table_extend_ct_timeout(struct nf_conn *ct)
if (nf_ct_is_confirmed(ct) &&
test_bit(IPS_OFFLOAD_BIT, &ct->status)) {
u8 l4proto = nf_ct_protonum(ct);
- u32 new_timeout = true;
+ u32 new_timeout = 1;
switch (l4proto) {
case IPPROTO_UDP:
@@ -549,7 +554,7 @@ static void nf_flow_table_extend_ct_timeout(struct nf_conn *ct)
*/
if (new_timeout) {
new_timeout += nfct_time_stamp;
- cmpxchg(&ct->timeout, expires, new_timeout);
+ cmpxchg(&ct->timeout, ct_timeout, new_timeout);
}
}
^ permalink raw reply
* Re: [PATCH] wifi: mt76: mt7925: add wcid publish check in mt76_sta_add
From: Jiajia Liu @ 2026-05-27 10:00 UTC (permalink / raw)
To: Sean Wang
Cc: Felix Fietkau, Lorenzo Bianconi, Ryder Lee, Shayne Chen,
Sean Wang, Matthias Brugger, AngeloGioacchino Del Regno,
Ming Yen Hsieh, Michael Lo, Leon Yen, linux-wireless,
linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <CAGp9LzqzddmyDHMNsaqigYpVEdo_Pmzwbeh5Ri5_Gr87cVL6Dg@mail.gmail.com>
On Tue, May 26, 2026 at 04:52:32PM -0500, Sean Wang wrote:
> Hi,
>
> On Tue, May 26, 2026 at 1:09 AM Jiajia Liu <liujiajia@kylinos.cn> wrote:
> >
> > Since mt7925_mac_sta_add publishes wcid, add publish check in mt76_sta_add
> > to avoid reinitializing the wcid->poll_list for mt7925.
> >
> > Found dev->sta_poll_list corruption when using mt7925 and 7.0-rc4.
> > According to the corruption information, prev->next was changed to itself.
> >
> > wlan0: disconnect from AP 90:fb:5d:94:8b:e3 for new auth to 90:fb:5d:94:8b:e2
> > wlan0: authenticate with 90:fb:5d:94:8b:e2 (local address=84:9e:56:9c:7e:6b)
> > wlan0: send auth to 90:fb:5d:94:8b:e2 (try 1/3)
> > slab kmalloc-8k start ffff8c80958a6000 pointer offset 4160 size 8192
> > list_add corruption. prev->next should be next (ffff8c808a7488f8), but was ffff8c80958a7040. (prev=ffff8c80958a7040).
> >
> > mt76_wcid_add_poll+0x95/0xd0 [mt76]
> > mt7925_mac_add_txs.part.0+0xa5/0xe0 [mt7925_common]
> > mt7925_rx_check+0xa7/0xc0 [mt7925_common]
> > mt76_dma_rx_poll+0x50d/0x790 [mt76]
> > mt792x_poll_rx+0x52/0xe0 [mt792x_lib]
> >
> > Signed-off-by: Jiajia Liu <liujiajia@kylinos.cn>
> > ---
> >
> > Reproduced and tested using the script below over ssh. Roam between two
> > bssids with the same SSID on a router.
> >
> > #!/bin/bash
> >
> > set -ex
> >
> > while :; do
> > num=$(sudo iw wlan0 scan | grep Polaris | wc -l)
> > if [ $num -eq 2 ]; then
> > break
> > fi
> > done
> >
> > for i in $(seq 1 500); do
> >
> > echo "index $i"
> > wpa_cli -i wlan0 roam 90:fb:5d:94:8b:e3
> > sleep 5
> > wpa_cli -i wlan0 roam 90:fb:5d:94:8b:e2
> > sleep 5
> >
> > done
> >
> > ---
> > drivers/net/wireless/mediatek/mt76/mac80211.c | 11 ++++++++---
> > drivers/net/wireless/mediatek/mt76/mt76.h | 1 +
> > drivers/net/wireless/mediatek/mt76/mt7925/main.c | 3 +++
> > 3 files changed, 12 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
> > index 4ae5e4715a9c..83f4f941b890 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mac80211.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
> > @@ -1595,11 +1595,16 @@ mt76_sta_add(struct mt76_phy *phy, struct ieee80211_vif *vif,
> > mtxq->wcid = wcid->idx;
> > }
> >
> > - ewma_signal_init(&wcid->rssi);
> > - rcu_assign_pointer(dev->wcid[wcid->idx], wcid);
> > + if (!test_bit(MT_WCID_FLAG_DRV_PUBLISH, &wcid->flags)) {
> > + ewma_signal_init(&wcid->rssi);
> > + rcu_assign_pointer(dev->wcid[wcid->idx], wcid);
> > + mt76_wcid_init(wcid, phy->band_idx);
> > + } else {
> > + wcid->phy_idx = phy->band_idx;
> > + }
> > +
> > phy->num_sta++;
> >
>
> Thanks for spotting the roaming issue.
>
> I think we can avoid adding MT_WCID_FLAG_DRV_PUBLISH and instead use the
> WCID table itself for the publish check.
>
> dev->wcid[] already encodes whether a WCID has been published, so checking
> it directly avoids adding a second mirror state. MT_WCID_FLAG_* is also
> better kept for WCID features that affect WTBL setup or data-path handling,
> rather than common bookkeeping state.
>
> Something like:
>
> @@ -1620,6 +1620,7 @@ mt76_sta_add(struct mt76_phy *phy, struct
> ieee80211_vif *vif,
> {
> struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
> struct mt76_dev *dev = phy->dev;
> + struct mt76_wcid *published;
> int ret;
> int i;
>
> @@ -1639,7 +1640,10 @@ mt76_sta_add(struct mt76_phy *phy, struct
> ieee80211_vif *vif,
> mtxq->wcid = wcid->idx;
> }
>
> - if (!test_bit(MT_WCID_FLAG_DRV_PUBLISH, &wcid->flags)) {
> + published = rcu_dereference_protected(dev->wcid[wcid->idx],
> + lockdep_is_held(&dev->mutex));
> + if (published != wcid) {
> + WARN_ON_ONCE(published);
> ewma_signal_init(&wcid->rssi);
> rcu_assign_pointer(dev->wcid[wcid->idx], wcid);
> mt76_wcid_init(wcid, phy->band_idx);
>
> ....
>
Thanks for the suggestion. Will update in v2.
>
> > - mt76_wcid_init(wcid, phy->band_idx);
> > out:
> > mutex_unlock(&dev->mutex);
> >
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
> > index 527bef97e122..8bfce686bff7 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt76.h
> > +++ b/drivers/net/wireless/mediatek/mt76/mt76.h
> > @@ -361,6 +361,7 @@ enum mt76_wcid_flags {
> > MT_WCID_FLAG_PS,
> > MT_WCID_FLAG_4ADDR,
> > MT_WCID_FLAG_HDR_TRANS,
> > + MT_WCID_FLAG_DRV_PUBLISH,
> > };
> >
> > #define MT76_N_WCIDS 1088
> > diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
> > index 73d3722739d0..35b5c718475c 100644
> > --- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
> > +++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
> > @@ -1102,6 +1102,9 @@ int mt7925_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
> > &msta->deflink);
> > }
> >
> > + if (!err)
> > + set_bit(MT_WCID_FLAG_DRV_PUBLISH, &msta->deflink.wcid.flags);
> > +
> > return err;
> > }
> > EXPORT_SYMBOL_GPL(mt7925_mac_sta_add);
> > --
> > 2.53.0
> >
> >
^ permalink raw reply
* Re: [PATCH 2/3] crypto: inside-secure: add EIP93 ESP packet backend
From: Simon Horman @ 2026-05-27 10:08 UTC (permalink / raw)
To: Jihong Min
Cc: Christian Marangi, Antoine Tenart, Herbert Xu, David S . Miller,
Lorenzo Bianconi, Andrew Lunn, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Steffen Klassert, linux-kernel, linux-crypto,
linux-arm-kernel, linux-mediatek, netdev
In-Reply-To: <20260523121522.3023992-3-hurryman2212@gmail.com>
On Sat, May 23, 2026 at 09:15:21PM +0900, Jihong Min wrote:
> Expose an EIP93 packet-mode IPsec backend for netdev drivers that need
> ESP encapsulation and decapsulation offload without advertising EIP93
> itself as a netdev.
>
> Add provider selection, capability reporting, SA lifecycle management,
> IPsec request completion, and provider fault notification around the
> existing EIP93 descriptor path.
>
> Assisted-by: Codex:gpt-5.5
> Signed-off-by: Jihong Min <hurryman2212@gmail.com>
...
> diff --git a/drivers/crypto/inside-secure/eip93/eip93-ipsec.c b/drivers/crypto/inside-secure/eip93/eip93-ipsec.c
...
> +static void eip93_ipsec_abort_requests(struct eip93_ipsec *ipsec, int err)
> +{
> + struct eip93_ipsec_sa *sa;
> +
> + while (true) {
> + bool found = false;
> +
> + spin_lock_bh(&ipsec->lock);
> + list_for_each_entry(sa, &ipsec->sa_list, node) {
> + spin_lock(&sa->lock);
> + if (sa->aborting) {
> + spin_unlock(&sa->lock);
> + continue;
> + }
> +
> + sa->aborting = true;
> + found = refcount_inc_not_zero(&sa->refcnt);
> + spin_unlock(&sa->lock);
> + if (found)
> + break;
> + }
> + spin_unlock_bh(&ipsec->lock);
> + if (!found)
> + return;
> +
> + eip93_ipsec_abort_sa(sa, err);
> + eip93_ipsec_sa_put(sa);
sa is the iterator for the list_for_each_entry loop.
However, here it is used outside of that context.
"If list_for_each_entry, etc complete a traversal of the list, the
iterator variable ends up pointing to an address at an offset from
the list head, and not a meaningful structure. Thus this value
should not be used after the end of the iterator.
https://www.spinics.net/lists/linux-kernel-janitors/msg11994.html
Flagged by Coccinelle.
> + }
> +}
...
^ permalink raw reply
* Re: [PATCH net-next v8 00/10] net: airoha: Support multiple net_devices connected to the same GDM port
From: Lorenzo Bianconi @ 2026-05-27 10:16 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley
Cc: Christian Marangi, Benjamin Larsson, linux-arm-kernel,
linux-mediatek, netdev, devicetree, Xuegang Lu, Madhur Agrawal
In-Reply-To: <20260519-airoha-eth-multi-serdes-v8-0-6bd70e329df6@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 6764 bytes --]
> 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.
In order to make easier the inclusion of this series I am splitting it in two
smaller ones:
- a preliminary rework series (just code adjustments)
- a smaller series where we introduce the real support for multiple net_devices
connected to the same FE GDM port.
This way we can unlock even other patches in my queue.
Regards,
Lorenzo
>
> ---
> 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 (10):
> dt-bindings: net: airoha: Add GDM port ethernet child node
> net: airoha: Introduce airoha_gdm_dev struct
> net: airoha: Move airoha_qdma pointer in airoha_gdm_dev struct
> net: airoha: Rely on airoha_gdm_dev pointer in airoha_is_lan_gdm_port()
> net: airoha: Move qos_sq_bmap in airoha_gdm_dev struct
> net: airoha: Move {cpu,fwd}_tx_packets 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 | 833 +++++++++++++++------
> drivers/net/ethernet/airoha/airoha_eth.h | 47 +-
> drivers/net/ethernet/airoha/airoha_ppe.c | 43 +-
> 4 files changed, 702 insertions(+), 277 deletions(-)
> ---
> base-commit: 7a348a95f696d20f15c776de4df8b4415bcf3d77
> change-id: 20260324-airoha-eth-multi-serdes-fb4b556ee756
>
> Best regards,
> --
> Lorenzo Bianconi <lorenzo@kernel.org>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply
* [PATCH net-next 0/6] net: airoha: Preliminary patches to support multiple net_devices connected to the same GDM port
From: Lorenzo Bianconi @ 2026-05-27 10:21 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Simon Horman, linux-arm-kernel, linux-mediatek, netdev,
Xuegang Lu, Lorenzo Bianconi
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 is a preliminary series to introduce support for multiple net_devices
connected to the same Frame Engine (FE) GDM port (GDM3 or GDM4) via an
external hw arbiter.
---
Lorenzo Bianconi (6):
net: airoha: Introduce airoha_gdm_dev struct
net: airoha: Move airoha_qdma pointer in airoha_gdm_dev struct
net: airoha: Rely on airoha_gdm_dev pointer in airoha_is_lan_gdm_port()
net: airoha: Move qos_sq_bmap in airoha_gdm_dev struct
net: airoha: Move {cpu,fwd}_tx_packets in airoha_gdm_dev struct
net: airoha: Rename airoha_set_gdm2_loopback in airoha_enable_gdm2_loopback
drivers/net/ethernet/airoha/airoha_eth.c | 445 ++++++++++++++++++-------------
drivers/net/ethernet/airoha/airoha_eth.h | 35 ++-
drivers/net/ethernet/airoha/airoha_ppe.c | 34 +--
3 files changed, 297 insertions(+), 217 deletions(-)
---
base-commit: aa064a614efcfa4c300609d1f01134e99a12ad10
change-id: 20260527-airoha-eth-multi-serdes-preliminary-51204fb642fc
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply
* [PATCH net-next 2/6] net: airoha: Move airoha_qdma pointer in airoha_gdm_dev struct
From: Lorenzo Bianconi @ 2026-05-27 10:21 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Simon Horman, linux-arm-kernel, linux-mediatek, netdev,
Xuegang Lu, Lorenzo Bianconi
In-Reply-To: <20260527-airoha-eth-multi-serdes-preliminary-v1-0-ec6ed73ef7fc@kernel.org>
Move airoha_qdma pointer from airoha_gdm_port struct to airoha_gdm_dev
one since the QDMA block used depends on the particular net_device
WAN/LAN configuration and in the current codebase net_device pointer is
associated to airoha_gdm_dev struct.
This is a preliminary patch to support multiple net_devices connected
to the same GDM{3,4} port via an external hw arbiter.
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 105 +++++++++++++++----------------
drivers/net/ethernet/airoha/airoha_eth.h | 9 ++-
drivers/net/ethernet/airoha/airoha_ppe.c | 17 ++---
3 files changed, 64 insertions(+), 67 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index b2684af2db76..0f37d26e4d52 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -71,9 +71,10 @@ 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_port *port, const u8 *addr)
+static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
{
- struct airoha_eth *eth = port->qdma->eth;
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
u32 val, reg;
reg = airoha_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H
@@ -85,7 +86,7 @@ static void airoha_set_macaddr(struct airoha_gdm_port *port, const u8 *addr)
airoha_fe_wr(eth, REG_FE_MAC_LMIN(reg), val);
airoha_fe_wr(eth, REG_FE_MAC_LMAX(reg), val);
- airoha_ppe_init_upd_mem(port);
+ airoha_ppe_init_upd_mem(dev);
}
static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,
@@ -101,10 +102,10 @@ static void airoha_set_gdm_port_fwd_cfg(struct airoha_eth *eth, u32 addr,
FIELD_PREP(GDM_UCFQ_MASK, val));
}
-static int airoha_set_vip_for_gdm_port(struct airoha_gdm_port *port,
- bool enable)
+static int airoha_set_vip_for_gdm_port(struct airoha_gdm_dev *dev, bool enable)
{
- struct airoha_eth *eth = port->qdma->eth;
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
u32 vip_port;
vip_port = eth->soc->ops.get_vip_port(port, port->nbq);
@@ -859,10 +860,13 @@ static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)
if (!port)
continue;
- if (port->qdma != qdma)
+ dev = port->dev;
+ if (!dev)
+ continue;
+
+ if (dev->qdma != qdma)
continue;
- dev = port->dev;
for (j = 0; j < dev->dev->num_tx_queues; j++) {
if (airoha_qdma_get_txq(qdma, j) != qid)
continue;
@@ -1563,9 +1567,10 @@ static void airoha_qdma_stop_napi(struct airoha_qdma *qdma)
}
}
-static void airoha_update_hw_stats(struct airoha_gdm_port *port)
+static void airoha_update_hw_stats(struct airoha_gdm_dev *dev)
{
- struct airoha_eth *eth = port->qdma->eth;
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
u32 val, i = 0;
spin_lock(&port->stats.lock);
@@ -1712,11 +1717,11 @@ 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;
- struct airoha_qdma *qdma = port->qdma;
+ 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(port, true);
+ err = airoha_set_vip_for_gdm_port(dev, true);
if (err)
return err;
@@ -1752,11 +1757,11 @@ static int airoha_dev_stop(struct net_device *netdev)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_gdm_port *port = dev->port;
- struct airoha_qdma *qdma = port->qdma;
+ struct airoha_qdma *qdma = dev->qdma;
int i;
netif_tx_disable(netdev);
- airoha_set_vip_for_gdm_port(port, false);
+ airoha_set_vip_for_gdm_port(dev, false);
for (i = 0; i < netdev->num_tx_queues; i++)
netdev_tx_reset_subqueue(netdev, i);
@@ -1782,21 +1787,21 @@ 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 airoha_gdm_port *port = dev->port;
int err;
err = eth_mac_addr(netdev, p);
if (err)
return err;
- airoha_set_macaddr(port, netdev->dev_addr);
+ airoha_set_macaddr(dev, netdev->dev_addr);
return 0;
}
-static int airoha_set_gdm2_loopback(struct airoha_gdm_port *port)
+static int airoha_set_gdm2_loopback(struct airoha_gdm_dev *dev)
{
- struct airoha_eth *eth = port->qdma->eth;
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
u32 val, pse_port, chan;
int i, src_port;
@@ -1843,7 +1848,7 @@ static int airoha_set_gdm2_loopback(struct airoha_gdm_port *port)
__field_prep(SP_CPORT_MASK(val), FE_PSE_PORT_CDM2));
for (i = 0; i < eth->soc->num_ppe; i++)
- airoha_ppe_set_cpu_port(port, i, AIROHA_GDM2_IDX);
+ 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);
@@ -1863,9 +1868,9 @@ static int airoha_dev_init(struct net_device *netdev)
int i;
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
- port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)];
- dev->dev->irq = port->qdma->irq_banks[0].irq;
- airoha_set_macaddr(port, netdev->dev_addr);
+ dev->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)];
+ dev->dev->irq = dev->qdma->irq_banks[0].irq;
+ airoha_set_macaddr(dev, netdev->dev_addr);
switch (port->id) {
case AIROHA_GDM3_IDX:
@@ -1874,7 +1879,7 @@ static int airoha_dev_init(struct net_device *netdev)
if (!eth->ports[1]) {
int err;
- err = airoha_set_gdm2_loopback(port);
+ err = airoha_set_gdm2_loopback(dev);
if (err)
return err;
}
@@ -1884,8 +1889,7 @@ static int airoha_dev_init(struct net_device *netdev)
}
for (i = 0; i < eth->soc->num_ppe; i++)
- airoha_ppe_set_cpu_port(port, i,
- airoha_get_fe_port(port));
+ airoha_ppe_set_cpu_port(dev, i, airoha_get_fe_port(dev));
return 0;
}
@@ -1897,7 +1901,7 @@ static void airoha_dev_get_stats64(struct net_device *netdev,
struct airoha_gdm_port *port = dev->port;
unsigned int start;
- airoha_update_hw_stats(port);
+ airoha_update_hw_stats(dev);
do {
start = u64_stats_fetch_begin(&port->stats.syncp);
storage->rx_packets = port->stats.rx_ok_pkts;
@@ -1917,8 +1921,8 @@ 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;
- struct airoha_eth *eth = port->qdma->eth;
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,
@@ -1992,10 +1996,10 @@ static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev)
#endif
}
-int airoha_get_fe_port(struct airoha_gdm_port *port)
+int airoha_get_fe_port(struct airoha_gdm_dev *dev)
{
- struct airoha_qdma *qdma = port->qdma;
- struct airoha_eth *eth = qdma->eth;
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
switch (eth->soc->version) {
case 0x7583:
@@ -2012,8 +2016,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
struct net_device *netdev)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
- struct airoha_qdma *qdma = port->qdma;
+ struct airoha_qdma *qdma = dev->qdma;
u32 nr_frags, tag, msg0, msg1, len;
struct airoha_queue_entry *e;
struct netdev_queue *txq;
@@ -2051,7 +2054,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
}
}
- fport = airoha_get_fe_port(port);
+ fport = airoha_get_fe_port(dev);
msg1 = FIELD_PREP(QDMA_ETH_TXMSG_FPORT_MASK, fport) |
FIELD_PREP(QDMA_ETH_TXMSG_METER_MASK, 0x7f);
@@ -2154,8 +2157,7 @@ static void airoha_ethtool_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *info)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
- struct airoha_eth *eth = port->qdma->eth;
+ struct airoha_eth *eth = dev->eth;
strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
@@ -2168,7 +2170,7 @@ static void airoha_ethtool_get_mac_stats(struct net_device *netdev,
struct airoha_gdm_port *port = dev->port;
unsigned int start;
- airoha_update_hw_stats(port);
+ airoha_update_hw_stats(dev);
do {
start = u64_stats_fetch_begin(&port->stats.syncp);
stats->FramesTransmittedOK = port->stats.tx_ok_pkts;
@@ -2208,7 +2210,7 @@ airoha_ethtool_get_rmon_stats(struct net_device *netdev,
ARRAY_SIZE(hw_stats->rx_len) + 1);
*ranges = airoha_ethtool_rmon_ranges;
- airoha_update_hw_stats(port);
+ airoha_update_hw_stats(dev);
do {
int i;
@@ -2228,18 +2230,17 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
const u16 *weights, u8 n_weights)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
int i;
for (i = 0; i < AIROHA_NUM_TX_RING; i++)
- airoha_qdma_clear(port->qdma, REG_QUEUE_CLOSE_CFG(channel),
+ airoha_qdma_clear(dev->qdma, REG_QUEUE_CLOSE_CFG(channel),
TXQ_DISABLE_CHAN_QUEUE_MASK(channel, i));
for (i = 0; i < n_weights; i++) {
u32 status;
int err;
- airoha_qdma_wr(port->qdma, REG_TXWRR_WEIGHT_CFG,
+ airoha_qdma_wr(dev->qdma, REG_TXWRR_WEIGHT_CFG,
TWRR_RW_CMD_MASK |
FIELD_PREP(TWRR_CHAN_IDX_MASK, channel) |
FIELD_PREP(TWRR_QUEUE_IDX_MASK, i) |
@@ -2247,13 +2248,12 @@ static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
err = read_poll_timeout(airoha_qdma_rr, status,
status & TWRR_RW_CMD_DONE,
USEC_PER_MSEC, 10 * USEC_PER_MSEC,
- true, port->qdma,
- REG_TXWRR_WEIGHT_CFG);
+ true, dev->qdma, REG_TXWRR_WEIGHT_CFG);
if (err)
return err;
}
- airoha_qdma_rmw(port->qdma, REG_CHAN_QOS_MODE(channel >> 3),
+ airoha_qdma_rmw(dev->qdma, REG_CHAN_QOS_MODE(channel >> 3),
CHAN_QOS_MODE_MASK(channel),
__field_prep(CHAN_QOS_MODE_MASK(channel), mode));
@@ -2319,9 +2319,9 @@ static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel,
struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_gdm_port *port = dev->port;
- u64 cpu_tx_packets = airoha_qdma_rr(port->qdma,
+ u64 cpu_tx_packets = airoha_qdma_rr(dev->qdma,
REG_CNTR_VAL(channel << 1));
- u64 fwd_tx_packets = airoha_qdma_rr(port->qdma,
+ u64 fwd_tx_packets = airoha_qdma_rr(dev->qdma,
REG_CNTR_VAL((channel << 1) + 1));
u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) +
(fwd_tx_packets - port->fwd_tx_packets);
@@ -2585,17 +2585,16 @@ static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev,
u32 bucket_size)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
int i, err;
for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
- err = airoha_qdma_set_trtcm_config(port->qdma, channel,
+ err = airoha_qdma_set_trtcm_config(dev->qdma, channel,
REG_EGRESS_TRTCM_CFG, i,
!!rate, TRTCM_METER_MODE);
if (err)
return err;
- err = airoha_qdma_set_trtcm_token_bucket(port->qdma, channel,
+ err = airoha_qdma_set_trtcm_token_bucket(dev->qdma, channel,
REG_EGRESS_TRTCM_CFG,
i, rate, bucket_size);
if (err)
@@ -2645,11 +2644,11 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
return 0;
}
-static int airoha_qdma_set_rx_meter(struct airoha_gdm_port *port,
+static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev,
u32 rate, u32 bucket_size,
enum trtcm_unit_type unit_type)
{
- struct airoha_qdma *qdma = port->qdma;
+ struct airoha_qdma *qdma = dev->qdma;
int i;
for (i = 0; i < ARRAY_SIZE(qdma->q_rx); i++) {
@@ -2728,7 +2727,6 @@ static int airoha_dev_tc_matchall(struct net_device *netdev,
{
enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT;
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
u32 rate = 0, bucket_size = 0;
switch (f->command) {
@@ -2753,7 +2751,7 @@ static int airoha_dev_tc_matchall(struct net_device *netdev,
fallthrough;
}
case TC_CLSMATCHALL_DESTROY:
- return airoha_qdma_set_rx_meter(port, rate, bucket_size,
+ return airoha_qdma_set_rx_meter(dev, rate, bucket_size,
unit_type);
default:
return -EOPNOTSUPP;
@@ -2765,8 +2763,7 @@ static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type,
{
struct net_device *netdev = cb_priv;
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
- struct airoha_eth *eth = port->qdma->eth;
+ struct airoha_eth *eth = dev->eth;
if (!tc_can_offload(netdev))
return -EOPNOTSUPP;
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index c78cabbec753..f1eea492217c 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -537,12 +537,12 @@ struct airoha_qdma {
struct airoha_gdm_dev {
struct airoha_gdm_port *port;
+ struct airoha_qdma *qdma;
struct net_device *dev;
struct airoha_eth *eth;
};
struct airoha_gdm_port {
- struct airoha_qdma *qdma;
struct airoha_gdm_dev *dev;
int id;
int nbq;
@@ -666,19 +666,18 @@ static inline bool airoha_is_7583(struct airoha_eth *eth)
return eth->soc->version == 0x7583;
}
-int airoha_get_fe_port(struct airoha_gdm_port *port);
+int airoha_get_fe_port(struct airoha_gdm_dev *dev);
bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
struct airoha_gdm_dev *dev);
-void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id,
- u8 fport);
+void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport);
bool airoha_ppe_is_enabled(struct airoha_eth *eth, int index);
void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
u16 hash, bool rx_wlan);
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_port *port);
+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev);
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 af7af4097b98..22f5f1bae730 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -84,9 +84,9 @@ static u32 airoha_ppe_get_timestamp(struct airoha_ppe *ppe)
AIROHA_FOE_IB1_BIND_TIMESTAMP);
}
-void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id, u8 fport)
+void airoha_ppe_set_cpu_port(struct airoha_gdm_dev *dev, u8 ppe_id, u8 fport)
{
- struct airoha_qdma *qdma = port->qdma;
+ struct airoha_qdma *qdma = dev->qdma;
struct airoha_eth *eth = qdma->eth;
u8 qdma_id = qdma - ð->qdma[0];
u32 fe_cpu_port;
@@ -180,8 +180,8 @@ static void airoha_ppe_hw_init(struct airoha_ppe *ppe)
if (!port)
continue;
- airoha_ppe_set_cpu_port(port, i,
- airoha_get_fe_port(port));
+ airoha_ppe_set_cpu_port(port->dev, i,
+ airoha_get_fe_port(port->dev));
}
}
}
@@ -1473,11 +1473,12 @@ 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_port *port)
+void airoha_ppe_init_upd_mem(struct airoha_gdm_dev *dev)
{
- struct airoha_eth *eth = port->qdma->eth;
- struct net_device *dev = port->dev->dev;
- const u8 *addr = dev->dev_addr;
+ 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;
val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 1/6] net: airoha: Introduce airoha_gdm_dev struct
From: Lorenzo Bianconi @ 2026-05-27 10:21 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Simon Horman, linux-arm-kernel, linux-mediatek, netdev,
Xuegang Lu, Lorenzo Bianconi
In-Reply-To: <20260527-airoha-eth-multi-serdes-preliminary-v1-0-ec6ed73ef7fc@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 port and
net_devices.
Introduce airoha_gdm_dev struct to collect net_device related info (e.g.
net_device and external phy pointer). Please note this is just a
preliminary patch and we are still supporting a single net_device for
each GDM port. Subsequent patches will add support for multiple 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 | 312 ++++++++++++++++++-------------
drivers/net/ethernet/airoha/airoha_eth.h | 13 +-
drivers/net/ethernet/airoha/airoha_ppe.c | 17 +-
3 files changed, 206 insertions(+), 136 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 6418fe0c9f80..b2684af2db76 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -600,6 +600,7 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
struct airoha_qdma_desc *desc = &q->desc[q->tail];
u32 hash, reason, msg1, desc_ctrl;
struct airoha_gdm_port *port;
+ struct net_device *netdev;
int data_len, len, p;
struct page *page;
@@ -626,6 +627,10 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
goto free_frag;
port = eth->ports[p];
+ if (!port->dev)
+ goto free_frag;
+
+ netdev = port->dev->dev;
if (!q->skb) { /* first buffer */
q->skb = napi_build_skb(e->buf - AIROHA_RX_HEADROOM,
q->buf_size);
@@ -635,8 +640,8 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
skb_reserve(q->skb, AIROHA_RX_HEADROOM);
__skb_put(q->skb, len);
skb_mark_for_recycle(q->skb);
- q->skb->dev = port->dev;
- q->skb->protocol = eth_type_trans(q->skb, port->dev);
+ q->skb->dev = netdev;
+ q->skb->protocol = eth_type_trans(q->skb, netdev);
q->skb->ip_summed = CHECKSUM_UNNECESSARY;
skb_record_rx_queue(q->skb, qid);
} else { /* scattered frame */
@@ -654,7 +659,7 @@ static int airoha_qdma_rx_process(struct airoha_queue *q, int budget)
if (FIELD_GET(QDMA_DESC_MORE_MASK, desc_ctrl))
continue;
- if (netdev_uses_dsa(port->dev)) {
+ if (netdev_uses_dsa(netdev)) {
/* 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
@@ -848,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;
int j;
if (!port)
@@ -856,11 +862,12 @@ static void airoha_qdma_wake_netdev_txqs(struct airoha_queue *q)
if (port->qdma != qdma)
continue;
- for (j = 0; j < port->dev->num_tx_queues; j++) {
+ dev = port->dev;
+ for (j = 0; j < dev->dev->num_tx_queues; j++) {
if (airoha_qdma_get_txq(qdma, j) != qid)
continue;
- netif_wake_subqueue(port->dev, j);
+ netif_wake_subqueue(dev->dev, j);
}
}
q->txq_stopped = false;
@@ -1700,19 +1707,20 @@ static void airoha_update_hw_stats(struct airoha_gdm_port *port)
spin_unlock(&port->stats.lock);
}
-static int airoha_dev_open(struct net_device *dev)
+static int airoha_dev_open(struct net_device *netdev)
{
- int err, len = ETH_HLEN + dev->mtu + ETH_FCS_LEN;
- struct airoha_gdm_port *port = netdev_priv(dev);
+ 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;
struct airoha_qdma *qdma = port->qdma;
u32 pse_port = FE_PSE_PORT_PPE1;
- netif_tx_start_all_queues(dev);
+ netif_tx_start_all_queues(netdev);
err = airoha_set_vip_for_gdm_port(port, true);
if (err)
return err;
- if (netdev_uses_dsa(dev))
+ if (netdev_uses_dsa(netdev))
airoha_fe_set(qdma->eth, REG_GDM_INGRESS_CFG(port->id),
GDM_STAG_EN_MASK);
else
@@ -1740,16 +1748,17 @@ static int airoha_dev_open(struct net_device *dev)
return 0;
}
-static int airoha_dev_stop(struct net_device *dev)
+static int airoha_dev_stop(struct net_device *netdev)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_qdma *qdma = port->qdma;
int i;
- netif_tx_disable(dev);
+ netif_tx_disable(netdev);
airoha_set_vip_for_gdm_port(port, false);
- for (i = 0; i < dev->num_tx_queues; i++)
- netdev_tx_reset_subqueue(dev, i);
+ 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);
@@ -1770,16 +1779,17 @@ static int airoha_dev_stop(struct net_device *dev)
return 0;
}
-static int airoha_dev_set_macaddr(struct net_device *dev, void *p)
+static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
int err;
- err = eth_mac_addr(dev, p);
+ err = eth_mac_addr(netdev, p);
if (err)
return err;
- airoha_set_macaddr(port, dev->dev_addr);
+ airoha_set_macaddr(port, netdev->dev_addr);
return 0;
}
@@ -1845,16 +1855,17 @@ static int airoha_set_gdm2_loopback(struct airoha_gdm_port *port)
return 0;
}
-static int airoha_dev_init(struct net_device *dev)
+static int airoha_dev_init(struct net_device *netdev)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
- struct airoha_eth *eth = port->eth;
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
+ struct airoha_eth *eth = dev->eth;
int i;
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
port->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)];
- port->dev->irq = port->qdma->irq_banks[0].irq;
- airoha_set_macaddr(port, dev->dev_addr);
+ dev->dev->irq = port->qdma->irq_banks[0].irq;
+ airoha_set_macaddr(port, netdev->dev_addr);
switch (port->id) {
case AIROHA_GDM3_IDX:
@@ -1879,10 +1890,11 @@ static int airoha_dev_init(struct net_device *dev)
return 0;
}
-static void airoha_dev_get_stats64(struct net_device *dev,
+static void airoha_dev_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *storage)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
unsigned int start;
airoha_update_hw_stats(port);
@@ -1901,36 +1913,39 @@ static void airoha_dev_get_stats64(struct net_device *dev,
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
-static int airoha_dev_change_mtu(struct net_device *dev, int mtu)
+static int airoha_dev_change_mtu(struct net_device *netdev, int mtu)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_eth *eth = port->qdma->eth;
u32 len = ETH_HLEN + mtu + ETH_FCS_LEN;
airoha_fe_rmw(eth, REG_GDM_LEN_CFG(port->id),
GDM_LONG_LEN_MASK,
FIELD_PREP(GDM_LONG_LEN_MASK, len));
- WRITE_ONCE(dev->mtu, mtu);
+ WRITE_ONCE(netdev->mtu, mtu);
return 0;
}
-static u16 airoha_dev_select_queue(struct net_device *dev, struct sk_buff *skb,
+static u16 airoha_dev_select_queue(struct net_device *netdev,
+ struct sk_buff *skb,
struct net_device *sb_dev)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
int queue, channel;
/* For dsa device select QoS channel according to the dsa user port
* index, rely on port id otherwise. Select QoS queue based on the
* skb priority.
*/
- channel = netdev_uses_dsa(dev) ? skb_get_queue_mapping(skb) : port->id;
+ channel = netdev_uses_dsa(netdev) ? skb_get_queue_mapping(skb) : port->id;
channel = channel % AIROHA_NUM_QOS_CHANNELS;
queue = (skb->priority - 1) % AIROHA_NUM_QOS_QUEUES; /* QoS queue */
queue = channel * AIROHA_NUM_QOS_QUEUES + queue;
- return queue < dev->num_tx_queues ? queue : 0;
+ return queue < netdev->num_tx_queues ? queue : 0;
}
static u32 airoha_get_dsa_tag(struct sk_buff *skb, struct net_device *dev)
@@ -1994,9 +2009,10 @@ int airoha_get_fe_port(struct airoha_gdm_port *port)
}
static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
- struct net_device *dev)
+ struct net_device *netdev)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_qdma *qdma = port->qdma;
u32 nr_frags, tag, msg0, msg1, len;
struct airoha_queue_entry *e;
@@ -2009,7 +2025,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
u8 fport;
qid = airoha_qdma_get_txq(qdma, skb_get_queue_mapping(skb));
- tag = airoha_get_dsa_tag(skb, dev);
+ tag = airoha_get_dsa_tag(skb, netdev);
msg0 = FIELD_PREP(QDMA_ETH_TXMSG_CHAN_MASK,
qid / AIROHA_NUM_QOS_QUEUES) |
@@ -2045,7 +2061,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
spin_lock_bh(&q->lock);
- txq = skb_get_tx_queue(dev, skb);
+ txq = skb_get_tx_queue(netdev, skb);
nr_frags = 1 + skb_shinfo(skb)->nr_frags;
if (q->queued + nr_frags >= q->ndesc) {
@@ -2069,9 +2085,9 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
dma_addr_t addr;
u32 val;
- addr = dma_map_single(dev->dev.parent, data, len,
+ addr = dma_map_single(netdev->dev.parent, data, len,
DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(dev->dev.parent, addr)))
+ if (unlikely(dma_mapping_error(netdev->dev.parent, addr)))
goto error_unmap;
list_move_tail(&e->list, &tx_list);
@@ -2120,7 +2136,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
error_unmap:
list_for_each_entry(e, &tx_list, list) {
- dma_unmap_single(dev->dev.parent, e->dma_addr, e->dma_len,
+ dma_unmap_single(netdev->dev.parent, e->dma_addr, e->dma_len,
DMA_TO_DEVICE);
e->dma_addr = 0;
}
@@ -2129,25 +2145,27 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
spin_unlock_bh(&q->lock);
error:
dev_kfree_skb_any(skb);
- dev->stats.tx_dropped++;
+ netdev->stats.tx_dropped++;
return NETDEV_TX_OK;
}
-static void airoha_ethtool_get_drvinfo(struct net_device *dev,
+static void airoha_ethtool_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *info)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_eth *eth = port->qdma->eth;
strscpy(info->driver, eth->dev->driver->name, sizeof(info->driver));
strscpy(info->bus_info, dev_name(eth->dev), sizeof(info->bus_info));
}
-static void airoha_ethtool_get_mac_stats(struct net_device *dev,
+static void airoha_ethtool_get_mac_stats(struct net_device *netdev,
struct ethtool_eth_mac_stats *stats)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
unsigned int start;
airoha_update_hw_stats(port);
@@ -2175,11 +2193,12 @@ static const struct ethtool_rmon_hist_range airoha_ethtool_rmon_ranges[] = {
};
static void
-airoha_ethtool_get_rmon_stats(struct net_device *dev,
+airoha_ethtool_get_rmon_stats(struct net_device *netdev,
struct ethtool_rmon_stats *stats,
const struct ethtool_rmon_hist_range **ranges)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_hw_stats *hw_stats = &port->stats;
unsigned int start;
@@ -2204,11 +2223,12 @@ airoha_ethtool_get_rmon_stats(struct net_device *dev,
} while (u64_stats_fetch_retry(&port->stats.syncp, start));
}
-static int airoha_qdma_set_chan_tx_sched(struct net_device *dev,
+static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev,
int channel, enum tx_sched_mode mode,
const u16 *weights, u8 n_weights)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
int i;
for (i = 0; i < AIROHA_NUM_TX_RING; i++)
@@ -2293,10 +2313,12 @@ static int airoha_qdma_set_tx_ets_sched(struct net_device *dev, int channel,
ARRAY_SIZE(w));
}
-static int airoha_qdma_get_tx_ets_stats(struct net_device *dev, int channel,
+static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel,
struct tc_ets_qopt_offload *opt)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
+
u64 cpu_tx_packets = airoha_qdma_rr(port->qdma,
REG_CNTR_VAL(channel << 1));
u64 fwd_tx_packets = airoha_qdma_rr(port->qdma,
@@ -2558,11 +2580,12 @@ static int airoha_qdma_set_trtcm_token_bucket(struct airoha_qdma *qdma,
mode, val);
}
-static int airoha_qdma_set_tx_rate_limit(struct net_device *dev,
+static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev,
int channel, u32 rate,
u32 bucket_size)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
int i, err;
for (i = 0; i <= TRTCM_PEAK_MODE; i++) {
@@ -2582,20 +2605,22 @@ static int airoha_qdma_set_tx_rate_limit(struct net_device *dev,
return 0;
}
-static int airoha_tc_htb_alloc_leaf_queue(struct net_device *dev,
+static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
struct tc_htb_qopt_offload *opt)
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */
- int err, num_tx_queues = dev->real_num_tx_queues;
- struct airoha_gdm_port *port = netdev_priv(dev);
+ int err, num_tx_queues = netdev->real_num_tx_queues;
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
if (opt->parent_classid != TC_HTB_CLASSID_ROOT) {
NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid");
return -EINVAL;
}
- err = airoha_qdma_set_tx_rate_limit(dev, channel, rate, opt->quantum);
+ err = airoha_qdma_set_tx_rate_limit(netdev, channel, rate,
+ opt->quantum);
if (err) {
NL_SET_ERR_MSG_MOD(opt->extack,
"failed configuring htb offload");
@@ -2605,9 +2630,10 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *dev,
if (opt->command == TC_HTB_NODE_MODIFY)
return 0;
- err = netif_set_real_num_tx_queues(dev, num_tx_queues + 1);
+ err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1);
if (err) {
- airoha_qdma_set_tx_rate_limit(dev, channel, 0, opt->quantum);
+ airoha_qdma_set_tx_rate_limit(netdev, channel, 0,
+ opt->quantum);
NL_SET_ERR_MSG_MOD(opt->extack,
"failed setting real_num_tx_queues");
return err;
@@ -2697,11 +2723,12 @@ static int airoha_tc_matchall_act_validate(struct tc_cls_matchall_offload *f)
return 0;
}
-static int airoha_dev_tc_matchall(struct net_device *dev,
+static int airoha_dev_tc_matchall(struct net_device *netdev,
struct tc_cls_matchall_offload *f)
{
enum trtcm_unit_type unit_type = TRTCM_BYTE_UNIT;
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
u32 rate = 0, bucket_size = 0;
switch (f->command) {
@@ -2736,18 +2763,19 @@ static int airoha_dev_tc_matchall(struct net_device *dev,
static int airoha_dev_setup_tc_block_cb(enum tc_setup_type type,
void *type_data, void *cb_priv)
{
- struct net_device *dev = cb_priv;
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct net_device *netdev = cb_priv;
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
struct airoha_eth *eth = port->qdma->eth;
- if (!tc_can_offload(dev))
+ if (!tc_can_offload(netdev))
return -EOPNOTSUPP;
switch (type) {
case TC_SETUP_CLSFLOWER:
return airoha_ppe_setup_tc_block_cb(ð->ppe->dev, type_data);
case TC_SETUP_CLSMATCHALL:
- return airoha_dev_tc_matchall(dev, type_data);
+ return airoha_dev_tc_matchall(netdev, type_data);
default:
return -EOPNOTSUPP;
}
@@ -2794,47 +2822,51 @@ static int airoha_dev_setup_tc_block(struct net_device *dev,
}
}
-static void airoha_tc_remove_htb_queue(struct net_device *dev, int queue)
+static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
- netif_set_real_num_tx_queues(dev, dev->real_num_tx_queues - 1);
- airoha_qdma_set_tx_rate_limit(dev, queue + 1, 0, 0);
+ netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
+ airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0);
clear_bit(queue, port->qos_sq_bmap);
}
-static int airoha_tc_htb_delete_leaf_queue(struct net_device *dev,
+static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
struct tc_htb_qopt_offload *opt)
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
if (!test_bit(channel, port->qos_sq_bmap)) {
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
return -EINVAL;
}
- airoha_tc_remove_htb_queue(dev, channel);
+ airoha_tc_remove_htb_queue(netdev, channel);
return 0;
}
-static int airoha_tc_htb_destroy(struct net_device *dev)
+static int airoha_tc_htb_destroy(struct net_device *netdev)
{
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
int q;
for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
- airoha_tc_remove_htb_queue(dev, q);
+ airoha_tc_remove_htb_queue(netdev, q);
return 0;
}
-static int airoha_tc_get_htb_get_leaf_queue(struct net_device *dev,
+static int airoha_tc_get_htb_get_leaf_queue(struct net_device *netdev,
struct tc_htb_qopt_offload *opt)
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port = dev->port;
if (!test_bit(channel, port->qos_sq_bmap)) {
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
@@ -2870,8 +2902,8 @@ static int airoha_tc_setup_qdisc_htb(struct net_device *dev,
return 0;
}
-static int airoha_dev_tc_setup(struct net_device *dev, enum tc_setup_type type,
- void *type_data)
+static int airoha_dev_tc_setup(struct net_device *dev,
+ enum tc_setup_type type, void *type_data)
{
switch (type) {
case TC_SETUP_QDISC_ETS:
@@ -2937,25 +2969,81 @@ static void airoha_metadata_dst_free(struct airoha_gdm_port *port)
}
}
-bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
- struct airoha_gdm_port *port)
+bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
+ struct airoha_gdm_dev *dev)
{
int i;
for (i = 0; i < ARRAY_SIZE(eth->ports); i++) {
- if (eth->ports[i] == port)
+ struct airoha_gdm_port *port = eth->ports[i];
+
+ if (!port)
+ continue;
+
+ if (port->dev == dev)
return true;
}
return false;
}
+static int airoha_alloc_gdm_device(struct airoha_eth *eth,
+ struct airoha_gdm_port *port,
+ struct device_node *np)
+{
+ struct airoha_gdm_dev *dev;
+ struct net_device *netdev;
+ int err;
+
+ netdev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*dev),
+ AIROHA_NUM_NETDEV_TX_RINGS,
+ AIROHA_NUM_RX_RING);
+ if (!netdev) {
+ dev_err(eth->dev, "alloc_etherdev failed\n");
+ return -ENOMEM;
+ }
+
+ netdev->netdev_ops = &airoha_netdev_ops;
+ netdev->ethtool_ops = &airoha_ethtool_ops;
+ netdev->max_mtu = AIROHA_MAX_MTU;
+ netdev->watchdog_timeo = 5 * HZ;
+ netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO6 |
+ NETIF_F_IPV6_CSUM | NETIF_F_SG | NETIF_F_TSO |
+ 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 */
+ err = netif_set_real_num_tx_queues(netdev, AIROHA_NUM_TX_RING);
+ if (err)
+ return err;
+
+ err = of_get_ethdev_address(np, netdev);
+ if (err) {
+ if (err == -EPROBE_DEFER)
+ return err;
+
+ eth_hw_addr_random(netdev);
+ dev_info(eth->dev, "generated random MAC address %pM\n",
+ netdev->dev_addr);
+ }
+
+ dev = netdev_priv(netdev);
+ dev->dev = netdev;
+ dev->port = port;
+ port->dev = dev;
+ dev->eth = eth;
+
+ return 0;
+}
+
static int airoha_alloc_gdm_port(struct airoha_eth *eth,
struct device_node *np)
{
const __be32 *id_ptr = of_get_property(np, "reg", NULL);
struct airoha_gdm_port *port;
- struct net_device *dev;
int err, p;
u32 id;
@@ -2977,53 +3065,22 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth,
return -EINVAL;
}
- dev = devm_alloc_etherdev_mqs(eth->dev, sizeof(*port),
- AIROHA_NUM_NETDEV_TX_RINGS,
- AIROHA_NUM_RX_RING);
- if (!dev) {
- dev_err(eth->dev, "alloc_etherdev failed\n");
+ port = devm_kzalloc(eth->dev, sizeof(*port), GFP_KERNEL);
+ if (!port)
return -ENOMEM;
- }
-
- dev->netdev_ops = &airoha_netdev_ops;
- dev->ethtool_ops = &airoha_ethtool_ops;
- dev->max_mtu = AIROHA_MAX_MTU;
- dev->watchdog_timeo = 5 * HZ;
- dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
- NETIF_F_TSO6 | NETIF_F_IPV6_CSUM |
- NETIF_F_SG | NETIF_F_TSO |
- NETIF_F_HW_TC;
- dev->features |= dev->hw_features;
- dev->vlan_features = dev->hw_features;
- dev->dev.of_node = np;
- SET_NETDEV_DEV(dev, eth->dev);
- /* reserve hw queues for HTB offloading */
- err = netif_set_real_num_tx_queues(dev, AIROHA_NUM_TX_RING);
- if (err)
- return err;
-
- err = of_get_ethdev_address(np, dev);
- if (err) {
- if (err == -EPROBE_DEFER)
- return err;
-
- eth_hw_addr_random(dev);
- dev_info(eth->dev, "generated random MAC address %pM\n",
- dev->dev_addr);
- }
-
- port = netdev_priv(dev);
u64_stats_init(&port->stats.syncp);
spin_lock_init(&port->stats.lock);
- port->eth = eth;
- port->dev = dev;
port->id = id;
/* XXX: Read nbq from DTS */
port->nbq = id == AIROHA_GDM3_IDX && airoha_is_7581(eth) ? 4 : 0;
eth->ports[p] = port;
- return airoha_metadata_dst_alloc(port);
+ err = airoha_metadata_dst_alloc(port);
+ if (err)
+ return err;
+
+ return airoha_alloc_gdm_device(eth, port, np);
}
static int airoha_register_gdm_devices(struct airoha_eth *eth)
@@ -3037,7 +3094,7 @@ static int airoha_register_gdm_devices(struct airoha_eth *eth)
if (!port)
continue;
- err = register_netdev(port->dev);
+ err = register_netdev(port->dev->dev);
if (err)
return err;
}
@@ -3146,12 +3203,14 @@ 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;
if (!port)
continue;
- if (port->dev->reg_state == NETREG_REGISTERED)
- unregister_netdev(port->dev);
+ dev = port->dev;
+ if (dev && dev->dev->reg_state == NETREG_REGISTERED)
+ unregister_netdev(dev->dev);
airoha_metadata_dst_free(port);
}
airoha_hw_cleanup(eth);
@@ -3172,11 +3231,14 @@ 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;
if (!port)
continue;
- unregister_netdev(port->dev);
+ dev = port->dev;
+ if (dev)
+ unregister_netdev(dev->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 d3781103abb5..c78cabbec753 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -535,10 +535,15 @@ struct airoha_qdma {
struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
};
+struct airoha_gdm_dev {
+ struct airoha_gdm_port *port;
+ struct net_device *dev;
+ struct airoha_eth *eth;
+};
+
struct airoha_gdm_port {
struct airoha_qdma *qdma;
- struct airoha_eth *eth;
- struct net_device *dev;
+ struct airoha_gdm_dev *dev;
int id;
int nbq;
@@ -662,8 +667,8 @@ static inline bool airoha_is_7583(struct airoha_eth *eth)
}
int airoha_get_fe_port(struct airoha_gdm_port *port);
-bool airoha_is_valid_gdm_port(struct airoha_eth *eth,
- struct airoha_gdm_port *port);
+bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
+ struct airoha_gdm_dev *dev);
void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id,
u8 fport);
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 26da519236bf..af7af4097b98 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -298,12 +298,12 @@ static void airoha_ppe_foe_set_bridge_addrs(struct airoha_foe_bridge *br,
static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
struct airoha_foe_entry *hwe,
- struct net_device *dev, int type,
+ struct net_device *netdev, int type,
struct airoha_flow_data *data,
int l4proto)
{
u32 qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f), ports_pad, val;
- int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&dev);
+ int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&netdev);
struct airoha_foe_mac_info_common *l2;
u8 smac_id = 0xf;
@@ -319,10 +319,11 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
hwe->ib1 = val;
val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f);
- if (dev) {
+ if (netdev) {
struct airoha_wdma_info info = {};
- if (!airoha_ppe_get_wdma_info(dev, data->eth.h_dest, &info)) {
+ if (!airoha_ppe_get_wdma_info(netdev, data->eth.h_dest,
+ &info)) {
val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, info.idx) |
FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT,
FE_PSE_PORT_CDM4);
@@ -332,12 +333,14 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
FIELD_PREP(AIROHA_FOE_MAC_WDMA_WCID,
info.wcid);
} else {
- struct airoha_gdm_port *port = netdev_priv(dev);
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_gdm_port *port;
u8 pse_port, channel;
- if (!airoha_is_valid_gdm_port(eth, port))
+ if (!airoha_is_valid_gdm_dev(eth, dev))
return -EINVAL;
+ port = dev->port;
if (dsa_port >= 0 || eth->ports[1])
pse_port = port->id == 4 ? FE_PSE_PORT_GDM4
: port->id;
@@ -1473,7 +1476,7 @@ void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port)
{
struct airoha_eth *eth = port->qdma->eth;
- struct net_device *dev = port->dev;
+ struct net_device *dev = port->dev->dev;
const u8 *addr = dev->dev_addr;
u32 val;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 3/6] net: airoha: Rely on airoha_gdm_dev pointer in airoha_is_lan_gdm_port()
From: Lorenzo Bianconi @ 2026-05-27 10:21 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Simon Horman, linux-arm-kernel, linux-mediatek, netdev,
Xuegang Lu, Lorenzo Bianconi
In-Reply-To: <20260527-airoha-eth-multi-serdes-preliminary-v1-0-ec6ed73ef7fc@kernel.org>
Rename airoha_is_lan_gdm_port in airoha_is_lan_gdm_dev. Moreover, rely
on airoha_gdm_dev pointer in airoha_is_lan_gdm_dev() instead of
airoha_gdm_port one.
This is a preliminary patch to support multiple net_devices connected to
the same GDM{3,4} port via an external hw arbiter.
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 6 ++----
drivers/net/ethernet/airoha/airoha_eth.h | 4 +++-
drivers/net/ethernet/airoha/airoha_ppe.c | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 0f37d26e4d52..c5d25f7640ac 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -73,12 +73,10 @@ static void airoha_qdma_irq_disable(struct airoha_irq_bank *irq_bank,
static void airoha_set_macaddr(struct airoha_gdm_dev *dev, const u8 *addr)
{
- struct airoha_gdm_port *port = dev->port;
struct airoha_eth *eth = dev->eth;
u32 val, reg;
- reg = airoha_is_lan_gdm_port(port) ? REG_FE_LAN_MAC_H
- : REG_FE_WAN_MAC_H;
+ 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);
@@ -1868,7 +1866,7 @@ static int airoha_dev_init(struct net_device *netdev)
int i;
/* QDMA0 is used for lan ports while QDMA1 is used for WAN ports */
- dev->qdma = ð->qdma[!airoha_is_lan_gdm_port(port)];
+ dev->qdma = ð->qdma[!airoha_is_lan_gdm_dev(dev)];
dev->dev->irq = dev->qdma->irq_banks[0].irq;
airoha_set_macaddr(dev, netdev->dev_addr);
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index f1eea492217c..f6f59d25abd9 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -647,8 +647,10 @@ static inline u16 airoha_qdma_get_txq(struct airoha_qdma *qdma, u16 qid)
return qid % ARRAY_SIZE(qdma->q_tx);
}
-static inline bool airoha_is_lan_gdm_port(struct airoha_gdm_port *port)
+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.
diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c
index 22f5f1bae730..047141b2d6d8 100644
--- a/drivers/net/ethernet/airoha/airoha_ppe.c
+++ b/drivers/net/ethernet/airoha/airoha_ppe.c
@@ -362,7 +362,7 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
/* For downlink traffic consume SRAM memory for hw
* forwarding descriptors queue.
*/
- if (airoha_is_lan_gdm_port(port))
+ if (airoha_is_lan_gdm_dev(dev))
val |= AIROHA_FOE_IB2_FAST_PATH;
if (dsa_port >= 0)
val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ,
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 4/6] net: airoha: Move qos_sq_bmap in airoha_gdm_dev struct
From: Lorenzo Bianconi @ 2026-05-27 10:21 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Simon Horman, linux-arm-kernel, linux-mediatek, netdev,
Xuegang Lu, Lorenzo Bianconi
In-Reply-To: <20260527-airoha-eth-multi-serdes-preliminary-v1-0-ec6ed73ef7fc@kernel.org>
Since now multiple net_devices connected to different QDMA blocks can
share the same GDM port, qos_sq_bmap field can be overwritten with the
configuration obtained from a net_device connected to a different QDMA
block. In order to fix the issue move qos_sq_bmap field from
airoha_gdm_port struct to airoha_gdm_dev one.
Add qos_channel_map bitmap in airoha_qdma struct to track if a shared
QDMA channel is already in use by another net_device.
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 58 ++++++++++++++++++++------------
drivers/net/ethernet/airoha/airoha_eth.h | 6 ++--
2 files changed, 40 insertions(+), 24 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index c5d25f7640ac..4f77a0c22162 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2602,30 +2602,40 @@ static int airoha_qdma_set_tx_rate_limit(struct net_device *netdev,
return 0;
}
-static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
- struct tc_htb_qopt_offload *opt)
+static int airoha_tc_htb_modify_queue(struct net_device *dev,
+ struct tc_htb_qopt_offload *opt)
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
u32 rate = div_u64(opt->rate, 1000) << 3; /* kbps */
- int err, num_tx_queues = netdev->real_num_tx_queues;
- struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
if (opt->parent_classid != TC_HTB_CLASSID_ROOT) {
NL_SET_ERR_MSG_MOD(opt->extack, "invalid parent classid");
return -EINVAL;
}
- err = airoha_qdma_set_tx_rate_limit(netdev, channel, rate,
- opt->quantum);
- if (err) {
+ return airoha_qdma_set_tx_rate_limit(dev, channel, rate, opt->quantum);
+}
+
+static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
+ struct tc_htb_qopt_offload *opt)
+{
+ u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
+ int err, num_tx_queues = netdev->real_num_tx_queues;
+ struct airoha_gdm_dev *dev = netdev_priv(netdev);
+ struct airoha_qdma *qdma = dev->qdma;
+
+ /* Here we need to check the requested QDMA channel is not already
+ * in use by another net_device running on the same QDMA block.
+ */
+ if (test_and_set_bit(channel, qdma->qos_channel_map)) {
NL_SET_ERR_MSG_MOD(opt->extack,
- "failed configuring htb offload");
- return err;
+ "qdma qos channel already in use");
+ return -EBUSY;
}
- if (opt->command == TC_HTB_NODE_MODIFY)
- return 0;
+ err = airoha_tc_htb_modify_queue(netdev, opt);
+ if (err)
+ goto error;
err = netif_set_real_num_tx_queues(netdev, num_tx_queues + 1);
if (err) {
@@ -2633,13 +2643,17 @@ static int airoha_tc_htb_alloc_leaf_queue(struct net_device *netdev,
opt->quantum);
NL_SET_ERR_MSG_MOD(opt->extack,
"failed setting real_num_tx_queues");
- return err;
+ goto error;
}
- set_bit(channel, port->qos_sq_bmap);
+ set_bit(channel, dev->qos_sq_bmap);
opt->qid = AIROHA_NUM_TX_RING + channel;
return 0;
+error:
+ clear_bit(channel, qdma->qos_channel_map);
+
+ return err;
}
static int airoha_qdma_set_rx_meter(struct airoha_gdm_dev *dev,
@@ -2820,11 +2834,13 @@ static int airoha_dev_setup_tc_block(struct net_device *dev,
static void airoha_tc_remove_htb_queue(struct net_device *netdev, int queue)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
+ struct airoha_qdma *qdma = dev->qdma;
netif_set_real_num_tx_queues(netdev, netdev->real_num_tx_queues - 1);
airoha_qdma_set_tx_rate_limit(netdev, queue + 1, 0, 0);
- clear_bit(queue, port->qos_sq_bmap);
+
+ clear_bit(queue, qdma->qos_channel_map);
+ clear_bit(queue, dev->qos_sq_bmap);
}
static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
@@ -2832,9 +2848,8 @@ static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
- if (!test_bit(channel, port->qos_sq_bmap)) {
+ if (!test_bit(channel, dev->qos_sq_bmap)) {
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
return -EINVAL;
}
@@ -2847,10 +2862,9 @@ static int airoha_tc_htb_delete_leaf_queue(struct net_device *netdev,
static int airoha_tc_htb_destroy(struct net_device *netdev)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
int q;
- for_each_set_bit(q, port->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
+ for_each_set_bit(q, dev->qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS)
airoha_tc_remove_htb_queue(netdev, q);
return 0;
@@ -2861,9 +2875,8 @@ static int airoha_tc_get_htb_get_leaf_queue(struct net_device *netdev,
{
u32 channel = TC_H_MIN(opt->classid) % AIROHA_NUM_QOS_CHANNELS;
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
- if (!test_bit(channel, port->qos_sq_bmap)) {
+ if (!test_bit(channel, dev->qos_sq_bmap)) {
NL_SET_ERR_MSG_MOD(opt->extack, "invalid queue id");
return -EINVAL;
}
@@ -2882,6 +2895,7 @@ static int airoha_tc_setup_qdisc_htb(struct net_device *dev,
case TC_HTB_DESTROY:
return airoha_tc_htb_destroy(dev);
case TC_HTB_NODE_MODIFY:
+ return airoha_tc_htb_modify_queue(dev, opt);
case TC_HTB_LEAF_ALLOC_QUEUE:
return airoha_tc_htb_alloc_leaf_queue(dev, opt);
case TC_HTB_LEAF_DEL:
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index f6f59d25abd9..a308a770116b 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -533,6 +533,8 @@ struct airoha_qdma {
struct airoha_queue q_tx[AIROHA_NUM_TX_RING];
struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
+
+ DECLARE_BITMAP(qos_channel_map, AIROHA_NUM_QOS_CHANNELS);
};
struct airoha_gdm_dev {
@@ -540,6 +542,8 @@ struct airoha_gdm_dev {
struct airoha_qdma *qdma;
struct net_device *dev;
struct airoha_eth *eth;
+
+ DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
};
struct airoha_gdm_port {
@@ -549,8 +553,6 @@ struct airoha_gdm_port {
struct airoha_hw_stats stats;
- DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
-
/* qos stats counters */
u64 cpu_tx_packets;
u64 fwd_tx_packets;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 6/6] net: airoha: Rename airoha_set_gdm2_loopback in airoha_enable_gdm2_loopback
From: Lorenzo Bianconi @ 2026-05-27 10:21 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Simon Horman, linux-arm-kernel, linux-mediatek, netdev,
Lorenzo Bianconi
In-Reply-To: <20260527-airoha-eth-multi-serdes-preliminary-v1-0-ec6ed73ef7fc@kernel.org>
This is a preliminary patch in order to allow the user to select if the
configured device will be used as hw lan or wan.
Please not this patch does not introduce any logical changes, just
cosmetic ones.
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 72c6f554508c..6574901ebd19 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -1796,7 +1796,7 @@ static int airoha_dev_set_macaddr(struct net_device *netdev, void *p)
return 0;
}
-static int airoha_set_gdm2_loopback(struct airoha_gdm_dev *dev)
+static int airoha_enable_gdm2_loopback(struct airoha_gdm_dev *dev)
{
struct airoha_gdm_port *port = dev->port;
struct airoha_eth *eth = dev->eth;
@@ -1877,7 +1877,7 @@ static int airoha_dev_init(struct net_device *netdev)
if (!eth->ports[1]) {
int err;
- err = airoha_set_gdm2_loopback(dev);
+ err = airoha_enable_gdm2_loopback(dev);
if (err)
return err;
}
--
2.54.0
^ permalink raw reply related
* [PATCH net-next 5/6] net: airoha: Move {cpu,fwd}_tx_packets in airoha_gdm_dev struct
From: Lorenzo Bianconi @ 2026-05-27 10:21 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Simon Horman, linux-arm-kernel, linux-mediatek, netdev,
Xuegang Lu, Lorenzo Bianconi
In-Reply-To: <20260527-airoha-eth-multi-serdes-preliminary-v1-0-ec6ed73ef7fc@kernel.org>
Since now multiple net_devices connected to different QDMA blocks can
share the same GDM port, cpu_tx_packets and fwd_tx_packets fields can
be overwritten with the value from a different QDMA block. In order to
fix the issue move cpu_tx_packets and fwd_tx_packets fields from
airoha_gdm_port struct to airoha_gdm_dev one.
Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 16 +++++++---------
drivers/net/ethernet/airoha/airoha_eth.h | 7 +++----
2 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 4f77a0c22162..72c6f554508c 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2315,19 +2315,17 @@ static int airoha_qdma_get_tx_ets_stats(struct net_device *netdev, int channel,
struct tc_ets_qopt_offload *opt)
{
struct airoha_gdm_dev *dev = netdev_priv(netdev);
- struct airoha_gdm_port *port = dev->port;
+ struct airoha_qdma *qdma = dev->qdma;
- u64 cpu_tx_packets = airoha_qdma_rr(dev->qdma,
- REG_CNTR_VAL(channel << 1));
- u64 fwd_tx_packets = airoha_qdma_rr(dev->qdma,
+ u64 cpu_tx_packets = airoha_qdma_rr(qdma, REG_CNTR_VAL(channel << 1));
+ u64 fwd_tx_packets = airoha_qdma_rr(qdma,
REG_CNTR_VAL((channel << 1) + 1));
- u64 tx_packets = (cpu_tx_packets - port->cpu_tx_packets) +
- (fwd_tx_packets - port->fwd_tx_packets);
+ u64 tx_packets = (cpu_tx_packets - dev->cpu_tx_packets) +
+ (fwd_tx_packets - dev->fwd_tx_packets);
_bstats_update(opt->stats.bstats, 0, tx_packets);
-
- port->cpu_tx_packets = cpu_tx_packets;
- port->fwd_tx_packets = fwd_tx_packets;
+ dev->cpu_tx_packets = cpu_tx_packets;
+ dev->fwd_tx_packets = fwd_tx_packets;
return 0;
}
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index a308a770116b..fbb50dc73af8 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -544,6 +544,9 @@ struct airoha_gdm_dev {
struct airoha_eth *eth;
DECLARE_BITMAP(qos_sq_bmap, AIROHA_NUM_QOS_CHANNELS);
+ /* qos stats counters */
+ u64 cpu_tx_packets;
+ u64 fwd_tx_packets;
};
struct airoha_gdm_port {
@@ -553,10 +556,6 @@ struct airoha_gdm_port {
struct airoha_hw_stats stats;
- /* qos stats counters */
- u64 cpu_tx_packets;
- u64 fwd_tx_packets;
-
struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS];
};
--
2.54.0
^ permalink raw reply related
* [PATCH v1 0/3] regulator: Use named initializers for platform_device_id arrays
From: Uwe Kleine-König (The Capable Hub) @ 2026-05-27 10:47 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown
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
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.
This robustness is needed as I want to do
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 3b0c9a251a2e..b84881f32444 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -610,4 +610,7 @@ struct dmi_system_id {
struct platform_device_id {
char name[PLATFORM_NAME_SIZE];
- kernel_ulong_t driver_data;
+ union {
+ kernel_ulong_t driver_data;
+ const void *driver_data_ptr;
+ };
};
which allows dropping several casts and eases porting CHERI to mainline
linux. A possible follow-up change is the following example:
diff --git a/drivers/regulator/bd96801-regulator.c b/drivers/regulator/bd96801-regulator.c
index 308279b31fd3..6bbad1f1ddd1 100644
--- a/drivers/regulator/bd96801-regulator.c
+++ b/drivers/regulator/bd96801-regulator.c
@@ -1211,7 +1211,7 @@ static int bd96801_probe(struct platform_device *pdev)
{
struct regulator_dev *ldo_errs_rdev_arr[BD96801_NUM_LDOS];
struct regulator_dev *all_rdevs[BD96801_NUM_REGULATORS];
- struct bd96801_pmic_data *pdata_template;
+ const struct bd96801_pmic_data *pdata_template;
struct bd96801_regulator_data *rdesc;
struct regulator_config config = {};
int ldo_errs_arr[BD96801_NUM_LDOS];
@@ -1224,7 +1224,7 @@ static int bd96801_probe(struct platform_device *pdev)
parent = pdev->dev.parent;
- pdata_template = (struct bd96801_pmic_data *)platform_get_device_id(pdev)->driver_data;
+ pdata_template = platform_get_device_id(pdev)->driver_data_ptr;
if (!pdata_template)
return -ENODEV;
@@ -1329,10 +1329,10 @@ static int bd96801_probe(struct platform_device *pdev)
}
static const struct platform_device_id bd96801_pmic_id[] = {
- { .name = "bd96801-regulator", .driver_data = (kernel_ulong_t)&bd96801_data },
- { .name = "bd96802-regulator", .driver_data = (kernel_ulong_t)&bd96802_data },
- { .name = "bd96805-regulator", .driver_data = (kernel_ulong_t)&bd96805_data },
- { .name = "bd96806-regulator", .driver_data = (kernel_ulong_t)&bd96806_data },
+ { .name = "bd96801-regulator", .driver_data_ptr = &bd96801_data },
+ { .name = "bd96802-regulator", .driver_data_ptr = &bd96802_data },
+ { .name = "bd96805-regulator", .driver_data_ptr = &bd96805_data },
+ { .name = "bd96806-regulator", .driver_data_ptr = &bd96806_data },
{ }
};
MODULE_DEVICE_TABLE(platform, bd96801_pmic_id);
which allows the compiler to notice that driver_data is supposed to
be const and thus requires the first hunk.
If you consider the last patch mostly churn, just drop it.
Best regards
Uwe
Uwe Kleine-König (The Capable Hub) (3):
regulator: Drop unused assignment of platform_device_id driver data
regulator: Use named initializers for platform_device_id arrays
regulator: Unify usage of space and comma in platform_device_id arrays
drivers/regulator/88pm8607.c | 4 +---
drivers/regulator/88pm886-regulator.c | 2 +-
drivers/regulator/bd71815-regulator.c | 4 ++--
drivers/regulator/bd71828-regulator.c | 6 +++---
drivers/regulator/bd718x7-regulator.c | 6 +++---
drivers/regulator/bd9571mwv-regulator.c | 4 ++--
drivers/regulator/bd9576-regulator.c | 6 +++---
drivers/regulator/bd96801-regulator.c | 10 +++++-----
drivers/regulator/hi6421-regulator.c | 2 +-
drivers/regulator/hi6421v530-regulator.c | 2 +-
drivers/regulator/hi6421v600-regulator.c | 2 +-
drivers/regulator/hi655x-regulator.c | 2 +-
drivers/regulator/lp873x-regulator.c | 2 +-
drivers/regulator/lp87565-regulator.c | 4 ++--
drivers/regulator/max14577-regulator.c | 4 ++--
drivers/regulator/max77541-regulator.c | 4 ++--
drivers/regulator/max77620-regulator.c | 8 ++++----
drivers/regulator/max77686-regulator.c | 4 ++--
drivers/regulator/max77693-regulator.c | 6 +++---
drivers/regulator/max77802-regulator.c | 4 ++--
drivers/regulator/max8997-regulator.c | 4 ++--
drivers/regulator/max8998.c | 4 ++--
drivers/regulator/mt6323-regulator.c | 4 ++--
drivers/regulator/mt6331-regulator.c | 4 ++--
drivers/regulator/mt6332-regulator.c | 4 ++--
drivers/regulator/mt6357-regulator.c | 4 ++--
drivers/regulator/mt6358-regulator.c | 4 ++--
drivers/regulator/mt6359-regulator.c | 4 ++--
drivers/regulator/mt6360-regulator.c | 4 ++--
drivers/regulator/mt6370-regulator.c | 4 ++--
drivers/regulator/mt6380-regulator.c | 4 ++--
drivers/regulator/mt6397-regulator.c | 4 ++--
drivers/regulator/pf1550-regulator.c | 2 +-
drivers/regulator/qcom-pm8008-regulator.c | 2 +-
drivers/regulator/rt4831-regulator.c | 4 ++--
drivers/regulator/rt5033-regulator.c | 2 +-
drivers/regulator/rt5120-regulator.c | 4 ++--
drivers/regulator/s2dos05-regulator.c | 4 ++--
drivers/regulator/s2mpa01.c | 4 ++--
drivers/regulator/s2mps11.c | 18 +++++++++---------
drivers/regulator/s5m8767.c | 4 ++--
drivers/regulator/sy7636a-regulator.c | 2 +-
drivers/regulator/tps65086-regulator.c | 2 +-
drivers/regulator/tps65218-regulator.c | 2 +-
drivers/regulator/tps65219-regulator.c | 6 +++---
drivers/regulator/tps65912-regulator.c | 2 +-
46 files changed, 95 insertions(+), 97 deletions(-)
base-commit: e7e28506af98ce4e1059e5ec59334b335c00a246
--
2.47.3
^ permalink raw reply related
* [PATCH v1 1/3] regulator: Drop unused assignment of platform_device_id driver data
From: Uwe Kleine-König (The Capable Hub) @ 2026-05-27 10:47 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown
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
In-Reply-To: <cover.1779878004.git.u.kleine-koenig@baylibre.com>
Several drivers explicitly set the .driver_data member of struct
platform_device_id to zero without relying on that value. Drop these
unused assignments.
While touching these arrays unify spacing, usage of commas and use
named initializers for .name.
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
---
drivers/regulator/88pm8607.c | 4 +---
drivers/regulator/max77686-regulator.c | 4 ++--
drivers/regulator/max77802-regulator.c | 4 ++--
drivers/regulator/max8997-regulator.c | 4 ++--
drivers/regulator/mt6323-regulator.c | 4 ++--
drivers/regulator/mt6331-regulator.c | 4 ++--
drivers/regulator/mt6332-regulator.c | 4 ++--
drivers/regulator/mt6358-regulator.c | 4 ++--
drivers/regulator/mt6359-regulator.c | 4 ++--
drivers/regulator/mt6360-regulator.c | 4 ++--
drivers/regulator/mt6370-regulator.c | 4 ++--
drivers/regulator/mt6380-regulator.c | 4 ++--
drivers/regulator/mt6397-regulator.c | 4 ++--
drivers/regulator/rt4831-regulator.c | 4 ++--
drivers/regulator/rt5120-regulator.c | 4 ++--
drivers/regulator/s2mpa01.c | 4 ++--
drivers/regulator/s5m8767.c | 4 ++--
17 files changed, 33 insertions(+), 35 deletions(-)
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index e6c436955e25..969554725a67 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -371,12 +371,10 @@ static int pm8607_regulator_probe(struct platform_device *pdev)
static const struct platform_device_id pm8607_regulator_driver_ids[] = {
{
.name = "88pm860x-regulator",
- .driver_data = 0,
}, {
.name = "88pm860x-preg",
- .driver_data = 0,
},
- { },
+ { }
};
MODULE_DEVICE_TABLE(platform, pm8607_regulator_driver_ids);
diff --git a/drivers/regulator/max77686-regulator.c b/drivers/regulator/max77686-regulator.c
index c7b270fd9e0c..3a0156f4d6e7 100644
--- a/drivers/regulator/max77686-regulator.c
+++ b/drivers/regulator/max77686-regulator.c
@@ -517,8 +517,8 @@ static int max77686_pmic_probe(struct platform_device *pdev)
}
static const struct platform_device_id max77686_pmic_id[] = {
- {"max77686-pmic", 0},
- { },
+ { .name = "max77686-pmic" },
+ { }
};
MODULE_DEVICE_TABLE(platform, max77686_pmic_id);
diff --git a/drivers/regulator/max77802-regulator.c b/drivers/regulator/max77802-regulator.c
index b2e87642bec4..4c05cc9c4bd2 100644
--- a/drivers/regulator/max77802-regulator.c
+++ b/drivers/regulator/max77802-regulator.c
@@ -546,8 +546,8 @@ static int max77802_pmic_probe(struct platform_device *pdev)
}
static const struct platform_device_id max77802_pmic_id[] = {
- {"max77802-pmic", 0},
- { },
+ { .name = "max77802-pmic" },
+ { }
};
MODULE_DEVICE_TABLE(platform, max77802_pmic_id);
diff --git a/drivers/regulator/max8997-regulator.c b/drivers/regulator/max8997-regulator.c
index e77621b6466c..e48ba694a906 100644
--- a/drivers/regulator/max8997-regulator.c
+++ b/drivers/regulator/max8997-regulator.c
@@ -1152,8 +1152,8 @@ static int max8997_pmic_probe(struct platform_device *pdev)
}
static const struct platform_device_id max8997_pmic_id[] = {
- { "max8997-pmic", 0},
- { },
+ { .name = "max8997-pmic" },
+ { }
};
MODULE_DEVICE_TABLE(platform, max8997_pmic_id);
diff --git a/drivers/regulator/mt6323-regulator.c b/drivers/regulator/mt6323-regulator.c
index b43da848a06e..bac226812b0b 100644
--- a/drivers/regulator/mt6323-regulator.c
+++ b/drivers/regulator/mt6323-regulator.c
@@ -401,8 +401,8 @@ static int mt6323_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id mt6323_platform_ids[] = {
- {"mt6323-regulator", 0},
- { /* sentinel */ },
+ { .name = "mt6323-regulator" },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, mt6323_platform_ids);
diff --git a/drivers/regulator/mt6331-regulator.c b/drivers/regulator/mt6331-regulator.c
index 0059f88c6fd7..eed9dda0481f 100644
--- a/drivers/regulator/mt6331-regulator.c
+++ b/drivers/regulator/mt6331-regulator.c
@@ -487,8 +487,8 @@ static int mt6331_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id mt6331_platform_ids[] = {
- {"mt6331-regulator", 0},
- { /* sentinel */ },
+ { .name = "mt6331-regulator" },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, mt6331_platform_ids);
diff --git a/drivers/regulator/mt6332-regulator.c b/drivers/regulator/mt6332-regulator.c
index 8d8331a2aca5..949fde37617c 100644
--- a/drivers/regulator/mt6332-regulator.c
+++ b/drivers/regulator/mt6332-regulator.c
@@ -402,8 +402,8 @@ static int mt6332_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id mt6332_platform_ids[] = {
- {"mt6332-regulator", 0},
- { /* sentinel */ },
+ { .name = "mt6332-regulator" },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, mt6332_platform_ids);
diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c
index 2604f674be49..f2bb3c1523ca 100644
--- a/drivers/regulator/mt6358-regulator.c
+++ b/drivers/regulator/mt6358-regulator.c
@@ -724,8 +724,8 @@ static int mt6358_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id mt6358_platform_ids[] = {
- {"mt6358-regulator", 0},
- { /* sentinel */ },
+ { .name = "mt6358-regulator" },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, mt6358_platform_ids);
diff --git a/drivers/regulator/mt6359-regulator.c b/drivers/regulator/mt6359-regulator.c
index af0e0339fbdd..7bda382ddd81 100644
--- a/drivers/regulator/mt6359-regulator.c
+++ b/drivers/regulator/mt6359-regulator.c
@@ -1130,8 +1130,8 @@ static int mt6359_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id mt6359_platform_ids[] = {
- {"mt6359-regulator", 0},
- { /* sentinel */ },
+ { .name = "mt6359-regulator" },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, mt6359_platform_ids);
diff --git a/drivers/regulator/mt6360-regulator.c b/drivers/regulator/mt6360-regulator.c
index 24cc9fc94e90..ed25e9603b2b 100644
--- a/drivers/regulator/mt6360-regulator.c
+++ b/drivers/regulator/mt6360-regulator.c
@@ -446,8 +446,8 @@ static int mt6360_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id mt6360_regulator_id_table[] = {
- { "mt6360-regulator", 0 },
- {},
+ { .name = "mt6360-regulator" },
+ { }
};
MODULE_DEVICE_TABLE(platform, mt6360_regulator_id_table);
diff --git a/drivers/regulator/mt6370-regulator.c b/drivers/regulator/mt6370-regulator.c
index c2cea904b0ca..a4ac4a42c108 100644
--- a/drivers/regulator/mt6370-regulator.c
+++ b/drivers/regulator/mt6370-regulator.c
@@ -371,8 +371,8 @@ static int mt6370_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id mt6370_devid_table[] = {
- { "mt6370-regulator", 0},
- {}
+ { .name = "mt6370-regulator" },
+ { }
};
MODULE_DEVICE_TABLE(platform, mt6370_devid_table);
diff --git a/drivers/regulator/mt6380-regulator.c b/drivers/regulator/mt6380-regulator.c
index 83e50df7f7c3..da901a75137a 100644
--- a/drivers/regulator/mt6380-regulator.c
+++ b/drivers/regulator/mt6380-regulator.c
@@ -314,8 +314,8 @@ static int mt6380_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id mt6380_platform_ids[] = {
- {"mt6380-regulator", 0},
- { /* sentinel */ },
+ { .name = "mt6380-regulator" },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, mt6380_platform_ids);
diff --git a/drivers/regulator/mt6397-regulator.c b/drivers/regulator/mt6397-regulator.c
index 92a2d92f84f9..e68df86ca4d9 100644
--- a/drivers/regulator/mt6397-regulator.c
+++ b/drivers/regulator/mt6397-regulator.c
@@ -392,8 +392,8 @@ static int mt6397_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id mt6397_platform_ids[] = {
- {"mt6397-regulator", 0},
- { /* sentinel */ },
+ { .name = "mt6397-regulator" },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, mt6397_platform_ids);
diff --git a/drivers/regulator/rt4831-regulator.c b/drivers/regulator/rt4831-regulator.c
index dfc868a24056..5c47fd57fdef 100644
--- a/drivers/regulator/rt4831-regulator.c
+++ b/drivers/regulator/rt4831-regulator.c
@@ -186,8 +186,8 @@ static int rt4831_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id rt4831_regulator_match[] = {
- { "rt4831-regulator", 0 },
- {}
+ { .name = "rt4831-regulator" },
+ { }
};
MODULE_DEVICE_TABLE(platform, rt4831_regulator_match);
diff --git a/drivers/regulator/rt5120-regulator.c b/drivers/regulator/rt5120-regulator.c
index f0d3efd160d4..a2a13ce2e67b 100644
--- a/drivers/regulator/rt5120-regulator.c
+++ b/drivers/regulator/rt5120-regulator.c
@@ -401,8 +401,8 @@ static int rt5120_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id rt5120_regulator_dev_table[] = {
- { "rt5120-regulator", 0 },
- {}
+ { .name = "rt5120-regulator" },
+ { }
};
MODULE_DEVICE_TABLE(platform, rt5120_regulator_dev_table);
diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c
index c22fdde67f9c..8171503861c1 100644
--- a/drivers/regulator/s2mpa01.c
+++ b/drivers/regulator/s2mpa01.c
@@ -367,8 +367,8 @@ static int s2mpa01_pmic_probe(struct platform_device *pdev)
}
static const struct platform_device_id s2mpa01_pmic_id[] = {
- { "s2mpa01-pmic", 0},
- { },
+ { .name = "s2mpa01-pmic" },
+ { }
};
MODULE_DEVICE_TABLE(platform, s2mpa01_pmic_id);
diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c
index fe2631378ccd..2794245d4042 100644
--- a/drivers/regulator/s5m8767.c
+++ b/drivers/regulator/s5m8767.c
@@ -916,8 +916,8 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
}
static const struct platform_device_id s5m8767_pmic_id[] = {
- { "s5m8767-pmic", 0},
- { },
+ { .name = "s5m8767-pmic" },
+ { }
};
MODULE_DEVICE_TABLE(platform, s5m8767_pmic_id);
--
2.47.3
^ permalink raw reply related
* [PATCH v1 2/3] regulator: Use named initializers for platform_device_id arrays
From: Uwe Kleine-König (The Capable Hub) @ 2026-05-27 10:47 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown
Cc: Karel Balej, Matti Vaittinen, Marek Vasut, Chanwoo Choi,
Krzysztof Kozlowski, Matthias Brugger, AngeloGioacchino Del Regno,
Samuel Kayode, André Draszik, Aaro Koskinen, Andreas Kemnade,
Kevin Hilman, Roger Quadros, Tony Lindgren, linux-kernel,
linux-renesas-soc, linux-arm-kernel, linux-mediatek, imx,
linux-arm-msm, linux-samsung-soc, linux-omap
In-Reply-To: <cover.1779878004.git.u.kleine-koenig@baylibre.com>
Named initializers are better readable and more robust to changes of the
struct definition. This robustness is relevant for a planned change to
struct platform_device_id replacing .driver_data by an anonymous unit.
While touching these arrays unify spacing and usage of commas.
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
---
drivers/regulator/88pm886-regulator.c | 2 +-
drivers/regulator/bd71815-regulator.c | 4 ++--
drivers/regulator/bd71828-regulator.c | 6 +++---
drivers/regulator/bd718x7-regulator.c | 6 +++---
drivers/regulator/bd9571mwv-regulator.c | 4 ++--
drivers/regulator/bd9576-regulator.c | 6 +++---
drivers/regulator/bd96801-regulator.c | 10 +++++-----
drivers/regulator/lp873x-regulator.c | 2 +-
drivers/regulator/lp87565-regulator.c | 4 ++--
drivers/regulator/max14577-regulator.c | 4 ++--
drivers/regulator/max77541-regulator.c | 4 ++--
drivers/regulator/max77693-regulator.c | 6 +++---
drivers/regulator/max8998.c | 4 ++--
drivers/regulator/mt6357-regulator.c | 4 ++--
drivers/regulator/pf1550-regulator.c | 2 +-
drivers/regulator/qcom-pm8008-regulator.c | 2 +-
drivers/regulator/rt5033-regulator.c | 2 +-
drivers/regulator/s2dos05-regulator.c | 4 ++--
drivers/regulator/s2mps11.c | 18 +++++++++---------
drivers/regulator/sy7636a-regulator.c | 2 +-
drivers/regulator/tps65086-regulator.c | 2 +-
drivers/regulator/tps65218-regulator.c | 2 +-
drivers/regulator/tps65219-regulator.c | 6 +++---
drivers/regulator/tps65912-regulator.c | 2 +-
24 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/drivers/regulator/88pm886-regulator.c b/drivers/regulator/88pm886-regulator.c
index a38bd4f312b7..7328cd1cf265 100644
--- a/drivers/regulator/88pm886-regulator.c
+++ b/drivers/regulator/88pm886-regulator.c
@@ -373,7 +373,7 @@ static int pm886_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id pm886_regulator_id_table[] = {
- { "88pm886-regulator", },
+ { .name = "88pm886-regulator" },
{ }
};
MODULE_DEVICE_TABLE(platform, pm886_regulator_id_table);
diff --git a/drivers/regulator/bd71815-regulator.c b/drivers/regulator/bd71815-regulator.c
index 668714f35464..4c2b20d1b284 100644
--- a/drivers/regulator/bd71815-regulator.c
+++ b/drivers/regulator/bd71815-regulator.c
@@ -607,8 +607,8 @@ static int bd7181x_probe(struct platform_device *pdev)
}
static const struct platform_device_id bd7181x_pmic_id[] = {
- { "bd71815-pmic", ROHM_CHIP_TYPE_BD71815 },
- { },
+ { .name = "bd71815-pmic", .driver_data = ROHM_CHIP_TYPE_BD71815 },
+ { }
};
MODULE_DEVICE_TABLE(platform, bd7181x_pmic_id);
diff --git a/drivers/regulator/bd71828-regulator.c b/drivers/regulator/bd71828-regulator.c
index 473beb4399d9..bd61caa8284a 100644
--- a/drivers/regulator/bd71828-regulator.c
+++ b/drivers/regulator/bd71828-regulator.c
@@ -1691,9 +1691,9 @@ static int bd71828_probe(struct platform_device *pdev)
}
static const struct platform_device_id bd71828_pmic_id[] = {
- { "bd71828-pmic", ROHM_CHIP_TYPE_BD71828 },
- { "bd72720-pmic", ROHM_CHIP_TYPE_BD72720 },
- { },
+ { .name = "bd71828-pmic", .driver_data = ROHM_CHIP_TYPE_BD71828 },
+ { .name = "bd72720-pmic", .driver_data = ROHM_CHIP_TYPE_BD72720 },
+ { }
};
MODULE_DEVICE_TABLE(platform, bd71828_pmic_id);
diff --git a/drivers/regulator/bd718x7-regulator.c b/drivers/regulator/bd718x7-regulator.c
index 1b5997c8482e..9cc29b9409d0 100644
--- a/drivers/regulator/bd718x7-regulator.c
+++ b/drivers/regulator/bd718x7-regulator.c
@@ -1816,9 +1816,9 @@ static int bd718xx_probe(struct platform_device *pdev)
}
static const struct platform_device_id bd718x7_pmic_id[] = {
- { "bd71837-pmic", ROHM_CHIP_TYPE_BD71837 },
- { "bd71847-pmic", ROHM_CHIP_TYPE_BD71847 },
- { },
+ { .name = "bd71837-pmic", .driver_data = ROHM_CHIP_TYPE_BD71837 },
+ { .name = "bd71847-pmic", .driver_data = ROHM_CHIP_TYPE_BD71847 },
+ { }
};
MODULE_DEVICE_TABLE(platform, bd718x7_pmic_id);
diff --git a/drivers/regulator/bd9571mwv-regulator.c b/drivers/regulator/bd9571mwv-regulator.c
index f4de24a281b1..5bf02dc0d20e 100644
--- a/drivers/regulator/bd9571mwv-regulator.c
+++ b/drivers/regulator/bd9571mwv-regulator.c
@@ -344,8 +344,8 @@ static int bd9571mwv_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id bd9571mwv_regulator_id_table[] = {
- { "bd9571mwv-regulator", ROHM_CHIP_TYPE_BD9571 },
- { "bd9574mwf-regulator", ROHM_CHIP_TYPE_BD9574 },
+ { .name = "bd9571mwv-regulator", .driver_data = ROHM_CHIP_TYPE_BD9571 },
+ { .name = "bd9574mwf-regulator", .driver_data = ROHM_CHIP_TYPE_BD9574 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, bd9571mwv_regulator_id_table);
diff --git a/drivers/regulator/bd9576-regulator.c b/drivers/regulator/bd9576-regulator.c
index bf5f9c3f2c97..fcdaaa56e356 100644
--- a/drivers/regulator/bd9576-regulator.c
+++ b/drivers/regulator/bd9576-regulator.c
@@ -1117,9 +1117,9 @@ static int bd957x_probe(struct platform_device *pdev)
}
static const struct platform_device_id bd957x_pmic_id[] = {
- { "bd9573-regulator", ROHM_CHIP_TYPE_BD9573 },
- { "bd9576-regulator", ROHM_CHIP_TYPE_BD9576 },
- { },
+ { .name = "bd9573-regulator", .driver_data = ROHM_CHIP_TYPE_BD9573 },
+ { .name = "bd9576-regulator", .driver_data = ROHM_CHIP_TYPE_BD9576 },
+ { }
};
MODULE_DEVICE_TABLE(platform, bd957x_pmic_id);
diff --git a/drivers/regulator/bd96801-regulator.c b/drivers/regulator/bd96801-regulator.c
index 129b20c33bad..308279b31fd3 100644
--- a/drivers/regulator/bd96801-regulator.c
+++ b/drivers/regulator/bd96801-regulator.c
@@ -1329,11 +1329,11 @@ static int bd96801_probe(struct platform_device *pdev)
}
static const struct platform_device_id bd96801_pmic_id[] = {
- { "bd96801-regulator", (kernel_ulong_t)&bd96801_data },
- { "bd96802-regulator", (kernel_ulong_t)&bd96802_data },
- { "bd96805-regulator", (kernel_ulong_t)&bd96805_data },
- { "bd96806-regulator", (kernel_ulong_t)&bd96806_data },
- { },
+ { .name = "bd96801-regulator", .driver_data = (kernel_ulong_t)&bd96801_data },
+ { .name = "bd96802-regulator", .driver_data = (kernel_ulong_t)&bd96802_data },
+ { .name = "bd96805-regulator", .driver_data = (kernel_ulong_t)&bd96805_data },
+ { .name = "bd96806-regulator", .driver_data = (kernel_ulong_t)&bd96806_data },
+ { }
};
MODULE_DEVICE_TABLE(platform, bd96801_pmic_id);
diff --git a/drivers/regulator/lp873x-regulator.c b/drivers/regulator/lp873x-regulator.c
index 84a134cfcd9c..7e837ddfa236 100644
--- a/drivers/regulator/lp873x-regulator.c
+++ b/drivers/regulator/lp873x-regulator.c
@@ -180,7 +180,7 @@ static int lp873x_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id lp873x_regulator_id_table[] = {
- { "lp873x-regulator", },
+ { .name = "lp873x-regulator" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, lp873x_regulator_id_table);
diff --git a/drivers/regulator/lp87565-regulator.c b/drivers/regulator/lp87565-regulator.c
index 1259b5d20153..34e7a5d323d7 100644
--- a/drivers/regulator/lp87565-regulator.c
+++ b/drivers/regulator/lp87565-regulator.c
@@ -229,8 +229,8 @@ static int lp87565_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id lp87565_regulator_id_table[] = {
- { "lp87565-regulator", },
- { "lp87565-q1-regulator", },
+ { .name = "lp87565-regulator" },
+ { .name = "lp87565-q1-regulator" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, lp87565_regulator_id_table);
diff --git a/drivers/regulator/max14577-regulator.c b/drivers/regulator/max14577-regulator.c
index 41fd15adfd1f..c9d8d5e31cbd 100644
--- a/drivers/regulator/max14577-regulator.c
+++ b/drivers/regulator/max14577-regulator.c
@@ -235,8 +235,8 @@ static int max14577_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id max14577_regulator_id[] = {
- { "max14577-regulator", MAXIM_DEVICE_TYPE_MAX14577, },
- { "max77836-regulator", MAXIM_DEVICE_TYPE_MAX77836, },
+ { .name = "max14577-regulator", .driver_data = MAXIM_DEVICE_TYPE_MAX14577 },
+ { .name = "max77836-regulator", .driver_data = MAXIM_DEVICE_TYPE_MAX77836 },
{ }
};
MODULE_DEVICE_TABLE(platform, max14577_regulator_id);
diff --git a/drivers/regulator/max77541-regulator.c b/drivers/regulator/max77541-regulator.c
index e6b3d9147c37..f2365930e9a9 100644
--- a/drivers/regulator/max77541-regulator.c
+++ b/drivers/regulator/max77541-regulator.c
@@ -133,8 +133,8 @@ static int max77541_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id max77541_regulator_platform_id[] = {
- { "max77540-regulator" },
- { "max77541-regulator" },
+ { .name = "max77540-regulator" },
+ { .name = "max77541-regulator" },
{ }
};
MODULE_DEVICE_TABLE(platform, max77541_regulator_platform_id);
diff --git a/drivers/regulator/max77693-regulator.c b/drivers/regulator/max77693-regulator.c
index 72a67d0c5f1e..a8b3a2058d34 100644
--- a/drivers/regulator/max77693-regulator.c
+++ b/drivers/regulator/max77693-regulator.c
@@ -271,9 +271,9 @@ static int max77693_pmic_probe(struct platform_device *pdev)
}
static const struct platform_device_id max77693_pmic_id[] = {
- { "max77693-pmic", TYPE_MAX77693 },
- { "max77843-regulator", TYPE_MAX77843 },
- {},
+ { .name = "max77693-pmic", .driver_data = TYPE_MAX77693 },
+ { .name = "max77843-regulator", .driver_data = TYPE_MAX77843 },
+ { }
};
MODULE_DEVICE_TABLE(platform, max77693_pmic_id);
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
index 254a77887f66..cc85fbe8b77c 100644
--- a/drivers/regulator/max8998.c
+++ b/drivers/regulator/max8998.c
@@ -752,8 +752,8 @@ static int max8998_pmic_probe(struct platform_device *pdev)
}
static const struct platform_device_id max8998_pmic_id[] = {
- { "max8998-pmic", TYPE_MAX8998 },
- { "lp3974-pmic", TYPE_LP3974 },
+ { .name = "max8998-pmic", .driver_data = TYPE_MAX8998 },
+ { .name = "lp3974-pmic", .driver_data = TYPE_LP3974 },
{ }
};
MODULE_DEVICE_TABLE(platform, max8998_pmic_id);
diff --git a/drivers/regulator/mt6357-regulator.c b/drivers/regulator/mt6357-regulator.c
index 09feb454ab6b..815ef7d3e5be 100644
--- a/drivers/regulator/mt6357-regulator.c
+++ b/drivers/regulator/mt6357-regulator.c
@@ -431,8 +431,8 @@ static int mt6357_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id mt6357_platform_ids[] = {
- { "mt6357-regulator" },
- { /* sentinel */ },
+ { .name = "mt6357-regulator" },
+ { /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, mt6357_platform_ids);
diff --git a/drivers/regulator/pf1550-regulator.c b/drivers/regulator/pf1550-regulator.c
index 1d1726528460..610eac9bb9cb 100644
--- a/drivers/regulator/pf1550-regulator.c
+++ b/drivers/regulator/pf1550-regulator.c
@@ -409,7 +409,7 @@ static int pf1550_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id pf1550_regulator_id[] = {
- { "pf1550-regulator", },
+ { .name = "pf1550-regulator" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, pf1550_regulator_id);
diff --git a/drivers/regulator/qcom-pm8008-regulator.c b/drivers/regulator/qcom-pm8008-regulator.c
index 90c78ee1c37b..9c9b8be2e15a 100644
--- a/drivers/regulator/qcom-pm8008-regulator.c
+++ b/drivers/regulator/qcom-pm8008-regulator.c
@@ -180,7 +180,7 @@ static int pm8008_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id pm8008_regulator_id_table[] = {
- { "pm8008-regulator" },
+ { .name = "pm8008-regulator" },
{ }
};
MODULE_DEVICE_TABLE(platform, pm8008_regulator_id_table);
diff --git a/drivers/regulator/rt5033-regulator.c b/drivers/regulator/rt5033-regulator.c
index 2ba74f205543..3aeab9a57871 100644
--- a/drivers/regulator/rt5033-regulator.c
+++ b/drivers/regulator/rt5033-regulator.c
@@ -116,7 +116,7 @@ static int rt5033_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id rt5033_regulator_id[] = {
- { "rt5033-regulator", },
+ { .name = "rt5033-regulator" },
{ }
};
MODULE_DEVICE_TABLE(platform, rt5033_regulator_id);
diff --git a/drivers/regulator/s2dos05-regulator.c b/drivers/regulator/s2dos05-regulator.c
index a1c394ddbaff..6e25f663496a 100644
--- a/drivers/regulator/s2dos05-regulator.c
+++ b/drivers/regulator/s2dos05-regulator.c
@@ -146,8 +146,8 @@ static int s2dos05_pmic_probe(struct platform_device *pdev)
}
static const struct platform_device_id s2dos05_pmic_id[] = {
- { "s2dos05-regulator" },
- { },
+ { .name = "s2dos05-regulator" },
+ { }
};
MODULE_DEVICE_TABLE(platform, s2dos05_pmic_id);
diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c
index 81cfd60460f8..0fb54617b8a7 100644
--- a/drivers/regulator/s2mps11.c
+++ b/drivers/regulator/s2mps11.c
@@ -2266,15 +2266,15 @@ static int s2mps11_pmic_probe(struct platform_device *pdev)
}
static const struct platform_device_id s2mps11_pmic_id[] = {
- { "s2mpg10-regulator", S2MPG10},
- { "s2mpg11-regulator", S2MPG11},
- { "s2mps11-regulator", S2MPS11X},
- { "s2mps13-regulator", S2MPS13X},
- { "s2mps14-regulator", S2MPS14X},
- { "s2mps15-regulator", S2MPS15X},
- { "s2mpu02-regulator", S2MPU02},
- { "s2mpu05-regulator", S2MPU05},
- { },
+ { .name = "s2mpg10-regulator", .driver_data = S2MPG10 },
+ { .name = "s2mpg11-regulator", .driver_data = S2MPG11 },
+ { .name = "s2mps11-regulator", .driver_data = S2MPS11X },
+ { .name = "s2mps13-regulator", .driver_data = S2MPS13X },
+ { .name = "s2mps14-regulator", .driver_data = S2MPS14X },
+ { .name = "s2mps15-regulator", .driver_data = S2MPS15X },
+ { .name = "s2mpu02-regulator", .driver_data = S2MPU02 },
+ { .name = "s2mpu05-regulator", .driver_data = S2MPU05 },
+ { }
};
MODULE_DEVICE_TABLE(platform, s2mps11_pmic_id);
diff --git a/drivers/regulator/sy7636a-regulator.c b/drivers/regulator/sy7636a-regulator.c
index 551647bc1052..c44c445ea139 100644
--- a/drivers/regulator/sy7636a-regulator.c
+++ b/drivers/regulator/sy7636a-regulator.c
@@ -147,7 +147,7 @@ static int sy7636a_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id sy7636a_regulator_id_table[] = {
- { "sy7636a-regulator", },
+ { .name = "sy7636a-regulator" },
{ }
};
MODULE_DEVICE_TABLE(platform, sy7636a_regulator_id_table);
diff --git a/drivers/regulator/tps65086-regulator.c b/drivers/regulator/tps65086-regulator.c
index 2d284c64eeb7..94bf96856d10 100644
--- a/drivers/regulator/tps65086-regulator.c
+++ b/drivers/regulator/tps65086-regulator.c
@@ -399,7 +399,7 @@ static int tps65086_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id tps65086_regulator_id_table[] = {
- { "tps65086-regulator", },
+ { .name = "tps65086-regulator" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, tps65086_regulator_id_table);
diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c
index f44b5767099c..8df81ceeb845 100644
--- a/drivers/regulator/tps65218-regulator.c
+++ b/drivers/regulator/tps65218-regulator.c
@@ -341,7 +341,7 @@ static int tps65218_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id tps65218_regulator_id_table[] = {
- { "tps65218-regulator", },
+ { .name = "tps65218-regulator" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, tps65218_regulator_id_table);
diff --git a/drivers/regulator/tps65219-regulator.c b/drivers/regulator/tps65219-regulator.c
index 324c3a33af8a..a667c3f44bb7 100644
--- a/drivers/regulator/tps65219-regulator.c
+++ b/drivers/regulator/tps65219-regulator.c
@@ -541,9 +541,9 @@ static int tps65219_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id tps65219_regulator_id_table[] = {
- { "tps65214-regulator", TPS65214 },
- { "tps65215-regulator", TPS65215 },
- { "tps65219-regulator", TPS65219 },
+ { .name = "tps65214-regulator", .driver_data = TPS65214 },
+ { .name = "tps65215-regulator", .driver_data = TPS65215 },
+ { .name = "tps65219-regulator", .driver_data = TPS65219 },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, tps65219_regulator_id_table);
diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c
index 7ff7877a2e09..4317ec62f18f 100644
--- a/drivers/regulator/tps65912-regulator.c
+++ b/drivers/regulator/tps65912-regulator.c
@@ -142,7 +142,7 @@ static int tps65912_regulator_probe(struct platform_device *pdev)
}
static const struct platform_device_id tps65912_regulator_id_table[] = {
- { "tps65912-regulator", },
+ { .name = "tps65912-regulator" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, tps65912_regulator_id_table);
--
2.47.3
^ permalink raw reply related
* Re: [PATCH] ASoC: mediatek: mt2701: allocate i2s_path with priv
From: Mark Brown @ 2026-05-27 10:13 UTC (permalink / raw)
To: linux-sound, Rosen Penev
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Matthias Brugger,
AngeloGioacchino Del Regno, linux-kernel, linux-arm-kernel,
linux-mediatek
In-Reply-To: <20260519010413.629214-1-rosenp@gmail.com>
On Mon, 18 May 2026 18:04:13 -0700, Rosen Penev wrote:
> ASoC: mediatek: mt2701: allocate i2s_path with priv
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-7.2
Thanks!
[1/1] ASoC: mediatek: mt2701: allocate i2s_path with priv
https://git.kernel.org/broonie/sound/c/344a4c96b292
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
* [bug report] wifi: mt76: mt7921: mt7925monitor-mode per-channel retune emits narrowband RF burst
From: John Henry @ 2026-05-27 12:24 UTC (permalink / raw)
To: Javier Tia, Bradley Pizzimenti, linux-wireless, linux-kernel, nbd,
lorenzo, ryder.lee, shayne.chen, sean.wang,
moderated list:ARM/Mediatek SoC support, Deren Wu, Nick Morrow,
Sean Wang
Just a kind reminder of this issue.
Please advise if this is already taken up in a separate issue I am
unaware of, but it is not directly related to the "iw set txpower
fixed accepted but ignored" issue.
On products available in the market, e.g. the Alfa AWUS036AXML
consumer product and the Netgear Nighthawk A9000, in Monitor Mode
there is RF generated when scanning through channels and we get to 5
or more channels in succession.
This does not seem to occur at all in managed mode.
This means if we scan the 2.4GHz channel list, an RF Spectrum analyzer
will show a narrow pulse generated on each channel as we progress
through the channels.
This can 100% be reproduced using standard iw set channel commands as
shown below:
FACE=$(iw dev | awk '/Interface wl/ {print $2; exit}')
iw reg set US ; sleep 1
ip link set "$IFACE" down
iw dev "$IFACE" set type monitor
ip link set "$IFACE" up
# This triggers narrowband bursts at channel center on each retune:
while true; do
for f in 2412 2417 2422 2427 2432; do
iw dev "$IFACE" set freq "$f" HT20
done
done
No special software required to reproduce.
I have shown that this occurs on all MT7921 based products, along with
MT7925 based products.
It does not occur if the channel list is set to the same 4 over and
over, no RF generated.
There are no calibration channel commands going from the driver to the
firmware, so I believe this is a firmware bug.
Best Regards,
John Henry
On Sun, May 17, 2026 at 9:01 AM John Henry <jshenry1963@gmail.com> wrote:
>
> Just a kind reminder of this issue, has anyone been able to reproduce
> this monitor mode issue?
> When scanning through channels, and the list of channels is > 4, there
> is a large transmit tick/burst coming from the MT7921u and the MT7925.
> This can easily be seen on an RF Spectrum Analyzer.
> Confirmed on an Alfa AWUS036AXML consumer product and the Netgear
> Nighthawk A9000.
> This can be reproduced with simple scripts.
>
> Reproduction with stock iw commands (no custom code):
>
> IFACE=$(iw dev | awk '/Interface wl/ {print $2; exit}')
> iw reg set US ; sleep 1
> ip link set "$IFACE" down
> iw dev "$IFACE" set type monitor
> ip link set "$IFACE" up
>
> # This triggers narrowband bursts at channel center on each retune:
> while true; do
> for f in 2412 2417 2422 2427 2432; do
> iw dev "$IFACE" set freq "$f" HT20
> done
> done
>
> # This does NOT (only 4 frequencies):
> while true; do
> for f in 2412 2422 2462 2484; do
> iw dev "$IFACE" set freq "$f" HT20
> done
> done
>
> Bursts are ~800 kHz wide at the base, -30 to -50 dBm OTA at close
> range, brief (estimated few hundred microseconds), at channel
> frequency. tx_stats counters remain zero throughout.
> On Mon, May 11, 2026 at 1:58 PM John Henry <jshenry1963@gmail.com> wrote:
> >
> > Bradley/Sean,
> >
> > Thank you all very much for the information.
> > I tested this on mt7921u based Alfa AWUS unit and also an mt7925 based
> > Netgear Nighthawk unit.
> > I can confirm that the RF tick issue is present on both models when in
> > Monitor Mode. I'm assuming it is in the base mt76?
> >
> > I attempted sudo iw dev wlxxx set txpower fixed nn where nn is the
> > minimum value, next few values up, and then a few near the max values,
> > and see no change in the signal strength of the RF Ticks when scanning
> > through 5 or more channels.
> >
> > Please keep this in mind when attempting to resolve the known txpower
> > 3dBm issue if possible, or please generate a new bug report for that
> > specifically so that I can track when it is patched, or in ??? version
> > so that I can test here locally.
> >
> > Incidentally, I'd appreciate it if anyone could please attempt to
> > repeat using the scripts I had shown in the previous posts and confirm
> > it is indeed seen by others.
> >
> > Thank you very much for your time and assistance
> >
> > John Henry
> >
> >
> >
> >
> > From: Bradley Pizzimenti <brad.pizzimenti@gmail.com>
> > To: linux-wireless@vger.kernel.org
> > Cc: linux-kernel@vger.kernel.org, nbd@nbd.name, lorenzo@kernel.org,
> > ryder.lee@mediatek.com, shayne.chen@mediatek.com,
> > sean.wang@mediatek.com
> > Subject: [bug report] wifi: mt76: mt7925: iw set txpower fixed
> > accepted but ignored
> > Date: Mon, 4 May 2026 15:04:35 -0700 [thread overview]
> > Message-ID: <CACjnFagN9zeSkwEv3-CSPJDUENPcEcOLjKyQoLQ91Yjn=rq5ww@mail.gmail.com>
> > (raw)
> >
> > Hi there maintainers,
> >
> > `iw dev <iface> set txpower fixed N` returns success on mt7925 for any
> > N tested, but the reported txpower never changes from a stuck value of
> > 3.00 dBm. The kernel accepts and ignores the call silently in both
> > directions (above and below the displayed value), and well below the
> > regulatory ceiling.
> >
> > I'm aware there's prior art on the cosmetic 3.00 dBm display issue
> > (Razvan Grigore's v2 series, Feb 2025; Ming Yen Hsieh's txpower init
> > refactor, Sept 2025). What seems potentially distinct here is that the
> > user-issued `iw set txpower fixed N` itself is silently no-op'd,
> > separate from the reported-value question. Reporting as breadcrumbs
> > in case the second observation is a separate bug rather than the same
> > one.
> >
> > Hardware
> > --------
> > MEDIATEK MT7925 [Filogic 360], 802.11be 2x2, PCI 14c3:7925
> > ASIC revision 0x79250000
> > Driver in use: mt7925e (in-tree)
> >
> > Firmware (from dmesg at probe)
> > ------------------------------
> > mt7925e 0000:01:00.0: HW/SW Version: 0x8a108a10,
> > Build Time: 20260106153007a
> > mt7925e 0000:01:00.0: WM Firmware Version: ____000000,
> > Build Time: 20260106153120
> > Files: mediatek/mt7925/WIFI_MT7925_PATCH_MCU_1_1_hdr.bin
> > mediatek/mt7925/WIFI_RAM_CODE_MT7925_1_1.bin
> >
> > Kernel
> > ------
> > 6.18.18-1-MANJARO (close to vanilla 6.18 stable; not yet tested on
> > wireless-next or nbd168/wireless HEAD -- happy to retest if needed,
> > but flagging the data point in case it helps as-is).
> >
> > Tools: iw version 6.17
> >
> > Regulatory
> > ----------
> > $ iw reg get
> > country US: DFS-FCC
> > ...
> > (5730 - 5850 @ 80), (N/A, 30), (N/A), AUTO-BW
> > ...
> >
> > Connection context: 5GHz channel 161 (5805 MHz), 80 MHz, VHT-MCS,
> > NSS 1. So we are on a band with a 30 dBm regulatory cap.
> >
> > Observed
> > --------
> > $ iw dev wlp1s0 info | grep txpower
> > txpower 3.00 dBm
> >
> > $ sudo iw dev wlp1s0 set txpower fixed 100 # 1 dBm
> > $ iw dev wlp1s0 info | grep txpower
> > txpower 3.00 dBm
> >
> > $ sudo iw dev wlp1s0 set txpower fixed 1500 # 15 dBm
> > $ iw dev wlp1s0 info | grep txpower
> > txpower 3.00 dBm
> >
> > $ sudo iw dev wlp1s0 set txpower auto
> > $ iw dev wlp1s0 info | grep txpower
> > txpower 3.00 dBm
> >
> > All four `set` invocations return exit code 0. The reported value
> > never moves.
> >
> > Expected
> > --------
> > Either:
> > - The reported txpower follows the requested value (or, where
> > capped, the actual applied value with extack indicating the
> > cap reason), or
> > - The set call returns an error rather than silently ignoring the
> > request.
> >
> > Caveats
> > -------
> > - Not yet tested on wireless-next or nbd168/wireless HEAD. If a
> > reproduction on a current dev tree would be useful, I can do that.
> > - I have not verified whether the actual radiated TX power changes
> > in response to `set txpower fixed`; I am reporting only the
> > user-visible behavior.
> >
> > Thanks,
> > Bradley
> >
> > On Wed, May 6, 2026 at 8:12 PM Sean Wang <sean.wang@kernel.org> wrote:
> > >
> > > Hi,
> > >
> > > The TX power reporting issue has already been investigated by Lucid
> > > from the Linux WiFi USB community, and there is a proposed solution.
> > > I think we can continue checking whether there are any remaining
> > > issues on top of that work. Please refer to the patches here:
> > > https://lists.infradead.org/pipermail/linux-mediatek/2026-April/105726.html
> > > Thanks everyone for reporting and raising these concerns.
> > >
> > > On Wed, May 6, 2026 at 3:09 PM Javier Tia <floss@jetm.me> wrote:
> > > >
> > > > On Sun May 4 22:04:48 2026 Bradley Pizzimenti wrote:
> > > > > `iw dev <iface> set txpower fixed N` returns success on mt7925 for
> > > > > any N tested, but the reported txpower never changes from a stuck
> > > > > value of 3.00 dBm.
> > > >
> > > > Hi Bradley,
> > > >
> > > > The 3 dBm display bug is a known issue we have seen when using mt7927
> > > > and a tested fix has been working well so far. The root cause is that
> > > > mt7925_mcu_set_rate_txpower() programs the per-band SKU tables into
> > > > firmware but never assigns phy->txpower_cur. mt76_get_txpower() then
> > > > computes:
> > > >
> > > > DIV_ROUND_UP(0 + 6, 2) = 3
> > > >
> > > > regardless of the actual power level. The RF output is unaffected;
> > > > it is a display-only bug.
> > > >
> > > > The fix reads the effective TX power back from the rate power limits
> > > > after programming the SKU tables and writes it to phy->txpower_cur,
> > > > following the same pattern used by mt7996:
> > > >
> > > > https://github.com/jetm/mediatek-mt7927-dkms/blob/master/mt7927-wifi-14-fix-reported-txpower-always-showing-3-db.patch
> > > >
> > > > This is part of a series we are targeting for wireless-next; not
> > > > yet upstream.
> > > >
> > > > > What seems potentially distinct here is that the user-issued
> > > > > `iw set txpower fixed N` itself is silently no-op'd, separate
> > > > > from the reported-value question.
> > > >
> > > > Agreed those are two separate issues. Our patch addresses the
> > > > display-only side: after applying it, iw will report the value the
> > > > firmware is actually using based on the SKU tables, rather than
> > > > always 3 dBm. Whether `set txpower fixed N` propagates to firmware
> > > > to change actual output power is orthogonal and not addressed here.
> > > >
> > > > If you can test the patch on your MT7925 and confirm the displayed
> > > > value reflects the correct power after association, a Tested-by
> > > > would be appreciated.
> > > >
> > > > Best,
> > > > Javier
> > > >
> > >
^ permalink raw reply
* Re: [PATCH 3/3] pinctrl: mediatek: fix SPDX comment style in header
From: Linus Walleij @ 2026-05-27 13:16 UTC (permalink / raw)
To: Mayur Kumar
Cc: sean.wang, matthias.bgg, angelogioacchino.delregno,
linux-mediatek, linux-gpio, linux-kernel, linux-arm-kernel
In-Reply-To: <20260511183017.228595-1-kmayur809@gmail.com>
On Mon, May 11, 2026 at 8:30 PM Mayur Kumar <kmayur809@gmail.com> wrote:
> Header files should use the C-style '/*' block comment for SPDX
> license identifiers. Correct the style in pinctrl-mtk-mt8365.h
> to satisfy checkpatch requirements.
>
> Signed-off-by: Mayur Kumar <kmayur809@gmail.com>
Patch applied!
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH 0/2] ASoC: mediatek: mt8183: Fix probe resource cleanup
From: Cássio Gabriel @ 2026-05-27 13:41 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Takashi Iwai, Jaroslav Kysela,
Matthias Brugger, AngeloGioacchino Del Regno, Chen-Yu Tsai,
Shunli Wang
Cc: linux-sound, linux-kernel, linux-arm-kernel, linux-mediatek,
notify, Cássio Gabriel, stable
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.
Second, the probe-time runtime PM resume used before reinitializing
the regmap cache is unchecked, and a regmap_reinit_cache() failure
skips the temporary PM put.
Fix both issues with a devm reserved-memory release action and
checked runtime PM resume handling.
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
Cássio Gabriel (2):
ASoC: mediatek: mt8183: Release reserved memory on cleanup
ASoC: mediatek: mt8183: Check runtime resume during probe
sound/soc/mediatek/mt8183/mt8183-afe-pcm.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
---
base-commit: 8cd773d4f8235aaf0b04927b3c9d2d0326def09b
change-id: 20260525-asoc-mt8183-probe-cleanup-eff58c2d4715
Best regards,
--
Cássio Gabriel <cassiogabrielcontato@gmail.com>
^ permalink raw reply
* [PATCH 1/2] ASoC: mediatek: mt8183: Release reserved memory on cleanup
From: Cássio Gabriel @ 2026-05-27 13:41 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Takashi Iwai, Jaroslav Kysela,
Matthias Brugger, AngeloGioacchino Del Regno, Chen-Yu Tsai,
Shunli Wang
Cc: linux-sound, linux-kernel, linux-arm-kernel, linux-mediatek,
notify, Cássio Gabriel, stable
In-Reply-To: <20260527-asoc-mt8183-probe-cleanup-v1-0-4f4f5593c8d1@gmail.com>
The MT8183 AFE probe can assign reserved memory with
of_reserved_mem_device_init(), but the assignment is never released on
driver removal or later probe failures.
Register a devm cleanup action so the reserved memory assignment is
released consistently, matching newer Mediatek AFE drivers.
Fixes: ec4a10ca4a68 ("ASoC: mediatek: use reserved memory or enable buffer pre-allocation")
Cc: stable@vger.kernel.org
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
sound/soc/mediatek/mt8183/mt8183-afe-pcm.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
index a7fef772760a..49a69728fd72 100644
--- a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
+++ b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
@@ -766,6 +766,11 @@ static const dai_register_cb dai_register_cbs[] = {
mt8183_dai_memif_register,
};
+static void mt8183_afe_release_reserved_mem(void *data)
+{
+ of_reserved_mem_device_release(data);
+}
+
static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
{
struct mtk_base_afe *afe;
@@ -794,6 +799,12 @@ static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
if (ret) {
dev_info(dev, "no reserved memory found, pre-allocating buffers instead\n");
afe->preallocate_buffers = true;
+ } else {
+ ret = devm_add_action_or_reset(dev,
+ mt8183_afe_release_reserved_mem,
+ dev);
+ if (ret)
+ return ret;
}
/* initial audio related clock */
--
2.54.0
^ permalink raw reply related
* [PATCH 2/2] ASoC: mediatek: mt8183: Check runtime resume during probe
From: Cássio Gabriel @ 2026-05-27 13:41 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Takashi Iwai, Jaroslav Kysela,
Matthias Brugger, AngeloGioacchino Del Regno, Chen-Yu Tsai,
Shunli Wang
Cc: linux-sound, linux-kernel, linux-arm-kernel, linux-mediatek,
notify, Cássio Gabriel, stable
In-Reply-To: <20260527-asoc-mt8183-probe-cleanup-v1-0-4f4f5593c8d1@gmail.com>
The MT8183 AFE probe uses pm_runtime_get_sync() before reading hardware
defaults into the regmap cache, but does not check whether runtime resume
failed. If regmap_reinit_cache() then fails, the temporary runtime PM
usage count is also not released.
Use pm_runtime_resume_and_get() so resume failures abort probe without
leaking a usage count, and release the temporary reference before
handling the regmap cache result.
Fixes: a94aec035a12 ("ASoC: mediatek: mt8183: add platform driver")
Cc: stable@vger.kernel.org
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
sound/soc/mediatek/mt8183/mt8183-afe-pcm.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
index 49a69728fd72..2634699534db 100644
--- a/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
+++ b/sound/soc/mediatek/mt8183/mt8183-afe-pcm.c
@@ -844,17 +844,21 @@ static int mt8183_afe_pcm_dev_probe(struct platform_device *pdev)
/* enable clock for regcache get default value from hw */
afe_priv->pm_runtime_bypass_reg_ctl = true;
- pm_runtime_get_sync(dev);
-
- ret = regmap_reinit_cache(afe->regmap, &mt8183_afe_regmap_config);
+ ret = pm_runtime_resume_and_get(dev);
if (ret) {
- dev_err(dev, "regmap_reinit_cache fail, ret %d\n", ret);
+ afe_priv->pm_runtime_bypass_reg_ctl = false;
goto err_pm_disable;
}
+ ret = regmap_reinit_cache(afe->regmap, &mt8183_afe_regmap_config);
pm_runtime_put_sync(dev);
afe_priv->pm_runtime_bypass_reg_ctl = false;
+ if (ret) {
+ dev_err(dev, "regmap_reinit_cache fail, ret %d\n", ret);
+ goto err_pm_disable;
+ }
+
regcache_cache_only(afe->regmap, true);
regcache_mark_dirty(afe->regmap);
--
2.54.0
^ permalink raw reply related
* Re: [PATCH mt76] wifi: mt76: mt7915: configure noise floor reporting on reset
From: Felix Fietkau @ 2026-05-27 13:56 UTC (permalink / raw)
To: David Bauer, Lorenzo Bianconi, Ryder Lee, Shayne Chen, Sean Wang,
Matthias Brugger, AngeloGioacchino Del Regno
Cc: linux-wireless, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20260516144944.2574053-1-mail@david-bauer.net>
On 16.05.26 16:49, David Bauer wrote:
> When performing a full system recovery of the MCU on a dual-phy
> platform, band 0 (usually 2.4GHz) stops reading correct noise floor
> data.
>
> This is due to noise floor reporting only being configured correctly
> for the second device PHY.
>
> Configure the respective registers correctly after restarting the MCU
> firmware to fix reported noise-floor values.
>
> Signed-off-by: David Bauer <mail@david-bauer.net>
Have you considered clearing MT76_STATE_RUNNING in mt7915_mac_restart
instead?
- Felix
^ permalink raw reply
* [PATCH 0/2] ASoC: mediatek: mt8192 probe cleanup
From: Cássio Gabriel @ 2026-05-27 13:55 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Takashi Iwai, Jaroslav Kysela,
Matthias Brugger, AngeloGioacchino Del Regno, Chen-Yu Tsai,
Jiaxin Yu
Cc: linux-sound, linux-kernel, linux-arm-kernel, linux-mediatek,
notify, Cássio Gabriel, stable
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.
The second patch checks the temporary runtime resume used while
reinitializing the regmap cache and makes the regcache failure path drop
the PM reference and clear pm_runtime_bypass_reg_ctl.
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
Cássio Gabriel (2):
ASoC: mediatek: mt8192: Release reserved memory on cleanup
ASoC: mediatek: mt8192: Check runtime resume during probe
sound/soc/mediatek/mt8192/mt8192-afe-pcm.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
---
base-commit: 93f1bbc69dbcbb29544769c4d6f3456749ad9013
change-id: 20260526-asoc-mt8192-probe-cleanup-3ef72f38e3d5
Best regards,
--
Cássio Gabriel <cassiogabrielcontato@gmail.com>
^ permalink raw reply
* [PATCH 1/2] ASoC: mediatek: mt8192: Release reserved memory on cleanup
From: Cássio Gabriel @ 2026-05-27 13:55 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Takashi Iwai, Jaroslav Kysela,
Matthias Brugger, AngeloGioacchino Del Regno, Chen-Yu Tsai,
Jiaxin Yu
Cc: linux-sound, linux-kernel, linux-arm-kernel, linux-mediatek,
notify, Cássio Gabriel, stable
In-Reply-To: <20260527-asoc-mt8192-probe-cleanup-v1-0-1bb834d05b72@gmail.com>
The MT8192 AFE probe calls of_reserved_mem_device_init() and falls
back to preallocated buffers when no reserved memory region is
available. When the reserved memory assignment succeeds, however, the
driver never releases it.
Register a devm cleanup action after a successful reserved-memory
assignment so the assignment is released on probe failure and driver
unbind.
Fixes: ec4a10ca4a68 ("ASoC: mediatek: use reserved memory or enable buffer pre-allocation")
Cc: stable@vger.kernel.org
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
sound/soc/mediatek/mt8192/mt8192-afe-pcm.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
index 3d32fe46118e..9f5057eeeff9 100644
--- a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
+++ b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
@@ -2155,6 +2155,11 @@ static const dai_register_cb dai_register_cbs[] = {
mt8192_dai_memif_register,
};
+static void mt8192_afe_release_reserved_mem(void *data)
+{
+ of_reserved_mem_device_release(data);
+}
+
static int mt8192_afe_pcm_dev_probe(struct platform_device *pdev)
{
struct mtk_base_afe *afe;
@@ -2184,6 +2189,10 @@ static int mt8192_afe_pcm_dev_probe(struct platform_device *pdev)
if (ret) {
dev_info(dev, "no reserved memory found, pre-allocating buffers instead\n");
afe->preallocate_buffers = true;
+ } else {
+ ret = devm_add_action_or_reset(dev, mt8192_afe_release_reserved_mem, dev);
+ if (ret)
+ return ret;
}
/* init audio related clock */
--
2.54.0
^ permalink raw reply related
* [PATCH 2/2] ASoC: mediatek: mt8192: Check runtime resume during probe
From: Cássio Gabriel @ 2026-05-27 13:55 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Takashi Iwai, Jaroslav Kysela,
Matthias Brugger, AngeloGioacchino Del Regno, Chen-Yu Tsai,
Jiaxin Yu
Cc: linux-sound, linux-kernel, linux-arm-kernel, linux-mediatek,
notify, Cássio Gabriel, stable
In-Reply-To: <20260527-asoc-mt8192-probe-cleanup-v1-0-1bb834d05b72@gmail.com>
The MT8192 AFE probe enables runtime PM temporarily while reinitializing
the regmap cache from hardware, but it uses pm_runtime_get_sync()
without checking the return value. If runtime resume fails, probe keeps
going without the device necessarily being accessible, and
pm_runtime_get_sync() may leave the PM usage count incremented.
The regmap_reinit_cache() failure path also returns before dropping the
temporary PM reference and before clearing pm_runtime_bypass_reg_ctl.
Use pm_runtime_resume_and_get() so resume failures do not leak a usage
count, and clear the temporary bypass flag after dropping the probe PM
reference on all regmap_reinit_cache() outcomes.
Fixes: 125ab5d588b0 ("ASoC: mediatek: mt8192: add platform driver")
Cc: stable@vger.kernel.org
Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
---
sound/soc/mediatek/mt8192/mt8192-afe-pcm.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
index 9f5057eeeff9..db0ae44a86af 100644
--- a/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
+++ b/sound/soc/mediatek/mt8192/mt8192-afe-pcm.c
@@ -2227,15 +2227,19 @@ static int mt8192_afe_pcm_dev_probe(struct platform_device *pdev)
/* enable clock for regcache get default value from hw */
afe_priv->pm_runtime_bypass_reg_ctl = true;
- pm_runtime_get_sync(dev);
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret) {
+ afe_priv->pm_runtime_bypass_reg_ctl = false;
+ return dev_err_probe(dev, ret, "failed to resume device\n");
+ }
ret = regmap_reinit_cache(afe->regmap, &mt8192_afe_regmap_config);
- if (ret)
- return dev_err_probe(dev, ret, "regmap_reinit_cache fail\n");
-
pm_runtime_put_sync(dev);
afe_priv->pm_runtime_bypass_reg_ctl = false;
+ if (ret)
+ return dev_err_probe(dev, ret, "regmap_reinit_cache fail\n");
+
regcache_cache_only(afe->regmap, true);
regcache_mark_dirty(afe->regmap);
--
2.54.0
^ permalink raw reply related
* Re: [PATCH RFC net-next v2] net: airoha: Add TCP LRO support
From: Alexander Lobakin @ 2026-05-27 14:12 UTC (permalink / raw)
To: Lorenzo Bianconi
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, linux-arm-kernel, linux-mediatek, netdev,
Madhur Agrawal
In-Reply-To: <ahYLvlIYH60cvkWB@lore-desk>
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 26 May 2026 23:08:14 +0200
>> From: Lorenzo Bianconi <lorenzo@kernel.org>
>> Date: Tue, 26 May 2026 08:58:05 +0200
[...]
>>> @@ -587,6 +630,85 @@ static int airoha_qdma_get_gdm_port(struct airoha_eth *eth,
>>> return port >= ARRAY_SIZE(eth->ports) ? -EINVAL : port;
>>> }
>>>
>>> +static int airoha_qdma_lro_rx_process(struct airoha_queue *q,
>>> + struct airoha_qdma_desc *desc)
>>> +{
>>> + u32 desc_ctrl = le32_to_cpu(READ_ONCE(desc->ctrl));
>>> + u32 msg1 = le32_to_cpu(READ_ONCE(desc->msg1));
>>> + u32 msg2 = le32_to_cpu(READ_ONCE(desc->msg2));
>>> + u32 msg3 = le32_to_cpu(READ_ONCE(desc->msg3));
>>
>> Why are these READ_ONCE()s needed? Does desc come from the HW (sorry I
>> didn't follow the whole code flow) or...?
>
> Correct, ctrl, msg1, msg2 and msg3 are subfields of the DMA descriptor read by
> airoha_qdma_rx_process() from the NIC. I guess here we have a similar issue as
> the one fixed in [0]
>
> [0] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=4ae0604a0673e11e2075b178387151fcad5111b5
Hmm, I never believed that we need READ_ONCE()s when reading HW
descriptors, I always thought dma_alloc_coherent() is enough.
But maybe I've been mistaking...
[...]
>>> +
>>> + if (*topt == cpu_to_be32((TCPOPT_NOP << 24) |
>>
>> Shouldn't this be `((u32)TCPOPT_NOP) << 24` to avoid sign issues?
>
> I guess this is same approach used in [1]. Am I missing something?
>
> [1] https://github.com/torvalds/linux/blob/master/net/ipv4/tcp_ipv4.c#L823
Yeah I also notice this in one more patch when scrolling netdev
yesterday. I guess it's okay here since TCPOPT_NOP is small and
constant and doesn't reach bit 31.
>
> Regards,
> Lorenzo
Thanks,
Olek
^ 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