* [PATCH v5 net 0/7] i40e: re-init and UAF fixes
From: Maciej Fijalkowski @ 2026-07-01 12:45 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, magnus.karlsson, kuba, pabeni, horms, przemyslaw.kitszel,
jacob.e.keller, Maciej Fijalkowski
v5:
- include three new patches to address last Sashiko review
*
- do not release the irq lump in rebuild path in patch 7
- clear dangling pointers from rx and xdp rings arrays
v4:
- add preceding patch that fixes a case when some of re-init allocations
failed and we missed de-registering netdev at failure path
- pull out i40e_vsi_setup() changes onto separate patch
v3:
- address UAF when ring arrays were freed before q_vector's ring
containers (Sashiko, Jacob)
- remove bool params from alloc/free array routines (Simon)
v2:
- NULL vsi->tx_rings in i40e_vsi_alloc_arrays() (Sashiko)
Maciej Fijalkowski (7):
i40e: unregister netdev before clearing VSI on reinit failure
i40e: avoid null ptr dereference in i40e_ptp_stop()
i40e: make ring pointers unreachable before freeing via rcu
i40e: avoid deadlock when calling unregister_netdev()
i40e: fix potential UAF in i40e_vsi_setup()'s error path
i40e: do not expose netdev too early
i40e: keep q_vectors array in sync with channel count changes
drivers/net/ethernet/intel/i40e/i40e_main.c | 128 ++++++++++++--------
drivers/net/ethernet/intel/i40e/i40e_ptp.c | 5 +-
2 files changed, 82 insertions(+), 51 deletions(-)
--
2.43.0
^ permalink raw reply
* [PATCH v5 net 1/7] i40e: unregister netdev before clearing VSI on reinit failure
From: Maciej Fijalkowski @ 2026-07-01 12:45 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, magnus.karlsson, kuba, pabeni, horms, przemyslaw.kitszel,
jacob.e.keller, Maciej Fijalkowski
In-Reply-To: <20260701124524.13644-1-maciej.fijalkowski@intel.com>
i40e_vsi_reinit_setup() tears down the existing VSI queue/ring backing
state before allocating replacement arrays and queue tracking. If one of
these early allocations fails, the function jumps directly to err_vsi
and calls i40e_vsi_clear().
For a registered netdev, this frees the VSI while
netdev_priv(netdev)->vsi can still point at it, leaving the registered
netdev with dangling private driver state.
Split the error path so failures after destructive reinit teardown first
unregister and free the netdev before clearing the VSI.
Fixes: d2a69fefd756 ("i40e: Fix changing previously set num_queue_pairs for PFs")
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index a04683004a56..471fa7f7b643 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -14274,7 +14274,7 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
i40e_set_num_rings_in_vsi(vsi);
ret = i40e_vsi_alloc_arrays(vsi, false);
if (ret)
- goto err_vsi;
+ goto err_netdev;
alloc_queue_pairs = vsi->alloc_queue_pairs *
(i40e_enabled_xdp_vsi(vsi) ? 2 : 1);
@@ -14284,7 +14284,7 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
dev_info(&pf->pdev->dev,
"failed to get tracking for %d queues for VSI %d err %d\n",
alloc_queue_pairs, vsi->seid, ret);
- goto err_vsi;
+ goto err_netdev;
}
vsi->base_queue = ret;
@@ -14309,6 +14309,7 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
err_rings:
i40e_vsi_free_q_vectors(vsi);
+err_netdev:
if (vsi->netdev_registered) {
vsi->netdev_registered = false;
unregister_netdev(vsi->netdev);
@@ -14318,7 +14319,6 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
if (vsi->type == I40E_VSI_MAIN)
i40e_devlink_destroy_port(pf);
i40e_aq_delete_element(&pf->hw, vsi->seid, NULL);
-err_vsi:
i40e_vsi_clear(vsi);
return NULL;
}
--
2.43.0
^ permalink raw reply related
* [PATCH v5 net 2/7] i40e: avoid null ptr dereference in i40e_ptp_stop()
From: Maciej Fijalkowski @ 2026-07-01 12:45 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, magnus.karlsson, kuba, pabeni, horms, przemyslaw.kitszel,
jacob.e.keller, Maciej Fijalkowski, Sashiko AI Review
In-Reply-To: <20260701124524.13644-1-maciej.fijalkowski@intel.com>
Sashiko reports:
***
If an allocation fails here during i40e_rebuild(), i40e_vsi_clear()
frees the
main VSI and sets pf->vsi[vsi->idx] = NULL, and the rebuild will abort
without
stopping the PTP clock.
Later, if the device is removed or unbound, i40e_remove()
unconditionally
calls i40e_ptp_stop(), which does:
drivers/net/ethernet/intel/i40e/i40e_ptp.c:i40e_ptp_stop() {
...
struct i40e_vsi *main_vsi = i40e_pf_get_main_vsi(pf);
...
dev_info(&pf->pdev->dev, "%s: removed PHC on %s\n", __func__,
main_vsi->netdev->name);
...
}
Would this cause a NULL pointer dereference since main_vsi is now NULL?
***
Check if main_vsi is not null before calling dev_info().
Fixes: beb0dff1251d ("i40e: enable PTP")
Reported-by: Sashiko AI Review <sashiko-bot@kernel.org>
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_ptp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
index ff62b5f2c815..ca93df4d6785 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
@@ -1556,8 +1556,9 @@ void i40e_ptp_stop(struct i40e_pf *pf)
if (pf->ptp_clock) {
ptp_clock_unregister(pf->ptp_clock);
pf->ptp_clock = NULL;
- dev_info(&pf->pdev->dev, "%s: removed PHC on %s\n", __func__,
- main_vsi->netdev->name);
+ if (main_vsi)
+ dev_info(&pf->pdev->dev, "%s: removed PHC on %s\n", __func__,
+ main_vsi->netdev->name);
}
if (i40e_is_ptp_pin_dev(&pf->hw)) {
--
2.43.0
^ permalink raw reply related
* [PATCH v5 net 3/7] i40e: make ring pointers unreachable before freeing via rcu
From: Maciej Fijalkowski @ 2026-07-01 12:45 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, magnus.karlsson, kuba, pabeni, horms, przemyslaw.kitszel,
jacob.e.keller, Maciej Fijalkowski, Sashiko AI Review
In-Reply-To: <20260701124524.13644-1-maciej.fijalkowski@intel.com>
Sashiko reports:
***
> err_config:
> + i40e_vsi_free_q_vectors(vsi);
> +err_qvec:
> i40e_vsi_clear_rings(vsi);
This is a pre-existing issue, but can the sequence in i40e_vsi_clear_rings()
lead to an RCU ordering violation?
In i40e_vsi_clear_rings(), the rings are freed before the array pointers are
nullified:
kfree_rcu(vsi->tx_rings[i], rcu);
WRITE_ONCE(vsi->tx_rings[i], NULL);
Under RCU rules, a pointer must be made unreachable to new readers before it
is handed off to kfree_rcu(). Could a new RCU reader (like
i40e_get_netdev_stats_struct_tx()) fetch the pointer after kfree_rcu() is
invoked, and access freed memory if the grace period expires while the
reader is still active?
***
Save the Tx ring pointer before clearing the published ring array slots
and pass the saved pointer to kfree_rcu(). This preserves the intended
RCU ordering, where new readers can no longer discover the ring through
vsi->tx_rings/rx_rings/xdp_rings before the object is queued for
deferred freeing, while avoiding a NULL kfree_rcu() argument after the
slot has already been cleared. Since the Tx pointer is the base of the
per-queue-pair allocation block, re-reading vsi->tx_rings[i] after
WRITE_ONCE(..., NULL) would otherwise turn the free into a no-op and
leak the whole ring block.
Fixes: 9f65e15b4f98 ("i40e: Move rings from pointer to array to array of pointers")
Reported-by: Sashiko AI Review <sashiko-bot@kernel.org>
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 471fa7f7b643..a29a89192a7a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -11699,11 +11699,13 @@ static void i40e_vsi_clear_rings(struct i40e_vsi *vsi)
if (vsi->tx_rings && vsi->tx_rings[0]) {
for (i = 0; i < vsi->alloc_queue_pairs; i++) {
- kfree_rcu(vsi->tx_rings[i], rcu);
+ struct i40e_ring *tx_ring = vsi->tx_rings[i];
+
WRITE_ONCE(vsi->tx_rings[i], NULL);
WRITE_ONCE(vsi->rx_rings[i], NULL);
if (vsi->xdp_rings)
WRITE_ONCE(vsi->xdp_rings[i], NULL);
+ kfree_rcu(tx_ring, rcu);
}
}
}
--
2.43.0
^ permalink raw reply related
* [PATCH v5 net 4/7] i40e: avoid deadlock when calling unregister_netdev()
From: Maciej Fijalkowski @ 2026-07-01 12:45 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, magnus.karlsson, kuba, pabeni, horms, przemyslaw.kitszel,
jacob.e.keller, Maciej Fijalkowski, Sashiko AI Review
In-Reply-To: <20260701124524.13644-1-maciej.fijalkowski@intel.com>
Sashiko reports:
***
> +err_netdev:
> if (vsi->netdev_registered) {
> vsi->netdev_registered = false;
> unregister_netdev(vsi->netdev);
Could this result in a deadlock when called during a device rebuild?
Looking at i40e_rebuild(), it explicitly acquires the RTNL lock before
proceeding:
drivers/net/ethernet/intel/i40e/i40e_main.c:i40e_rebuild() {
...
if (!lock_acquired)
rtnl_lock();
ret = i40e_setup_pf_switch(pf, reinit, true);
...
}
If i40e_setup_pf_switch() calls i40e_vsi_reinit_setup() and takes this new
err_netdev path, unregister_netdev() will unconditionally attempt to acquire
rtnl_lock(), leading to a deadlock on the non-recursive mutex.
***
Use unregister_netdevice() when the rebuild path already holds RTNL, and
keep unregister_netdev() for callers that do not. This avoids both
recursive RTNL locking and dropping RTNL in the middle of the VSI unwind
path.
Fixes: bc7d338fbb3f ("i40e: reinit flow for the main VSI")
Reported-by: Sashiko AI Review <sashiko-bot@kernel.org>
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index a29a89192a7a..e88cf7cfbd84 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -14257,7 +14257,8 @@ static int i40e_vsi_setup_vectors(struct i40e_vsi *vsi)
* Returns pointer to the successfully allocated and configured VSI sw struct
* on success, otherwise returns NULL on failure.
**/
-static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
+static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi,
+ bool lock_acquired)
{
struct i40e_vsi *main_vsi;
u16 alloc_queue_pairs;
@@ -14314,7 +14315,10 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
err_netdev:
if (vsi->netdev_registered) {
vsi->netdev_registered = false;
- unregister_netdev(vsi->netdev);
+ if (lock_acquired)
+ unregister_netdevice(vsi->netdev);
+ else
+ unregister_netdev(vsi->netdev);
free_netdev(vsi->netdev);
vsi->netdev = NULL;
}
@@ -15036,7 +15040,7 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit, bool lock_acqui
main_vsi = i40e_vsi_setup(pf, I40E_VSI_MAIN,
uplink_seid, 0);
else if (reinit)
- main_vsi = i40e_vsi_reinit_setup(main_vsi);
+ main_vsi = i40e_vsi_reinit_setup(main_vsi, lock_acquired);
if (!main_vsi) {
dev_info(&pf->pdev->dev, "setup of MAIN VSI failed\n");
i40e_cloud_filter_exit(pf);
--
2.43.0
^ permalink raw reply related
* [PATCH v5 net 5/7] i40e: fix potential UAF in i40e_vsi_setup()'s error path
From: Maciej Fijalkowski @ 2026-07-01 12:45 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, magnus.karlsson, kuba, pabeni, horms, przemyslaw.kitszel,
jacob.e.keller, Maciej Fijalkowski
In-Reply-To: <20260701124524.13644-1-maciej.fijalkowski@intel.com>
Sashiko pointed out an issue where error path in i40e_vsi_reinit_setup()
released ring memory but then when freeing q_vectors, the rings mapped
to q_vectors where touched which implies a regular use-after-free bug.
Apparently i40e_vsi_setup() has the same problem, so swap the allocation
and freeing order and fix the 13 year old bug.
Fixes: 41c445ff0f48 ("i40e: main driver core")
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index e88cf7cfbd84..fcdd13af08ea 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -14466,14 +14466,14 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
fallthrough;
case I40E_VSI_FDIR:
/* set up vectors and rings if needed */
- ret = i40e_vsi_setup_vectors(vsi);
- if (ret)
- goto err_msix;
-
ret = i40e_alloc_rings(vsi);
if (ret)
goto err_rings;
+ ret = i40e_vsi_setup_vectors(vsi);
+ if (ret)
+ goto err_qvec;
+
/* map all of the rings to the q_vectors */
i40e_vsi_map_rings_to_vectors(vsi);
@@ -14493,10 +14493,10 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
return vsi;
err_config:
+ i40e_vsi_free_q_vectors(vsi);
+err_qvec:
i40e_vsi_clear_rings(vsi);
err_rings:
- i40e_vsi_free_q_vectors(vsi);
-err_msix:
if (vsi->netdev_registered) {
vsi->netdev_registered = false;
unregister_netdev(vsi->netdev);
--
2.43.0
^ permalink raw reply related
* [PATCH v5 net 6/7] i40e: do not expose netdev too early
From: Maciej Fijalkowski @ 2026-07-01 12:45 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, magnus.karlsson, kuba, pabeni, horms, przemyslaw.kitszel,
jacob.e.keller, Maciej Fijalkowski, Sashiko AI Review
In-Reply-To: <20260701124524.13644-1-maciej.fijalkowski@intel.com>
i40e_vsi_setup() registers the netdev before rings and q_vectors are fully
allocated and mapped. Once register_netdev() returns, userspace can reach
netdev callbacks such as ndo_open(), so the VSI backing state must already
be ready.
Move register_netdev() to the end of the setup path, after ring/q_vector
allocation, ring mapping and RSS configuration. Keep freeing an allocated
but not registered netdev on the error path.
Fixes: 41c445ff0f48 ("i40e: main driver core")
Reported-by: Sashiko AI Review <sashiko-bot@kernel.org>
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 29 ++++++++++++---------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index fcdd13af08ea..a9ec53cfd905 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -14454,15 +14454,6 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
goto err_netdev;
SET_NETDEV_DEVLINK_PORT(vsi->netdev, &pf->devlink_port);
}
- ret = register_netdev(vsi->netdev);
- if (ret)
- goto err_dl_port;
- vsi->netdev_registered = true;
- netif_carrier_off(vsi->netdev);
-#ifdef CONFIG_I40E_DCB
- /* Setup DCB netlink interface */
- i40e_dcbnl_setup(vsi);
-#endif /* CONFIG_I40E_DCB */
fallthrough;
case I40E_VSI_FDIR:
/* set up vectors and rings if needed */
@@ -14490,6 +14481,19 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
if (ret)
goto err_config;
}
+
+ if (vsi->netdev) {
+ ret = register_netdev(vsi->netdev);
+ if (ret)
+ goto err_config;
+ vsi->netdev_registered = true;
+ netif_carrier_off(vsi->netdev);
+#ifdef CONFIG_I40E_DCB
+ /* Setup DCB netlink interface */
+ i40e_dcbnl_setup(vsi);
+#endif /* CONFIG_I40E_DCB */
+ }
+
return vsi;
err_config:
@@ -14500,13 +14504,14 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
if (vsi->netdev_registered) {
vsi->netdev_registered = false;
unregister_netdev(vsi->netdev);
- free_netdev(vsi->netdev);
- vsi->netdev = NULL;
}
-err_dl_port:
if (vsi->type == I40E_VSI_MAIN)
i40e_devlink_destroy_port(pf);
err_netdev:
+ if (vsi->netdev) {
+ free_netdev(vsi->netdev);
+ vsi->netdev = NULL;
+ }
i40e_aq_delete_element(&pf->hw, vsi->seid, NULL);
err_vsi:
i40e_vsi_clear(vsi);
--
2.43.0
^ permalink raw reply related
* [PATCH v5 net 7/7] i40e: keep q_vectors array in sync with channel count changes
From: Maciej Fijalkowski @ 2026-07-01 12:45 UTC (permalink / raw)
To: intel-wired-lan
Cc: netdev, magnus.karlsson, kuba, pabeni, horms, przemyslaw.kitszel,
jacob.e.keller, Maciej Fijalkowski
In-Reply-To: <20260701124524.13644-1-maciej.fijalkowski@intel.com>
For the main VSI, i40e_set_num_rings_in_vsi() always derives
num_q_vectors from pf->num_lan_msix. At the same time, ethtool -L stores
the user requested channel count in vsi->req_queue_pairs and the queue
setup path uses that value for the effective number of queue pairs.
This leaves queue and vector counts out of sync after shrinking channel
count via ethtool -L. The active queue configuration is reduced, but the
VSI still keeps the full PF-sized q_vector topology.
That mismatch breaks reconfiguration flows which rely on vector/NAPI
state matching the effective channel configuration. In particular,
toggling /sys/class/net/<dev>/threaded after reducing the channel count
can hang, and later channel-count changes can fail because VSI reinit
does not rebuild q_vectors to match the new vector count.
Fix this by making the main VSI num_q_vectors follow the effective
requested channel count, capped by the available MSI-X vectors. Update
i40e_vsi_reinit_setup() to rebuild q_vectors during VSI reinit so the
vector topology is refreshed together with the ring arrays when channel
count changes.
Keep alloc_queue_pairs unchanged and based on pf->num_lan_qps so the VSI
retains its full queue capacity. Also do not touch irq_pile when
rebuilding vectors.
Selftest napi_threaded.py was originally used when Jakub reported hang
on /sys/class/net/<dev>/threaded toggle. In order to make it pass on
i40e, use persistent NAPI configuration for q_vector NAPIs so NAPI
identity and threaded settings survive q_vector reallocation across
channel-count changes. This is achieved by using netif_napi_add_config()
when configuring q_vectors.
$ export NETIF=ens259f1np1
$ sudo -E env PATH="$PATH" ./tools/testing/selftests/drivers/net/napi_threaded.py
TAP version 13
1..3
ok 1 napi_threaded.napi_init
ok 2 napi_threaded.change_num_queues
ok 3 napi_threaded.enable_dev_threaded_disable_napi_threaded
Totals: pass:3 fail:0 xfail:0 xpass:0 skip:0 error:0
Reported-by: Jakub Kicinski <kuba@kernel.org>
Closes: https://lore.kernel.org/intel-wired-lan/20260316133100.6054a11f@kernel.org/
Fixes: d2a69fefd756 ("i40e: Fix changing previously set num_queue_pairs for PFs")
Signed-off-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 69 +++++++++++++--------
1 file changed, 44 insertions(+), 25 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index a9ec53cfd905..8a23bd99bd12 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -11406,10 +11406,14 @@ static void i40e_service_timer(struct timer_list *t)
static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)
{
struct i40e_pf *pf = vsi->back;
+ u16 qps;
switch (vsi->type) {
case I40E_VSI_MAIN:
vsi->alloc_queue_pairs = pf->num_lan_qps;
+ qps = vsi->req_queue_pairs ?
+ min(vsi->req_queue_pairs, pf->num_lan_qps) :
+ pf->num_lan_qps;
if (!vsi->num_tx_desc)
vsi->num_tx_desc = ALIGN(I40E_DEFAULT_NUM_DESCRIPTORS,
I40E_REQ_DESCRIPTOR_MULTIPLE);
@@ -11417,7 +11421,7 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)
vsi->num_rx_desc = ALIGN(I40E_DEFAULT_NUM_DESCRIPTORS,
I40E_REQ_DESCRIPTOR_MULTIPLE);
if (test_bit(I40E_FLAG_MSIX_ENA, pf->flags))
- vsi->num_q_vectors = pf->num_lan_msix;
+ vsi->num_q_vectors = clamp(qps, 1, pf->num_lan_msix);
else
vsi->num_q_vectors = 1;
@@ -11469,12 +11473,11 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)
/**
* i40e_vsi_alloc_arrays - Allocate queue and vector pointer arrays for the vsi
* @vsi: VSI pointer
- * @alloc_qvectors: a bool to specify if q_vectors need to be allocated.
*
* On error: returns error code (negative)
* On success: returns 0
**/
-static int i40e_vsi_alloc_arrays(struct i40e_vsi *vsi, bool alloc_qvectors)
+static int i40e_vsi_alloc_arrays(struct i40e_vsi *vsi)
{
struct i40e_ring **next_rings;
int size;
@@ -11493,19 +11496,20 @@ static int i40e_vsi_alloc_arrays(struct i40e_vsi *vsi, bool alloc_qvectors)
}
vsi->rx_rings = next_rings;
- if (alloc_qvectors) {
- /* allocate memory for q_vector pointers */
- size = sizeof(struct i40e_q_vector *) * vsi->num_q_vectors;
- vsi->q_vectors = kzalloc(size, GFP_KERNEL);
- if (!vsi->q_vectors) {
- ret = -ENOMEM;
- goto err_vectors;
- }
+ /* allocate memory for q_vector pointers */
+ size = sizeof(struct i40e_q_vector *) * vsi->num_q_vectors;
+ vsi->q_vectors = kzalloc(size, GFP_KERNEL);
+ if (!vsi->q_vectors) {
+ ret = -ENOMEM;
+ goto err_vectors;
}
return ret;
err_vectors:
kfree(vsi->tx_rings);
+ vsi->tx_rings = NULL;
+ vsi->rx_rings = NULL;
+ vsi->xdp_rings = NULL;
return ret;
}
@@ -11578,7 +11582,7 @@ static int i40e_vsi_mem_alloc(struct i40e_pf *pf, enum i40e_vsi_type type)
if (ret)
goto err_rings;
- ret = i40e_vsi_alloc_arrays(vsi, true);
+ ret = i40e_vsi_alloc_arrays(vsi);
if (ret)
goto err_rings;
@@ -11603,18 +11607,15 @@ static int i40e_vsi_mem_alloc(struct i40e_pf *pf, enum i40e_vsi_type type)
/**
* i40e_vsi_free_arrays - Free queue and vector pointer arrays for the VSI
* @vsi: VSI pointer
- * @free_qvectors: a bool to specify if q_vectors need to be freed.
*
* On error: returns error code (negative)
* On success: returns 0
**/
-static void i40e_vsi_free_arrays(struct i40e_vsi *vsi, bool free_qvectors)
+static void i40e_vsi_free_arrays(struct i40e_vsi *vsi)
{
/* free the ring and vector containers */
- if (free_qvectors) {
- kfree(vsi->q_vectors);
- vsi->q_vectors = NULL;
- }
+ kfree(vsi->q_vectors);
+ vsi->q_vectors = NULL;
kfree(vsi->tx_rings);
vsi->tx_rings = NULL;
vsi->rx_rings = NULL;
@@ -11674,7 +11675,7 @@ static int i40e_vsi_clear(struct i40e_vsi *vsi)
i40e_put_lump(pf->irq_pile, vsi->base_vector, vsi->idx);
bitmap_free(vsi->af_xdp_zc_qps);
- i40e_vsi_free_arrays(vsi, true);
+ i40e_vsi_free_arrays(vsi);
i40e_clear_rss_config_user(vsi);
pf->vsi[vsi->idx] = NULL;
@@ -12048,7 +12049,8 @@ static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx)
cpumask_copy(&q_vector->affinity_mask, cpu_possible_mask);
if (vsi->netdev)
- netif_napi_add(vsi->netdev, &q_vector->napi, i40e_napi_poll);
+ netif_napi_add_config(vsi->netdev, &q_vector->napi,
+ i40e_napi_poll, v_idx);
/* tie q_vector and vsi together */
vsi->q_vectors[v_idx] = q_vector;
@@ -14203,8 +14205,9 @@ int i40e_vsi_release(struct i40e_vsi *vsi)
**/
static int i40e_vsi_setup_vectors(struct i40e_vsi *vsi)
{
- int ret = -ENOENT;
struct i40e_pf *pf = vsi->back;
+ bool reuse_irq_lump = false;
+ int ret = -ENOENT;
if (vsi->q_vectors[0]) {
dev_info(&pf->pdev->dev, "VSI %d has existing q_vectors\n",
@@ -14212,7 +14215,10 @@ static int i40e_vsi_setup_vectors(struct i40e_vsi *vsi)
return -EEXIST;
}
- if (vsi->base_vector) {
+ if (vsi->type == I40E_VSI_MAIN && vsi->base_vector)
+ reuse_irq_lump = true;
+
+ if (vsi->base_vector && !reuse_irq_lump) {
dev_info(&pf->pdev->dev, "VSI %d has non-zero base vector %d\n",
vsi->seid, vsi->base_vector);
return -EEXIST;
@@ -14232,6 +14238,10 @@ static int i40e_vsi_setup_vectors(struct i40e_vsi *vsi)
*/
if (!test_bit(I40E_FLAG_MSIX_ENA, pf->flags))
return ret;
+
+ if (reuse_irq_lump)
+ return ret;
+
if (vsi->num_q_vectors)
vsi->base_vector = i40e_get_lump(pf, pf->irq_pile,
vsi->num_q_vectors, vsi->idx);
@@ -14271,11 +14281,20 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi,
pf = vsi->back;
i40e_put_lump(pf->qp_pile, vsi->base_queue, vsi->idx);
+ i40e_vsi_free_q_vectors(vsi);
i40e_vsi_clear_rings(vsi);
+ i40e_vsi_free_arrays(vsi);
- i40e_vsi_free_arrays(vsi, false);
i40e_set_num_rings_in_vsi(vsi);
- ret = i40e_vsi_alloc_arrays(vsi, false);
+ ret = i40e_vsi_alloc_arrays(vsi);
+ if (ret)
+ goto err_netdev;
+
+ /* Rebuild q_vectors during VSI reinit because the effective channel
+ * count may change num_q_vectors. Keep vector topology aligned with the
+ * queue configuration after ethtool's .set_channels() callback.
+ */
+ ret = i40e_vsi_setup_vectors(vsi);
if (ret)
goto err_netdev;
@@ -14287,7 +14306,7 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi,
dev_info(&pf->pdev->dev,
"failed to get tracking for %d queues for VSI %d err %d\n",
alloc_queue_pairs, vsi->seid, ret);
- goto err_netdev;
+ goto err_rings;
}
vsi->base_queue = ret;
--
2.43.0
^ permalink raw reply related
* [PATCH net-next] net/mlx5e: MACsec: annotate context list traversals
From: Runyu Xiao @ 2026-07-01 12:40 UTC (permalink / raw)
To: borisp, saeedm, leon, tariqt, mbloch
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, sd, dtatulea,
cjubran, horms, jianbol, netdev, linux-rdma, linux-kernel,
runyu.xiao, jianhao.xu
The MACsec offload control paths take macsec->lock before looking up
MACsec device and RX SC contexts. The lookup helpers walk RCU lists, but
the iterators do not currently pass the mutex condition, so
CONFIG_PROVE_RCU_LIST cannot see the existing writer/control-path
protection.
Pass lockdep_is_held(&macsec->lock) to the list iterators in the MACsec
lookup helpers. The RX SC helper does not otherwise need the MACsec
context, so pass it in only to express the existing lockdep condition.
This was found by our static analysis tool and then manually reviewed
against the current tree. The dynamic triage evidence is a
target-matched CONFIG_PROVE_RCU_LIST warning; the change is limited
to documenting the existing protection contract.
This is a lockdep annotation cleanup. It does not change MACsec context
lifetime or list updates.
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
---
.../mellanox/mlx5/core/en_accel/macsec.c | 23 +++++++++++--------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
index 528b04d4de41..3028e327e36d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c
@@ -405,11 +405,13 @@ static int mlx5e_macsec_init_sa(struct macsec_context *ctx,
}
static struct mlx5e_macsec_rx_sc *
-mlx5e_macsec_get_rx_sc_from_sc_list(const struct list_head *list, sci_t sci)
+mlx5e_macsec_get_rx_sc_from_sc_list(struct mlx5e_macsec *macsec,
+ const struct list_head *list, sci_t sci)
{
struct mlx5e_macsec_rx_sc *iter;
- list_for_each_entry_rcu(iter, list, rx_sc_list_element) {
+ list_for_each_entry_rcu(iter, list, rx_sc_list_element,
+ lockdep_is_held(&macsec->lock)) {
if (iter->sci == sci)
return iter;
}
@@ -473,14 +475,15 @@ static bool mlx5e_macsec_secy_features_validate(struct macsec_context *ctx)
}
static struct mlx5e_macsec_device *
-mlx5e_macsec_get_macsec_device_context(const struct mlx5e_macsec *macsec,
+mlx5e_macsec_get_macsec_device_context(struct mlx5e_macsec *macsec,
const struct macsec_context *ctx)
{
struct mlx5e_macsec_device *iter;
const struct list_head *list;
list = &macsec->macsec_device_list_head;
- list_for_each_entry_rcu(iter, list, macsec_device_list_element) {
+ list_for_each_entry_rcu(iter, list, macsec_device_list_element,
+ lockdep_is_held(&macsec->lock)) {
if (iter->netdev == ctx->secy->netdev)
return iter;
}
@@ -692,7 +695,7 @@ static int mlx5e_macsec_add_rxsc(struct macsec_context *ctx)
}
rx_sc_list = &macsec_device->macsec_rx_sc_list_head;
- rx_sc = mlx5e_macsec_get_rx_sc_from_sc_list(rx_sc_list, ctx_rx_sc->sci);
+ rx_sc = mlx5e_macsec_get_rx_sc_from_sc_list(macsec, rx_sc_list, ctx_rx_sc->sci);
if (rx_sc) {
netdev_err(ctx->netdev, "MACsec offload: rx_sc (sci %lld) already exists\n",
ctx_rx_sc->sci);
@@ -775,7 +778,7 @@ static int mlx5e_macsec_upd_rxsc(struct macsec_context *ctx)
}
list = &macsec_device->macsec_rx_sc_list_head;
- rx_sc = mlx5e_macsec_get_rx_sc_from_sc_list(list, ctx_rx_sc->sci);
+ rx_sc = mlx5e_macsec_get_rx_sc_from_sc_list(macsec, list, ctx_rx_sc->sci);
if (!rx_sc) {
err = -EINVAL;
goto out;
@@ -853,7 +856,7 @@ static int mlx5e_macsec_del_rxsc(struct macsec_context *ctx)
}
list = &macsec_device->macsec_rx_sc_list_head;
- rx_sc = mlx5e_macsec_get_rx_sc_from_sc_list(list, ctx->rx_sc->sci);
+ rx_sc = mlx5e_macsec_get_rx_sc_from_sc_list(macsec, list, ctx->rx_sc->sci);
if (!rx_sc) {
netdev_err(ctx->netdev,
"MACsec offload rx_sc sci %lld doesn't exist\n",
@@ -894,7 +897,7 @@ static int mlx5e_macsec_add_rxsa(struct macsec_context *ctx)
}
list = &macsec_device->macsec_rx_sc_list_head;
- rx_sc = mlx5e_macsec_get_rx_sc_from_sc_list(list, sci);
+ rx_sc = mlx5e_macsec_get_rx_sc_from_sc_list(macsec, list, sci);
if (!rx_sc) {
netdev_err(ctx->netdev,
"MACsec offload rx_sc sci %lld doesn't exist\n",
@@ -978,7 +981,7 @@ static int mlx5e_macsec_upd_rxsa(struct macsec_context *ctx)
}
list = &macsec_device->macsec_rx_sc_list_head;
- rx_sc = mlx5e_macsec_get_rx_sc_from_sc_list(list, sci);
+ rx_sc = mlx5e_macsec_get_rx_sc_from_sc_list(macsec, list, sci);
if (!rx_sc) {
netdev_err(ctx->netdev,
"MACsec offload rx_sc sci %lld doesn't exist\n",
@@ -1035,7 +1038,7 @@ static int mlx5e_macsec_del_rxsa(struct macsec_context *ctx)
}
list = &macsec_device->macsec_rx_sc_list_head;
- rx_sc = mlx5e_macsec_get_rx_sc_from_sc_list(list, sci);
+ rx_sc = mlx5e_macsec_get_rx_sc_from_sc_list(macsec, list, sci);
if (!rx_sc) {
netdev_err(ctx->netdev,
"MACsec offload rx_sc sci %lld doesn't exist\n",
--
2.34.1
^ permalink raw reply related
* Re: [PATCH 2/3] arm64: dts: socfpga: agilex5: Add SoCDK TSN Config2 board
From: Andrew Lunn @ 2026-07-01 12:47 UTC (permalink / raw)
To: Nazle Asmade, Muhammad Nazim Amirul
Cc: dinguyen@kernel.org, maxime.chevallier@bootlin.com,
rmk+kernel@armlinux.org.uk, krzk+dt@kernel.org,
conor+dt@kernel.org, robh@kernel.org, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
andrew+netdev@lunn.ch, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <5a0c962e-1af0-4d6a-b871-d8a0b0197ff5@altera.com>
> > # There are a small number of cases where the MAC has hard coded
> > # delays which cannot be disabled. The 'phy-mode' only describes the
> > # PCB. The inability to disable the delays in the MAC does not change
> > # the meaning of 'phy-mode'. It does however mean that a 'phy-mode' of
> > # 'rgmii' is now invalid, it cannot be supported, since both the PCB
> > # and the MAC and PHY adding delays cannot result in a functional
> > # link. Thus the MAC should report a fatal error for any modes which
> > # cannot be supported. When the MAC implements the delay, it must
> > # ensure that the PHY does not also implement the same delay. So it
> > # must modify the phy-mode it passes to the PHY, removing the delay it
> > # has added. Failure to remove the delay will result in a
> > # non-functioning link.
> >
> > Andrew
> >
> > ---
> > pw-bot: cr
> Hi Andrew,
>
> The delays are provided by the FPGA GMII-to-RGMII converter soft IP,
> which is hardcoded in the FPGA bitstream and cannot be disabled or
> modified from the driver side.
>
> Using phy-mode = "rgmii" is intentional here — it prevents the PHY from
> adding its own internal delays on top, since the FPGA converter already
> provides the full required delay. This is consistent with how all other
> Agilex5 SoCDK board variants are described, as seen in commit
> c5637e5ceb4b ("arm64: dts: socfpga: agilex5: Fix phy-mode to rgmii as HW
> provides clock delay") already in Dinh Nguyen's tree, which applies the
> same rationale across all Agilex5 boards.
I've become more insistent that designs get this correct. So i don't
care too much about past systems. Many vendors are having to fix up
their drivers and DT in order to make new boards consistent.
You can look at your system as the FPGA being the MAC, and the PHY is
the PHY. The PCB is not providing the delay, the MAC is. This exactly
fits the description above.
Andrew
^ permalink raw reply
* [PATCH net-next] amt: no longer rely on RTNL in amt_fill_info()
From: Eric Dumazet @ 2026-07-01 12:50 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Andrew Lunn, netdev,
eric.dumazet, Eric Dumazet
Update amt_fill_info() to run under RCU read lock instead of RTNL.
The AMT device configuration fields (mode, relay_port, gw_port, local_ip,
discovery_ip, max_tunnels) and stream_dev pointer are initialized during
device creation (amt_newlink) and are immutable. Accessing them locklessly
is safe. The stream_dev net_device structure is protected from being freed
by RCU.
The only field that can change concurrently is amt->remote_ip, which is
updated in the packet receive path (amt_advertisement_handler) and
workqueue (amt_req_work). Add READ_ONCE()/WRITE_ONCE() annotations
around amt->remote_ip to prevent data races.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
drivers/net/amt.c | 43 +++++++++++++++++++++++++++----------------
1 file changed, 27 insertions(+), 16 deletions(-)
diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index 724a8163a5142a6835950abb63d80f29417b2654..5cf97c65576fc23b6faac1d686b0fd90b0e05433 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -708,11 +708,13 @@ static void amt_send_request(struct amt_dev *amt, bool v6)
struct iphdr *iph;
struct rtable *rt;
struct flowi4 fl4;
+ __be32 remote_ip;
struct sock *sk;
u32 len;
int err;
rcu_read_lock();
+ remote_ip = READ_ONCE(amt->remote_ip);
sk = rcu_dereference(amt->sk);
if (!sk)
goto out;
@@ -721,7 +723,7 @@ static void amt_send_request(struct amt_dev *amt, bool v6)
goto out;
rt = ip_route_output_ports(amt->net, &fl4, sk,
- amt->remote_ip, amt->local_ip,
+ remote_ip, amt->local_ip,
amt->gw_port, amt->relay_port,
IPPROTO_UDP, 0,
amt->stream_dev->ifindex);
@@ -762,7 +764,7 @@ static void amt_send_request(struct amt_dev *amt, bool v6)
udph->check = 0;
offset = skb_transport_offset(skb);
skb->csum = skb_checksum(skb, offset, skb->len - offset, 0);
- udph->check = csum_tcpudp_magic(amt->local_ip, amt->remote_ip,
+ udph->check = csum_tcpudp_magic(amt->local_ip, remote_ip,
sizeof(*udph) + sizeof(*amtrh),
IPPROTO_UDP, skb->csum);
@@ -773,7 +775,7 @@ static void amt_send_request(struct amt_dev *amt, bool v6)
iph->tos = AMT_TOS;
iph->frag_off = 0;
iph->ttl = ip4_dst_hoplimit(&rt->dst);
- iph->daddr = amt->remote_ip;
+ iph->daddr = remote_ip;
iph->saddr = amt->local_ip;
iph->protocol = IPPROTO_UDP;
iph->tot_len = htons(len);
@@ -962,7 +964,7 @@ static void amt_event_send_request(struct amt_dev *amt)
amt->qi = AMT_INIT_REQ_TIMEOUT;
WRITE_ONCE(amt->ready4, false);
WRITE_ONCE(amt->ready6, false);
- amt->remote_ip = 0;
+ WRITE_ONCE(amt->remote_ip, 0);
amt_update_gw_status(amt, AMT_STATUS_INIT, false);
amt->req_cnt = 0;
amt->nonce = 0;
@@ -999,6 +1001,7 @@ static bool amt_send_membership_update(struct amt_dev *amt,
struct sk_buff *skb,
bool v6)
{
+ __be32 remote_ip = READ_ONCE(amt->remote_ip);
struct amt_header_membership_update *amtmu;
struct iphdr *iph;
struct flowi4 fl4;
@@ -1018,13 +1021,13 @@ static bool amt_send_membership_update(struct amt_dev *amt,
skb_reset_inner_headers(skb);
memset(&fl4, 0, sizeof(struct flowi4));
fl4.flowi4_oif = amt->stream_dev->ifindex;
- fl4.daddr = amt->remote_ip;
+ fl4.daddr = remote_ip;
fl4.saddr = amt->local_ip;
fl4.flowi4_dscp = inet_dsfield_to_dscp(AMT_TOS);
fl4.flowi4_proto = IPPROTO_UDP;
rt = ip_route_output_key(amt->net, &fl4);
if (IS_ERR(rt)) {
- netdev_dbg(amt->dev, "no route to %pI4\n", &amt->remote_ip);
+ netdev_dbg(amt->dev, "no route to %pI4\n", &remote_ip);
return true;
}
@@ -2272,8 +2275,8 @@ static bool amt_advertisement_handler(struct amt_dev *amt, struct sk_buff *skb)
amt->nonce != amta->nonce)
return true;
- amt->remote_ip = amta->ip4;
- netdev_dbg(amt->dev, "advertised remote ip = %pI4\n", &amt->remote_ip);
+ WRITE_ONCE(amt->remote_ip, amta->ip4);
+ netdev_dbg(amt->dev, "advertised remote ip = %pI4\n", &amta->ip4);
mod_delayed_work(amt_wq, &amt->req_wq, 0);
amt_update_gw_status(amt, AMT_STATUS_RECEIVED_ADVERTISEMENT, true);
@@ -2773,6 +2776,7 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
{
struct amt_dev *amt;
struct iphdr *iph;
+ __be32 remote_ip;
int type;
bool err;
@@ -2783,6 +2787,7 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
kfree_skb(skb);
goto out;
}
+ remote_ip = READ_ONCE(amt->remote_ip);
skb->dev = amt->dev;
iph = ip_hdr(skb);
@@ -2807,7 +2812,7 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
}
goto out;
case AMT_MSG_MULTICAST_DATA:
- if (iph->saddr != amt->remote_ip) {
+ if (iph->saddr != remote_ip) {
netdev_dbg(amt->dev, "Invalid Relay IP\n");
err = true;
goto drop;
@@ -2818,7 +2823,7 @@ static int amt_rcv(struct sock *sk, struct sk_buff *skb)
else
goto out;
case AMT_MSG_MEMBERSHIP_QUERY:
- if (iph->saddr != amt->remote_ip) {
+ if (iph->saddr != remote_ip) {
netdev_dbg(amt->dev, "Invalid Relay IP\n");
err = true;
goto drop;
@@ -3000,7 +3005,7 @@ static int amt_dev_open(struct net_device *dev)
return err;
amt->req_cnt = 0;
- amt->remote_ip = 0;
+ WRITE_ONCE(amt->remote_ip, 0);
amt->nonce = 0;
get_random_bytes(&amt->key, sizeof(siphash_key_t));
@@ -3045,7 +3050,7 @@ static int amt_dev_stop(struct net_device *dev)
amt->ready4 = false;
amt->ready6 = false;
amt->req_cnt = 0;
- amt->remote_ip = 0;
+ WRITE_ONCE(amt->remote_ip, 0);
list_for_each_entry_safe(tunnel, tmp, &amt->tunnel_list, list) {
list_del_rcu(&tunnel->list);
@@ -3244,7 +3249,7 @@ static int amt_newlink(struct net_device *dev,
"gateway port must not be 0");
goto err;
}
- amt->remote_ip = 0;
+ WRITE_ONCE(amt->remote_ip, 0);
amt->discovery_ip = nla_get_in_addr(data[IFLA_AMT_DISCOVERY_IP]);
if (ipv4_is_loopback(amt->discovery_ip) ||
ipv4_is_zeronet(amt->discovery_ip) ||
@@ -3308,8 +3313,10 @@ static size_t amt_get_size(const struct net_device *dev)
static int amt_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
- struct amt_dev *amt = netdev_priv(dev);
+ const struct amt_dev *amt = netdev_priv(dev);
+ __be32 remote_ip;
+ rcu_read_lock();
if (nla_put_u32(skb, IFLA_AMT_MODE, amt->mode))
goto nla_put_failure;
if (nla_put_be16(skb, IFLA_AMT_RELAY_PORT, amt->relay_port))
@@ -3322,15 +3329,19 @@ static int amt_fill_info(struct sk_buff *skb, const struct net_device *dev)
goto nla_put_failure;
if (nla_put_in_addr(skb, IFLA_AMT_DISCOVERY_IP, amt->discovery_ip))
goto nla_put_failure;
- if (amt->remote_ip)
- if (nla_put_in_addr(skb, IFLA_AMT_REMOTE_IP, amt->remote_ip))
+
+ remote_ip = READ_ONCE(amt->remote_ip);
+ if (remote_ip)
+ if (nla_put_in_addr(skb, IFLA_AMT_REMOTE_IP, remote_ip))
goto nla_put_failure;
if (nla_put_u32(skb, IFLA_AMT_MAX_TUNNELS, amt->max_tunnels))
goto nla_put_failure;
+ rcu_read_unlock();
return 0;
nla_put_failure:
+ rcu_read_unlock();
return -EMSGSIZE;
}
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* [PATCH net-next] tun: no longer rely on RTNL in tun_fill_info()
From: Eric Dumazet @ 2026-07-01 12:51 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Kuniyuki Iwashima, Andrew Lunn, netdev,
eric.dumazet, Eric Dumazet
Update tun_fill_info() to read device configuration fields (flags, owner,
group, numqueues, numdisabled) locklessly using READ_ONCE().
Annotate all writes to these fields in the control paths with WRITE_ONCE()
to prevent data races, as these fields can be modified concurrently via
ioctls (TUNSETPERSIST, TUNSETOWNER, TUNSETGROUP, TUNSETIFF) or queue
attaching/detaching.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
drivers/net/tun.c | 64 +++++++++++++++++++++++++----------------------
1 file changed, 34 insertions(+), 30 deletions(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index ffbe6f13fb1fa2333227a6b085806c82a362c0a4..fc8ad6a35708825006f7d199a8f220f30e43df9e 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -532,7 +532,7 @@ static void tun_disable_queue(struct tun_struct *tun, struct tun_file *tfile)
{
tfile->detached = tun;
list_add_tail(&tfile->next, &tun->disabled);
- ++tun->numdisabled;
+ WRITE_ONCE(tun->numdisabled, tun->numdisabled + 1);
}
static struct tun_struct *tun_enable_queue(struct tun_file *tfile)
@@ -541,7 +541,7 @@ static struct tun_struct *tun_enable_queue(struct tun_file *tfile)
tfile->detached = NULL;
list_del_init(&tfile->next);
- --tun->numdisabled;
+ WRITE_ONCE(tun->numdisabled, tun->numdisabled - 1);
return tun;
}
@@ -600,7 +600,7 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
rcu_assign_pointer(tun->tfiles[tun->numqueues - 1],
NULL);
- --tun->numqueues;
+ WRITE_ONCE(tun->numqueues, tun->numqueues - 1);
if (clean) {
RCU_INIT_POINTER(tfile->tun, NULL);
sock_put(&tfile->sk);
@@ -663,7 +663,7 @@ static void tun_detach_all(struct net_device *dev)
tfile->socket.sk->sk_shutdown = RCV_SHUTDOWN;
tfile->socket.sk->sk_data_ready(tfile->socket.sk);
RCU_INIT_POINTER(tfile->tun, NULL);
- --tun->numqueues;
+ WRITE_ONCE(tun->numqueues, tun->numqueues - 1);
}
list_for_each_entry(tfile, &tun->disabled, next) {
tfile->socket.sk->sk_shutdown = RCV_SHUTDOWN;
@@ -786,7 +786,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file,
if (publish_tun)
rcu_assign_pointer(tfile->tun, tun);
rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile);
- tun->numqueues++;
+ WRITE_ONCE(tun->numqueues, tun->numqueues + 1);
tun_set_real_num_queues(tun);
out:
return err;
@@ -943,8 +943,8 @@ static int tun_net_init(struct net_device *dev)
NETIF_F_HW_VLAN_STAG_TX);
dev->lltx = true;
- tun->flags = (tun->flags & ~TUN_FEATURES) |
- (ifr->ifr_flags & TUN_FEATURES);
+ WRITE_ONCE(tun->flags, (tun->flags & ~TUN_FEATURES) |
+ (ifr->ifr_flags & TUN_FEATURES));
INIT_LIST_HEAD(&tun->disabled);
err = tun_attach(tun, tun->file, false, ifr->ifr_flags & IFF_NAPI,
@@ -2370,32 +2370,36 @@ static size_t tun_get_size(const struct net_device *dev)
static int tun_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
- struct tun_struct *tun = netdev_priv(dev);
+ const struct tun_struct *tun = netdev_priv(dev);
+ unsigned int flags = READ_ONCE(tun->flags);
+ kuid_t owner = READ_ONCE(tun->owner);
+ kgid_t group = READ_ONCE(tun->group);
- if (nla_put_u8(skb, IFLA_TUN_TYPE, tun->flags & TUN_TYPE_MASK))
+ if (nla_put_u8(skb, IFLA_TUN_TYPE, flags & TUN_TYPE_MASK))
goto nla_put_failure;
- if (uid_valid(tun->owner) &&
+ if (uid_valid(owner) &&
nla_put_u32(skb, IFLA_TUN_OWNER,
- from_kuid_munged(current_user_ns(), tun->owner)))
+ from_kuid_munged(current_user_ns(), owner)))
goto nla_put_failure;
- if (gid_valid(tun->group) &&
+ if (gid_valid(group) &&
nla_put_u32(skb, IFLA_TUN_GROUP,
- from_kgid_munged(current_user_ns(), tun->group)))
+ from_kgid_munged(current_user_ns(), group)))
goto nla_put_failure;
- if (nla_put_u8(skb, IFLA_TUN_PI, !(tun->flags & IFF_NO_PI)))
+ if (nla_put_u8(skb, IFLA_TUN_PI, !(flags & IFF_NO_PI)))
goto nla_put_failure;
- if (nla_put_u8(skb, IFLA_TUN_VNET_HDR, !!(tun->flags & IFF_VNET_HDR)))
+ if (nla_put_u8(skb, IFLA_TUN_VNET_HDR, !!(flags & IFF_VNET_HDR)))
goto nla_put_failure;
- if (nla_put_u8(skb, IFLA_TUN_PERSIST, !!(tun->flags & IFF_PERSIST)))
+ if (nla_put_u8(skb, IFLA_TUN_PERSIST, !!(flags & IFF_PERSIST)))
goto nla_put_failure;
if (nla_put_u8(skb, IFLA_TUN_MULTI_QUEUE,
- !!(tun->flags & IFF_MULTI_QUEUE)))
+ !!(flags & IFF_MULTI_QUEUE)))
goto nla_put_failure;
- if (tun->flags & IFF_MULTI_QUEUE) {
- if (nla_put_u32(skb, IFLA_TUN_NUM_QUEUES, tun->numqueues))
+ if (flags & IFF_MULTI_QUEUE) {
+ if (nla_put_u32(skb, IFLA_TUN_NUM_QUEUES,
+ READ_ONCE(tun->numqueues)))
goto nla_put_failure;
if (nla_put_u32(skb, IFLA_TUN_NUM_DISABLED_QUEUES,
- tun->numdisabled))
+ READ_ONCE(tun->numdisabled)))
goto nla_put_failure;
}
@@ -2814,8 +2818,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
return 0;
}
- tun->flags = (tun->flags & ~TUN_FEATURES) |
- (ifr->ifr_flags & TUN_FEATURES);
+ WRITE_ONCE(tun->flags, (READ_ONCE(tun->flags) & ~TUN_FEATURES) |
+ (ifr->ifr_flags & TUN_FEATURES));
netdev_state_change(dev);
} else {
@@ -3213,13 +3217,13 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
/* Disable/Enable persist mode. Keep an extra reference to the
* module to prevent the module being unprobed.
*/
- if (arg && !(tun->flags & IFF_PERSIST)) {
- tun->flags |= IFF_PERSIST;
+ if (arg && !(READ_ONCE(tun->flags) & IFF_PERSIST)) {
+ WRITE_ONCE(tun->flags, READ_ONCE(tun->flags) | IFF_PERSIST);
__module_get(THIS_MODULE);
do_notify = true;
}
- if (!arg && (tun->flags & IFF_PERSIST)) {
- tun->flags &= ~IFF_PERSIST;
+ if (!arg && (READ_ONCE(tun->flags) & IFF_PERSIST)) {
+ WRITE_ONCE(tun->flags, READ_ONCE(tun->flags) & ~IFF_PERSIST);
module_put(THIS_MODULE);
do_notify = true;
}
@@ -3235,10 +3239,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
ret = -EINVAL;
break;
}
- tun->owner = owner;
+ WRITE_ONCE(tun->owner, owner);
do_notify = true;
netif_info(tun, drv, tun->dev, "owner set to %u\n",
- from_kuid(&init_user_ns, tun->owner));
+ from_kuid(&init_user_ns, owner));
break;
case TUNSETGROUP:
@@ -3248,10 +3252,10 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd,
ret = -EINVAL;
break;
}
- tun->group = group;
+ WRITE_ONCE(tun->group, group);
do_notify = true;
netif_info(tun, drv, tun->dev, "group set to %u\n",
- from_kgid(&init_user_ns, tun->group));
+ from_kgid(&init_user_ns, group));
break;
case TUNSETLINK:
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related
* Re: [PATCH net-next v7 4/4] net: phy: realtek: load firmware for RTL8261C_CG
From: Andrew Lunn @ 2026-07-01 12:52 UTC (permalink / raw)
To: Javen
Cc: hkallweit1@gmail.com, linux@armlinux.org.uk, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
顾晓军, nb@tipi-net.de, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, daniel@makrotopia.org,
vladimir.oltean@nxp.com, nic_swsd@realtek.com
In-Reply-To: <00ed7993f38d4597a8c20f71bc7da58e@realsil.com.cn>
On Wed, Jul 01, 2026 at 03:12:34AM +0000, Javen wrote:
> >
> >On Mon, Jun 29, 2026 at 02:47:18PM +0800, javen wrote:
> >> From: Javen Xu <javen_xu@realsil.com.cn>
> >>
> >> This patch adds support for loading firmware. Download some parameters
> >> for RTL8261C_CG.
> >>
> >> Signed-off-by: Javen Xu <javen_xu@realsil.com.cn>
> >> ---
> >> Changes in v2:
> >> - remove __pack, struct rtl8261x_fw_header and rtl8261x_fw_entry will
> >> not pad
> >> - reverse xmas tree for some definition
> >> - add explanation on rtl_phy_write_mmd_bits()
> >>
> >> Changes in v3:
> >> - add struct rtl8261x_priv
> >>
> >> Changes in v4:
> >> - add struct device *dev
> >>
> >> Changes in v5:
> >> - no changes
> >>
> >> Changes in v6:
> >> - replace rtl_phy_write_mmd_bits with phy_modify_mmd, keep mdio lock
> >> - check msb and lsb at the beginning of rtl8261x_fw_execute_entry()
> >> - add comments on rtl8261x_config_init()
> >>
> >> Changes in v7:
> >> - no changes
> >> ---
> >> drivers/net/phy/realtek/realtek_main.c | 220
> >> +++++++++++++++++++++++++
> >> 1 file changed, 220 insertions(+)
> >>
> >> diff --git a/drivers/net/phy/realtek/realtek_main.c
> >> b/drivers/net/phy/realtek/realtek_main.c
> >> index ef3700894ebf..bf7bc19fb44c 100644
> >> --- a/drivers/net/phy/realtek/realtek_main.c
> >> +++ b/drivers/net/phy/realtek/realtek_main.c
> >> @@ -8,7 +8,9 @@
> >> * Copyright (c) 2004 Freescale Semiconductor, Inc.
> >> */
> >> #include <linux/bitops.h>
> >> +#include <linux/crc32.h>
> >> #include <linux/ethtool_netlink.h>
> >> +#include <linux/firmware.h>
> >> #include <linux/of.h>
> >> #include <linux/phy.h>
> >> #include <linux/pm_wakeirq.h>
> >> @@ -281,6 +283,42 @@
> >> RTL8261X_INT_ALDPS_CHG | \
> >> RTL8261X_INT_JABBER)
> >>
> >> +#define FW_MAIN_MAGIC 0x52544C38
> >> +#define FW_SUB_MAGIC_8261C 0x32363143
> >> +#define RTL8261X_POLL_TIMEOUT_MS 100
> >> +
> >> +#define RTL8261C_CE_FW_NAME "rtl_nic/rtl8261c.bin"
> >> +MODULE_FIRMWARE(RTL8261C_CE_FW_NAME);
> >> +
> >> +enum rtl8261x_fw_op {
> >> + OP_WRITE = 0x00, /* Write */
> >> + OP_POLL = 0x02, /* Polling */
> >> +};
> >> +
> >> +struct rtl8261x_fw_header {
> >> + __le32 main_magic; /* Main magic number 0x52544C38 ("RTL8") */
> >> + __le32 sub_magic; /* Sub magic number */
> >> + __le16 version_major; /* Major version */
> >> + __le16 version_minor; /* Minor version */
> >> + __le16 num_entries; /* Number of entries */
> >> + __le16 reserved; /* Reserved */
> >> + __le32 crc32; /* CRC32 checksum */
> >> +};
> >> +
> >> +struct rtl8261x_fw_entry {
> >> + __u8 type; /* Operation type (OP_*) */
> >> + __u8 dev; /* MMD device */
> >> + __le16 addr; /* Register address */
> >> + __u8 msb; /* MSB bit position */
> >> + __u8 lsb; /* LSB bit position */
> >> + __le16 value; /* Value to write/compare */
> >> + __le16 timeout_ms; /* Poll timeout in milliseconds */
> >> + __u8 poll_set; /* Poll for set (1) or clear (0) */
> >> + __u8 reserved; /* Reserved */
> >> +};
> >
> >Are there other devices which need firmware download? Do they use the
> >same header? I'm just wondering if this will be reused by other devices?
> >
> Hi Andrew,
>
> Currently, RTL8261C is the only device which needs this firmware download flow.
>
> Future Realtek PHY ICs which require firmware download are expected to use the same firmware format, so
> the current header/entry definition is intended to be reusable.
If this is going to be re-used, then O.K. I was asking because it is
more complex than it needs to be for just one PHY.
Andrew
^ permalink raw reply
* [PATCH net-next] net: rmnet: annotate endpoint lookup under RTNL
From: Runyu Xiao @ 2026-07-01 12:40 UTC (permalink / raw)
To: subash.a.kasiviswanathan, sean.tranchetti
Cc: andrew+netdev, davem, edumazet, kuba, pabeni, netdev,
linux-kernel, runyu.xiao, jianhao.xu
rmnet_get_endpoint() is shared by packet receive paths and
RTNL-protected control paths. The receive paths already run under RCU/BH
context through the RX handler, while the control paths reach
rmnet_get_endpoint() after obtaining the rmnet port with
rmnet_get_port_rtnl().
The helper walks port->muxed_ep[] with hlist_for_each_entry_rcu(). Pass
lockdep_rtnl_is_held() as the non-RCU protection condition so
CONFIG_PROVE_RCU_LIST can see the RTNL-protected control-path calls
while preserving the existing RCU-reader behavior for data paths.
This was found by our static analysis tool and then manually reviewed
against the current tree. The dynamic triage evidence is a
target-matched CONFIG_PROVE_RCU_LIST warning; the change is limited
to documenting the existing protection contract.
This is a lockdep annotation cleanup. It does not change endpoint
lifetime or hash updates.
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
---
drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
index ba8763cac9d9..977fb80d8bf8 100644
--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
@@ -423,7 +423,8 @@ struct rmnet_endpoint *rmnet_get_endpoint(struct rmnet_port *port, u8 mux_id)
{
struct rmnet_endpoint *ep;
- hlist_for_each_entry_rcu(ep, &port->muxed_ep[mux_id], hlnode) {
+ hlist_for_each_entry_rcu(ep, &port->muxed_ep[mux_id], hlnode,
+ lockdep_rtnl_is_held()) {
if (ep->mux_id == mux_id)
return ep;
}
--
2.34.1
^ permalink raw reply related
* Re: [PATCH net-next V4 3/6] devlink: Parse eswitch mode boot defaults
From: Mark Bloch @ 2026-07-01 12:55 UTC (permalink / raw)
To: Jiri Pirko
Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Andrew Lunn,
Jonathan Corbet, Shuah Khan, netdev, linux-rdma, linux-doc
In-Reply-To: <akTencQhKSanuFeW@FV6GYCPJ69>
On 01/07/2026 12:38, Jiri Pirko wrote:
> Mon, Jun 29, 2026 at 08:20:58PM +0200, mbloch@nvidia.com wrote:
>> Add devlink_eswitch_mode= kernel command line parsing for a default
>> eswitch mode.
>>
>> The supported syntax selects either all devlink handles or one explicit
>> comma-separated handle list:
>>
>> devlink_eswitch_mode=*=<mode>
>>
>> devlink_eswitch_mode=<handle>[,<handle>...]=<mode>
>>
>> where <mode> is one of legacy, switchdev or switchdev_inactive. All
>> selected handles receive the same mode. Assigning different modes to
>> different handle lists in the same parameter value is not supported.
>>
>> Store the parsed selector and mode in devlink core so the default can be
>> applied by a downstream patch.
>>
>> Document the devlink_eswitch_mode= syntax and duplicate handle handling.
>>
>> Signed-off-by: Mark Bloch <mbloch@nvidia.com>
>> ---
>> .../admin-guide/kernel-parameters.txt | 25 ++
>> .../networking/devlink/devlink-defaults.rst | 78 ++++++
>> Documentation/networking/devlink/index.rst | 1 +
>> net/devlink/core.c | 227 ++++++++++++++++++
>> 4 files changed, 331 insertions(+)
>> create mode 100644 Documentation/networking/devlink/devlink-defaults.rst
>>
>> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
>> index b5493a7f8f22..117300dd589c 100644
>> --- a/Documentation/admin-guide/kernel-parameters.txt
>> +++ b/Documentation/admin-guide/kernel-parameters.txt
>> @@ -1249,6 +1249,31 @@ Kernel parameters
>> dell_smm_hwmon.fan_max=
>> [HW] Maximum configurable fan speed.
>>
>> + devlink_eswitch_mode=
>> + [NET]
>> + Format:
>> + <selector>=<mode>
>> +
>> + <selector>:
>> + * | <handle>[,<handle>...]
>> +
>> + <handle>:
>> + <bus-name>/<dev-name>
>> +
>> + Configure default devlink eswitch mode for matching
>> + devlink instances during device initialization.
>> +
>> + <mode>:
>> + legacy | switchdev | switchdev_inactive
>> +
>> + Examples:
>> + devlink_eswitch_mode=*=switchdev
>> + devlink_eswitch_mode=pci/0000:08:00.0=switchdev
>> + devlink_eswitch_mode=pci/0000:08:00.0,pci/0000:09:00.1=switchdev_inactive
>> +
>> + See Documentation/networking/devlink/devlink-defaults.rst
>> + for the full syntax.
>> +
>> dfltcc= [HW,S390]
>> Format: { on | off | def_only | inf_only | always }
>> on: s390 zlib hardware support for compression on
>> diff --git a/Documentation/networking/devlink/devlink-defaults.rst b/Documentation/networking/devlink/devlink-defaults.rst
>> new file mode 100644
>> index 000000000000..380c9e99210e
>> --- /dev/null
>> +++ b/Documentation/networking/devlink/devlink-defaults.rst
>> @@ -0,0 +1,78 @@
>> +.. SPDX-License-Identifier: GPL-2.0
>> +
>> +==============================
>> +Devlink Eswitch Mode Defaults
>> +==============================
>> +
>> +Devlink eswitch mode defaults allow the eswitch mode to be provided on the
>> +kernel command line and applied to matching devlink instances during device
>> +initialization.
>> +
>> +The devlink device is selected by its devlink handle. For PCI devices this is
>> +the same handle shown by ``devlink dev show``, for example
>> +``pci/0000:08:00.0``.
>> +
>> +Kernel command line syntax
>> +==========================
>> +
>> +Defaults are specified with the ``devlink_eswitch_mode=`` kernel command line
>> +parameter.
>> +
>> +The general syntax is::
>> +
>> + devlink_eswitch_mode=<selector>=<mode>
>> +
>> +``<selector>`` is either ``*`` or one or more devlink handles::
>> +
>> + * | <bus-name>/<dev-name>[,<bus-name>/<dev-name>...]
>> +
>> +``*`` applies the mode to every devlink instance. All handles in the same
>> +selector receive the same eswitch mode.
>> +
>> +``<mode>`` is one of ``legacy``, ``switchdev`` or ``switchdev_inactive``.
>> +
>> +Syntax rules
>> +------------
>> +
>> +The following syntax rules apply:
>> +
>> +* Specify the default in one ``devlink_eswitch_mode=`` parameter. Repeated
>> + ``devlink_eswitch_mode=`` parameters are not accumulated.
>> +* The ``devlink_eswitch_mode=`` value is limited by the kernel command line
>> + size.
>> +* Whitespace is not allowed within the parameter value.
>> +* ``<selector>`` must be either ``*`` or a handle list. ``*`` cannot be
>> + combined with explicit handles.
>> +* ``<bus-name>`` and ``<dev-name>`` must not be empty.
>> +* ``<dev-name>`` may contain ``:``. This allows PCI names such as
>> + ``0000:08:00.0``.
>> +* Handles must not contain whitespace, ``*``, ``=`` or more than one ``/``.
>> +* A comma separates handles.
>> +* Comma-separated default assignments are not supported.
>> +* Duplicate handles are rejected and the devlink eswitch mode default is
>> + ignored.
>> +
>> +The eswitch mode default corresponds to the userspace command::
>> +
>> + devlink dev eswitch set <handle> mode <value>
>> +
>> +
>> +Examples
>> +========
>> +
>> +Set all devlink instances to switchdev mode::
>> +
>> + devlink_eswitch_mode=*=switchdev
>> +
>> +Set one PCI devlink instance to switchdev mode::
>> +
>> + devlink_eswitch_mode=pci/0000:08:00.0=switchdev
>> +
>> +Set two PCI devlink instances to switchdev inactive mode::
>> +
>> + devlink_eswitch_mode=pci/0000:08:00.0,pci/0000:09:00.1=switchdev_inactive
>> +
>> +The following is invalid because comma-separated default assignments are not
>> +supported::
>> +
>> + devlink_eswitch_mode=pci/0000:08:00.0=switchdev,pci/0000:09:00.0=switchdev_inactive
>
> Interesting. I would think that this is something user may want to set
> for some usecases, no?
>
>
>> diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst
>> index 32f70879ddd0..93f09cb18c44 100644
>> --- a/Documentation/networking/devlink/index.rst
>> +++ b/Documentation/networking/devlink/index.rst
>> @@ -56,6 +56,7 @@ general.
>> :maxdepth: 1
>>
>> devlink-dpipe
>> + devlink-defaults
>> devlink-eswitch-attr
>> devlink-flash
>> devlink-health
>> diff --git a/net/devlink/core.c b/net/devlink/core.c
>
> Wanna have this in a separate file perhaps? "default.c"?
>
>
>> index fe9f6a0a67d5..5126509a9c4e 100644
>> --- a/net/devlink/core.c
>> +++ b/net/devlink/core.c
>> @@ -4,6 +4,10 @@
>> * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
>> */
>>
>> +#include <linux/init.h>
>> +#include <linux/list.h>
>> +#include <linux/slab.h>
>> +#include <linux/string.h>
>> #include <net/genetlink.h>
>> #define CREATE_TRACE_POINTS
>> #include <trace/events/devlink.h>
>> @@ -16,6 +20,193 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report);
>>
>> DEFINE_XARRAY_FLAGS(devlinks, XA_FLAGS_ALLOC);
>>
>> +static char *devlink_default_esw_mode_param;
>> +static bool devlink_default_esw_mode_match_all;
>> +static enum devlink_eswitch_mode devlink_default_esw_mode;
>> +static LIST_HEAD(devlink_default_esw_mode_nodes);
>> +
>> +struct devlink_default_esw_mode_node {
>> + struct list_head list;
>> + char *bus_name;
>> + char *dev_name;
>> +};
>> +
>> +static int __init
>> +devlink_default_esw_mode_to_value(const char *str,
>> + enum devlink_eswitch_mode *mode)
>> +{
>> + if (!strcmp(str, "legacy")) {
>> + *mode = DEVLINK_ESWITCH_MODE_LEGACY;
>> + return 0;
>> + }
>> + if (!strcmp(str, "switchdev")) {
>> + *mode = DEVLINK_ESWITCH_MODE_SWITCHDEV;
>> + return 0;
>> + }
>> + if (!strcmp(str, "switchdev_inactive")) {
>> + *mode = DEVLINK_ESWITCH_MODE_SWITCHDEV_INACTIVE;
>> + return 0;
>> + }
>> +
>> + return -EINVAL;
>> +}
>> +
>> +static int __init
>> +devlink_default_esw_mode_handle_parse(char *handle, char **bus_name,
>> + char **dev_name)
>> +{
>> + char *slash;
>> + char *p;
>> +
>> + if (!*handle)
>> + return -EINVAL;
>> +
>> + for (p = handle; *p; p++) {
>> + if (*p == '*' || *p == '=')
>> + return -EINVAL;
>> + }
>> +
>> + slash = strchr(handle, '/');
>> + if (!slash || slash == handle || !slash[1])
>> + return -EINVAL;
>> + if (strchr(slash + 1, '/'))
>> + return -EINVAL;
>> +
>> + *slash = '\0';
>> +
>> + *bus_name = handle;
>> + *dev_name = slash + 1;
>> + return 0;
>> +}
>> +
>> +static struct devlink_default_esw_mode_node *
>> +devlink_default_esw_mode_node_find(const char *bus_name, const char *dev_name)
>> +{
>> + struct devlink_default_esw_mode_node *node;
>> +
>> + list_for_each_entry(node, &devlink_default_esw_mode_nodes, list) {
>> + if (!strcmp(node->bus_name, bus_name) &&
>> + !strcmp(node->dev_name, dev_name))
>> + return node;
>> + }
>> +
>> + return NULL;
>> +}
>> +
>> +static int __init
>> +devlink_default_esw_mode_node_add(const char *bus_name, const char *dev_name)
>> +{
>> + struct devlink_default_esw_mode_node *node;
>> +
>> + if (devlink_default_esw_mode_node_find(bus_name, dev_name))
>> + return -EEXIST;
>> +
>> + node = kzalloc_obj(*node);
>> + if (!node)
>> + return -ENOMEM;
>> +
>> + INIT_LIST_HEAD(&node->list);
>> + node->bus_name = kstrdup(bus_name, GFP_KERNEL);
>> + node->dev_name = kstrdup(dev_name, GFP_KERNEL);
>> + if (!node->bus_name || !node->dev_name) {
>> + kfree(node->bus_name);
>> + kfree(node->dev_name);
>> + kfree(node);
>> + return -ENOMEM;
>> + }
>> +
>> + list_add_tail(&node->list, &devlink_default_esw_mode_nodes);
>> + return 0;
>> +}
>> +
>> +static int __init devlink_default_esw_mode_handles_parse(char *handles)
>> +{
>> + char *handle;
>> + int err;
>> +
>> + if (!strcmp(handles, "*")) {
>> + devlink_default_esw_mode_match_all = true;
>> + return 0;
>> + }
>> +
>> + while ((handle = strsep(&handles, ",")) != NULL) {
>> + char *bus_name;
>> + char *dev_name;
>> +
>> + err = devlink_default_esw_mode_handle_parse(handle, &bus_name,
>> + &dev_name);
>> + if (err)
>> + return err;
>> +
>> + err = devlink_default_esw_mode_node_add(bus_name, dev_name);
>> + if (err)
>> + return err;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static void __init
>> +devlink_default_esw_mode_node_free(struct devlink_default_esw_mode_node *node)
>> +{
>> + kfree(node->bus_name);
>> + kfree(node->dev_name);
>> + kfree(node);
>> +}
>> +
>> +static void __init devlink_default_esw_mode_nodes_clear(void)
>> +{
>> + struct devlink_default_esw_mode_node *node;
>> + struct devlink_default_esw_mode_node *node_tmp;
>> +
>> + list_for_each_entry_safe(node, node_tmp,
>> + &devlink_default_esw_mode_nodes, list) {
>> + list_del(&node->list);
>> + devlink_default_esw_mode_node_free(node);
>> + }
>> +
>> + devlink_default_esw_mode_match_all = false;
>> +}
>> +
>> +static int __init devlink_default_esw_mode_parse(char *str)
>> +{
>> + char *handles;
>> + char *separator;
>> + char *mode;
>> + enum devlink_eswitch_mode esw_mode;
>> + int err;
>> +
>> + if (!*str)
>> + return -EINVAL;
>> +
>> + separator = strrchr(str, '=');
>> + if (!separator || separator == str || !separator[1])
>> + return -EINVAL;
>> +
>> + *separator = '\0';
>> + handles = str;
>> + mode = separator + 1;
>> +
>> + err = devlink_default_esw_mode_to_value(mode, &esw_mode);
>> + if (err)
>> + return err;
>> +
>> + err = devlink_default_esw_mode_handles_parse(handles);
>> + if (err)
>> + devlink_default_esw_mode_nodes_clear();
>> + else
>> + devlink_default_esw_mode = esw_mode;
>> +
>> + return err;
>> +}
>> +
>> +static int __init devlink_default_esw_mode_setup(char *str)
>> +{
>> + devlink_default_esw_mode_param = str;
>> + return 1;
>> +}
>> +__setup("devlink_eswitch_mode=", devlink_default_esw_mode_setup);
>> +
>> static struct devlink *devlinks_xa_get(unsigned long index)
>> {
>> struct devlink *devlink;
>> @@ -382,6 +573,14 @@ struct devlink *devlinks_xa_lookup_get(struct net *net, unsigned long index)
>> /**
>> * devl_register - Register devlink instance
>> * @devlink: devlink
>> + *
>> + * Make @devlink visible to userspace. Drivers must call this only after the
>> + * instance is fully initialized and its devlink operations can be called.
>> + *
>> + * Context: Caller must hold the devlink instance lock. Use devlink_register()
>> + * when the lock is not already held.
>> + *
>> + * Return: 0 on success.
>> */
>> int devl_register(struct devlink *devlink)
>> {
>> @@ -580,6 +779,31 @@ static int __init devlink_init(void)
>> {
>> int err;
>>
>> + if (devlink_default_esw_mode_param) {
>> + char *def;
>> +
>> + def = kstrdup(devlink_default_esw_mode_param, GFP_KERNEL);
>> + if (!def) {
>> + devlink_default_esw_mode_param = NULL;
>> + pr_warn("devlink: devlink_eswitch_mode parameter ignored, failed to allocate memory\n");
>> + } else {
>> + err = devlink_default_esw_mode_parse(def);
>> + kfree(def);
>> + if (err == -EEXIST) {
>> + devlink_default_esw_mode_param = NULL;
>> + pr_warn("devlink: duplicate eswitch mode handles ignored\n");
>> + } else if (err == -EINVAL) {
>> + devlink_default_esw_mode_param = NULL;
>> + pr_warn("devlink: invalid devlink_eswitch_mode parameter ignored\n");
>> + } else if (err == -ENOMEM) {
>> + devlink_default_esw_mode_param = NULL;
>> + pr_warn("devlink: devlink_eswitch_mode parameter ignored, failed to allocate memory\n");
>> + } else if (err) {
>> + goto out;
>> + }
>
> Move this to a separate helper alongside the other "default" functions?
I did that in the following patch. If I respin I'll do it in this one.
Mark
>
>
>> + }
>> + }
>> +
>> err = register_pernet_subsys(&devlink_pernet_ops);
>> if (err)
>> goto out;
>> @@ -595,7 +819,10 @@ static int __init devlink_init(void)
>> out_unreg_pernet_subsys:
>> unregister_pernet_subsys(&devlink_pernet_ops);
>> out:
>> + if (err)
>> + devlink_default_esw_mode_nodes_clear();
>> WARN_ON(err);
>> +
>> return err;
>> }
>>
>> --
>> 2.43.0
>>
^ permalink raw reply
* Re: [PATCH net-next V4 4/6] devlink: Apply eswitch mode boot defaults
From: Mark Bloch @ 2026-07-01 12:57 UTC (permalink / raw)
To: Jiri Pirko
Cc: Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman,
Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Andrew Lunn,
Jonathan Corbet, Shuah Khan, netdev, linux-rdma, linux-doc
In-Reply-To: <akThPmvUHvCMT2cp@FV6GYCPJ69>
On 01/07/2026 12:48, Jiri Pirko wrote:
> Mon, Jun 29, 2026 at 08:20:59PM +0200, mbloch@nvidia.com wrote:
>> Apply parsed devlink_eswitch_mode= defaults after devlink registration
>> and after successful reload.
>>
>> devl_register() may still be called before the device is ready for an
>
> How so? I would assume that driver calls devl_register only after
> everything is up and running and ready. If not, isn't it a bug?
>
You would think so :)
Some drivers, mlx5 included, call devl_register() while holding the
devlink instance lock and then finish setting up state before releasing
the lock.
In v3 I tried to enforce exactly that model, move devl_register() to
be the last thing the driver does. Jakub pushed back on making that a
general rule. So in v4 I changed the approach. devl_register() only
schedules the work, and the actual eswitch mode change can run only
after the driver releases the devlink lock.
Mark
>
>> eswitch mode change, so keep a per-devlink delayed work item and pending
>> flag for the registration path. Registration queues the work, and the
>> worker tries to take the devlink instance lock.
>>
>> If the lock is busy, the worker requeues itself with a delay.
>>
>> For successful reloads that performed DRIVER_REINIT, devlink_reload()
>> already holds the devlink instance lock and the driver has completed
>> reload_up(). Clear pending work and apply the default directly from the
>> reload path instead of queueing work.
>>
>> If a user sets eswitch mode through netlink before the pending
>> registration work runs, clear the pending flag so the queued default does
>> not override that user request. Cancel pending default apply work when
>> freeing the devlink instance.
>
> These AI generated code descriptive messages are generally not very
> useful :(
>
^ permalink raw reply
* Re: [PATCH net] ipvs: fix PMTU for GUE/GRE tunnel ICMP errors
From: Julian Anastasov @ 2026-07-01 12:58 UTC (permalink / raw)
To: Yizhou Zhao
Cc: netdev, Simon Horman, Pablo Neira Ayuso, Florian Westphal,
Phil Sutter, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, lvs-devel, netfilter-devel, coreteam, linux-kernel,
stable, Yuxiang Yang, Ao Wang, Xuewei Feng, Qi Li, Ke Xu
In-Reply-To: <20260701065941.46249-1-zhaoyz24@mails.tsinghua.edu.cn>
Hello,
On Wed, 1 Jul 2026, Yizhou Zhao wrote:
> When an ICMP Fragmentation Needed error is received for a tunneled IPVS
> connection, ip_vs_in_icmp() recomputes the MTU that the original packet
> can use by subtracting the tunnel overhead from the reported next-hop
> MTU.
>
> The current code always subtracts sizeof(struct iphdr), which is only
> the IPIP overhead. For GUE and GRE tunnels, ipvs_udp_decap() and
> ipvs_gre_decap() already compute the additional tunnel header length,
> but that value is scoped to the decapsulation block and is lost before
> the ICMP_FRAG_NEEDED handling. As a result, the ICMP error sent back to
> the client advertises an MTU that is too large, so PMTUD can fail to
> converge for GUE/GRE-tunneled real servers.
>
> With a reported next-hop MTU of 1400, a GUE tunnel currently returns
> 1380 to the client. The correct value is 1368:
>
> 1400 - sizeof(struct iphdr) - sizeof(struct udphdr) -
> sizeof(struct guehdr)
>
> Hoist the tunnel header length into the main ip_vs_in_icmp() scope and
> subtract sizeof(struct iphdr) + ulen in the Fragmentation Needed path.
> The IPIP path keeps ulen as 0, so its existing 1400 - 20 = 1380 result
> is unchanged.
>
> Fixes: 508f744c0de3 ("ipvs: strip udp tunnel headers from icmp errors")
> Cc: stable@vger.kernel.org
> Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
> Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn>
> Reported-by: Ao Wang <wangao@seu.edu.cn>
> Reported-by: Xuewei Feng <fengxw06@126.com>
> Reported-by: Qi Li <qli01@tsinghua.edu.cn>
> Reported-by: Ke Xu <xuke@tsinghua.edu.cn>
> Assisted-by: Claude Code:GLM-5.2
> Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn>
> ---
> net/netfilter/ipvs/ip_vs_core.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
> index d40b404c1bf62..74c5bd8b5f48 100644
> --- a/net/netfilter/ipvs/ip_vs_core.c
> +++ b/net/netfilter/ipvs/ip_vs_core.c
> @@ -1765,8 +1765,9 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
> struct ip_vs_proto_data *pd;
> unsigned int offset, offset2, ihl, verdict;
> bool tunnel, new_cp = false;
> union nf_inet_addr *raddr;
> char *outer_proto = "IPIP";
> + int ulen = 0;
>
> *related = 1;
>
The change look correct but there is something to fix:
1. first hunk is bad, does not apply to the nf tree (-8+9 vs -6+7
lines):
# patch -p1 --dry-run < /tmp/file.patch
checking file net/netfilter/ipvs/ip_vs_core.c
Hunk #1 succeeded at 1765 with fuzz 2.
2. the first two words in Assisted-by line should not contain
white spaces:
# scripts/checkpatch.pl --strict /tmp/file.patch
WARNING: Assisted-by expects 'AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2]' format
#40: Assisted-by: Claude Code:GLM-5.2
Please send v2 after solving the above problems. Thanks!
> @@ -1831,7 +1832,6 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
> /* Error for our tunnel must arrive at LOCAL_IN */
> (skb_rtable(skb)->rt_flags & RTCF_LOCAL)) {
> __u8 iproto;
> - int ulen;
>
> /* Non-first fragment has no UDP/GRE header */
> if (unlikely(cih->frag_off & htons(IP_OFFSET)))
> @@ -1936,8 +1936,8 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related,
> if (dest_dst)
> mtu = dst_mtu(dest_dst->dst_cache);
> }
> - if (mtu > 68 + sizeof(struct iphdr))
> - mtu -= sizeof(struct iphdr);
> + if (mtu > 68 + sizeof(struct iphdr) + ulen)
> + mtu -= sizeof(struct iphdr) + ulen;
> info = htonl(mtu);
> }
> /* Strip outer IP, ICMP and IPIP/UDP/GRE, go to IP header of
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply
* Re: [PATCH net-next v7 4/4] net: phy: realtek: load firmware for RTL8261C_CG
From: Andrew Lunn @ 2026-07-01 13:00 UTC (permalink / raw)
To: javen
Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, freddy_gu, nb,
netdev, linux-kernel, daniel, vladimir.oltean, nic_swsd
In-Reply-To: <20260629064718.1349-5-javen_xu@realsil.com.cn>
On Mon, Jun 29, 2026 at 02:47:18PM +0800, javen wrote:
> From: Javen Xu <javen_xu@realsil.com.cn>
>
> This patch adds support for loading firmware. Download some parameters
> for RTL8261C_CG.
>
> Signed-off-by: Javen Xu <javen_xu@realsil.com.cn>
> ---
> Changes in v2:
> - remove __pack, struct rtl8261x_fw_header and rtl8261x_fw_entry will not pad
> - reverse xmas tree for some definition
> - add explanation on rtl_phy_write_mmd_bits()
>
> Changes in v3:
> - add struct rtl8261x_priv
>
> Changes in v4:
> - add struct device *dev
>
> Changes in v5:
> - no changes
>
> Changes in v6:
> - replace rtl_phy_write_mmd_bits with phy_modify_mmd, keep mdio lock
> - check msb and lsb at the beginning of rtl8261x_fw_execute_entry()
> - add comments on rtl8261x_config_init()
>
> Changes in v7:
> - no changes
> ---
> drivers/net/phy/realtek/realtek_main.c | 220 +++++++++++++++++++++++++
> 1 file changed, 220 insertions(+)
>
> diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
> index ef3700894ebf..bf7bc19fb44c 100644
> --- a/drivers/net/phy/realtek/realtek_main.c
> +++ b/drivers/net/phy/realtek/realtek_main.c
> @@ -8,7 +8,9 @@
> * Copyright (c) 2004 Freescale Semiconductor, Inc.
> */
> #include <linux/bitops.h>
> +#include <linux/crc32.h>
> #include <linux/ethtool_netlink.h>
> +#include <linux/firmware.h>
> #include <linux/of.h>
> #include <linux/phy.h>
> #include <linux/pm_wakeirq.h>
> @@ -281,6 +283,42 @@
> RTL8261X_INT_ALDPS_CHG | \
> RTL8261X_INT_JABBER)
>
> +#define FW_MAIN_MAGIC 0x52544C38
> +#define FW_SUB_MAGIC_8261C 0x32363143
> +#define RTL8261X_POLL_TIMEOUT_MS 100
> +
> +#define RTL8261C_CE_FW_NAME "rtl_nic/rtl8261c.bin"
> +MODULE_FIRMWARE(RTL8261C_CE_FW_NAME);
> +
> +enum rtl8261x_fw_op {
> + OP_WRITE = 0x00, /* Write */
> + OP_POLL = 0x02, /* Polling */
> +};
> +
> +struct rtl8261x_fw_header {
> + __le32 main_magic; /* Main magic number 0x52544C38 ("RTL8") */
> + __le32 sub_magic; /* Sub magic number */
> + __le16 version_major; /* Major version */
> + __le16 version_minor; /* Minor version */
> + __le16 num_entries; /* Number of entries */
> + __le16 reserved; /* Reserved */
> + __le32 crc32; /* CRC32 checksum */
> +};
> +
> +struct rtl8261x_fw_entry {
> + __u8 type; /* Operation type (OP_*) */
> + __u8 dev; /* MMD device */
> + __le16 addr; /* Register address */
> + __u8 msb; /* MSB bit position */
> + __u8 lsb; /* LSB bit position */
> + __le16 value; /* Value to write/compare */
> + __le16 timeout_ms; /* Poll timeout in milliseconds */
> + __u8 poll_set; /* Poll for set (1) or clear (0) */
> + __u8 reserved; /* Reserved */
> +};
> +
> +#define FW_HEADER_SIZE sizeof(struct rtl8261x_fw_header)
> +#define FW_ENTRY_SIZE sizeof(struct rtl8261x_fw_entry)
>
> /* RTL8211E and RTL8211F support up to three LEDs */
> #define RTL8211x_LED_COUNT 3
> @@ -300,6 +338,11 @@ struct rtl821x_priv {
> u16 iner;
> };
>
> +struct rtl8261x_priv {
> + const char *fw_name;
> + bool fw_loaded;
> +};
> +
> static int rtl821x_read_page(struct phy_device *phydev)
> {
> return __phy_read(phydev, RTL821x_PAGE_SELECT);
> @@ -342,8 +385,16 @@ static int rtl821x_modify_ext_page(struct phy_device *phydev, u16 ext_page,
>
> static int rtl8261x_probe(struct phy_device *phydev)
> {
> + struct device *dev = &phydev->mdio.dev;
> + struct rtl8261x_priv *priv;
> int sub_phy_id, ret;
>
> + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
> + if (!priv)
> + return -ENOMEM;
> +
> + phydev->priv = priv;
> +
> ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, RTL8261X_EXT_ADDR_REG,
> RTL_8261X_SUB_PHY_ID_ADDR);
> if (ret < 0)
> @@ -357,6 +408,7 @@ static int rtl8261x_probe(struct phy_device *phydev)
>
> switch (sub_phy_id) {
> case RTL8261C_CE_MODEL:
> + priv->fw_name = RTL8261C_CE_FW_NAME;
> phydev_info(phydev, "RTL8261C detected (sub_id 0x%02x)\n", sub_phy_id);
> break;
>
> @@ -407,6 +459,153 @@ static int rtl8261x_read_status(struct phy_device *phydev)
> return 0;
> }
>
> +static int rtl8261x_verify_firmware(struct phy_device *phydev, const struct firmware *fw)
> +{
> + const struct rtl8261x_fw_header *hdr;
> + u32 main_magic, sub_magic;
> + u32 calc_crc, file_crc;
> + size_t data_len;
> + u16 num_entries;
> +
> + if (fw->size < FW_HEADER_SIZE) {
> + phydev_err(phydev, "Firmware too small: %zu bytes\n", fw->size);
> + return -EINVAL;
> + }
> +
> + hdr = (const struct rtl8261x_fw_header *)fw->data;
> +
> + main_magic = le32_to_cpu(hdr->main_magic);
> + if (main_magic != FW_MAIN_MAGIC) {
> + phydev_err(phydev, "Invalid firmware magic: 0x%08x\n", main_magic);
> + return -EINVAL;
> + }
> +
> + sub_magic = le32_to_cpu(hdr->sub_magic);
> + if (sub_magic != FW_SUB_MAGIC_8261C) {
> + phydev_err(phydev, "Invalid sub magic: 0x%08x\n", sub_magic);
> + return -EINVAL;
> + }
> +
> + num_entries = le16_to_cpu(hdr->num_entries);
> + data_len = num_entries * FW_ENTRY_SIZE;
> +
> + if (fw->size != sizeof(*hdr) + data_len) {
> + phydev_err(phydev, "Firmware size mismatch\n");
> + return -EINVAL;
> + }
> +
> + calc_crc = crc32(~0, fw->data + FW_HEADER_SIZE, data_len) ^ ~0;
> + file_crc = le32_to_cpu(hdr->crc32);
> +
> + if (calc_crc != file_crc) {
> + phydev_err(phydev, "CRC32 mismatch: calculated=0x%08x file=0x%08x\n",
> + calc_crc, file_crc);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static int rtl8261x_fw_execute_entry(struct phy_device *phydev,
> + const struct rtl8261x_fw_entry *entry)
> +{
> + u16 addr, value, timeout_ms;
> + u8 dev, msb, lsb, poll_set;
> + u32 bits, expect_val;
> + int ret = 0;
> + int val;
> +
> + dev = entry->dev;
> + addr = le16_to_cpu(entry->addr);
> + msb = entry->msb;
> + lsb = entry->lsb;
> + value = le16_to_cpu(entry->value);
> + timeout_ms = le16_to_cpu(entry->timeout_ms);
> + poll_set = entry->poll_set;
> +
> + if (timeout_ms == 0)
> + timeout_ms = RTL8261X_POLL_TIMEOUT_MS;
> +
> + if (msb > 15 || lsb > msb) {
> + phydev_err(phydev, "Invalid firmware bits: msb=%d, lsb=%d\n", msb, lsb);
> + return -EINVAL;
> + }
> +
> + switch (entry->type) {
> + case OP_WRITE:
> + ret = phy_modify_mmd(phydev, dev, addr,
> + GENMASK(msb, lsb), (value << lsb) & GENMASK(msb, lsb));
> + if (ret) {
> + phydev_err(phydev, "WRITE failed: dev=%d addr=0x%04x\n", dev, addr);
> + return ret;
Here you have a return on error.
> + }
> + break;
> +
> + case OP_POLL: {
> + bits = GENMASK(msb, lsb);
> + expect_val = (value << lsb) & bits;
> +
> + if (poll_set)
> + ret = phy_read_mmd_poll_timeout(phydev, dev, addr, val,
> + (val & bits) == expect_val,
> + 1000, timeout_ms * 1000, false);
> + else
> + ret = phy_read_mmd_poll_timeout(phydev, dev, addr, val,
> + (val & bits) != expect_val,
> + 1000, timeout_ms * 1000, false);
> + if (ret)
> + phydev_err(phydev, "POLL timeout: dev=%d addr=0x%04x\n",
> + dev, addr);
> + break;
Here you don't. It would be better if the code was consistent.
> + }
> + default:
> + phydev_err(phydev, "Unknown firmware operation: %d\n", entry->type);
> + ret = -EINVAL;
> + break;
> + }
> +
> + return ret;
> +}
> +
> +static int rtl8261x_fw_load(struct phy_device *phydev)
> +{
> + struct rtl8261x_priv *priv = phydev->priv;
> + const struct rtl8261x_fw_entry *entry;
> + const struct rtl8261x_fw_header *hdr;
> + const struct firmware *fw;
> + int ret, i;
> +
> + if (!priv->fw_name)
> + return 0;
> +
> + ret = request_firmware(&fw, priv->fw_name, &phydev->mdio.dev);
> + if (ret) {
> + phydev_err(phydev, "Failed to load firmware %s: %d\n", priv->fw_name, ret);
> + return ret;
> + }
> +
> + ret = rtl8261x_verify_firmware(phydev, fw);
> + if (ret)
> + goto release_fw;
> +
> + hdr = (const struct rtl8261x_fw_header *)fw->data;
> +
> + entry = (const struct rtl8261x_fw_entry *)(fw->data + FW_HEADER_SIZE);
> + for (i = 0; i < le16_to_cpu(hdr->num_entries); i++, entry++) {
> + ret = rtl8261x_fw_execute_entry(phydev, entry);
> + if (ret) {
> + phydev_err(phydev, "Entry %d failed: %d\n", i, ret);
> + goto release_fw;
> + }
> + }
> +
> + priv->fw_loaded = true;
> +
> +release_fw:
> + release_firmware(fw);
> + return ret;
> +}
> +
> static int rtl8261x_config_intr(struct phy_device *phydev)
> {
> int ret;
> @@ -484,6 +683,26 @@ static int rtl8261x_config_aneg(struct phy_device *phydev)
> return 0;
> }
>
> +static int rtl8261x_config_init(struct phy_device *phydev)
> +{
> + struct rtl8261x_priv *priv = phydev->priv;
> + int ret = 0;
> +
> + /* The firmware parameters are preserved across IEEE soft resets and
> + * suspend/resume cycles. Reloading is only necessary after a power
> + * cycle or hard reset.
> + */
> + if (priv->fw_name && !priv->fw_loaded) {
> + ret = rtl8261x_fw_load(phydev);
> + if (ret) {
> + phydev_err(phydev, "Firmware loading failed: %d\n", ret);
It seems pretty verbose when things go wrong. Do you need an error
message at every level?
Andrew
---
pw-bot: cr
^ permalink raw reply
* [PATCH net v2] net: usb: lan78xx: disable VLAN filter in promiscuous mode
From: Enrico Pozzobon via B4 Relay @ 2026-07-01 13:09 UTC (permalink / raw)
To: Thangaraj Samynathan, Rengarajan Sundararajan, UNGLinuxDriver,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Woojung.Huh
Cc: netdev, linux-usb, linux-kernel, Enrico Pozzobon
From: Enrico Pozzobon <enrico.pozzobon@dissecto.com>
The hardware VLAN filter (RFE_CTL_VLAN_FILTER_) drops VLAN-tagged frames
whose VID has not been registered via lan78xx_vlan_rx_add_vid(). It is
left enabled in promiscuous mode, so packet capture (e.g. tcpdump or
Wireshark) does not see tagged frames for unregistered VIDs.
Clear the filter while the interface is promiscuous and restore it from
NETIF_F_HW_VLAN_CTAG_FILTER otherwise. Enforce the same condition in
lan78xx_set_features() so netdev_update_features() cannot re-enable the
filter while promiscuous.
Fixes: 55d7de9de6c3 ("Microchip's LAN7800 family USB 2/3 to 10/100/1000 Ethernet device driver")
Signed-off-by: Enrico Pozzobon <enrico.pozzobon@dissecto.com>
---
Currently, on microchip lan7801, enabling promiscuous mode does not
result in VLAN tagged packets being captured. This patch fixes this,
forcing the RFE_CTL_VLAN_FILTER_ flag to be off when promiscuous mode is
enabled.
---
Changes in v2:
- moved VLAN filter logic into lan78xx_update_vlan_filter()
- Link to v1: https://patch.msgid.link/20260630-lan78xx-vlan-promisc-v1-1-fbf0f903bd8f@dissecto.com
To: Thangaraj Samynathan <Thangaraj.S@microchip.com>
To: Rengarajan Sundararajan <Rengarajan.S@microchip.com>
To: UNGLinuxDriver@microchip.com
To: Andrew Lunn <andrew+netdev@lunn.ch>
To: "David S. Miller" <davem@davemloft.net>
To: Eric Dumazet <edumazet@google.com>
To: Jakub Kicinski <kuba@kernel.org>
To: Paolo Abeni <pabeni@redhat.com>
To: Woojung.Huh@microchip.com
Cc: netdev@vger.kernel.org
Cc: linux-usb@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
drivers/net/usb/lan78xx.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index c4cebacabcb5..cb782d81d84f 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -1499,6 +1499,17 @@ static void lan78xx_deferred_multicast_write(struct work_struct *param)
return;
}
+static void lan78xx_update_vlan_filter(struct lan78xx_priv *pdata,
+ struct net_device *netdev,
+ netdev_features_t features)
+{
+ if ((features & NETIF_F_HW_VLAN_CTAG_FILTER) &&
+ !(netdev->flags & IFF_PROMISC))
+ pdata->rfe_ctl |= RFE_CTL_VLAN_FILTER_;
+ else
+ pdata->rfe_ctl &= ~RFE_CTL_VLAN_FILTER_;
+}
+
static void lan78xx_set_multicast(struct net_device *netdev)
{
struct lan78xx_net *dev = netdev_priv(netdev);
@@ -1533,6 +1544,8 @@ static void lan78xx_set_multicast(struct net_device *netdev)
}
}
+ lan78xx_update_vlan_filter(pdata, dev->net, dev->net->features);
+
if (netdev_mc_count(dev->net)) {
struct netdev_hw_addr *ha;
int i;
@@ -3074,10 +3087,7 @@ static int lan78xx_set_features(struct net_device *netdev,
else
pdata->rfe_ctl &= ~RFE_CTL_VLAN_STRIP_;
- if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
- pdata->rfe_ctl |= RFE_CTL_VLAN_FILTER_;
- else
- pdata->rfe_ctl &= ~RFE_CTL_VLAN_FILTER_;
+ lan78xx_update_vlan_filter(pdata, netdev, features);
spin_unlock_irqrestore(&pdata->rfe_ctl_lock, flags);
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20260623-lan78xx-vlan-promisc-83af8a48a7ec
Best regards,
--
Enrico Pozzobon <enrico.pozzobon@dissecto.com>
^ permalink raw reply related
* [PATCH 00/15] MT8189: Add support for system and base clock controllers
From: Louis-Alexis Eyraud @ 2026-07-01 13:11 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Chun-Jie Chen, Philipp Zabel,
Edward-JW Yang, Richard Cochran
Cc: kernel, linux-clk, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, netdev, Louis-Alexis Eyraud, Irving-CH Lin
This series is a continuation by AngeloGioacchino Del Regno and I of a
previous series ([1]), that adds the clock controller support for
the Mediatek MT8189 SoC and its variants (MT8371, MT8391).
The first major changes is the split of the series in two:
- one for all basic clock controllers including system ones (this
series)
- one for the multimedia and graphics related clock controllers (to be
send in the future)
We chose to separate the multimedia clock drivers from the base system
ones, as there is currently an unsolvable inter-dependency between the
power domains and multimedia clocks; the power domains need a
dual-stage bring-up, where only a part of the multimedia clocks are
accessible in the first power domain powerup stage, and the rest when
the second stage (SRAM enablement) is done.
The current workarounds for this issue, such as removing the is_enabled
operation from the impacted clock controllers clk_ops table or
let the multimedia power domain always on, were quickly discarded
for upstream.
The second major change is the dt-bindings patch that got heavily
reworked, not only because of the split choice. We took the opportunity
to regroup in the MT8186 clock and system clock dt-bindings the
description of several other Mediatek SoC (MT8188, MT8192 and MT8195)
and add in them the MT8189 new ones.
The rationale is to ease maintainability and have common files for
several currently supported SoC or new future ones, that have the same
kind of clock controller design.
Finally the pending remarks from peer reviews on the v6 revision of [1]
were also taken into account and new fixes and cleanups were also
added.
A more detailed changelog between [1] and this series:
- Removed multimedia and graphics related clock controllers code and
definitions from series
- Added new dt-bindings patches to factorise existing MT8188, MT8192
and MT8195 in MT8186 clock dt-bindings
- Heavily modified the MT8189 dt-bindings to add new compatibles
in MT8186 clock dt-bindings
- Created a new dt-bindings include for the MT8189 reset controller
definitions (include/dt-bindings/reset/mediatek,mt8189-resets.h)
- Removed unnecessary `syscon` compatible fallback from MT8189 base
clock controllers
- Added missing 'mediatek,mt8189-fhctl' compatible declaration in
dt-bindings
- Modified Kconfig to COMMON_CLK_MT8189 be tristate (and not bool) to
allow all MT8189 clock controller drivers to be built as modules (it
was partial)
- Fix pll unregisters in clk_mt8189_apmixed_probe error case
- Reparent several clocks to correct 26M references in clk-mt8189-bus.c,
clk-mt8189-topckgen.c and clk-mt8189-vlpckgen.c
- Removed CLK_SET_RATE_NO_REPARENT flag from mfg_sel_mfgpll
- Rename TOPCKGEN_fmipi_csi_up26m clock to fmipi_csi_up26m to remove caps usage
- Implemented reset controllers in clk-mt8189-ufs.c
- Updated all file headers to update copyrights and add all authors
- Added all co-developed-by trailers
The series is based on linux-next tree (tag: next-20260630) and has
been tested on Mediatek Genio 520-EVK (MT8371) and 720-EVK (MT8391) boards
with board hardware enablement patch series (new series revision for
those boards to be sent soon after this one).
[1]: https://lore.kernel.org/linux-mediatek/20260309120512.3624804-1-irving-ch.lin@mediatek.com/
[2]: https://lore.kernel.org/linux-mediatek/20260309120512.3624804-2-irving-ch.lin@mediatek.com/
---
Louis-Alexis Eyraud (15):
dt-bindings: clock: mediatek: reorder MT8186 compatibles
dt-bindings: clock: mediatek: regroup MT8188 dt-bindings into MT8186
dt-bindings: clock: mediatek: regroup MT8192 dt-bindings into MT8186
dt-bindings: clock: mediatek: regroup MT8195 dt-bindings into MT8186
dt-bindings: clock: mediatek: Add MT8189 clocks
clk: mediatek: Add MT8189 apmixedsys clock support
clk: mediatek: Add MT8189 topckgen clock support
clk: mediatek: Add MT8189 vlpckgen clock support
clk: mediatek: Add MT8189 vlpcfg clock support
clk: mediatek: Add MT8189 bus clock support
clk: mediatek: Add MT8189 dbgao clock support
clk: mediatek: Add MT8189 dvfsrc clock support
clk: mediatek: Add MT8189 i2c clock support
clk: mediatek: Add MT8189 scp clock support
clk: mediatek: Add MT8189 ufs clock support
.../bindings/clock/mediatek,mt8186-clock.yaml | 171 +++-
.../bindings/clock/mediatek,mt8186-fhctl.yaml | 1 +
.../bindings/clock/mediatek,mt8186-sys-clock.yaml | 42 +-
.../bindings/clock/mediatek,mt8188-clock.yaml | 93 --
.../bindings/clock/mediatek,mt8188-sys-clock.yaml | 58 --
.../bindings/clock/mediatek,mt8192-clock.yaml | 191 ----
.../bindings/clock/mediatek,mt8192-sys-clock.yaml | 68 --
.../bindings/clock/mediatek,mt8195-clock.yaml | 238 -----
.../bindings/clock/mediatek,mt8195-sys-clock.yaml | 76 --
drivers/clk/mediatek/Kconfig | 79 ++
drivers/clk/mediatek/Makefile | 8 +
drivers/clk/mediatek/clk-mt8189-apmixedsys.c | 196 ++++
drivers/clk/mediatek/clk-mt8189-bus.c | 200 ++++
drivers/clk/mediatek/clk-mt8189-dbgao.c | 98 ++
drivers/clk/mediatek/clk-mt8189-dvfsrc.c | 58 ++
drivers/clk/mediatek/clk-mt8189-iic.c | 122 +++
drivers/clk/mediatek/clk-mt8189-scp.c | 77 ++
drivers/clk/mediatek/clk-mt8189-topckgen.c | 1024 ++++++++++++++++++++
drivers/clk/mediatek/clk-mt8189-ufs.c | 133 +++
drivers/clk/mediatek/clk-mt8189-vlpcfg.c | 115 +++
drivers/clk/mediatek/clk-mt8189-vlpckgen.c | 284 ++++++
include/dt-bindings/clock/mediatek,mt8189-clk.h | 433 +++++++++
include/dt-bindings/reset/mediatek,mt8189-resets.h | 17 +
23 files changed, 3046 insertions(+), 736 deletions(-)
---
base-commit: ba7c57499e5999aeae8dd4f954eb2600589d80aa
change-id: 20260630-mt8189-clocks-system-base-70714e4ff2aa
Best regards,
--
Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
^ permalink raw reply
* [PATCH 01/15] dt-bindings: clock: mediatek: reorder MT8186 compatibles
From: Louis-Alexis Eyraud @ 2026-07-01 13:11 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Chun-Jie Chen, Philipp Zabel,
Edward-JW Yang, Richard Cochran
Cc: kernel, linux-clk, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, netdev, Louis-Alexis Eyraud
In-Reply-To: <20260701-mt8189-clocks-system-base-v1-0-2b048feea50a@collabora.com>
In order to prepare regrouping several Mediatek SoC clock controller
dt-bindings files into the MT8186 ones, reorder the MT8186 clock
controller compatibles so they are sorted alphanumerically.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
.../bindings/clock/mediatek,mt8186-clock.yaml | 17 +++++++++--------
.../bindings/clock/mediatek,mt8186-sys-clock.yaml | 4 ++--
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
index f4e58bfa504f..37e1d7487ab4 100644
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
@@ -23,18 +23,19 @@ properties:
compatible:
items:
- enum:
- - mediatek,mt8186-imp_iic_wrap
- - mediatek,mt8186-mfgsys
- - mediatek,mt8186-wpesys
- - mediatek,mt8186-imgsys1
- - mediatek,mt8186-imgsys2
- - mediatek,mt8186-vdecsys
- - mediatek,mt8186-vencsys
- mediatek,mt8186-camsys
- mediatek,mt8186-camsys_rawa
- mediatek,mt8186-camsys_rawb
- - mediatek,mt8186-mdpsys
+ - mediatek,mt8186-imgsys1
+ - mediatek,mt8186-imgsys2
+ - mediatek,mt8186-imp_iic_wrap
- mediatek,mt8186-ipesys
+ - mediatek,mt8186-mdpsys
+ - mediatek,mt8186-mfgsys
+ - mediatek,mt8186-vdecsys
+ - mediatek,mt8186-vencsys
+ - mediatek,mt8186-wpesys
+
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
index 1c446fbc5108..c857a40ca2f0 100644
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
@@ -27,10 +27,10 @@ properties:
compatible:
items:
- enum:
+ - mediatek,mt8186-apmixedsys
+ - mediatek,mt8186-infracfg_ao
- mediatek,mt8186-mcusys
- mediatek,mt8186-topckgen
- - mediatek,mt8186-infracfg_ao
- - mediatek,mt8186-apmixedsys
- const: syscon
reg:
--
2.54.0
^ permalink raw reply related
* [PATCH 02/15] dt-bindings: clock: mediatek: regroup MT8188 dt-bindings into MT8186
From: Louis-Alexis Eyraud @ 2026-07-01 13:11 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Chun-Jie Chen, Philipp Zabel,
Edward-JW Yang, Richard Cochran
Cc: kernel, linux-clk, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, netdev, Louis-Alexis Eyraud
In-Reply-To: <20260701-mt8189-clocks-system-base-v1-0-2b048feea50a@collabora.com>
Regroup the MT8188 clock and system clock dt-bindings into MT8186 ones
to ease maintainability and have common files for several currently
supported SoC or new future ones, that have the same kind of clock
controller design.
Note:
The `#clock-cells` property is a required property for all compatibles
declared in MT8188 clock and system clock dt-bindings but not in MT8186
ones.
To avoid ABI breakage, conditional blocks to check this requirement
for MT8188 compatibles are added, rather than enforcing it for MT8186
compatibles.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
.../bindings/clock/mediatek,mt8186-clock.yaml | 82 ++++++++++++++++++-
.../bindings/clock/mediatek,mt8186-sys-clock.yaml | 20 ++++-
.../bindings/clock/mediatek,mt8188-clock.yaml | 93 ----------------------
.../bindings/clock/mediatek,mt8188-sys-clock.yaml | 58 --------------
4 files changed, 100 insertions(+), 153 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
index 37e1d7487ab4..28e05b5fb23b 100644
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/clock/mediatek,mt8186-clock.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: MediaTek Functional Clock Controller for MT8186
+title: MediaTek Functional Clock Controller for Mediatek SoCs
maintainers:
- Chun-Jie Chen <chun-jie.chen@mediatek.com>
@@ -35,6 +35,30 @@ properties:
- mediatek,mt8186-vdecsys
- mediatek,mt8186-vencsys
- mediatek,mt8186-wpesys
+ - mediatek,mt8188-adsp-audio26m
+ - mediatek,mt8188-camsys
+ - mediatek,mt8188-camsys-rawa
+ - mediatek,mt8188-camsys-rawb
+ - mediatek,mt8188-camsys-yuva
+ - mediatek,mt8188-camsys-yuvb
+ - mediatek,mt8188-ccusys
+ - mediatek,mt8188-imgsys
+ - mediatek,mt8188-imgsys-wpe1
+ - mediatek,mt8188-imgsys-wpe2
+ - mediatek,mt8188-imgsys-wpe3
+ - mediatek,mt8188-imgsys1-dip-nr
+ - mediatek,mt8188-imgsys1-dip-top
+ - mediatek,mt8188-imp-iic-wrap-c
+ - mediatek,mt8188-imp-iic-wrap-en
+ - mediatek,mt8188-imp-iic-wrap-w
+ - mediatek,mt8188-ipesys
+ - mediatek,mt8188-mfgcfg
+ - mediatek,mt8188-vdecsys
+ - mediatek,mt8188-vdecsys-soc
+ - mediatek,mt8188-vencsys
+ - mediatek,mt8188-wpesys
+ - mediatek,mt8188-wpesys-vpp0
+
reg:
maxItems: 1
@@ -42,10 +66,66 @@ properties:
'#clock-cells':
const: 1
+ '#reset-cells':
+ const: 1
+
required:
- compatible
- reg
+allOf:
+ - if:
+ properties:
+ compatible:
+ enum:
+ - mediatek,mt8188-adsp-audio26m
+ - mediatek,mt8188-camsys
+ - mediatek,mt8188-camsys-rawa
+ - mediatek,mt8188-camsys-rawb
+ - mediatek,mt8188-camsys-yuva
+ - mediatek,mt8188-camsys-yuvb
+ - mediatek,mt8188-ccusys
+ - mediatek,mt8188-imgsys
+ - mediatek,mt8188-imgsys-wpe1
+ - mediatek,mt8188-imgsys-wpe2
+ - mediatek,mt8188-imgsys-wpe3
+ - mediatek,mt8188-imgsys1-dip-nr
+ - mediatek,mt8188-imgsys1-dip-top
+ - mediatek,mt8188-imp-iic-wrap-c
+ - mediatek,mt8188-imp-iic-wrap-en
+ - mediatek,mt8188-imp-iic-wrap-w
+ - mediatek,mt8188-ipesys
+ - mediatek,mt8188-mfgcfg
+ - mediatek,mt8188-vdecsys
+ - mediatek,mt8188-vdecsys-soc
+ - mediatek,mt8188-vencsys
+ - mediatek,mt8188-wpesys
+ - mediatek,mt8188-wpesys-vpp0
+ then:
+ required:
+ - '#clock-cells'
+
+ - if:
+ properties:
+ compatible:
+ enum:
+ - mediatek,mt8188-camsys-rawa
+ - mediatek,mt8188-camsys-rawb
+ - mediatek,mt8188-camsys-yuva
+ - mediatek,mt8188-camsys-yuvb
+ - mediatek,mt8188-imgsys-wpe1
+ - mediatek,mt8188-imgsys-wpe2
+ - mediatek,mt8188-imgsys-wpe3
+ - mediatek,mt8188-imgsys1-dip-nr
+ - mediatek,mt8188-imgsys1-dip-top
+ - mediatek,mt8188-ipesys
+ then:
+ required:
+ - '#reset-cells'
+ else:
+ properties:
+ reset-cells: false
+
additionalProperties: false
examples:
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
index c857a40ca2f0..edf9562ca8b9 100644
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/clock/mediatek,mt8186-sys-clock.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: MediaTek System Clock Controller for MT8186
+title: MediaTek System Clock Controller for Mediatek SoCs
maintainers:
- Chun-Jie Chen <chun-jie.chen@mediatek.com>
@@ -31,6 +31,10 @@ properties:
- mediatek,mt8186-infracfg_ao
- mediatek,mt8186-mcusys
- mediatek,mt8186-topckgen
+ - mediatek,mt8188-apmixedsys
+ - mediatek,mt8188-infracfg-ao
+ - mediatek,mt8188-pericfg-ao
+ - mediatek,mt8188-topckgen
- const: syscon
reg:
@@ -46,6 +50,20 @@ required:
- compatible
- reg
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - mediatek,mt8188-apmixedsys
+ - mediatek,mt8188-infracfg-ao
+ - mediatek,mt8188-pericfg-ao
+ - mediatek,mt8188-topckgen
+ then:
+ required:
+ - '#clock-cells'
+
additionalProperties: false
examples:
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8188-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8188-clock.yaml
deleted file mode 100644
index 5403242545ab..000000000000
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8188-clock.yaml
+++ /dev/null
@@ -1,93 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/clock/mediatek,mt8188-clock.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: MediaTek Functional Clock Controller for MT8188
-
-maintainers:
- - Garmin Chang <garmin.chang@mediatek.com>
-
-description: |
- The clock architecture in MediaTek like below
- PLLs -->
- dividers -->
- muxes
- -->
- clock gate
-
- The devices provide clock gate control in different IP blocks.
-
-properties:
- compatible:
- enum:
- - mediatek,mt8188-adsp-audio26m
- - mediatek,mt8188-camsys
- - mediatek,mt8188-camsys-rawa
- - mediatek,mt8188-camsys-rawb
- - mediatek,mt8188-camsys-yuva
- - mediatek,mt8188-camsys-yuvb
- - mediatek,mt8188-ccusys
- - mediatek,mt8188-imgsys
- - mediatek,mt8188-imgsys-wpe1
- - mediatek,mt8188-imgsys-wpe2
- - mediatek,mt8188-imgsys-wpe3
- - mediatek,mt8188-imgsys1-dip-nr
- - mediatek,mt8188-imgsys1-dip-top
- - mediatek,mt8188-imp-iic-wrap-c
- - mediatek,mt8188-imp-iic-wrap-en
- - mediatek,mt8188-imp-iic-wrap-w
- - mediatek,mt8188-ipesys
- - mediatek,mt8188-mfgcfg
- - mediatek,mt8188-vdecsys
- - mediatek,mt8188-vdecsys-soc
- - mediatek,mt8188-vencsys
- - mediatek,mt8188-wpesys
- - mediatek,mt8188-wpesys-vpp0
-
- reg:
- maxItems: 1
-
- '#clock-cells':
- const: 1
-
- '#reset-cells':
- const: 1
-
-required:
- - compatible
- - reg
- - '#clock-cells'
-
-allOf:
- - if:
- properties:
- compatible:
- contains:
- enum:
- - mediatek,mt8188-camsys-rawa
- - mediatek,mt8188-camsys-rawb
- - mediatek,mt8188-camsys-yuva
- - mediatek,mt8188-camsys-yuvb
- - mediatek,mt8188-imgsys-wpe1
- - mediatek,mt8188-imgsys-wpe2
- - mediatek,mt8188-imgsys-wpe3
- - mediatek,mt8188-imgsys1-dip-nr
- - mediatek,mt8188-imgsys1-dip-top
- - mediatek,mt8188-ipesys
-
- then:
- required:
- - '#reset-cells'
-
-additionalProperties: false
-
-examples:
- - |
- clock-controller@11283000 {
- compatible = "mediatek,mt8188-imp-iic-wrap-c";
- reg = <0x11283000 0x1000>;
- #clock-cells = <1>;
- };
-
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8188-sys-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8188-sys-clock.yaml
deleted file mode 100644
index db13d51a4903..000000000000
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8188-sys-clock.yaml
+++ /dev/null
@@ -1,58 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/clock/mediatek,mt8188-sys-clock.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: MediaTek System Clock Controller for MT8188
-
-maintainers:
- - Garmin Chang <garmin.chang@mediatek.com>
-
-description: |
- The clock architecture in MediaTek like below
- PLLs -->
- dividers -->
- muxes
- -->
- clock gate
-
- The apmixedsys provides most of PLLs which generated from SoC 26m.
- The topckgen provides dividers and muxes which provide the clock source to other IP blocks.
- The infracfg_ao provides clock gate in peripheral and infrastructure IP blocks.
- The mcusys provides mux control to select the clock source in AP MCU.
- The device nodes also provide the system control capacity for configuration.
-
-properties:
- compatible:
- items:
- - enum:
- - mediatek,mt8188-apmixedsys
- - mediatek,mt8188-infracfg-ao
- - mediatek,mt8188-pericfg-ao
- - mediatek,mt8188-topckgen
- - const: syscon
-
- reg:
- maxItems: 1
-
- '#clock-cells':
- const: 1
-
- '#reset-cells':
- const: 1
-
-required:
- - compatible
- - reg
- - '#clock-cells'
-
-additionalProperties: false
-
-examples:
- - |
- clock-controller@10000000 {
- compatible = "mediatek,mt8188-topckgen", "syscon";
- reg = <0x10000000 0x1000>;
- #clock-cells = <1>;
- };
--
2.54.0
^ permalink raw reply related
* [PATCH 03/15] dt-bindings: clock: mediatek: regroup MT8192 dt-bindings into MT8186
From: Louis-Alexis Eyraud @ 2026-07-01 13:11 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Chun-Jie Chen, Philipp Zabel,
Edward-JW Yang, Richard Cochran
Cc: kernel, linux-clk, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, netdev, Louis-Alexis Eyraud
In-Reply-To: <20260701-mt8189-clocks-system-base-v1-0-2b048feea50a@collabora.com>
Regroup the MT8192 clock and system clock dt-bindings into MT8186 ones
to ease maintainability and have common files for several currently
supported SoC or new future ones, that have the same kind of clock
controller design.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
.../bindings/clock/mediatek,mt8186-clock.yaml | 21 ++-
.../bindings/clock/mediatek,mt8186-sys-clock.yaml | 4 +
.../bindings/clock/mediatek,mt8192-clock.yaml | 191 ---------------------
.../bindings/clock/mediatek,mt8192-sys-clock.yaml | 68 --------
4 files changed, 24 insertions(+), 260 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
index 28e05b5fb23b..3b543c810f18 100644
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
@@ -58,7 +58,26 @@ properties:
- mediatek,mt8188-vencsys
- mediatek,mt8188-wpesys
- mediatek,mt8188-wpesys-vpp0
-
+ - mediatek,mt8192-camsys
+ - mediatek,mt8192-camsys_rawa
+ - mediatek,mt8192-camsys_rawb
+ - mediatek,mt8192-camsys_rawc
+ - mediatek,mt8192-imgsys
+ - mediatek,mt8192-imgsys2
+ - mediatek,mt8192-imp_iic_wrap_c
+ - mediatek,mt8192-imp_iic_wrap_e
+ - mediatek,mt8192-imp_iic_wrap_s
+ - mediatek,mt8192-imp_iic_wrap_ws
+ - mediatek,mt8192-imp_iic_wrap_w
+ - mediatek,mt8192-imp_iic_wrap_n
+ - mediatek,mt8192-ipesys
+ - mediatek,mt8192-mdpsys
+ - mediatek,mt8192-mfgcfg
+ - mediatek,mt8192-msdc_top
+ - mediatek,mt8192-scp_adsp
+ - mediatek,mt8192-vdecsys_soc
+ - mediatek,mt8192-vdecsys
+ - mediatek,mt8192-vencsys
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
index edf9562ca8b9..4500842b20de 100644
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
@@ -35,6 +35,10 @@ properties:
- mediatek,mt8188-infracfg-ao
- mediatek,mt8188-pericfg-ao
- mediatek,mt8188-topckgen
+ - mediatek,mt8192-apmixedsys
+ - mediatek,mt8192-infracfg
+ - mediatek,mt8192-pericfg
+ - mediatek,mt8192-topckgen
- const: syscon
reg:
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8192-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8192-clock.yaml
deleted file mode 100644
index b8d690e28bdc..000000000000
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8192-clock.yaml
+++ /dev/null
@@ -1,191 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/clock/mediatek,mt8192-clock.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: MediaTek Functional Clock Controller for MT8192
-
-maintainers:
- - Chun-Jie Chen <chun-jie.chen@mediatek.com>
-
-description:
- The Mediatek functional clock controller provides various clocks on MT8192.
-
-properties:
- compatible:
- items:
- - enum:
- - mediatek,mt8192-scp_adsp
- - mediatek,mt8192-imp_iic_wrap_c
- - mediatek,mt8192-imp_iic_wrap_e
- - mediatek,mt8192-imp_iic_wrap_s
- - mediatek,mt8192-imp_iic_wrap_ws
- - mediatek,mt8192-imp_iic_wrap_w
- - mediatek,mt8192-imp_iic_wrap_n
- - mediatek,mt8192-msdc_top
- - mediatek,mt8192-mfgcfg
- - mediatek,mt8192-imgsys
- - mediatek,mt8192-imgsys2
- - mediatek,mt8192-vdecsys_soc
- - mediatek,mt8192-vdecsys
- - mediatek,mt8192-vencsys
- - mediatek,mt8192-camsys
- - mediatek,mt8192-camsys_rawa
- - mediatek,mt8192-camsys_rawb
- - mediatek,mt8192-camsys_rawc
- - mediatek,mt8192-ipesys
- - mediatek,mt8192-mdpsys
-
- reg:
- maxItems: 1
-
- '#clock-cells':
- const: 1
-
-required:
- - compatible
- - reg
-
-additionalProperties: false
-
-examples:
- - |
- scp_adsp: clock-controller@10720000 {
- compatible = "mediatek,mt8192-scp_adsp";
- reg = <0x10720000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imp_iic_wrap_c: clock-controller@11007000 {
- compatible = "mediatek,mt8192-imp_iic_wrap_c";
- reg = <0x11007000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imp_iic_wrap_e: clock-controller@11cb1000 {
- compatible = "mediatek,mt8192-imp_iic_wrap_e";
- reg = <0x11cb1000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imp_iic_wrap_s: clock-controller@11d03000 {
- compatible = "mediatek,mt8192-imp_iic_wrap_s";
- reg = <0x11d03000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imp_iic_wrap_ws: clock-controller@11d23000 {
- compatible = "mediatek,mt8192-imp_iic_wrap_ws";
- reg = <0x11d23000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imp_iic_wrap_w: clock-controller@11e01000 {
- compatible = "mediatek,mt8192-imp_iic_wrap_w";
- reg = <0x11e01000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imp_iic_wrap_n: clock-controller@11f02000 {
- compatible = "mediatek,mt8192-imp_iic_wrap_n";
- reg = <0x11f02000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- msdc_top: clock-controller@11f10000 {
- compatible = "mediatek,mt8192-msdc_top";
- reg = <0x11f10000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- mfgcfg: clock-controller@13fbf000 {
- compatible = "mediatek,mt8192-mfgcfg";
- reg = <0x13fbf000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imgsys: clock-controller@15020000 {
- compatible = "mediatek,mt8192-imgsys";
- reg = <0x15020000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imgsys2: clock-controller@15820000 {
- compatible = "mediatek,mt8192-imgsys2";
- reg = <0x15820000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- vdecsys_soc: clock-controller@1600f000 {
- compatible = "mediatek,mt8192-vdecsys_soc";
- reg = <0x1600f000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- vdecsys: clock-controller@1602f000 {
- compatible = "mediatek,mt8192-vdecsys";
- reg = <0x1602f000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- vencsys: clock-controller@17000000 {
- compatible = "mediatek,mt8192-vencsys";
- reg = <0x17000000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- camsys: clock-controller@1a000000 {
- compatible = "mediatek,mt8192-camsys";
- reg = <0x1a000000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- camsys_rawa: clock-controller@1a04f000 {
- compatible = "mediatek,mt8192-camsys_rawa";
- reg = <0x1a04f000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- camsys_rawb: clock-controller@1a06f000 {
- compatible = "mediatek,mt8192-camsys_rawb";
- reg = <0x1a06f000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- camsys_rawc: clock-controller@1a08f000 {
- compatible = "mediatek,mt8192-camsys_rawc";
- reg = <0x1a08f000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- ipesys: clock-controller@1b000000 {
- compatible = "mediatek,mt8192-ipesys";
- reg = <0x1b000000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- mdpsys: clock-controller@1f000000 {
- compatible = "mediatek,mt8192-mdpsys";
- reg = <0x1f000000 0x1000>;
- #clock-cells = <1>;
- };
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8192-sys-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8192-sys-clock.yaml
deleted file mode 100644
index bf8c9aacdf1e..000000000000
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8192-sys-clock.yaml
+++ /dev/null
@@ -1,68 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/clock/mediatek,mt8192-sys-clock.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: MediaTek System Clock Controller for MT8192
-
-maintainers:
- - Chun-Jie Chen <chun-jie.chen@mediatek.com>
-
-description:
- The Mediatek system clock controller provides various clocks and system configuration
- like reset and bus protection on MT8192.
-
-properties:
- compatible:
- items:
- - enum:
- - mediatek,mt8192-topckgen
- - mediatek,mt8192-infracfg
- - mediatek,mt8192-pericfg
- - mediatek,mt8192-apmixedsys
- - const: syscon
-
- reg:
- maxItems: 1
-
- '#clock-cells':
- const: 1
-
- '#reset-cells':
- const: 1
-
-required:
- - compatible
- - reg
-
-additionalProperties: false
-
-examples:
- - |
- topckgen: syscon@10000000 {
- compatible = "mediatek,mt8192-topckgen", "syscon";
- reg = <0x10000000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- infracfg: syscon@10001000 {
- compatible = "mediatek,mt8192-infracfg", "syscon";
- reg = <0x10001000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- pericfg: syscon@10003000 {
- compatible = "mediatek,mt8192-pericfg", "syscon";
- reg = <0x10003000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- apmixedsys: syscon@1000c000 {
- compatible = "mediatek,mt8192-apmixedsys", "syscon";
- reg = <0x1000c000 0x1000>;
- #clock-cells = <1>;
- };
--
2.54.0
^ permalink raw reply related
* [PATCH 04/15] dt-bindings: clock: mediatek: regroup MT8195 dt-bindings into MT8186
From: Louis-Alexis Eyraud @ 2026-07-01 13:11 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Chun-Jie Chen, Philipp Zabel,
Edward-JW Yang, Richard Cochran
Cc: kernel, linux-clk, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, netdev, Louis-Alexis Eyraud
In-Reply-To: <20260701-mt8189-clocks-system-base-v1-0-2b048feea50a@collabora.com>
Regroup the MT8195 clock and system clock dt-bindings into MT8186 ones
to ease maintainability and have common files for several currently
supported SoC or new future ones, that have the same kind of clock
controller design.
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
.../bindings/clock/mediatek,mt8186-clock.yaml | 25 +++
.../bindings/clock/mediatek,mt8186-sys-clock.yaml | 4 +
.../bindings/clock/mediatek,mt8195-clock.yaml | 238 ---------------------
.../bindings/clock/mediatek,mt8195-sys-clock.yaml | 76 -------
4 files changed, 29 insertions(+), 314 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
index 3b543c810f18..84e602c7d326 100644
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
@@ -78,6 +78,31 @@ properties:
- mediatek,mt8192-vdecsys_soc
- mediatek,mt8192-vdecsys
- mediatek,mt8192-vencsys
+ - mediatek,mt8195-apusys_pll
+ - mediatek,mt8195-camsys
+ - mediatek,mt8195-camsys_rawa
+ - mediatek,mt8195-camsys_yuva
+ - mediatek,mt8195-camsys_rawb
+ - mediatek,mt8195-camsys_yuvb
+ - mediatek,mt8195-camsys_mraw
+ - mediatek,mt8195-ccusys
+ - mediatek,mt8195-imgsys
+ - mediatek,mt8195-imgsys1_dip_top
+ - mediatek,mt8195-imgsys1_dip_nr
+ - mediatek,mt8195-imgsys1_wpe
+ - mediatek,mt8195-imp_iic_wrap_s
+ - mediatek,mt8195-imp_iic_wrap_w
+ - mediatek,mt8195-ipesys
+ - mediatek,mt8195-mfgcfg
+ - mediatek,mt8195-scp_adsp
+ - mediatek,mt8195-vdecsys_soc
+ - mediatek,mt8195-vdecsys
+ - mediatek,mt8195-vdecsys_core1
+ - mediatek,mt8195-vencsys
+ - mediatek,mt8195-vencsys_core1
+ - mediatek,mt8195-wpesys
+ - mediatek,mt8195-wpesys_vpp0
+ - mediatek,mt8195-wpesys_vpp1
reg:
maxItems: 1
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
index 4500842b20de..c4288b91e6b6 100644
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
@@ -39,6 +39,10 @@ properties:
- mediatek,mt8192-infracfg
- mediatek,mt8192-pericfg
- mediatek,mt8192-topckgen
+ - mediatek,mt8195-apmixedsys
+ - mediatek,mt8195-infracfg_ao
+ - mediatek,mt8195-pericfg_ao
+ - mediatek,mt8195-topckgen
- const: syscon
reg:
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8195-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8195-clock.yaml
deleted file mode 100644
index fcc963aff087..000000000000
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8195-clock.yaml
+++ /dev/null
@@ -1,238 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/clock/mediatek,mt8195-clock.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: MediaTek Functional Clock Controller for MT8195
-
-maintainers:
- - Chun-Jie Chen <chun-jie.chen@mediatek.com>
-
-description:
- The clock architecture in Mediatek like below
- PLLs -->
- dividers -->
- muxes
- -->
- clock gate
-
- The devices except apusys_pll provide clock gate control in different IP blocks.
- The apusys_pll provides Plls which generated from SoC 26m for AI Processing Unit.
-
-properties:
- compatible:
- items:
- - enum:
- - mediatek,mt8195-scp_adsp
- - mediatek,mt8195-imp_iic_wrap_s
- - mediatek,mt8195-imp_iic_wrap_w
- - mediatek,mt8195-mfgcfg
- - mediatek,mt8195-wpesys
- - mediatek,mt8195-wpesys_vpp0
- - mediatek,mt8195-wpesys_vpp1
- - mediatek,mt8195-imgsys
- - mediatek,mt8195-imgsys1_dip_top
- - mediatek,mt8195-imgsys1_dip_nr
- - mediatek,mt8195-imgsys1_wpe
- - mediatek,mt8195-ipesys
- - mediatek,mt8195-camsys
- - mediatek,mt8195-camsys_rawa
- - mediatek,mt8195-camsys_yuva
- - mediatek,mt8195-camsys_rawb
- - mediatek,mt8195-camsys_yuvb
- - mediatek,mt8195-camsys_mraw
- - mediatek,mt8195-ccusys
- - mediatek,mt8195-vdecsys_soc
- - mediatek,mt8195-vdecsys
- - mediatek,mt8195-vdecsys_core1
- - mediatek,mt8195-vencsys
- - mediatek,mt8195-vencsys_core1
- - mediatek,mt8195-apusys_pll
- reg:
- maxItems: 1
-
- '#clock-cells':
- const: 1
-
-required:
- - compatible
- - reg
-
-additionalProperties: false
-
-examples:
- - |
- scp_adsp: clock-controller@10720000 {
- compatible = "mediatek,mt8195-scp_adsp";
- reg = <0x10720000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imp_iic_wrap_s: clock-controller@11d03000 {
- compatible = "mediatek,mt8195-imp_iic_wrap_s";
- reg = <0x11d03000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imp_iic_wrap_w: clock-controller@11e05000 {
- compatible = "mediatek,mt8195-imp_iic_wrap_w";
- reg = <0x11e05000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- mfgcfg: clock-controller@13fbf000 {
- compatible = "mediatek,mt8195-mfgcfg";
- reg = <0x13fbf000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- wpesys: clock-controller@14e00000 {
- compatible = "mediatek,mt8195-wpesys";
- reg = <0x14e00000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- wpesys_vpp0: clock-controller@14e02000 {
- compatible = "mediatek,mt8195-wpesys_vpp0";
- reg = <0x14e02000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- wpesys_vpp1: clock-controller@14e03000 {
- compatible = "mediatek,mt8195-wpesys_vpp1";
- reg = <0x14e03000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imgsys: clock-controller@15000000 {
- compatible = "mediatek,mt8195-imgsys";
- reg = <0x15000000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imgsys1_dip_top: clock-controller@15110000 {
- compatible = "mediatek,mt8195-imgsys1_dip_top";
- reg = <0x15110000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imgsys1_dip_nr: clock-controller@15130000 {
- compatible = "mediatek,mt8195-imgsys1_dip_nr";
- reg = <0x15130000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- imgsys1_wpe: clock-controller@15220000 {
- compatible = "mediatek,mt8195-imgsys1_wpe";
- reg = <0x15220000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- ipesys: clock-controller@15330000 {
- compatible = "mediatek,mt8195-ipesys";
- reg = <0x15330000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- camsys: clock-controller@16000000 {
- compatible = "mediatek,mt8195-camsys";
- reg = <0x16000000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- camsys_rawa: clock-controller@1604f000 {
- compatible = "mediatek,mt8195-camsys_rawa";
- reg = <0x1604f000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- camsys_yuva: clock-controller@1606f000 {
- compatible = "mediatek,mt8195-camsys_yuva";
- reg = <0x1606f000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- camsys_rawb: clock-controller@1608f000 {
- compatible = "mediatek,mt8195-camsys_rawb";
- reg = <0x1608f000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- camsys_yuvb: clock-controller@160af000 {
- compatible = "mediatek,mt8195-camsys_yuvb";
- reg = <0x160af000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- camsys_mraw: clock-controller@16140000 {
- compatible = "mediatek,mt8195-camsys_mraw";
- reg = <0x16140000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- ccusys: clock-controller@17200000 {
- compatible = "mediatek,mt8195-ccusys";
- reg = <0x17200000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- vdecsys_soc: clock-controller@1800f000 {
- compatible = "mediatek,mt8195-vdecsys_soc";
- reg = <0x1800f000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- vdecsys: clock-controller@1802f000 {
- compatible = "mediatek,mt8195-vdecsys";
- reg = <0x1802f000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- vdecsys_core1: clock-controller@1803f000 {
- compatible = "mediatek,mt8195-vdecsys_core1";
- reg = <0x1803f000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- vencsys: clock-controller@1a000000 {
- compatible = "mediatek,mt8195-vencsys";
- reg = <0x1a000000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- vencsys_core1: clock-controller@1b000000 {
- compatible = "mediatek,mt8195-vencsys_core1";
- reg = <0x1b000000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- apusys_pll: clock-controller@190f3000 {
- compatible = "mediatek,mt8195-apusys_pll";
- reg = <0x190f3000 0x1000>;
- #clock-cells = <1>;
- };
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8195-sys-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8195-sys-clock.yaml
deleted file mode 100644
index 69f096eb168d..000000000000
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8195-sys-clock.yaml
+++ /dev/null
@@ -1,76 +0,0 @@
-# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
-%YAML 1.2
----
-$id: http://devicetree.org/schemas/clock/mediatek,mt8195-sys-clock.yaml#
-$schema: http://devicetree.org/meta-schemas/core.yaml#
-
-title: MediaTek System Clock Controller for MT8195
-
-maintainers:
- - Chun-Jie Chen <chun-jie.chen@mediatek.com>
-
-description:
- The clock architecture in Mediatek like below
- PLLs -->
- dividers -->
- muxes
- -->
- clock gate
-
- The apmixedsys provides most of PLLs which generated from SoC 26m.
- The topckgen provides dividers and muxes which provide the clock source to other IP blocks.
- The infracfg_ao and pericfg_ao provides clock gate in peripheral and infrastructure IP blocks.
-
-properties:
- compatible:
- items:
- - enum:
- - mediatek,mt8195-topckgen
- - mediatek,mt8195-infracfg_ao
- - mediatek,mt8195-apmixedsys
- - mediatek,mt8195-pericfg_ao
- - const: syscon
-
- reg:
- maxItems: 1
-
- '#clock-cells':
- const: 1
-
- '#reset-cells':
- const: 1
-
-required:
- - compatible
- - reg
-
-additionalProperties: false
-
-examples:
- - |
- topckgen: syscon@10000000 {
- compatible = "mediatek,mt8195-topckgen", "syscon";
- reg = <0x10000000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- infracfg_ao: syscon@10001000 {
- compatible = "mediatek,mt8195-infracfg_ao", "syscon";
- reg = <0x10001000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- apmixedsys: syscon@1000c000 {
- compatible = "mediatek,mt8195-apmixedsys", "syscon";
- reg = <0x1000c000 0x1000>;
- #clock-cells = <1>;
- };
-
- - |
- pericfg_ao: syscon@11003000 {
- compatible = "mediatek,mt8195-pericfg_ao", "syscon";
- reg = <0x11003000 0x1000>;
- #clock-cells = <1>;
- };
--
2.54.0
^ permalink raw reply related
* [PATCH 05/15] dt-bindings: clock: mediatek: Add MT8189 clocks
From: Louis-Alexis Eyraud @ 2026-07-01 13:11 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Brian Masney, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Matthias Brugger,
AngeloGioacchino Del Regno, Chun-Jie Chen, Philipp Zabel,
Edward-JW Yang, Richard Cochran
Cc: kernel, linux-clk, devicetree, linux-kernel, linux-arm-kernel,
linux-mediatek, netdev, Irving-CH Lin, Louis-Alexis Eyraud
In-Reply-To: <20260701-mt8189-clocks-system-base-v1-0-2b048feea50a@collabora.com>
Add dt schema and IDs for the clocks of MediaTek MT8189 SoC.
The MT8189 clock IP provide clock control for main system
(apmixedsys, topcksys and vlpcksys) and subsys (eg. peri, scp,
ufs...).
Also, add compatible for frequency hopping and spread spectrum clock
functionality and reset controller header file for MT8189 UFS reset
controller support.
Co-developed-by: Irving-CH Lin <irving-ch.lin@mediatek.com>
Signed-off-by: Irving-CH Lin <irving-ch.lin@mediatek.com>
Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
---
.../bindings/clock/mediatek,mt8186-clock.yaml | 28 ++
.../bindings/clock/mediatek,mt8186-fhctl.yaml | 1 +
.../bindings/clock/mediatek,mt8186-sys-clock.yaml | 10 +
include/dt-bindings/clock/mediatek,mt8189-clk.h | 433 +++++++++++++++++++++
include/dt-bindings/reset/mediatek,mt8189-resets.h | 17 +
5 files changed, 489 insertions(+)
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
index 84e602c7d326..e30ed16f321d 100644
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt8186-clock.yaml
@@ -58,6 +58,19 @@ properties:
- mediatek,mt8188-vencsys
- mediatek,mt8188-wpesys
- mediatek,mt8188-wpesys-vpp0
+ - mediatek,mt8189-dbg-ao
+ - mediatek,mt8189-dem
+ - mediatek,mt8189-dvfsrc-top
+ - mediatek,mt8189-iic-wrap-e
+ - mediatek,mt8189-iic-wrap-en
+ - mediatek,mt8189-iic-wrap-s
+ - mediatek,mt8189-iic-wrap-ws
+ - mediatek,mt8189-scp-clk
+ - mediatek,mt8189-scp-i2c-clk
+ - mediatek,mt8189-ufscfg-ao
+ - mediatek,mt8189-ufscfg-pdn
+ - mediatek,mt8189-vlpcfg
+ - mediatek,mt8189-vlpcfg-ao
- mediatek,mt8192-camsys
- mediatek,mt8192-camsys_rawa
- mediatek,mt8192-camsys_rawb
@@ -145,6 +158,19 @@ allOf:
- mediatek,mt8188-vencsys
- mediatek,mt8188-wpesys
- mediatek,mt8188-wpesys-vpp0
+ - mediatek,mt8189-dbg-ao
+ - mediatek,mt8189-dem
+ - mediatek,mt8189-dvfsrc-top
+ - mediatek,mt8189-iic-wrap-e
+ - mediatek,mt8189-iic-wrap-en
+ - mediatek,mt8189-iic-wrap-s
+ - mediatek,mt8189-iic-wrap-ws
+ - mediatek,mt8189-scp-clk
+ - mediatek,mt8189-scp-i2c-clk
+ - mediatek,mt8189-ufscfg-ao
+ - mediatek,mt8189-ufscfg-pdn
+ - mediatek,mt8189-vlpcfg
+ - mediatek,mt8189-vlpcfg-ao
then:
required:
- '#clock-cells'
@@ -163,6 +189,8 @@ allOf:
- mediatek,mt8188-imgsys1-dip-nr
- mediatek,mt8188-imgsys1-dip-top
- mediatek,mt8188-ipesys
+ - mediatek,mt8189-ufscfg-ao
+ - mediatek,mt8189-ufscfg-pdn
then:
required:
- '#reset-cells'
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8186-fhctl.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8186-fhctl.yaml
index d00327d12e1e..824e3b2bd6c0 100644
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8186-fhctl.yaml
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt8186-fhctl.yaml
@@ -20,6 +20,7 @@ properties:
- mediatek,mt6795-fhctl
- mediatek,mt8173-fhctl
- mediatek,mt8186-fhctl
+ - mediatek,mt8189-fhctl
- mediatek,mt8192-fhctl
- mediatek,mt8195-fhctl
diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
index c4288b91e6b6..35094ed68548 100644
--- a/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/mediatek,mt8186-sys-clock.yaml
@@ -35,6 +35,11 @@ properties:
- mediatek,mt8188-infracfg-ao
- mediatek,mt8188-pericfg-ao
- mediatek,mt8188-topckgen
+ - mediatek,mt8189-apmixedsys
+ - mediatek,mt8189-infra-ao
+ - mediatek,mt8189-peri-ao
+ - mediatek,mt8189-topckgen
+ - mediatek,mt8189-vlpckgen
- mediatek,mt8192-apmixedsys
- mediatek,mt8192-infracfg
- mediatek,mt8192-pericfg
@@ -68,6 +73,11 @@ allOf:
- mediatek,mt8188-infracfg-ao
- mediatek,mt8188-pericfg-ao
- mediatek,mt8188-topckgen
+ - mediatek,mt8189-apmixedsys
+ - mediatek,mt8189-infra-ao
+ - mediatek,mt8189-peri-ao
+ - mediatek,mt8189-topckgen
+ - mediatek,mt8189-vlpckgen
then:
required:
- '#clock-cells'
diff --git a/include/dt-bindings/clock/mediatek,mt8189-clk.h b/include/dt-bindings/clock/mediatek,mt8189-clk.h
new file mode 100644
index 000000000000..ca433f969698
--- /dev/null
+++ b/include/dt-bindings/clock/mediatek,mt8189-clk.h
@@ -0,0 +1,433 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2025-2026 MediaTek Inc.
+ * Qiqi Wang <qiqi.wang@mediatek.com>
+ * Irving-CH Lin <irving-ch.lin@mediatek.com>
+ * Copyright (C) 2026 Collabora Ltd.
+ * Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+ */
+
+#ifndef _DT_BINDINGS_CLK_MT8189_H
+#define _DT_BINDINGS_CLK_MT8189_H
+
+/* TOPCKGEN */
+#define CLK_TOP_AXI_SEL 0
+#define CLK_TOP_AXI_PERI_SEL 1
+#define CLK_TOP_AXI_U_SEL 2
+#define CLK_TOP_BUS_AXIMEM_SEL 3
+#define CLK_TOP_DISP0_SEL 4
+#define CLK_TOP_MMINFRA_SEL 5
+#define CLK_TOP_UART_SEL 6
+#define CLK_TOP_SPI0_SEL 7
+#define CLK_TOP_SPI1_SEL 8
+#define CLK_TOP_SPI2_SEL 9
+#define CLK_TOP_SPI3_SEL 10
+#define CLK_TOP_SPI4_SEL 11
+#define CLK_TOP_SPI5_SEL 12
+#define CLK_TOP_MSDC_MACRO_0P_SEL 13
+#define CLK_TOP_MSDC50_0_HCLK_SEL 14
+#define CLK_TOP_MSDC50_0_SEL 15
+#define CLK_TOP_AES_MSDCFDE_SEL 16
+#define CLK_TOP_MSDC_MACRO_1P_SEL 17
+#define CLK_TOP_MSDC30_1_SEL 18
+#define CLK_TOP_MSDC30_1_HCLK_SEL 19
+#define CLK_TOP_MSDC_MACRO_2P_SEL 20
+#define CLK_TOP_MSDC30_2_SEL 21
+#define CLK_TOP_MSDC30_2_HCLK_SEL 22
+#define CLK_TOP_AUD_INTBUS_SEL 23
+#define CLK_TOP_ATB_SEL 24
+#define CLK_TOP_DISP_PWM_SEL 25
+#define CLK_TOP_USB_TOP_P0_SEL 26
+#define CLK_TOP_USB_XHCI_P0_SEL 27
+#define CLK_TOP_USB_TOP_P1_SEL 28
+#define CLK_TOP_USB_XHCI_P1_SEL 29
+#define CLK_TOP_USB_TOP_P2_SEL 30
+#define CLK_TOP_USB_XHCI_P2_SEL 31
+#define CLK_TOP_USB_TOP_P3_SEL 32
+#define CLK_TOP_USB_XHCI_P3_SEL 33
+#define CLK_TOP_USB_TOP_P4_SEL 34
+#define CLK_TOP_USB_XHCI_P4_SEL 35
+#define CLK_TOP_I2C_SEL 36
+#define CLK_TOP_SENINF_SEL 37
+#define CLK_TOP_SENINF1_SEL 38
+#define CLK_TOP_AUD_ENGEN1_SEL 39
+#define CLK_TOP_AUD_ENGEN2_SEL 40
+#define CLK_TOP_AES_UFSFDE_SEL 41
+#define CLK_TOP_U_SEL 42
+#define CLK_TOP_U_MBIST_SEL 43
+#define CLK_TOP_AUD_1_SEL 44
+#define CLK_TOP_AUD_2_SEL 45
+#define CLK_TOP_VENC_SEL 46
+#define CLK_TOP_VDEC_SEL 47
+#define CLK_TOP_PWM_SEL 48
+#define CLK_TOP_AUDIO_H_SEL 49
+#define CLK_TOP_MCUPM_SEL 50
+#define CLK_TOP_MEM_SUB_SEL 51
+#define CLK_TOP_MEM_SUB_PERI_SEL 52
+#define CLK_TOP_MEM_SUB_U_SEL 53
+#define CLK_TOP_EMI_N_SEL 54
+#define CLK_TOP_DSI_OCC_SEL 55
+#define CLK_TOP_AP2CONN_HOST_SEL 56
+#define CLK_TOP_IMG1_SEL 57
+#define CLK_TOP_IPE_SEL 58
+#define CLK_TOP_CAM_SEL 59
+#define CLK_TOP_CAMTM_SEL 60
+#define CLK_TOP_DSP_SEL 61
+#define CLK_TOP_SR_PKA_SEL 62
+#define CLK_TOP_DXCC_SEL 63
+#define CLK_TOP_MFG_REF_SEL 64
+#define CLK_TOP_MDP0_SEL 65
+#define CLK_TOP_DP_SEL 66
+#define CLK_TOP_EDP_SEL 67
+#define CLK_TOP_EDP_FAVT_SEL 68
+#define CLK_TOP_ETH_250M_SEL 69
+#define CLK_TOP_ETH_62P4M_PTP_SEL 70
+#define CLK_TOP_ETH_50M_RMII_SEL 71
+#define CLK_TOP_SFLASH_SEL 72
+#define CLK_TOP_GCPU_SEL 73
+#define CLK_TOP_MAC_TL_SEL 74
+#define CLK_TOP_VDSTX_DG_CTS_SEL 75
+#define CLK_TOP_PLL_DPIX_SEL 76
+#define CLK_TOP_ECC_SEL 77
+#define CLK_TOP_APLL_I2SIN0_MCK_SEL 78
+#define CLK_TOP_APLL_I2SIN1_MCK_SEL 79
+#define CLK_TOP_APLL_I2SIN2_MCK_SEL 80
+#define CLK_TOP_APLL_I2SIN3_MCK_SEL 81
+#define CLK_TOP_APLL_I2SIN4_MCK_SEL 82
+#define CLK_TOP_APLL_I2SIN6_MCK_SEL 83
+#define CLK_TOP_APLL_I2SOUT0_MCK_SEL 84
+#define CLK_TOP_APLL_I2SOUT1_MCK_SEL 85
+#define CLK_TOP_APLL_I2SOUT2_MCK_SEL 86
+#define CLK_TOP_APLL_I2SOUT3_MCK_SEL 87
+#define CLK_TOP_APLL_I2SOUT4_MCK_SEL 88
+#define CLK_TOP_APLL_I2SOUT6_MCK_SEL 89
+#define CLK_TOP_APLL_FMI2S_MCK_SEL 90
+#define CLK_TOP_APLL_TDMOUT_MCK_SEL 91
+#define CLK_TOP_MFG_SEL_MFGPLL 92
+#define CLK_TOP_APLL12_CK_DIV_I2SIN0 93
+#define CLK_TOP_APLL12_CK_DIV_I2SIN1 94
+#define CLK_TOP_APLL12_CK_DIV_I2SOUT0 95
+#define CLK_TOP_APLL12_CK_DIV_I2SOUT1 96
+#define CLK_TOP_APLL12_CK_DIV_FMI2S 97
+#define CLK_TOP_APLL12_CK_DIV_TDMOUT_M 98
+#define CLK_TOP_APLL12_CK_DIV_TDMOUT_B 99
+#define CLK_TOP_MAINPLL_D3 100
+#define CLK_TOP_MAINPLL_D4 101
+#define CLK_TOP_MAINPLL_D4_D2 102
+#define CLK_TOP_MAINPLL_D4_D4 103
+#define CLK_TOP_MAINPLL_D4_D8 104
+#define CLK_TOP_MAINPLL_D5 105
+#define CLK_TOP_MAINPLL_D5_D2 106
+#define CLK_TOP_MAINPLL_D5_D4 107
+#define CLK_TOP_MAINPLL_D5_D8 108
+#define CLK_TOP_MAINPLL_D6 109
+#define CLK_TOP_MAINPLL_D6_D2 110
+#define CLK_TOP_MAINPLL_D6_D4 111
+#define CLK_TOP_MAINPLL_D6_D8 112
+#define CLK_TOP_MAINPLL_D7 113
+#define CLK_TOP_MAINPLL_D7_D2 114
+#define CLK_TOP_MAINPLL_D7_D4 115
+#define CLK_TOP_MAINPLL_D7_D8 116
+#define CLK_TOP_MAINPLL_D9 117
+#define CLK_TOP_UNIVPLL_D2 118
+#define CLK_TOP_UNIVPLL_D3 119
+#define CLK_TOP_UNIVPLL_D4 120
+#define CLK_TOP_UNIVPLL_D4_D2 121
+#define CLK_TOP_UNIVPLL_D4_D4 122
+#define CLK_TOP_UNIVPLL_D4_D8 123
+#define CLK_TOP_UNIVPLL_D5 124
+#define CLK_TOP_UNIVPLL_D5_D2 125
+#define CLK_TOP_UNIVPLL_D5_D4 126
+#define CLK_TOP_UNIVPLL_D6 127
+#define CLK_TOP_UNIVPLL_D6_D2 128
+#define CLK_TOP_UNIVPLL_D6_D4 129
+#define CLK_TOP_UNIVPLL_D6_D8 130
+#define CLK_TOP_UNIVPLL_D6_D16 131
+#define CLK_TOP_UNIVPLL_D7 132
+#define CLK_TOP_UNIVPLL_D7_D2 133
+#define CLK_TOP_UNIVPLL_D7_D3 134
+#define CLK_TOP_LVDSTX_DG_CTS 135
+#define CLK_TOP_UNIVPLL_192M 136
+#define CLK_TOP_UNIVPLL_192M_D2 137
+#define CLK_TOP_UNIVPLL_192M_D4 138
+#define CLK_TOP_UNIVPLL_192M_D8 139
+#define CLK_TOP_UNIVPLL_192M_D10 140
+#define CLK_TOP_UNIVPLL_192M_D16 141
+#define CLK_TOP_UNIVPLL_192M_D32 142
+#define CLK_TOP_APLL1_D2 143
+#define CLK_TOP_APLL1_D4 144
+#define CLK_TOP_APLL1_D8 145
+#define CLK_TOP_APLL1_D3 146
+#define CLK_TOP_APLL2_D2 147
+#define CLK_TOP_APLL2_D4 148
+#define CLK_TOP_APLL2_D8 149
+#define CLK_TOP_APLL2_D3 150
+#define CLK_TOP_MMPLL_D4 151
+#define CLK_TOP_MMPLL_D4_D2 152
+#define CLK_TOP_MMPLL_D4_D4 153
+#define CLK_TOP_VPLL_DPIX 154
+#define CLK_TOP_MMPLL_D5 155
+#define CLK_TOP_MMPLL_D5_D2 156
+#define CLK_TOP_MMPLL_D5_D4 157
+#define CLK_TOP_MMPLL_D6 158
+#define CLK_TOP_MMPLL_D6_D2 159
+#define CLK_TOP_MMPLL_D7 160
+#define CLK_TOP_MMPLL_D9 161
+#define CLK_TOP_TVDPLL1_D2 162
+#define CLK_TOP_TVDPLL1_D4 163
+#define CLK_TOP_TVDPLL1_D8 164
+#define CLK_TOP_TVDPLL1_D16 165
+#define CLK_TOP_TVDPLL2_D2 166
+#define CLK_TOP_TVDPLL2_D4 167
+#define CLK_TOP_TVDPLL2_D8 168
+#define CLK_TOP_TVDPLL2_D16 169
+#define CLK_TOP_ETHPLL_D2 170
+#define CLK_TOP_ETHPLL_D8 171
+#define CLK_TOP_ETHPLL_D10 172
+#define CLK_TOP_MSDCPLL_D2 173
+#define CLK_TOP_UFSPLL_D2 174
+#define CLK_TOP_F26M_CK_D2 175
+#define CLK_TOP_OSC_D2 176
+#define CLK_TOP_OSC_D4 177
+#define CLK_TOP_OSC_D8 178
+#define CLK_TOP_OSC_D16 179
+#define CLK_TOP_OSC_D3 180
+#define CLK_TOP_OSC_D7 181
+#define CLK_TOP_OSC_D10 182
+#define CLK_TOP_OSC_D20 183
+#define CLK_TOP_FMCNT_P0_EN 184
+#define CLK_TOP_FMCNT_P1_EN 185
+#define CLK_TOP_FMCNT_P2_EN 186
+#define CLK_TOP_FMCNT_P3_EN 187
+#define CLK_TOP_FMCNT_P4_EN 188
+#define CLK_TOP_USB_F26M_CK_EN 189
+#define CLK_TOP_SSPXTP_F26M_CK_EN 190
+#define CLK_TOP_USB2_PHY_RF_P0_EN 191
+#define CLK_TOP_USB2_PHY_RF_P1_EN 192
+#define CLK_TOP_USB2_PHY_RF_P2_EN 193
+#define CLK_TOP_USB2_PHY_RF_P3_EN 194
+#define CLK_TOP_USB2_PHY_RF_P4_EN 195
+#define CLK_TOP_USB2_26M_CK_P0_EN 196
+#define CLK_TOP_USB2_26M_CK_P1_EN 197
+#define CLK_TOP_USB2_26M_CK_P2_EN 198
+#define CLK_TOP_USB2_26M_CK_P3_EN 199
+#define CLK_TOP_USB2_26M_CK_P4_EN 200
+#define CLK_TOP_F26M_CK_EN 201
+#define CLK_TOP_AP2CON_EN 202
+#define CLK_TOP_EINT_N_EN 203
+#define CLK_TOP_TOPCKGEN_FMIPI_CSI_UP26M_CK_EN 204
+#define CLK_TOP_EINT_E_EN 205
+#define CLK_TOP_EINT_W_EN 206
+#define CLK_TOP_EINT_S_EN 207
+
+/* INFRACFG_AO */
+#define CLK_IFRAO_CQ_DMA_FPC 0
+#define CLK_IFRAO_DEBUGSYS 1
+#define CLK_IFRAO_DBG_TRACE 2
+#define CLK_IFRAO_CQ_DMA 3
+
+/* APMIXEDSYS */
+#define CLK_APMIXED_ARMPLL_LL 0
+#define CLK_APMIXED_ARMPLL_BL 1
+#define CLK_APMIXED_CCIPLL 2
+#define CLK_APMIXED_MAINPLL 3
+#define CLK_APMIXED_UNIVPLL 4
+#define CLK_APMIXED_MMPLL 5
+#define CLK_APMIXED_MFGPLL 6
+#define CLK_APMIXED_APLL1 7
+#define CLK_APMIXED_APLL2 8
+#define CLK_APMIXED_EMIPLL 9
+#define CLK_APMIXED_APUPLL2 10
+#define CLK_APMIXED_APUPLL 11
+#define CLK_APMIXED_TVDPLL1 12
+#define CLK_APMIXED_TVDPLL2 13
+#define CLK_APMIXED_ETHPLL 14
+#define CLK_APMIXED_MSDCPLL 15
+#define CLK_APMIXED_UFSPLL 16
+
+/* PERICFG_AO */
+#define CLK_PERAO_UART0 0
+#define CLK_PERAO_UART1 1
+#define CLK_PERAO_UART2 2
+#define CLK_PERAO_UART3 3
+#define CLK_PERAO_PWM_H 4
+#define CLK_PERAO_PWM_B 5
+#define CLK_PERAO_PWM_FB1 6
+#define CLK_PERAO_PWM_FB2 7
+#define CLK_PERAO_PWM_FB3 8
+#define CLK_PERAO_PWM_FB4 9
+#define CLK_PERAO_DISP_PWM0 10
+#define CLK_PERAO_DISP_PWM1 11
+#define CLK_PERAO_SPI0_B 12
+#define CLK_PERAO_SPI1_B 13
+#define CLK_PERAO_SPI2_B 14
+#define CLK_PERAO_SPI3_B 15
+#define CLK_PERAO_SPI4_B 16
+#define CLK_PERAO_SPI5_B 17
+#define CLK_PERAO_SPI0_H 18
+#define CLK_PERAO_SPI1_H 19
+#define CLK_PERAO_SPI2_H 20
+#define CLK_PERAO_SPI3_H 21
+#define CLK_PERAO_SPI4_H 22
+#define CLK_PERAO_SPI5_H 23
+#define CLK_PERAO_AXI 24
+#define CLK_PERAO_AHB_APB 25
+#define CLK_PERAO_TL 26
+#define CLK_PERAO_REF 27
+#define CLK_PERAO_I2C 28
+#define CLK_PERAO_DMA_B 29
+#define CLK_PERAO_SSUSB0_REF 30
+#define CLK_PERAO_SSUSB0_FRMCNT 31
+#define CLK_PERAO_SSUSB0_SYS 32
+#define CLK_PERAO_SSUSB0_XHCI 33
+#define CLK_PERAO_SSUSB0_F 34
+#define CLK_PERAO_SSUSB0_H 35
+#define CLK_PERAO_SSUSB1_REF 36
+#define CLK_PERAO_SSUSB1_FRMCNT 37
+#define CLK_PERAO_SSUSB1_SYS 38
+#define CLK_PERAO_SSUSB1_XHCI 39
+#define CLK_PERAO_SSUSB1_F 40
+#define CLK_PERAO_SSUSB1_H 41
+#define CLK_PERAO_SSUSB2_REF 42
+#define CLK_PERAO_SSUSB2_FRMCNT 43
+#define CLK_PERAO_SSUSB2_SYS 44
+#define CLK_PERAO_SSUSB2_XHCI 45
+#define CLK_PERAO_SSUSB2_F 46
+#define CLK_PERAO_SSUSB2_H 47
+#define CLK_PERAO_SSUSB3_REF 48
+#define CLK_PERAO_SSUSB3_FRMCNT 49
+#define CLK_PERAO_SSUSB3_SYS 50
+#define CLK_PERAO_SSUSB3_XHCI 51
+#define CLK_PERAO_SSUSB3_F 52
+#define CLK_PERAO_SSUSB3_H 53
+#define CLK_PERAO_SSUSB4_REF 54
+#define CLK_PERAO_SSUSB4_FRMCNT 55
+#define CLK_PERAO_SSUSB4_SYS 56
+#define CLK_PERAO_SSUSB4_XHCI 57
+#define CLK_PERAO_SSUSB4_F 58
+#define CLK_PERAO_SSUSB4_H 59
+#define CLK_PERAO_MSDC0 60
+#define CLK_PERAO_MSDC0_H 61
+#define CLK_PERAO_MSDC0_FAES 62
+#define CLK_PERAO_MSDC0_MST_F 63
+#define CLK_PERAO_MSDC0_SLV_H 64
+#define CLK_PERAO_MSDC1 65
+#define CLK_PERAO_MSDC1_H 66
+#define CLK_PERAO_MSDC1_MST_F 67
+#define CLK_PERAO_MSDC1_SLV_H 68
+#define CLK_PERAO_MSDC2 69
+#define CLK_PERAO_MSDC2_H 70
+#define CLK_PERAO_MSDC2_MST_F 71
+#define CLK_PERAO_MSDC2_SLV_H 72
+#define CLK_PERAO_SFLASH 73
+#define CLK_PERAO_SFLASH_F 74
+#define CLK_PERAO_SFLASH_H 75
+#define CLK_PERAO_SFLASH_P 76
+#define CLK_PERAO_AUDIO0 77
+#define CLK_PERAO_AUDIO1 78
+#define CLK_PERAO_AUDIO2 79
+#define CLK_PERAO_AUXADC_26M 80
+
+/* UFSCFG_AO_REG */
+#define CLK_UFSCFG_AO_REG_UNIPRO_TX_SYM 0
+#define CLK_UFSCFG_AO_REG_UNIPRO_RX_SYM0 1
+#define CLK_UFSCFG_AO_REG_UNIPRO_RX_SYM1 2
+#define CLK_UFSCFG_AO_REG_UNIPRO_SYS 3
+#define CLK_UFSCFG_AO_REG_U_SAP_CFG 4
+#define CLK_UFSCFG_AO_REG_U_PHY_TOP_AHB_S_BUS 5
+
+/* UFSCFG_PDN_REG */
+#define CLK_UFSCFG_REG_UFSHCI_UFS 0
+#define CLK_UFSCFG_REG_UFSHCI_AES 1
+#define CLK_UFSCFG_REG_UFSHCI_U_AHB 2
+#define CLK_UFSCFG_REG_UFSHCI_U_AXI 3
+
+/* IMP_IIC_WRAP_WS */
+#define CLK_IMPWS_I2C2 0
+
+/* IMP_IIC_WRAP_E */
+#define CLK_IMPE_I2C0 0
+#define CLK_IMPE_I2C1 1
+
+/* IMP_IIC_WRAP_S */
+#define CLK_IMPS_I2C3 0
+#define CLK_IMPS_I2C4 1
+#define CLK_IMPS_I2C5 2
+#define CLK_IMPS_I2C6 3
+
+/* IMP_IIC_WRAP_EN */
+#define CLK_IMPEN_I2C7 0
+#define CLK_IMPEN_I2C8 1
+
+/* VLPCFG_REG */
+#define CLK_VLPCFG_REG_SCP 0
+#define CLK_VLPCFG_REG_RG_R_APXGPT_26M 1
+#define CLK_VLPCFG_REG_DPMSRCK_TEST 2
+#define CLK_VLPCFG_REG_RG_DPMSRRTC_TEST 3
+#define CLK_VLPCFG_REG_DPMSRULP_TEST 4
+#define CLK_VLPCFG_REG_SPMI_P_MST 5
+#define CLK_VLPCFG_REG_SPMI_P_MST_32K 6
+#define CLK_VLPCFG_REG_PMIF_SPMI_P_SYS 7
+#define CLK_VLPCFG_REG_PMIF_SPMI_P_TMR 8
+#define CLK_VLPCFG_REG_PMIF_SPMI_M_SYS 9
+#define CLK_VLPCFG_REG_PMIF_SPMI_M_TMR 10
+#define CLK_VLPCFG_REG_DVFSRC 11
+#define CLK_VLPCFG_REG_PWM_VLP 12
+#define CLK_VLPCFG_REG_SRCK 13
+#define CLK_VLPCFG_REG_SSPM_F26M 14
+#define CLK_VLPCFG_REG_SSPM_F32K 15
+#define CLK_VLPCFG_REG_SSPM_ULPOSC 16
+#define CLK_VLPCFG_REG_VLP_32K_COM 17
+#define CLK_VLPCFG_REG_VLP_26M_COM 18
+
+/* VLP_CKSYS */
+#define CLK_VLP_CK_SCP_SEL 0
+#define CLK_VLP_CK_PWRAP_ULPOSC_SEL 1
+#define CLK_VLP_CK_SPMI_P_MST_SEL 2
+#define CLK_VLP_CK_DVFSRC_SEL 3
+#define CLK_VLP_CK_PWM_VLP_SEL 4
+#define CLK_VLP_CK_AXI_VLP_SEL 5
+#define CLK_VLP_CK_SYSTIMER_26M_SEL 6
+#define CLK_VLP_CK_SSPM_SEL 7
+#define CLK_VLP_CK_SSPM_F26M_SEL 8
+#define CLK_VLP_CK_SRCK_SEL 9
+#define CLK_VLP_CK_SCP_SPI_SEL 10
+#define CLK_VLP_CK_SCP_IIC_SEL 11
+#define CLK_VLP_CK_SCP_SPI_HIGH_SPD_SEL 12
+#define CLK_VLP_CK_SCP_IIC_HIGH_SPD_SEL 13
+#define CLK_VLP_CK_SSPM_ULPOSC_SEL 14
+#define CLK_VLP_CK_APXGPT_26M_SEL 15
+#define CLK_VLP_CK_VADSP_SEL 16
+#define CLK_VLP_CK_VADSP_VOWPLL_SEL 17
+#define CLK_VLP_CK_VADSP_UARTHUB_BCLK_SEL 18
+#define CLK_VLP_CK_CAMTG0_SEL 19
+#define CLK_VLP_CK_CAMTG1_SEL 20
+#define CLK_VLP_CK_CAMTG2_SEL 21
+#define CLK_VLP_CK_AUD_ADC_SEL 22
+#define CLK_VLP_CK_KP_IRQ_GEN_SEL 23
+#define CLK_VLP_CK_VADSYS_VLP_26M_EN 24
+#define CLK_VLP_CK_FMIPI_CSI_UP26M_CK_EN 25
+
+/* SCP_IIC */
+#define CLK_SCP_IIC_I2C0_W1S 0
+#define CLK_SCP_IIC_I2C1_W1S 1
+
+/* SCP */
+#define CLK_SCP_SET_SPI0 0
+#define CLK_SCP_SET_SPI1 1
+
+/* VLPCFG_AO_REG */
+#define CLK_VLPCFG_AO_APEINT_RX 0
+
+/* DVFSRC_TOP */
+#define CLK_DVFSRC_TOP_DVFSRC_EN 0
+
+/* DBGAO */
+#define CLK_DBGAO_ATB_EN 0
+
+/* DEM */
+#define CLK_DEM_ATB_EN 0
+#define CLK_DEM_BUSCLK_EN 1
+#define CLK_DEM_SYSCLK_EN 2
+
+#endif /* _DT_BINDINGS_CLK_MT8189_H */
diff --git a/include/dt-bindings/reset/mediatek,mt8189-resets.h b/include/dt-bindings/reset/mediatek,mt8189-resets.h
new file mode 100644
index 000000000000..0f31984374be
--- /dev/null
+++ b/include/dt-bindings/reset/mediatek,mt8189-resets.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (c) 2026 Collabora Ltd.
+ * Author: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+ */
+
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8189
+#define _DT_BINDINGS_RESET_CONTROLLER_MT8189
+
+/* UFS resets */
+#define MT8189_UFSAO_RST_UFS_MPHY 0
+
+#define MT8189_UFSPDN_RST_UFS_UNIPRO 0
+#define MT8189_UFSPDN_RST_UFS_CRYPTO 1
+#define MT8189_UFSPDN_RST_UFS_HCI 2
+
+#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8189 */
--
2.54.0
^ permalink raw reply related
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