* Re: [PATCH v2 08/19] iommu/fsl: use platform_device_set_of_node()
From: Frank Li @ 2026-06-29 14:08 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Lee Jones, Mark Brown, Thierry Reding, Sebastian Hesselbarth,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Srinivas Kandagatla, Greg Kroah-Hartman, Vinod Koul,
Rafael J. Wysocki, Danilo Krummrich, Rob Herring, Saravana Kannan,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Christophe Leroy (CS GROUP), Andi Shyti, Andy Shevchenko,
Joerg Roedel, Will Deacon, Robin Murphy, Doug Berger,
Florian Fainelli, Broadcom internal kernel review list,
Ulf Hansson, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Matthew Brost, Thomas Hellström, Rodrigo Vivi,
David Airlie, Simona Vetter, Peter Chen, Paul Cercueil, Bin Liu,
Philipp Zabel, Maximilian Luz, Hans de Goede, Ilpo Järvinen,
Krzysztof Kozlowski, Benjamin Herrenschmidt, brgl, linux-kernel,
netdev, linux-arm-msm, linux-sound, driver-core, devicetree,
linuxppc-dev, linux-i2c, iommu, linux-pm, imx, linux-arm-kernel,
intel-xe, dri-devel, linux-usb, linux-mips, platform-driver-x86
In-Reply-To: <20260629-pdev-fwnode-ref-v2-8-8abe2513f96e@oss.qualcomm.com>
On Mon, Jun 29, 2026 at 11:12:31AM +0200, Bartosz Golaszewski wrote:
> [You don't often get email from bartosz.golaszewski@oss.qualcomm.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
>
> Ahead of reworking the reference counting logic for platform devices,
> encapsulate the assignment of the OF node for dynamically allocated
> platform devices with the provided helper.
>
> Acked-by: Robin Murphy <robin.murphy@arm.com>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> ---
> drivers/iommu/fsl_pamu.c | 7 +++----
> 1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
> index 25aa477a95a95cb4fa4e132727cde0a936750ee2..012839fa0d8a27cafc6a441373f4f6da794388c1 100644
> --- a/drivers/iommu/fsl_pamu.c
> +++ b/drivers/iommu/fsl_pamu.c
> @@ -973,7 +973,8 @@ static __init int fsl_pamu_init(void)
> ret = -ENOMEM;
> goto error_device_alloc;
> }
> - pdev->dev.of_node = of_node_get(np);
> +
> + platform_device_set_of_node(pdev, np);
>
> ret = pamu_domain_init();
> if (ret)
> @@ -985,12 +986,10 @@ static __init int fsl_pamu_init(void)
> goto error_device_add;
> }
>
> + of_node_put(np);
there are other place miss of_node_put() at error pass.
Can you use auto cleanup
struct device_node *np __free(device_node) = of_find_compatible_node().
Frank
> return 0;
>
> error_device_add:
> - of_node_put(pdev->dev.of_node);
> - pdev->dev.of_node = NULL;
> -
> platform_device_put(pdev);
>
> error_device_alloc:
>
> --
> 2.47.3
>
>
^ permalink raw reply
* Re: [PATCH 00/13] treewide: replace linux/gpio.h
From: Andreas Schwab @ 2026-06-29 14:01 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-gpio, Arnd Bergmann, Bartosz Golaszewski, Andrew Lunn,
Sebastian Hesselbarth, Gregory Clement, Frank Li, Robert Jarzmik,
Krzysztof Kozlowski, Greg Ungerer, Thomas Bogendoerfer,
Hauke Mehrtens, Rafał Miłecki, Yoshinori Sato,
John Paul Adrian Glaubitz, Linus Walleij, Dmitry Torokhov,
Jakub Kicinski, Paolo Abeni, Dominik Brodowski, linux-kernel,
linux-arm-kernel, linux-samsung-soc, patches, linux-m68k,
linux-mips, linux-sh, linux-input, linux-media, netdev,
linux-sunxi, linux-phy, linux-rockchip, linux-sound
In-Reply-To: <20260629132633.1300009-1-arnd@kernel.org>
On Jun 29 2026, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> The linux/gpio.h header used to be the global definition for the gpio
> interfaces, with 1100 users back in linux-3.17. In linux-7.2, only about
> 130 of those remain, so this series cleans out the rest.
>
> In each subsystem, we can replace the header either with
> linux/gpio/consumer.h for users of the modern gpio descriptor interface,
A few of them already used <linux/gpio/consumer.h>, and is duplicated
now.
--
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1
"And now for something completely different."
^ permalink raw reply
* RE: [PATCH iwl-next v5 2/2] ice: implement symmetric RSS hash configuration
From: Loktionov, Aleksandr @ 2026-06-29 14:10 UTC (permalink / raw)
To: Jakub Kicinski
Cc: intel-wired-lan@lists.osuosl.org, Nguyen, Anthony L,
netdev@vger.kernel.org
In-Reply-To: <20260626152636.1e48330f@kernel.org>
> -----Original Message-----
> From: Jakub Kicinski <kuba@kernel.org>
> Sent: Saturday, June 27, 2026 12:27 AM
> To: Loktionov, Aleksandr <aleksandr.loktionov@intel.com>
> Cc: intel-wired-lan@lists.osuosl.org; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; netdev@vger.kernel.org
> Subject: Re: [PATCH iwl-next v5 2/2] ice: implement symmetric RSS hash
> configuration
>
> On Fri, 26 Jun 2026 07:47:30 +0200 Aleksandr Loktionov wrote:
> > - /* Update the VSI's hash function */
> > - if (rxfh->input_xfrm & RXH_XFRM_SYM_XOR)
> > - hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ;
> > + /* Handle RSS symmetric hash transformation */
> > + if (rxfh->input_xfrm != RXH_XFRM_NO_CHANGE) {
> > + u8 new_hfunc;
>
> I think this is the very bad part. Please extract it out and send it
> as a fix to net. Looks like any changes to RSS confing on ice randomly
> enable xfrm sym. I isolated it to the ntuple.py test which just
> changes the indir table, and the driver says:
>
> ice 0000:e1:00.0 ens1f0np0: Hash function set to: Symmetric Toeplitz
>
Good day, Jakub
I understood on TEID; I will drop the ethtool core patch.
One question before respinning the ice feature patch: ice GTP RSS profiles
include TEID in the hardware hash fields. Since TEID is not generally
symmetric across UL/DL, should the driver:
1. report RXH_GTP_TEID honestly and let the core reject symmetric-xor
when GTP flow types are part of the preflight check;
2. hide RXH_GTP_TEID while symmetric-xor is enabled, even though that
misrepresents the hardware hash input;
3. reject symmetric-xor for configurations where GTP profiles include
TEID; or
4. change/program the ice GTP profile, if possible, to exclude TEID
under symmetric-xor?
My preference is (1) or (3), but I do not want to encode the wrong uAPI
semantics.
> Which we never asked for. I drafted this before seeing your reply:
>
> --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c
> +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c
> @@ -3692,10 +3692,10 @@ ice_set_rxfh(struct net_device *netdev, struct
> ethtool_rxfh_param *rxfh,
> struct netlink_ext_ack *extack) {
> struct ice_netdev_priv *np = netdev_priv(netdev);
> - u8 hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ;
> struct ice_vsi *vsi = np->vsi;
> struct ice_pf *pf = vsi->back;
> struct device *dev;
> + u8 hfunc;
> int err;
>
> dev = ice_pf_to_dev(pf);
> @@ -3714,9 +3714,12 @@ ice_set_rxfh(struct net_device *netdev, struct
> ethtool_rxfh_param *rxfh,
> return -EOPNOTSUPP;
> }
>
> - /* Update the VSI's hash function */
> - if (rxfh->input_xfrm & RXH_XFRM_SYM_XOR)
> + if (rxfh->input_xfrm == RXH_XFRM_NO_CHANGE)
> + hfunc = vsi->rss_hfunc;
> + else if (rxfh->input_xfrm & RXH_XFRM_SYM_XOR)
> hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ;
> + else /* input_xfrm == 0; core rejects any other value */
> + hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ;
>
> err = ice_set_rss_hfunc(vsi, hfunc);
^ permalink raw reply
* Re: [External Mail] Re: [PATCH v3 2/7] net: wwan: t9xx: Add control plane transaction layer
From: Andrew Lunn @ 2026-06-29 14:10 UTC (permalink / raw)
To: Wu. JackBB (GSM)
Cc: Loic Poulain, Sergey Ryazanov, Johannes Berg, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Wen-Zhi Huang, Shi-Wei Yeh, Minano Tseng, Matthias Brugger,
AngeloGioacchino Del Regno, Simon Horman, Jonathan Corbet,
Shuah Khan, linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-mediatek@lists.infradead.org, linux-doc@vger.kernel.org
In-Reply-To: <49939d4d682f4c1fb359973ea2cdbd00@compal.com>
> > > - devm_kfree(dev, mdev);
> > > + mtk_dev_free(mdev);
> >
> > Why are you removing devm_ calls?
>
> mtk_dev_alloc/mtk_dev_free are paired wrappers so the caller
> doesn't need to know the underlying allocation mechanism.
> The devm_kfree is still called inside mtk_dev_free.
Two different issues here:
1) If you don't want to use devm_, don't use devm_ from the
beginning. A patch should not change how a previous patch works, since
you are wasting reviewer time reviewing code which you later change.
2) Do you understand what devm_ actually does? Since you use
devm_free() i don't think you actually understand what devm_ is all
about.
Andrew
^ permalink raw reply
* Re: Please apply 736b380e28d0 and eca856950f7c down to 6.1.y
From: Salvatore Bonaccorso @ 2026-06-29 14:13 UTC (permalink / raw)
To: Wongi Lee, Greg Kroah-Hartman
Cc: stable, Sasha Levin, netdev, David Ahern, Ido Schimmel,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Jungwoo Lee
In-Reply-To: <ajum4HXbhgdRl6Vz@DESKTOP-19IMU7U.localdomain>
Hi Greg,
On Wed, Jun 24, 2026 at 06:44:00PM +0900, Wongi Lee wrote:
> On Wed, Jun 24, 2026 at 11:37:29AM +0200, Greg Kroah-Hartman wrote:
> > On Wed, Jun 24, 2026 at 06:30:03PM +0900, Wongi Lee wrote:
> > > On Wed, Jun 24, 2026 at 11:00:45AM +0200, Greg Kroah-Hartman wrote:
> > > > On Wed, Jun 24, 2026 at 05:14:38PM +0900, Wongi Lee wrote:
> > > > > Hi,
> > > > >
> > > > > Could the following upstream commits be queued for the active stable
> > > > > trees?
> > > > >
> > > > > commit 736b380e28d0480c7bc3e022f1950f31fe53a7c5
> > > > > ("ipv6: account for fraggap on the paged allocation path")
> > > >
> > > > I do not see that commit id in Linus's tree, are you sure it is correct?
> > > >
> > > > > commit eca856950f7cb1a221e02b99d758409f2c5cec42
> > > > > ("ipv4: account for fraggap on the paged allocation path")
> > > >
> > > > Same here, no id of that one in Linus's tree that I can see.
> > > >
> > > > thanks,
> > > >
> > > > greg k-h
> > >
> > >
> > > Hi Greg,
> > >
> > > First, sorry for confusing you.
> > >
> > > The commit IDs are from netdev/net.git:
> > >
> > > 736b380e28d0480c7bc3e022f1950f31fe53a7c5
> > > https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=736b380e28d0
> > >
> > > eca856950f7cb1a221e02b99d758409f2c5cec42
> > > https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=eca856950f7c
> > >
> > > They were applied to netdev without Cc: stable@vger.kernel.org, so I
> > > wanted to flag them for stable handling but I send it too fast (before
> > > merge).
> > >
> > > I will resend the request with the Linus tree commit ID.
> >
> > They have to be in Linus's tree, before we can take them in a stable
> > release, right?
> >
> > And why were they not originally tagged with the cc: stable? That would
> > save you time in the future as it would all just happen automatically.
> >
> > thanks,
> >
> > greg k-h
>
> Right, my fault.
>
> Also I just forgot cc'ing stable when sending it. I'll apply it next time.
Small heads-up: Both commits are now in Linus' tree and included in
v7.2-rc1:
$ git describe --contains 736b380e28d0480c7bc3e022f1950f31fe53a7c5
v7.2-rc1~29^2~66^2
$ git describe --contains eca856950f7cb1a221e02b99d758409f2c5cec42
v7.2-rc1~29^2~66^2~1
Can you queue those as needed down to the 6.1.y stable series?
Thank you already,
Regards,
Salvatore
^ permalink raw reply
* [PATCH net v2] net/liquidio: drop cached VF pci_dev LUT and resolve VF for FLR on request
From: Yuho Choi @ 2026-06-29 14:16 UTC (permalink / raw)
To: Andrew Lunn, David S . Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Kory Maincent, Zilin Guan, Uwe Kleine-Koenig,
Vadim Fedorenko, Marco Crivellari
Cc: netdev, linux-kernel, Yuho Choi
The PF SR-IOV enable path caches VF pci_dev pointers in
dpiring_to_vfpcidev_lut[] by iterating with pci_get_device(). Those
entries do not own a reference, because the iterator drops the previous
device reference on each step. The cached pointer is then dereferenced
later when handling OCTEON_VF_FLR_REQUEST.
Replace cached VF mapping with runtime lookup on mailbox DPI ring:
derive VF index from q_no, resolve the VF via exported PCI IOV helpers,
validate with PF pointer + VF ID, then pcie_flr() and pci_dev_put().
Also, remove unused dpiring_to_vfpcidev_lut init/cleanup and simplify
Xgene PCI probe by using port->dev->of_node directly.
Fixes: ca6139ffc67ee ("liquidio CN23XX: sysfs VF config support")
Fixes: 8c978d059224 ("liquidio CN23XX: Mailbox support")
Signed-off-by: Yuho Choi <dbgh9129@gmail.com>
---
Changes in v2:
- Replace use of pci_iov_virtfn_bus() with runtime VF lookup using exported helpers.
.../net/ethernet/cavium/liquidio/lio_main.c | 27 ---------------
.../ethernet/cavium/liquidio/octeon_device.h | 3 --
.../ethernet/cavium/liquidio/octeon_mailbox.c | 33 ++++++++++++++++++-
3 files changed, 32 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c
index 0db08ac3d098..e303956b4bf1 100644
--- a/drivers/net/ethernet/cavium/liquidio/lio_main.c
+++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c
@@ -3779,9 +3779,7 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
static int octeon_enable_sriov(struct octeon_device *oct)
{
unsigned int num_vfs_alloced = oct->sriov_info.num_vfs_alloced;
- struct pci_dev *vfdev;
int err;
- u32 u;
if (OCTEON_CN23XX_PF(oct) && num_vfs_alloced) {
err = pci_enable_sriov(oct->pci_dev,
@@ -3794,23 +3792,6 @@ static int octeon_enable_sriov(struct octeon_device *oct)
return err;
}
oct->sriov_info.sriov_enabled = 1;
-
- /* init lookup table that maps DPI ring number to VF pci_dev
- * struct pointer
- */
- u = 0;
- vfdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
- OCTEON_CN23XX_VF_VID, NULL);
- while (vfdev) {
- if (vfdev->is_virtfn &&
- (vfdev->physfn == oct->pci_dev)) {
- oct->sriov_info.dpiring_to_vfpcidev_lut[u] =
- vfdev;
- u += oct->sriov_info.rings_per_vf;
- }
- vfdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
- OCTEON_CN23XX_VF_VID, vfdev);
- }
}
return num_vfs_alloced;
@@ -3818,8 +3799,6 @@ static int octeon_enable_sriov(struct octeon_device *oct)
static int lio_pci_sriov_disable(struct octeon_device *oct)
{
- int u;
-
if (pci_vfs_assigned(oct->pci_dev)) {
dev_err(&oct->pci_dev->dev, "VFs are still assigned to VMs.\n");
return -EPERM;
@@ -3827,12 +3806,6 @@ static int lio_pci_sriov_disable(struct octeon_device *oct)
pci_disable_sriov(oct->pci_dev);
- u = 0;
- while (u < MAX_POSSIBLE_VFS) {
- oct->sriov_info.dpiring_to_vfpcidev_lut[u] = NULL;
- u += oct->sriov_info.rings_per_vf;
- }
-
oct->sriov_info.num_vfs_alloced = 0;
dev_info(&oct->pci_dev->dev, "oct->pf_num:%d disabled VFs\n",
oct->pf_num);
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.h b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
index 19344b21f8fb..858a0fff2cc0 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_device.h
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.h
@@ -390,9 +390,6 @@ struct octeon_sriov_info {
struct lio_trusted_vf trusted_vf;
- /*lookup table that maps DPI ring number to VF pci_dev struct pointer*/
- struct pci_dev *dpiring_to_vfpcidev_lut[MAX_POSSIBLE_VFS];
-
u64 vf_macaddr[MAX_POSSIBLE_VFS];
u16 vf_vlantci[MAX_POSSIBLE_VFS];
diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
index ad685f5d0a13..697fcdc41e3c 100644
--- a/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
+++ b/drivers/net/ethernet/cavium/liquidio/octeon_mailbox.c
@@ -26,6 +26,31 @@
#include "octeon_mailbox.h"
#include "cn23xx_pf_device.h"
+static struct pci_dev *lio_vf_pci_dev_by_qno(struct octeon_device *oct, u32 q_no)
+{
+ struct pci_dev *vfdev = NULL;
+ int vfidx;
+
+ if (!oct->sriov_info.rings_per_vf)
+ return NULL;
+
+ if (q_no % oct->sriov_info.rings_per_vf)
+ return NULL;
+
+ vfidx = q_no / oct->sriov_info.rings_per_vf;
+ if (vfidx >= oct->sriov_info.num_vfs_alloced)
+ return NULL;
+
+ while ((vfdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
+ OCTEON_CN23XX_VF_VID, vfdev))) {
+ if (pci_physfn(vfdev) && pci_physfn(vfdev) == oct->pci_dev &&
+ pci_iov_vf_id(vfdev) == vfidx)
+ return vfdev;
+ }
+
+ return NULL;
+}
+
/**
* octeon_mbox_read:
* @mbox: Pointer mailbox
@@ -237,6 +262,7 @@ static int octeon_mbox_process_cmd(struct octeon_mbox *mbox,
struct octeon_mbox_cmd *mbox_cmd)
{
struct octeon_device *oct = mbox->oct_dev;
+ struct pci_dev *vfdev;
switch (mbox_cmd->msg.s.cmd) {
case OCTEON_VF_ACTIVE:
@@ -260,7 +286,12 @@ static int octeon_mbox_process_cmd(struct octeon_mbox *mbox,
dev_info(&oct->pci_dev->dev,
"got a request for FLR from VF that owns DPI ring %u\n",
mbox->q_no);
- pcie_flr(oct->sriov_info.dpiring_to_vfpcidev_lut[mbox->q_no]);
+ vfdev = lio_vf_pci_dev_by_qno(oct, mbox->q_no);
+ if (!vfdev)
+ break;
+
+ pcie_flr(vfdev);
+ pci_dev_put(vfdev);
break;
case OCTEON_PF_CHANGED_VF_MACADDR:
--
2.43.0
^ permalink raw reply related
* Re: [PATCH 1/3] arm64: dts: qcom: sm8450: Add IPA support
From: Konrad Dybcio @ 2026-06-29 14:18 UTC (permalink / raw)
To: Esteban Urrutia, Bjorn Andersson, Konrad Dybcio, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Alex Elder
Cc: linux-arm-msm, devicetree, linux-kernel, netdev
In-Reply-To: <b1f872f5-66cc-45fc-ad42-c308f8970691@proton.me>
On 6/24/26 3:52 AM, Esteban Urrutia wrote:
> On 6/23/26 5:37 AM, Konrad Dybcio wrote:
>> size = 0xb0000 for the RAM and uC regions that the driver seems
>> to poke at (at a glance anyway..)
>
> Sorry, I don't quite understand. Could you please clarify?
Please alter the size of the register range that I mentioned this under,
as the range is wider than what you specified - the driver takes a big
offset from this base and accesses far outside the bounds of that range
Konrad
^ permalink raw reply
* Re: [PATCH iproute2-next] devlink: support u32-array values in devlink param show/set
From: David Ahern @ 2026-06-29 14:19 UTC (permalink / raw)
To: Ratheesh Kannoth, pablo
Cc: stephen, kuba, linux-kernel, netdev, andrew+netdev, davem,
edumazet, pabeni, sgoutham, Jiri Pirko
In-Reply-To: <akHW1ZiovKdwUq6s@rkannoth-OptiPlex-7090>
On 6/28/26 8:22 PM, Ratheesh Kannoth wrote:
> On 2026-06-28 at 22:49:48, David Ahern (dsahern@kernel.org) wrote:
>> On 6/14/26 10:10 PM, Ratheesh Kannoth wrote:
>>> @@ -3904,6 +3935,14 @@ static int cmd_dev_param_set(struct dl *dl)
>>> if (!strcmp(dl->opts.param_value, ctx.value.vstr))
>>> return 0;
>>> break;
>>> + case 129:
>>
>> no magic numbers. What does 129 represent? Is there a named macro for
>> it? If not, why not if this is part of a UAPI?
>
> The magic number 129 actually represents DEVLINK_PARAM_TYPE_U64_ARRAY from the kernel UAPI (include/uapi/linux/devlink.h).
The uapi is actually devlink_var_attr_type and in this case
DEVLINK_VAR_ATTR_TYPE_U64_ARRAY.
>
> The other cases in this switch block utilize MNL_TYPE_* constants from libmnl. I previously tried to
> patch libmnl to add a matching MNL_TYPE_UARR = 129 macro, but the netfilter maintainers declined it,
> noting that the enum is internal to libmnl (thread: https://lore.kernel.org/netfilter-devel/20260623043755.2435685-1-rkannoth@marvell.com/).
I agree with them.
Looking at the use of devlink_var_attr_type it is duplicating MNL values
for the early entries, but it is not nla_type as part of the nla_attr
uapi. Seems to me the 'nla_type' reference in the code is misleading.
I think cmd_dev_param_set in iproute2 needs to be changed to reference
devlink_var_attr_type instead of MNL_TYPE_*. With that as a prep patch,
add in the new use of DEVLINK_VAR_ATTR_TYPE_U64_ARRAY for this patch.
@Jiri: agree?
And then your subject line and commit message need to be updated to
reference a u64 array, not u32, correct?
>
> To resolve this without magic numbers, I can use the existing kernel macro directly in
> the case statement with an explanatory comment, like so:
>
> /* DEVLINK_PARAM_TYPE_U64_ARRAY maps to 129 */
> case DEVLINK_PARAM_TYPE_U64_ARRAY:
>
> Please let me know if this approach works for you, or if you prefer a different handling.
>
>>
^ permalink raw reply
* Re: [PATCH net 1/1] sctp: avoid auth_enable sysctl UAF during netns teardown
From: Xin Long @ 2026-06-29 14:22 UTC (permalink / raw)
To: Ren Wei
Cc: linux-sctp, netdev, marcelo.leitner, davem, edumazet, pabeni,
horms, matttbe, yuantan098, yifanwucs, tomapufckgml, bird,
roxy520tt
In-Reply-To: <CADvbK_cYeewNprxJ88TdRnCr2QTh1px8vxdqikBovb+dTEtp8Q@mail.gmail.com>
On Mon, Jun 29, 2026 at 10:04 AM Xin Long <lucien.xin@gmail.com> wrote:
>
> On Sun, Jun 28, 2026 at 4:40 AM Ren Wei <n05ec@lzu.edu.cn> wrote:
> >
> > From: Zhiling Zou <roxy520tt@gmail.com>
> >
> > proc_sctp_do_auth() updates the SCTP control socket after changing
> > net.sctp.auth_enable. The handler gets the per-net SCTP state from
> > ctl->data, so an already opened sysctl file can still target a network
> > namespace while that namespace is being torn down.
> >
> > SCTP unregisters its per-net sysctls from sctp_defaults_exit(), but
> > sctp_ctrlsock_exit() runs earlier because the control-socket pernet ops
> > are registered after the defaults ops. This leaves a teardown window
> > where auth_enable is still writable after inet_ctl_sock_destroy() has
> > released net->sctp.ctl_sock, leading to a use-after-free when the sysctl
> > handler locks and dereferences the stale socket.
> >
> > Unregister the per-net SCTP sysctl table before destroying the control
> > socket. Make sctp_sysctl_net_unregister() tolerate a missing header and
> > clear the saved pointer so the later defaults exit path and init-error
> > path can safely share the same unregister helper.
> >
> > Fixes: 15649fd5415e ("sctp: sysctl: auth_enable: avoid using current->nsproxy")
> > Cc: stable@vger.kernel.org
> > Reported-by: Yuan Tan <yuantan098@gmail.com>
> > Reported-by: Yifan Wu <yifanwucs@gmail.com>
> > Reported-by: Juefei Pu <tomapufckgml@gmail.com>
> > Reported-by: Xin Liu <bird@lzu.edu.cn>
> > Assisted-by: Codex:gpt-5.4
> > Signed-off-by: Zhiling Zou <roxy520tt@gmail.com>
> > Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
> > ---
> > net/sctp/protocol.c | 3 +++
> > net/sctp/sysctl.c | 9 +++++++--
> > 2 files changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
> > index 587b0017a67d..ae381d304bd5 100644
> > --- a/net/sctp/protocol.c
> > +++ b/net/sctp/protocol.c
> > @@ -1457,8 +1457,11 @@ static int __net_init sctp_ctrlsock_init(struct net *net)
> >
> > static void __net_exit sctp_ctrlsock_exit(struct net *net)
> > {
> > + sctp_sysctl_net_unregister(net);
> > +
> > /* Free the control endpoint. */
> > inet_ctl_sock_destroy(net->sctp.ctl_sock);
> > + net->sctp.ctl_sock = NULL;
> > }
> >
> > static struct pernet_operations sctp_ctrlsock_ops = {
> > diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
> > index 15e7db9a3ab2..fca840484ebf 100644
> > --- a/net/sctp/sysctl.c
> > +++ b/net/sctp/sysctl.c
> > @@ -615,11 +615,16 @@ int sctp_sysctl_net_register(struct net *net)
> >
> > void sctp_sysctl_net_unregister(struct net *net)
> > {
> > + struct ctl_table_header *header = net->sctp.sysctl_header;
> > const struct ctl_table *table;
> >
> > - table = net->sctp.sysctl_header->ctl_table_arg;
> > - unregister_net_sysctl_table(net->sctp.sysctl_header);
> > + if (!header)
> > + return;
> > +
> > + table = header->ctl_table_arg;
> > + unregister_net_sysctl_table(header);
> > kfree(table);
> > + net->sctp.sysctl_header = NULL;
> > }
> >
> > static struct ctl_table_header *sctp_sysctl_header;
> > --
> > 2.43.0
> >
>
> Please also move sctp_sysctl_net_register() to sctp_ctrlsock_init(), and call
> it AFTER sctp_ctl_sock_init().
>
> This is not just for being symmetric, but also fixes two problems:
>
> 1. A regression caused by this patch:
>
> If sctp_v4_protosw_init() or sctp_v6_protosw_init() fails in sctp_init(),
> there's no place to call sctp_sysctl_net_unregister() on the err path.
>
> 2. A pre-existing issue reported by sashiko-gemini:
>
> > diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
> > index 15e7db9a3ab2e..fca840484ebf7 100644
> > --- a/net/sctp/sysctl.c
> > +++ b/net/sctp/sysctl.c
> > @@ -615,11 +615,16 @@ int sctp_sysctl_net_register(struct net *net)
> >
> > void sctp_sysctl_net_unregister(struct net *net)
> > {
> > + struct ctl_table_header *header = net->sctp.sysctl_header;
> > const struct ctl_table *table;
> This is a pre-existing issue, but I noticed a potential race condition
> during SCTP module initialization related to the sysctls modified here.
> During sctp_init(), sctp_defaults_ops registers the sysctls globally before
> sctp_ctrlsock_ops allocates net->sctp.ctl_sock:
> sctp_init() {
> ...
> status = register_pernet_subsys(&sctp_defaults_ops);
> if (status)
> goto err_register_defaults;
> ...
> status = register_pernet_subsys(&sctp_ctrlsock_ops);
> ...
> }
> If userspace accesses the sysctls in this window, proc_sctp_do_auth() could
> dereference a NULL pointer since it assumes ctl_sock is ready:
> proc_sctp_do_auth() {
> ...
> struct sock *sk = net->sctp.ctl_sock;
> net->sctp.auth_enable = new_value;
> /* Update the value in the control socket */
> lock_sock(sk);
> ...
> }
> Can we hit a kernel panic here if the sysctl is modified during automatic
> module loading?
> [...]
>
Also, if you don't mind, please try to address another issue reported
in sashiko-gemini:
> diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
> index 587b0017a67d5..ae381d304bd53 100644
> --- a/net/sctp/protocol.c
> +++ b/net/sctp/protocol.c
> @@ -1457,8 +1457,11 @@ static int __net_init sctp_ctrlsock_init(struct net *net)
>
> static void __net_exit sctp_ctrlsock_exit(struct net *net)
> {
This isn't a bug introduced by this patch, but while reviewing the netns
teardown sequence, I noticed the SCTP UDP tunnel sockets appear to leak.
In sctp_defaults_exit():
sctp_defaults_exit() {
/* Free the local address list */
sctp_free_addr_wq(net);
sctp_free_local_addr_list(net);
...
}
Should sctp_defaults_exit() call sctp_udp_sock_stop(net) to ensure the
UDP tunnel sockets are closed?
If a user creates a network namespace, writes to the net.sctp.udp_port sysctl
to allocate the sockets, and then destroys the namespace, could these sockets
remain active and cause a use-after-free of struct net when packets arrive?
[...]
maybe by adding sctp_udp_sock_stop() in sctp_ctrlsock_exit(), and call it AFTER
sctp_sysctl_net_unregister() in a separate patch.
Thanks.
^ permalink raw reply
* Re: [PATCH 00/13] treewide: replace linux/gpio.h
From: Arnd Bergmann @ 2026-06-29 14:24 UTC (permalink / raw)
To: Andreas Schwab, Arnd Bergmann
Cc: open list:GPIO SUBSYSTEM, Bartosz Golaszewski, Andrew Lunn,
Sebastian Hesselbarth, Gregory Clement, Frank Li, Robert Jarzmik,
Krzysztof Kozlowski, Greg Ungerer, Thomas Bogendoerfer,
Hauke Mehrtens, Rafał Miłecki, Yoshinori Sato,
John Paul Adrian Glaubitz, Linus Walleij, Dmitry Torokhov,
Jakub Kicinski, Paolo Abeni, Dominik Brodowski, linux-kernel,
linux-arm-kernel, linux-samsung-soc, patches, linux-m68k,
linux-mips, linux-sh, linux-input, linux-media, Netdev,
linux-sunxi, linux-phy, linux-rockchip, linux-sound
In-Reply-To: <mvmik71win7.fsf@suse.de>
On Mon, Jun 29, 2026, at 16:01, Andreas Schwab wrote:
> On Jun 29 2026, Arnd Bergmann wrote:
>
>> From: Arnd Bergmann <arnd@arndb.de>
>>
>> The linux/gpio.h header used to be the global definition for the gpio
>> interfaces, with 1100 users back in linux-3.17. In linux-7.2, only about
>> 130 of those remain, so this series cleans out the rest.
>>
>> In each subsystem, we can replace the header either with
>> linux/gpio/consumer.h for users of the modern gpio descriptor interface,
>
> A few of them already used <linux/gpio/consumer.h>, and is duplicated
> now.
Indeed, I have removed the extra ones now and folded those into
the patches.
Arnd
diff --git a/drivers/gpib/gpio/gpib_bitbang.c b/drivers/gpib/gpio/gpib_bitbang.c
index 2e8d895db06a..34d14b94a0b8 100644
--- a/drivers/gpib/gpio/gpib_bitbang.c
+++ b/drivers/gpib/gpio/gpib_bitbang.c
@@ -64,7 +64,6 @@
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/machine.h>
-#include <linux/gpio/consumer.h>
#include <linux/irq.h>
static int sn7516x_used = 1, sn7516x;
diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c
index 98d0269a978f..8863b741d1a3 100644
--- a/drivers/input/keyboard/matrix_keypad.c
+++ b/drivers/input/keyboard/matrix_keypad.c
@@ -16,7 +16,6 @@
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/module.h>
-#include <linux/gpio/consumer.h>
#include <linux/input/matrix_keypad.h>
#include <linux/slab.h>
#include <linux/of.h>
diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c
index eb11bf2e9436..a6c984205123 100644
--- a/drivers/input/misc/soc_button_array.c
+++ b/drivers/input/misc/soc_button_array.c
@@ -15,7 +15,6 @@
#include <linux/dmi.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio_keys.h>
-#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
static bool use_low_level_irq;
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
index 88c5c52e0e38..5f5adc9c9e83 100644
--- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c
@@ -16,7 +16,6 @@
#include <linux/net_tstamp.h>
#include <linux/ptp_classify.h>
#include <linux/ptp_pch.h>
-#include <linux/gpio/consumer.h>
#define PCH_GBE_MAR_ENTRIES 16
#define PCH_GBE_SHORT_PKT 64
diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c
index a18263d5bb02..06151f207134 100644
--- a/drivers/net/phy/mdio_device.c
+++ b/drivers/net/phy/mdio_device.c
@@ -9,7 +9,6 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/gpio/consumer.h>
-#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
diff --git a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
index d9c06129ed23..171bf097a8b8 100644
--- a/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
+++ b/drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
@@ -4,7 +4,6 @@
#include <linux/delay.h>
#include <linux/extcon-provider.h>
#include <linux/gpio/consumer.h>
-#include <linux/gpio/consumer.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c
index 2233babc0078..1f5dba49ace4 100644
--- a/drivers/phy/ti/phy-j721e-wiz.c
+++ b/drivers/phy/ti/phy-j721e-wiz.c
@@ -12,7 +12,6 @@
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/gpio/consumer.h>
-#include <linux/gpio/consumer.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mfd/syscon.h>
diff --git a/include/linux/mfd/ti-lmu.h b/include/linux/mfd/ti-lmu.h
index 5040c7d1e1b9..2089ec5124e8 100644
--- a/include/linux/mfd/ti-lmu.h
+++ b/include/linux/mfd/ti-lmu.h
@@ -10,7 +10,6 @@
#ifndef __MFD_TI_LMU_H__
#define __MFD_TI_LMU_H__
-#include <linux/gpio/consumer.h>
#include <linux/notifier.h>
#include <linux/regmap.h>
#include <linux/gpio/consumer.h>
diff --git a/sound/soc/codecs/cs42l84.c b/sound/soc/codecs/cs42l84.c
index 36c3abc21fed..f2448b4c11fc 100644
--- a/sound/soc/codecs/cs42l84.c
+++ b/sound/soc/codecs/cs42l84.c
@@ -16,7 +16,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/i2c.h>
-#include <linux/gpio/consumer.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/acpi.h>
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index 8b05d6f9b429..cbed11136935 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -7,7 +7,6 @@
#include <linux/delay.h>
#include <linux/gpio/consumer.h>
-#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
^ permalink raw reply related
* Re: [PATCH net-next v10 1/5] hinic3: Add ethtool queue ops
From: Andrew Lunn @ 2026-06-29 14:25 UTC (permalink / raw)
To: Fan Gong
Cc: Wu Di, Teng Peisen, netdev, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Andrew Lunn,
Ioana Ciornei, Mohsin Bashir, Dimitri Daskalakis,
Harshitha Ramamurthy, linux-kernel, linux-doc, luosifu, Xin Guo,
Zhou Shuai, Wu Like, Shi Jing, Zheng Jiezhen, Maxime Chevallier
In-Reply-To: <3414df08001307c6d96c17ffc0921206c62f85a1.1782718232.git.wudi234@huawei.com>
> @@ -315,21 +315,28 @@ static void hinic3_link_status_change(struct net_device *netdev,
> {
> struct hinic3_nic_dev *nic_dev = netdev_priv(netdev);
>
> + if (!mutex_trylock(&nic_dev->state_lock))
> + return;
> +
> if (link_status_up) {
> if (netif_carrier_ok(netdev))
> - return;
> + goto err_unlock;
So ignoring a link status change, leaving the carrier set wrongly,
because some other thread has the mutex locked, is O.K? It would be
good to explain in the commit message why this is correct, because it
is not obvious.
Andrew
^ permalink raw reply
* Re: [PATCH v2] Wireguard: Fix data-race in rx/tx counter
From: Andrew Lunn @ 2026-06-29 14:51 UTC (permalink / raw)
To: Rafael Passos
Cc: andrew+netdev, tytso, Jason, davem, edumazet, kuba, linux-kernel,
netdev, pabeni, syzbot+9ca7674fa7521a3f1bc2, syzkaller-bugs,
wireguard
In-Reply-To: <20260629125913.2354450-1-rafael@rcpassos.me>
> When looking around drivers/net, I found a few u64_stats uses without
> per-cpu. I will do some digging to understand the reasoning behind it,
> compared to the original "bare u64 counters" in wireguard.
/*
* Protect against 64-bit values tearing on 32-bit architectures. This is
* typically used for statistics read/update in different subsystems.
The assumption is, updating a 64 bit value on a 64 bit machine is a
single operation. You either see the old value, or the new value. For
statistics counters, we general don't care about valid but slightly
outdated values.
On a 32 bit machine, updating a 64 bit value requires up to two reads
and two writes. So if a reader and a writer operate at the same time,
the reader might see one of the invalid intermediary states, also know
as tearing. We do care about a totally wrong value.
u64_stats_sync.h gives you a mechanism which is totally free on 64bit
systems, but gives the needed protection on 32 bit systems to avoid
seeing tears.
You only need mutual exclusion on the writer side, from other
writers. If you have per-cpu counters, you naturally get mutual
exclusion, the CPU cannot be a writer twice to its own per CPU
counters. However, without per-CPU counters, you need some form of
locking. I don't know the locking used in wireguard, it might already
be in place? If so, this would be a cheap solution.
Andrew
^ permalink raw reply
* Re: [PATCH v2] ptp: ocp: add I2C ISP support for ADVA TimeCard CPLD
From: Vadim Fedorenko @ 2026-06-29 14:53 UTC (permalink / raw)
To: Sagi Maimon, jonathan.lemon, richardcochran, andrew+netdev, davem,
edumazet, kuba, pabeni
Cc: linux-kernel, netdev
In-Reply-To: <20260628053840.4305-1-maimon.sagi@gmail.com>
On 28/06/2026 06:38, Sagi Maimon wrote:
> The ADVA TimeCard programs its on-board CPLD (Lattice MachXO3)
> via I2C using in-system programming (ISP).
>
> The CPLD resides on a secondary I2C bus controlled by the
> embedded MicroBlaze. To allow programming, the driver must
> take ownership of this bus and expose it to userspace.
>
> Add support to:
> - enable the i2c-dev interface to expose /dev/i2c-N
> - provide sysfs control over the secondary I2C bus
>
> Signed-off-by: Sagi Maimon <maimon.sagi@gmail.com>
> ---
> Address comments from:
> - Andrew Lunn: https://www.spinics.net/lists/netdev/msg1200997.html
I don't see anything regarding module_request() part.
It looks like you want to expose raw I2C access for user-space software
to do direct writes to the HW, which is not modeled as a device in
kernel. Exposure of /dev/i2c bus affects other Time Cards where we tried
to hide to avoid direct writes to EEPROM areas.
If you need some addresses of i2c bus to be accessible, it's better to
implement these accesses as sysfs or debugfs attributes and expose them
for ADVA cards.
^ permalink raw reply
* [ANN] net-next is OPEN
From: Jakub Kicinski @ 2026-06-29 14:59 UTC (permalink / raw)
To: netdev
Hi!
net-next is now open, and accepting v7.3 patches.
It will probably be quite bumpy in July with a lot of vacations
and netdev.conf along the way.
^ permalink raw reply
* Re: [PATCH net-next v11 1/7] dt-bindings: phy: document the serdes PHY on sa8255p
From: Geert Uytterhoeven @ 2026-06-29 14:51 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Maxime Coquelin, Alexandre Torgue,
Vinod Koul, Giuseppe Cavallaro, Chen-Yu Tsai, Jernej Skrabec,
Neil Armstrong, Kevin Hilman, Jerome Brunet, Shawn Guo,
Fabio Estevam, Jan Petrous, s32, Mohd Ayaan Anwar, Romain Gantois,
Magnus Damm, Maxime Ripard, Christophe Roullier, Radu Rendec,
linux-arm-msm, devicetree, linux-kernel, netdev, linux-stm32,
linux-arm-kernel, Drew Fustini, linux-sunxi, linux-amlogic,
linux-mips, imx, linux-renesas-soc, linux-rockchip, sophgo,
linux-riscv, Bartosz Golaszewski, Bartosz Golaszewski
In-Reply-To: <CAMRc=Me3jaZXiXa1sFXr=8Do4sCd+XN1pKTcWC8-0j78SjCkKA@mail.gmail.com>
Hi Bartosz,
On Mon, 29 Jun 2026 at 16:07, Bartosz Golaszewski <brgl@kernel.org> wrote:
> On Mon, 29 Jun 2026 15:51:31 +0200, Geert Uytterhoeven
> <geert@linux-m68k.org> said:
> > On Mon, 29 Jun 2026 at 13:29, Bartosz Golaszewski
> > <bartosz.golaszewski@oss.qualcomm.com> wrote:
> >> Describe the SGMII/SerDes PHY present on the Qualcomm sa8255p platforms.
> >> This is essentially the same hardware as sa8775p rev3 but the PHY is
> >> managed by firmware over SCMI.
> >
> > So why can't it be reuse the DT bindings, and be compatible with
> > qcom,sa8775p-dwmac-sgmii-phy?
> >
> >> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> >
> >> --- /dev/null
> >> +++ b/Documentation/devicetree/bindings/phy/qcom,sa8255p-dwmac-sgmii-phy.yaml
> >
> >> + power-domains:
> >> + maxItems: 1
> >> +
> >> + power-domain-names:
> >> + items:
> >> + - const: serdes
> >
> >> +examples:
> >> + - |
> >> + phy@8901000 {
> >> + compatible = "qcom,sa8255p-dwmac-sgmii-phy";
> >> + reg = <0x08901000 0xe10>;
> >> + #phy-cells = <0>;
> >> + power-domains = <&scmi7_dvfs 0>;
> >> + power-domain-names = "serdes";
> >
> > Ah, this uses power-domains, while the existing bindings for
> > qcom,sa8775p-dwmac-sgmii-phy use a clock.
> > I guess the clock is the correct hardware description?
> >
> > Adding to my list of examples for backing a hardware-to-SCMI remapping
> > driver...
> >
>
> Russell King asked me to put the PHY logic for SCMI pm domains into the PHY
> driver instead of the MAC driver where it was previously. Instead of cramming
> both HLOS and firmware handling into the same driver, I figured it makes more
> sense to have a dedicated, cleaner driver as the two share very little code (if
> any).
I think you are mixing up DT bindings and driver implementation?
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH bpf-next v5 1/3] bpf: Add BPF_FIB_LOOKUP_VLAN flag to bpf_fib_lookup() helper
From: Toke Høiland-Jørgensen @ 2026-06-29 15:08 UTC (permalink / raw)
To: David Ahern, Avinash Duduskar, ast, daniel, andrii
Cc: eddyz87, memxor, martin.lau, song, yonghong.song, jolsa, emil,
john.fastabend, sdf, davem, edumazet, kuba, pabeni, horms, shuah,
hawk, yatsenko, leon.hwang, kpsingh, a.s.protopopov, ameryhung,
rongtao, eyal.birger, bpf, netdev, linux-kernel, linux-kselftest
In-Reply-To: <d820adf6-4a33-45e9-9cfa-17f11a37c9e8@kernel.org>
David Ahern <dsahern@kernel.org> writes:
> On 6/23/26 9:05 PM, Avinash Duduskar wrote:
>> diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
>> index 89b36de5fdbb..e00f0392e728 100644
>> --- a/include/uapi/linux/bpf.h
>> +++ b/include/uapi/linux/bpf.h
>> @@ -3532,6 +3532,29 @@ union bpf_attr {
>> * Use the mark present in *params*->mark for the fib lookup.
>> * This option should not be used with BPF_FIB_LOOKUP_DIRECT,
>> * as it only has meaning for full lookups.
>> + * **BPF_FIB_LOOKUP_VLAN**
>
> This flag should not be needed. Patches for vlan support were never
> submitted (I have them in some old branch). Since the vlan params are
> initialized to 0, no new flag should be needed. Besides, these are
> output parameters.
There's no enforcement from the kernel side of the parameters being
zero, though? So we do need the flag for feature detection; unless we
expect applications to do that out of band? But then we'd need a
mechanism to do that which could be... the presence of the flag in the
ENUM (and thus in BTF)? :)
-Toke
^ permalink raw reply
* Re: [PATCH bpf-next v5 1/3] bpf: Add BPF_FIB_LOOKUP_VLAN flag to bpf_fib_lookup() helper
From: Toke Høiland-Jørgensen @ 2026-06-29 15:11 UTC (permalink / raw)
To: Avinash Duduskar, ast, daniel, andrii
Cc: eddyz87, memxor, martin.lau, song, yonghong.song, jolsa, emil,
john.fastabend, sdf, davem, edumazet, kuba, pabeni, horms, shuah,
hawk, yatsenko, leon.hwang, kpsingh, a.s.protopopov, ameryhung,
rongtao, eyal.birger, bpf, netdev, linux-kernel, linux-kselftest,
dsahern
In-Reply-To: <20260624115442.4112419-1-avinash.duduskar@gmail.com>
Avinash Duduskar <avinash.duduskar@gmail.com> writes:
>> > + if (flags & BPF_FIB_LOOKUP_VLAN)
>> > + return -EINVAL;
>> > +
>>
>> This is fine, but we should probably reject the input flag as well in
>> the next patch (for symmetry).
>
> I dug into this and I don't think the two are symmetric. The egress
> reject is right for exactly the reason you gave: in tc you can redirect
> to the VLAN device directly, so reducing the egress to the physical
> parent is only needed for XDP. But that is a transmit argument, and
> VLAN_INPUT never touches the egress or redirect side. It only sets the
> lookup's ingress (flowi_iif), which picks the iif policy rule and the VRF
> table, and there is no XDP-only constraint there for the symmetry to
> mirror.
>
> tc also has a real user for it. In __netif_receive_skb_core() the tcx
> ingress hook runs before vlan_do_receive() demuxes the frame, so a clsact
> program on the physical port sees a tagged frame with skb->dev still the
> physical device and the tag in skb->vlan_tci. That is exactly the
> physical-ifindex-plus-tag input VLAN_INPUT takes, and it wants the
> subinterface-scoped answer. The 2/3 selftest already runs the VLAN_INPUT
> cases on the tc path, including the VRF-table-selection ones, and they
> pass, so this isn't a theoretical tc path.
>
> So I would keep VLAN_INPUT allowed on both. If you would rather hold a
> uniform "both VLAN flags are XDP-only" line under the same
> restrict-now-relax-later rule as the TBID and OUTPUT combos, I will add
> the reject, but unlike the egress case it removes a working tc path
> rather than one tc cannot use. Happy either way, just let me know.
Hmm, OK, I'm fine with keeping it available for TC then.
-Toke
^ permalink raw reply
* Re: [PATCH net] netfilter: nf_nat_masquerade: recalculate TCP TS offset when port is randomized
From: Florian Westphal @ 2026-06-29 15:23 UTC (permalink / raw)
To: xietangxin
Cc: Pablo Neira Ayuso, Phil Sutter, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, gaoxingwang, huyizhen,
netfilter-devel, coreteam, netdev, linux-kernel, stable
In-Reply-To: <20260629093408.3927103-1-xietangxin@h-partners.com>
xietangxin <xietangxin@h-partners.com> wrote:
> Problem observed in Kubernetes environments where MASQUERADE target with
> --random-fully is configured by default. after commit
> 165573e41f2f ("tcp: secure_seq: add back ports to TS offset") TCP short
> connection QPS dropped from ~20000 to ~10000. This added source and
> destination ports into TS offset calculation.
>
> However, with MASQUERADE --random-fully, when multiple internal connections
> (e.g sport 10000,20000) are mapped to the same external port (e.g 30000),
> their TS offsets are calculated as ts_offset(10000) and ts_offset(20000).
> If the server reuses the TIME_WAIT slot from the first connection, there is
> a chance that ts_offset(20000) < ts_offset(10000), breaking TSval
> monotonicity for the same 4-tuple and causing RST packets:
> Client -> Server 24870 -> 80 [SYN] TSval=2294041168
> Server -> Client 80 -> 24870 [ACK] TSecr=2846236456
> Client -> Server 24870 -> 80 [RST] Seq=855605690
>
> After nf_nat_setup_info() successfully assigns a new randomized
> source port, recalculate the TS offset using the new port and
> update the SYN packet's TSval accordingly.
I don't think this is related to masquerade but to snat (port address
rewrite) in general.
I think you could place your new helper in nf_nat_core.c and call it
from nf_nat_l4proto_unique_tuple() once we've found a usable tuple:
668 another_round:
669 for (i = 0; i < attempts; i++, off++) {
670 *keyptr = htons(min + off % range_size);
671 if (!nf_nat_used_tuple_harder(tuple, ct, attempts - i))
... here.
672 return;
673 }
^ permalink raw reply
* [PATCH net-next v2 5/8] net: mdio: realtek-rtl9300: Add c45 over c22 mitigation
From: Markus Stockhausen @ 2026-06-29 15:23 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
In-Reply-To: <20260629152336.2239826-1-markus.stockhausen@gmx.de>
When reading the PHY state on c22 based buses the hardware polling unit
reads the EEE status with a sequence similar to this:
...
phy_write(phy, 31, 0x0);
phy_write(phy, 13, 0x7); /* c45 over c22 MDIO_AN_EEE_ADV */
phy_write(phy, 14, 0x3c);
phy_write(phy, 13, 0x8007);
phy_read(phy, 14);
phy_write(phy, 13, 0x7); /* c45 over c22 MDIO_AN_EEE_LPABLE */
phy_write(phy, 14, 0x3d);
phy_write(phy, 13, 0x8007);
...
If the Linux kernel wants to do the same in mmd_phy_read() via a call to
mmd_phy_indirect() this most likely fails. The commands are issued in a
straight sequence but between two of them the hardware polling might run
a status check for the same PHY. This effectively breaks the kernel access
and makes use of c45 over c22 unusable.
Detailed analysis shows that for RTL838x, RTL930x and RTL931x polling
can be safely deactivated during operation. The MAC layer will continue
to show the last known state. RTL839x is an exception from this. As soon
as polling is disabled the MAC link status register shows "port down".
Enhance the driver to detect this register 13/14/13/14 access sequence.
Before the first access to register 13 of a PHY disable polling for the
corresponding port. Reenable polling as soon as the sequence is finished
or any other unexpected input is detected. Some details about the stop
and start timing:
- The stopping is issued inflight while the polling engine is working.
After it is finished no new polling for the port will be issued (tested
with only one port with active polling).
- Reenabling the polling engine happens within ~25us after the last
command of the MMD sequence. This is mostly due to MMIO overhead.
Technically speaking, add a simple state machine that increments a
per-port MMD counter for each successful step of the sequence. When the
first command starts (counter=1) stop polling. When the last command
finishes (counter=4), errors happen or unexpected data is sent, start
polling.
Additionally add a global "link flapping" option that allows to disable
the state tracker for the to-be-added RTL839x series completely.
Remark! The priv->bus[] array already existed since the initial driver
version but was never filled. To make use of it in this patch add
the initialization too.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 54 +++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index a8e9a497a0dc..8b60645093e3 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -197,6 +197,7 @@ struct otto_emdio_priv {
DECLARE_BITMAP(phy_poll, MAX_PORTS);
DECLARE_BITMAP(valid_ports, MAX_PORTS);
u16 page[MAX_PORTS];
+ u8 mmd_state[MAX_PORTS];
u8 smi_bus[MAX_PORTS];
u8 smi_addr[MAX_PORTS];
bool smi_bus_is_c45[MAX_SMI_BUSSES];
@@ -210,6 +211,7 @@ struct otto_emdio_info {
u32 cmd_read;
u32 cmd_write;
struct otto_emdio_cmd_regs cmd_regs;
+ bool link_flap;
u8 num_buses;
u8 num_ports;
u16 num_pages;
@@ -259,6 +261,47 @@ static int otto_emdio_set_port_polling(struct otto_emdio_priv *priv, int port, b
BIT(port % 32), active);
}
+static int otto_emdio_mmd_prefix(struct otto_emdio_priv *priv, int port, int regnum)
+{
+ u8 newstate, *state = &priv->mmd_state[port];
+ int expected, ret = 0;
+
+ if (!test_bit(port, priv->phy_poll))
+ return 0;
+ /*
+ * Disabled polling might produce link flapping and false notification interrupts on the
+ * MAC layer. In this case disable c45 over c22 MMD access because chances are high that
+ * the register 13/14/13/14 sequence is intercepted by a parallel hardware access. As
+ * a workaround the PHY must provide its own mmd read/write() callbacks and redirect to
+ * normal c22 registers. See rtlgen_read_mmd().
+ */
+ if (priv->info->link_flap)
+ return (regnum == MII_MMD_DATA || regnum == MII_MMD_CTRL) ? -EIO : 0;
+
+ expected = (*state & 1) ? MII_MMD_DATA : MII_MMD_CTRL;
+ newstate = regnum == expected ? *state + 1 : 0;
+
+ if (newstate == 1 || newstate < *state)
+ ret = otto_emdio_set_port_polling(priv, port, !newstate);
+ *state = newstate;
+
+ return ret;
+}
+
+static void otto_emdio_mmd_postfix(struct otto_emdio_priv *priv, int port, int cmdret)
+{
+ struct mii_bus *bus = priv->bus[priv->smi_bus[port]];
+
+ if (!test_bit(port, priv->phy_poll))
+ return;
+
+ if (cmdret || priv->mmd_state[port] == 4) {
+ priv->mmd_state[port] = 0;
+ if (otto_emdio_set_port_polling(priv, port, true))
+ dev_err(bus->parent, "failed to enable polling for port %d\n", port);
+ }
+}
+
static int otto_emdio_run_cmd(struct mii_bus *bus, u32 cmd,
struct otto_emdio_cmd_regs *cmd_data)
{
@@ -465,10 +508,15 @@ static int otto_emdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
return port;
scoped_guard(mutex, &priv->lock) {
+ ret = otto_emdio_mmd_prefix(priv, port, regnum);
+ if (ret)
+ return ret;
+
if (regnum == 31)
return priv->page[port];
ret = priv->info->read_c22(bus, port, regnum, &value);
+ otto_emdio_mmd_postfix(priv, port, ret);
}
return ret ? ret : value;
@@ -484,6 +532,10 @@ static int otto_emdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u16
return port;
scoped_guard(mutex, &priv->lock) {
+ ret = otto_emdio_mmd_prefix(priv, port, regnum);
+ if (ret)
+ return ret;
+
if (regnum == 31) {
if (value >= RAW_PAGE(priv))
return -EINVAL;
@@ -493,6 +545,7 @@ static int otto_emdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u16
}
ret = priv->info->write_c22(bus, port, regnum, value);
+ otto_emdio_mmd_postfix(priv, port, ret);
}
return ret;
@@ -665,6 +718,7 @@ static int otto_emdio_probe_one(struct device *dev, struct otto_emdio_priv *priv
if (!bus)
return -ENOMEM;
+ priv->bus[mdio_bus] = bus;
bus->name = "Realtek Switch MDIO Bus";
if (priv->smi_bus_is_c45[mdio_bus]) {
bus->read_c45 = otto_emdio_read_c45;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v2 2/8] net: mdio: realtek-rtl9300: Add page tracking
From: Markus Stockhausen @ 2026-06-29 15:23 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
In-Reply-To: <20260629152336.2239826-1-markus.stockhausen@gmx.de>
The hardware polling unit of the Realtek switches has a very special
handling for PHY register 31 (aka Realtek page register) in place.
- On the RTL838x it is permanently reset to zero.
- On other devices there is some magic saving/restoring (aka parking)
in the background in place.
This makes access to PHYs a gamble.
As of now all known existing hardware designs have Realtek based 1G PHYs.
Otherwise the polling engine and the MAC status update will not work at
all and the vendor SDK would fail totally.
This driver differentiates clearly between c22 and c45 buses. During
probing it enables only one of the protocols for a bus. So it is safe
to assume that any c22 access will only target a Realtek based 1G PHY.
Intercept access to register 31 and store the desired value for each port
in the driver. When issuing access to other registers add the saved page.
This given, the hardware will run two consecutive c22 commands that are
not interrupted by polling.
... hardware poll ...
phy_write(phy, 31, page)
phy_write(phy, reg, value)
... hardware poll ...
Remark! To keep this simple, writes to register 31 are only accepted
if they are lower than the device specific raw page - 0..4094/8190.
Otherwise -EINVAL is returned. Under the above assumption (Only 1G
Realtek PHYs on c22 bus) this is no limitation.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 26 +++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 6ece095d7e97..616edcde15d9 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -193,6 +193,7 @@ struct otto_emdio_priv {
struct regmap *regmap;
struct mutex lock; /* protect HW access */
DECLARE_BITMAP(valid_ports, MAX_PORTS);
+ u16 page[MAX_PORTS];
u8 smi_bus[MAX_PORTS];
u8 smi_addr[MAX_PORTS];
bool smi_bus_is_c45[MAX_SMI_BUSSES];
@@ -337,7 +338,7 @@ static int otto_emdio_9300_read_c22(struct mii_bus *bus, int port, int regnum, u
struct otto_emdio_cmd_regs cmd_data = {
.c22_data = FIELD_PREP(RTL9300_PHY_CTRL_REG_ADDR, regnum) |
FIELD_PREP(RTL9300_PHY_CTRL_PARK_PAGE, 0x1f) |
- FIELD_PREP(RTL9300_PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv)),
+ FIELD_PREP(RTL9300_PHY_CTRL_MAIN_PAGE, priv->page[port]),
.io_data = FIELD_PREP(RTL9300_PHY_CTRL_INDATA, port),
};
@@ -351,7 +352,7 @@ static int otto_emdio_9300_write_c22(struct mii_bus *bus, int port, int regnum,
struct otto_emdio_cmd_regs cmd_data = {
.c22_data = FIELD_PREP(RTL9300_PHY_CTRL_REG_ADDR, regnum) |
FIELD_PREP(RTL9300_PHY_CTRL_PARK_PAGE, 0x1f) |
- FIELD_PREP(RTL9300_PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv)),
+ FIELD_PREP(RTL9300_PHY_CTRL_MAIN_PAGE, priv->page[port]),
.io_data = FIELD_PREP(RTL9300_PHY_CTRL_INDATA, value),
.port_mask_low = BIT(port),
};
@@ -391,7 +392,7 @@ static int otto_emdio_9310_read_c22(struct mii_bus *bus, int port, int regnum, u
struct otto_emdio_cmd_regs cmd_data = {
.broadcast = FIELD_PREP(RTL9310_BC_PORT_ID, port),
.c22_data = FIELD_PREP(RTL9310_PHY_CTRL_REG_ADDR, regnum) |
- FIELD_PREP(RTL9310_PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv)),
+ FIELD_PREP(RTL9310_PHY_CTRL_MAIN_PAGE, priv->page[port]),
};
return otto_emdio_read_cmd(bus, RTL9310_PHY_CTRL_TYPE_C22, &cmd_data,
@@ -403,7 +404,7 @@ static int otto_emdio_9310_write_c22(struct mii_bus *bus, int port, int regnum,
struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
struct otto_emdio_cmd_regs cmd_data = {
.c22_data = FIELD_PREP(RTL9310_PHY_CTRL_REG_ADDR, regnum) |
- FIELD_PREP(RTL9310_PHY_CTRL_MAIN_PAGE, RAW_PAGE(priv)),
+ FIELD_PREP(RTL9310_PHY_CTRL_MAIN_PAGE, priv->page[port]),
.io_data = FIELD_PREP(RTL9310_PHY_CTRL_INDATA, value),
.port_mask_high = (u32)(BIT_ULL(port) >> 32),
.port_mask_low = (u32)(BIT_ULL(port)),
@@ -449,8 +450,12 @@ static int otto_emdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
if (port < 0)
return port;
- scoped_guard(mutex, &priv->lock)
+ scoped_guard(mutex, &priv->lock) {
+ if (regnum == 31)
+ return priv->page[port];
+
ret = priv->info->read_c22(bus, port, regnum, &value);
+ }
return ret ? ret : value;
}
@@ -464,8 +469,17 @@ static int otto_emdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u16
if (port < 0)
return port;
- scoped_guard(mutex, &priv->lock)
+ scoped_guard(mutex, &priv->lock) {
+ if (regnum == 31) {
+ if (value >= RAW_PAGE(priv))
+ return -EINVAL;
+
+ priv->page[port] = value;
+ return 0;
+ }
+
ret = priv->info->write_c22(bus, port, regnum, value);
+ }
return ret;
}
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v2 1/8] net: mdio: realtek-rtl9300: Add polling documentation
From: Markus Stockhausen @ 2026-06-29 15:23 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
In-Reply-To: <20260629152336.2239826-1-markus.stockhausen@gmx.de>
Add a detailed explanation how the hardware polling unit in the
Realtek Otto switches works. This simplifies developing future
patches and reviewing them.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 66 +++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 892ed3780a65..6ece095d7e97 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -35,6 +35,72 @@
*
* The driver works out the mapping based on the MDIO bus described in device tree and phandles on
* the ethernet-ports property.
+ *
+ * The devices have a hardware polling unit that runs in the background without any CPU load. It
+ * constantly scans the MDIO bus and the attached PHYs and updates the MAC status registers.
+ *
+ * How does the polling work?
+ *
+ * Each device has a SMI_POLL_CTRL register. A per-port bitmask decides if the hardware polling of
+ * the associated bus/address is active or not. The hardware runs a tight loop over this and for
+ * each set polling bit it issues a status check for the PHY. Attaching a logic analyzer to the
+ * MDIO bus of an RTL8380 and RTL8393 gives the following commands (in kernel notation):
+ *
+ * RTL8380 RTL8393
+ * --------------------------- ---------------------------
+ * phy_write(phy, 31, 0x0); phy_read(phy, 0);
+ * phy_write(phy, 13, 0x7); phy_read(phy, 1);
+ * phy_write(phy, 14, 0x3c); phy_read(phy, 4);
+ * phy_write(phy, 13, 0x8007); phy_read(phy, 5);
+ * phy_read(phy, 14); phy_read(phy, 6);
+ * phy_write(phy, 13, 0x7); phy_read(phy, 9);
+ * phy_write(phy, 14, 0x3d); phy_read(phy, 10);
+ * phy_write(phy, 13, 0x8007); phy_read(phy, 15);
+ * phy_read(phy, 14); phy_write(phy, 13, 0x7);
+ * phy_read(phy, 9); phy_write(phy, 14, 0x3c);
+ * phy_read(phy, 10); phy_write(phy, 13, 0x4007);
+ * phy_read(phy, 15); phy_read(phy, 14);
+ * phy_read(phy, 0); phy_write(phy, 13, 0x7);
+ * phy_read(phy, 1); phy_write(phy, 14, 0x3d);
+ * phy_read(phy, 4); phy_write(phy, 13, 0x4007);
+ * phy_read(phy, 5); phy_read(phy, 14);
+ * phy_read(phy, 6);
+ *
+ * The c45 over c22 register 13/14 sequences read MDIO_AN_EEE_ADV and MDIO_AN_EEE_LPABLE. As soon
+ * as one PHY status is read, the polling engine goes over to the next PHY. Basically the bus is
+ * always busy and the MAC status is updated in real-time.
+ *
+ * How does MDIO access from kernel work?
+ *
+ * When issuing MDIO accesses via an MMIO based interface the final write to the command register
+ * sets a "run command now" bit. Between two polling sequences for different PHYs the hardware
+ * checks if a user command needs to run and sends it onto the bus. Afterwards it simply continues
+ * its polling work. Inspecting the command sequence for a paged read on the logic analyzer gives:
+ *
+ * RTL8380 RTL8393
+ * --------------------------- ---------------------------
+ * phy_write(phy, 31, page); phy_write(phy, 31, page);
+ * phy_write(phy, reg, value); phy_write(phy, reg, value);
+ * phy_write(phy, 31, 0);
+ *
+ * What does this mean?
+ *
+ * There are slight differences in polling and PHY access between the models but the challenge
+ * stays the same. On the one hand that greatly simplifies the MAC layer, on the other hand it
+ * has some implications for the kernel PHY subsystem.
+ *
+ * - Without the polling and a proper MAC status, some of the link handling features do not work.
+ * Especially an unpopulated MAC_LINK_STS register cancels operations to other MAC registers.
+ * - The Realtek page register 31 is magically modified in the background. On the RTL838x it is
+ * simply reset. Other devices have hardware mitigations for this in place.
+ * - A c45 over c22 kernel access sequence is most likely to fail because chances are high that
+ * the polling engine overwrites registers 13/14 in between.
+ * - PHY firmware loading can have issues. Especially if a PHY is designed to expect a clean
+ * sequence of registers and values without deviation.
+ * - An access to one PHY will need to wait for the next free slot of the polling engine.
+ *
+ * Conclusion: Kernel access to the PHYs must know and handle any interference that arises from
+ * the above described hardware polling.
*/
#include <linux/bitfield.h>
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v2 0/8] net: mdio: realtek-rtl9300: Add RTL83xx support
From: Markus Stockhausen @ 2026-06-29 15:23 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
The Realtek Otto switch platform consists of four different series
- RTL838x aka maple : 28 port 1G Switches
- RTL839x aka cypress : 52 port 1G Switches
- RTL930x aka longan : 28 port 1G/2.5G/10G Switches
- RTL931x aka mango : 56 port 1G/2.5G/10G Switches
While the MDIO hardware polling unit and its necessity for the MAC
layer was always well known, no detailed documentation was available.
For this series the MDIO bus was inspected with a logic analyzer for
a better understanding how polling and kernel access interact on the
bus. All this will be explained now in the driver comments.
This patch series adds support for the RTL83xx devices. For this
- Enhance device tree binding.
- Add special handling for limitations enforced by hardware polling.
These already have minor side effects on RTL93xx devices but are even
more critical for the RTL83xx hardware.
- Add RTL83xx coding.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
v1 -> v2:
- The polling activation logic was refactored. V1 simply activated
polling after bus probing. Now a dedicated phydev/bus callback
takes care of this and also handles deferred PHY probing. (Sashiko)
- Run MMD prefix helper before register 31 (aka Realtek page register)
handling. (Jakub's bot)
- Always run MMD postfix - even if the c22 register access fails. This
ensures that the MMD state machine stays consistent. Adapt the error
handling inside the postfix function to not overwrite the real MDIO
return code (Sashiko, Jakub's bot)
- Drop unused RTL8390_PHY_CTRL_PARK_PAGE define. Like on RTL931x this
field must not be set and thus can be ignored. (Sashiko)
- Change title in device tree documentation. Because of this do NOT
add the Reviewed-by of Krzysztof. (Jakub's bot)
- Fix wrong use of RTL839x in commit message of patch "c45 over c22
mitigation". RTL930x was wrongly named RTL839x in the list of good
devices. (Markus)
- Fix typos (e.g. c22 over c45) in polling documentation (Jakub's bot)
v1: https://lore.kernel.org/netdev/20260613112946.1071411-1-markus.stockhausen@gmx.de/
v1 Sashiko review: https://sashiko.dev/#/patchset/20260613112946.1071411-1-markus.stockhausen@gmx.de
Daniel Golle (1):
net: phy: add (*notify_phy_attach/detach)() hooks to struct mii_bus
Markus Stockhausen (7):
net: mdio: realtek-rtl9300: Add polling documentation
net: mdio: realtek-rtl9300: Add page tracking
net: mdio: realtek-rtl9300: Configure hardware polling during probing
net: mdio: realtek-rtl9300: Add c45 over c22 mitigation
net: mdio: realtek-rtl9300: Increase MDIO timeout
net: mdio: realtek-rtl9300: Add support for RTL838x
net: mdio: realtek-rtl9300: Add support for RTL839x
drivers/net/mdio/mdio-realtek-rtl9300.c | 450 +++++++++++++++++++++++-
drivers/net/phy/phy_device.c | 9 +
include/linux/phy.h | 4 +
3 files changed, 454 insertions(+), 9 deletions(-)
--
2.54.0
^ permalink raw reply
* [PATCH net-next v2 8/8] net: mdio: realtek-rtl9300: Add support for RTL839x
From: Markus Stockhausen @ 2026-06-29 15:23 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
In-Reply-To: <20260629152336.2239826-1-markus.stockhausen@gmx.de>
The MDIO driver has been prepared for multiple device support. Add all
required bits for the RTL839x (aka cypress) series. This is straightforward
but some things are worth mentioning.
- The device has a lot in common with the RTL931x series. 8192 (Realtek)
pages and 7 MMIO registers
- There are two SMI buses for 1G PHYs. Neither the bus nor address map
registers exist.
- The MAC layer shows link flapping when temporarily deactivating the
hardware polling for one port. Mark this in the info structure.
- The hardware has not much to configure. So the setup_controller()
function is not needed.
- c22 read/write functions must be called with PARK_PAGE = 0. Keep code
clean and avoid setting it to zero, matching the behavior of the RTL9310
logic.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 103 ++++++++++++++++++++++++
1 file changed, 103 insertions(+)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 24a281b46526..6a65a6b0f122 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -139,6 +139,28 @@
#define RTL8380_SMI_POLL_CTRL 0xa17c
#define RTL8380_SMI_PORT0_5_ADDR_CTRL 0xa1c8
+#define RTL8390_NUM_BUSES 2
+#define RTL8390_NUM_PAGES 8192
+#define RTL8390_NUM_PORTS 52
+#define RTL8390_BCAST_PHYID_CTRL 0x03ec
+#define RTL8390_PHYREG_ACCESS_CTRL 0x03dc
+#define RTL8390_PHY_CTRL_REG_ADDR GENMASK(9, 5)
+#define RTL8390_PHY_CTRL_MAIN_PAGE GENMASK(22, 10)
+#define RTL8390_PHY_CTRL_FAIL BIT(1)
+#define RTL8390_PHY_CTRL_WRITE BIT(3)
+#define RTL8390_PHY_CTRL_READ 0
+#define RTL8390_PHY_CTRL_TYPE_C45 BIT(2)
+#define RTL8390_PHY_CTRL_TYPE_C22 0
+#define RTL8390_PHYREG_CTRL 0x03e0
+#define RTL8390_PHY_CTRL_EXT_PAGE GENMASK(8, 0)
+#define RTL8390_PHYREG_DATA_CTRL 0x03f0
+#define RTL8390_PHY_CTRL_INDATA GENMASK(31, 16)
+#define RTL8390_PHY_CTRL_DATA GENMASK(15, 0)
+#define RTL8390_PHYREG_MMD_CTRL 0x03f4
+#define RTL8390_PHYREG_PORT_CTRL_LOW 0x03e4
+#define RTL8390_PHYREG_PORT_CTRL_HIGH 0x03e8
+#define RTL8390_SMI_PORT_POLLING_CTRL 0x03fc
+
#define RTL9300_NUM_BUSES 4
#define RTL9300_NUM_PAGES 4096
#define RTL9300_NUM_PORTS 28
@@ -465,6 +487,62 @@ static int otto_emdio_8380_write_c45(struct mii_bus *bus, int port,
return otto_emdio_write_cmd(bus, RTL8380_PHY_CTRL_TYPE_C45, &cmd_data);
}
+static int otto_emdio_8390_read_c22(struct mii_bus *bus, int port, int regnum, u32 *value)
+{
+ struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
+ struct otto_emdio_cmd_regs cmd_data = {
+ .c22_data = FIELD_PREP(RTL8390_PHY_CTRL_REG_ADDR, regnum) |
+ FIELD_PREP(RTL8390_PHY_CTRL_MAIN_PAGE, priv->page[port]),
+ .ext_page = FIELD_PREP(RTL8390_PHY_CTRL_EXT_PAGE, 0x1ff),
+ .io_data = FIELD_PREP(RTL8390_PHY_CTRL_INDATA, port),
+ };
+
+ return otto_emdio_read_cmd(bus, RTL8390_PHY_CTRL_TYPE_C22, &cmd_data,
+ RTL8390_PHY_CTRL_DATA, value);
+}
+
+static int otto_emdio_8390_write_c22(struct mii_bus *bus, int port, int regnum, u16 value)
+{
+ struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
+ struct otto_emdio_cmd_regs cmd_data = {
+ .c22_data = FIELD_PREP(RTL8390_PHY_CTRL_REG_ADDR, regnum) |
+ FIELD_PREP(RTL8390_PHY_CTRL_MAIN_PAGE, priv->page[port]),
+ .ext_page = FIELD_PREP(RTL8390_PHY_CTRL_EXT_PAGE, 0x1ff),
+ .io_data = FIELD_PREP(RTL8390_PHY_CTRL_INDATA, value),
+ .port_mask_high = (u32)(BIT_ULL(port) >> 32),
+ .port_mask_low = (u32)(BIT_ULL(port)),
+ };
+
+ return otto_emdio_write_cmd(bus, RTL8390_PHY_CTRL_TYPE_C22, &cmd_data);
+}
+
+static int otto_emdio_8390_read_c45(struct mii_bus *bus, int port,
+ int dev_addr, int regnum, u32 *value)
+{
+ struct otto_emdio_cmd_regs cmd_data = {
+ .c45_data = FIELD_PREP(PHY_CTRL_MMD_DEVAD, dev_addr) |
+ FIELD_PREP(PHY_CTRL_MMD_REG, regnum),
+ .io_data = FIELD_PREP(RTL8390_PHY_CTRL_INDATA, port),
+ };
+
+ return otto_emdio_read_cmd(bus, RTL8390_PHY_CTRL_TYPE_C45, &cmd_data,
+ RTL8390_PHY_CTRL_DATA, value);
+}
+
+static int otto_emdio_8390_write_c45(struct mii_bus *bus, int port,
+ int dev_addr, int regnum, u16 value)
+{
+ struct otto_emdio_cmd_regs cmd_data = {
+ .c45_data = FIELD_PREP(PHY_CTRL_MMD_DEVAD, dev_addr) |
+ FIELD_PREP(PHY_CTRL_MMD_REG, regnum),
+ .io_data = FIELD_PREP(RTL8390_PHY_CTRL_INDATA, value),
+ .port_mask_high = (u32)(BIT_ULL(port) >> 32),
+ .port_mask_low = (u32)(BIT_ULL(port)),
+ };
+
+ return otto_emdio_write_cmd(bus, RTL8390_PHY_CTRL_TYPE_C45, &cmd_data);
+}
+
static int otto_emdio_9300_read_c22(struct mii_bus *bus, int port, int regnum, u32 *value)
{
struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
@@ -1023,6 +1101,30 @@ static const struct otto_emdio_info otto_emdio_8380_info = {
.write_c45 = otto_emdio_8380_write_c45,
};
+static const struct otto_emdio_info otto_emdio_8390_info = {
+ .cmd_fail = RTL8390_PHY_CTRL_FAIL,
+ .cmd_read = RTL8390_PHY_CTRL_READ,
+ .cmd_write = RTL8390_PHY_CTRL_WRITE,
+ .cmd_regs = {
+ .broadcast = RTL8390_BCAST_PHYID_CTRL,
+ .c22_data = RTL8390_PHYREG_ACCESS_CTRL,
+ .c45_data = RTL8390_PHYREG_MMD_CTRL,
+ .ext_page = RTL8390_PHYREG_CTRL,
+ .io_data = RTL8390_PHYREG_DATA_CTRL,
+ .port_mask_low = RTL8390_PHYREG_PORT_CTRL_LOW,
+ .port_mask_high = RTL8390_PHYREG_PORT_CTRL_HIGH,
+ },
+ .link_flap = true,
+ .num_buses = RTL8390_NUM_BUSES,
+ .num_pages = RTL8390_NUM_PAGES,
+ .num_ports = RTL8390_NUM_PORTS,
+ .poll_ctrl = RTL8390_SMI_PORT_POLLING_CTRL,
+ .read_c22 = otto_emdio_8390_read_c22,
+ .read_c45 = otto_emdio_8390_read_c45,
+ .write_c22 = otto_emdio_8390_write_c22,
+ .write_c45 = otto_emdio_8390_write_c45,
+};
+
static const struct otto_emdio_info otto_emdio_9300_info = {
.addr_map_base = RTL9300_SMI_PORT0_5_ADDR_CTRL,
.bus_map_base = RTL9300_SMI_PORT0_15_POLLING_SEL,
@@ -1074,6 +1176,7 @@ static const struct otto_emdio_info otto_emdio_9310_info = {
static const struct of_device_id otto_emdio_ids[] = {
{ .compatible = "realtek,rtl8380-mdio", .data = &otto_emdio_8380_info },
+ { .compatible = "realtek,rtl8391-mdio", .data = &otto_emdio_8390_info },
{ .compatible = "realtek,rtl9301-mdio", .data = &otto_emdio_9300_info },
{ .compatible = "realtek,rtl9311-mdio", .data = &otto_emdio_9310_info },
{}
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v2 6/8] net: mdio: realtek-rtl9300: Increase MDIO timeout
From: Markus Stockhausen @ 2026-06-29 15:23 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
In-Reply-To: <20260629152336.2239826-1-markus.stockhausen@gmx.de>
RTL838x devices with 28 ports produce PHY access timeout errors during
one of three boots while waiting for MDIO command completion. This is
currently set to 1ms.
Background: Access to the Realtek Otto ethernet MDIO bus must wait for
a free slot between two hardware polls. The polling sequence consists
of at least 17 commands on the RTL838x devices. This delay can be nicely
seen when disabling polling completely. The following times are measured
on a bus running on the default 2.5MHz. Time measured is from the last
register write that sets the command-start-bit until the hardware
responds with the command-finished-bit set.
- average c22 read with polling enabled on all ports: ~380us
- average c22 read with polling enabled on one port: ~380us
- average c22 read with polling completely disabled: ~180us
For this bus frequency the bare hardware runtime for a single command
(32 bit preamble + 32 bit data) is ~25us. So the hardware adds quite
some overhead. On top of this comes the fact that the RTL838x devices
are low on resources (500Mhz 4Kec core with 16K cache).
Increase the timeout to 10ms to be on the safe side.
Remark! In a future patch the bus clock frequency will be made
configurable with a minimum frequency of 1.25MHz. Setting this
(e.g. for debugging purposes) doubles the command run times but
will safely stay below 10ms.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 8b60645093e3..206f4e85b82d 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -310,9 +310,9 @@ static int otto_emdio_run_cmd(struct mii_bus *bus, u32 cmd,
u32 cmdstate;
int ret;
- /* Defensive pre check just in case something goes horrible wrong */
+ /* Defensive pre check just in case something goes horribly wrong */
ret = regmap_read_poll_timeout(priv->regmap, info->cmd_regs.c22_data,
- cmdstate, !(cmdstate & PHY_CTRL_CMD), 10, 1000);
+ cmdstate, !(cmdstate & PHY_CTRL_CMD), 10, 10000);
if (ret)
return ret;
@@ -352,7 +352,7 @@ static int otto_emdio_run_cmd(struct mii_bus *bus, u32 cmd,
return ret;
ret = regmap_read_poll_timeout(priv->regmap, info->cmd_regs.c22_data,
- cmdstate, !(cmdstate & PHY_CTRL_CMD), 10, 1000);
+ cmdstate, !(cmdstate & PHY_CTRL_CMD), 10, 10000);
if (ret)
return ret;
--
2.54.0
^ permalink raw reply related
* [PATCH net-next v2 7/8] net: mdio: realtek-rtl9300: Add support for RTL838x
From: Markus Stockhausen @ 2026-06-29 15:23 UTC (permalink / raw)
To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
chris.packham, daniel, robh, krzk+dt, conor+dt, devicetree
Cc: Markus Stockhausen
In-Reply-To: <20260629152336.2239826-1-markus.stockhausen@gmx.de>
The MDIO driver has been prepared for multiple device support. Add all
required bits for the RTL838x (aka maple) series. This is straightforward
but some things are worth mentioning.
- The device has a lot in common with the RTL930x series. 28 ports, 4096
(Realtek) pages, 4 MMIO registers
- The MDIO engine has no fail bit. Thus the mask is set to zero
- There is only one SMI bus for 1G PHYs. No bus_map_base register exists.
- The setup_controller() function needs no c45 setup but must activate
the PHY access.
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
drivers/net/mdio/mdio-realtek-rtl9300.c | 108 ++++++++++++++++++++++++
1 file changed, 108 insertions(+)
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 206f4e85b82d..24a281b46526 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -117,6 +117,28 @@
#include <linux/property.h>
#include <linux/regmap.h>
+#define RTL8380_NUM_BUSES 1
+#define RTL8380_NUM_PAGES 4096
+#define RTL8380_NUM_PORTS 28
+#define RTL8380_SMI_GLB_CTRL 0xa100
+#define RTL8380_SMI_PHY_PATCH_DONE BIT(15)
+#define RTL8380_SMI_ACCESS_PHY_CTRL_0 0xa1b8
+#define RTL8380_SMI_ACCESS_PHY_CTRL_1 0xa1bc
+#define RTL8380_PHY_CTRL_REG_ADDR GENMASK(24, 20)
+#define RTL8380_PHY_CTRL_PARK_PAGE GENMASK(19, 15)
+#define RTL8380_PHY_CTRL_MAIN_PAGE GENMASK(14, 3)
+#define RTL8380_PHY_CTRL_WRITE BIT(2)
+#define RTL8380_PHY_CTRL_READ 0
+#define RTL8380_PHY_CTRL_TYPE_C45 BIT(1)
+#define RTL8380_PHY_CTRL_TYPE_C22 0
+#define RTL8380_PHY_CTRL_FAIL 0 /* no fail indicator */
+#define RTL8380_SMI_ACCESS_PHY_CTRL_2 0xa1c0
+#define RTL8380_PHY_CTRL_INDATA GENMASK(31, 16)
+#define RTL8380_PHY_CTRL_DATA GENMASK(15, 0)
+#define RTL8380_SMI_ACCESS_PHY_CTRL_3 0xa1c4
+#define RTL8380_SMI_POLL_CTRL 0xa17c
+#define RTL8380_SMI_PORT0_5_ADDR_CTRL 0xa1c8
+
#define RTL9300_NUM_BUSES 4
#define RTL9300_NUM_PAGES 4096
#define RTL9300_NUM_PORTS 28
@@ -389,6 +411,60 @@ static int otto_emdio_write_cmd(struct mii_bus *bus, u32 cmd,
return otto_emdio_run_cmd(bus, cmd | priv->info->cmd_write, cmd_data);
}
+static int otto_emdio_8380_read_c22(struct mii_bus *bus, int port, int regnum, u32 *value)
+{
+ struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
+ struct otto_emdio_cmd_regs cmd_data = {
+ .c22_data = FIELD_PREP(RTL8380_PHY_CTRL_REG_ADDR, regnum) |
+ FIELD_PREP(RTL8380_PHY_CTRL_PARK_PAGE, 0x1f) |
+ FIELD_PREP(RTL8380_PHY_CTRL_MAIN_PAGE, priv->page[port]),
+ .io_data = FIELD_PREP(RTL8380_PHY_CTRL_INDATA, port),
+ };
+
+ return otto_emdio_read_cmd(bus, RTL8380_PHY_CTRL_TYPE_C22, &cmd_data,
+ RTL8380_PHY_CTRL_DATA, value);
+}
+
+static int otto_emdio_8380_write_c22(struct mii_bus *bus, int port, int regnum, u16 value)
+{
+ struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
+ struct otto_emdio_cmd_regs cmd_data = {
+ .c22_data = FIELD_PREP(RTL8380_PHY_CTRL_REG_ADDR, regnum) |
+ FIELD_PREP(RTL8380_PHY_CTRL_PARK_PAGE, 0x1f) |
+ FIELD_PREP(RTL8380_PHY_CTRL_MAIN_PAGE, priv->page[port]),
+ .io_data = FIELD_PREP(RTL8380_PHY_CTRL_INDATA, value),
+ .port_mask_low = BIT(port),
+ };
+
+ return otto_emdio_write_cmd(bus, RTL8380_PHY_CTRL_TYPE_C22, &cmd_data);
+}
+
+static int otto_emdio_8380_read_c45(struct mii_bus *bus, int port,
+ int dev_addr, int regnum, u32 *value)
+{
+ struct otto_emdio_cmd_regs cmd_data = {
+ .c45_data = FIELD_PREP(PHY_CTRL_MMD_DEVAD, dev_addr) |
+ FIELD_PREP(PHY_CTRL_MMD_REG, regnum),
+ .io_data = FIELD_PREP(RTL8380_PHY_CTRL_INDATA, port),
+ };
+
+ return otto_emdio_read_cmd(bus, RTL8380_PHY_CTRL_TYPE_C45, &cmd_data,
+ RTL8380_PHY_CTRL_DATA, value);
+}
+
+static int otto_emdio_8380_write_c45(struct mii_bus *bus, int port,
+ int dev_addr, int regnum, u16 value)
+{
+ struct otto_emdio_cmd_regs cmd_data = {
+ .c45_data = FIELD_PREP(PHY_CTRL_MMD_DEVAD, dev_addr) |
+ FIELD_PREP(PHY_CTRL_MMD_REG, regnum),
+ .io_data = FIELD_PREP(RTL8380_PHY_CTRL_INDATA, value),
+ .port_mask_low = BIT(port),
+ };
+
+ return otto_emdio_write_cmd(bus, RTL8380_PHY_CTRL_TYPE_C45, &cmd_data);
+}
+
static int otto_emdio_9300_read_c22(struct mii_bus *bus, int port, int regnum, u32 *value)
{
struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
@@ -619,6 +695,15 @@ static int otto_emdio_setup_topology(struct otto_emdio_priv *priv)
return 0;
}
+static int otto_emdio_8380_setup_controller(struct otto_emdio_priv *priv)
+{
+ /*
+ * PHY_PATCH_DONE enables PHY control via SoC. This is required for PHY access, including
+ * patching and must be set before the PHYs are probed.
+ */
+ return regmap_set_bits(priv->regmap, RTL8380_SMI_GLB_CTRL, RTL8380_SMI_PHY_PATCH_DONE);
+}
+
static int otto_emdio_9300_setup_controller(struct otto_emdio_priv *priv)
{
u32 glb_ctrl_mask = 0, glb_ctrl_val = 0;
@@ -916,6 +1001,28 @@ static int otto_emdio_probe(struct platform_device *pdev)
return 0;
}
+static const struct otto_emdio_info otto_emdio_8380_info = {
+ .addr_map_base = RTL8380_SMI_PORT0_5_ADDR_CTRL,
+ .cmd_fail = RTL8380_PHY_CTRL_FAIL,
+ .cmd_read = RTL8380_PHY_CTRL_READ,
+ .cmd_write = RTL8380_PHY_CTRL_WRITE,
+ .cmd_regs = {
+ .c22_data = RTL8380_SMI_ACCESS_PHY_CTRL_1,
+ .c45_data = RTL8380_SMI_ACCESS_PHY_CTRL_3,
+ .io_data = RTL8380_SMI_ACCESS_PHY_CTRL_2,
+ .port_mask_low = RTL8380_SMI_ACCESS_PHY_CTRL_0,
+ },
+ .num_buses = RTL8380_NUM_BUSES,
+ .num_pages = RTL8380_NUM_PAGES,
+ .num_ports = RTL8380_NUM_PORTS,
+ .poll_ctrl = RTL8380_SMI_POLL_CTRL,
+ .setup_controller = otto_emdio_8380_setup_controller,
+ .read_c22 = otto_emdio_8380_read_c22,
+ .read_c45 = otto_emdio_8380_read_c45,
+ .write_c22 = otto_emdio_8380_write_c22,
+ .write_c45 = otto_emdio_8380_write_c45,
+};
+
static const struct otto_emdio_info otto_emdio_9300_info = {
.addr_map_base = RTL9300_SMI_PORT0_5_ADDR_CTRL,
.bus_map_base = RTL9300_SMI_PORT0_15_POLLING_SEL,
@@ -966,6 +1073,7 @@ static const struct otto_emdio_info otto_emdio_9310_info = {
};
static const struct of_device_id otto_emdio_ids[] = {
+ { .compatible = "realtek,rtl8380-mdio", .data = &otto_emdio_8380_info },
{ .compatible = "realtek,rtl9301-mdio", .data = &otto_emdio_9300_info },
{ .compatible = "realtek,rtl9311-mdio", .data = &otto_emdio_9310_info },
{}
--
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