* Re: [PATCH net-next v12 12/12] net: airoha: add phylink support [not found] <6a79e6fa.332d3c56.21a33c.b60f@mx.google.com> @ 2026-08-10 15:14 ` win847 0 siblings, 0 replies; 5+ messages in thread From: win847 @ 2026-08-10 15:14 UTC (permalink / raw) To: Christian Marangi; +Cc: netdev On Mon, Aug 10, 2026 at 10:57:59PM +0800, Christian Marangi wrote: > If you are ok, I can integrate the change in the next revision. Thanks Christian, please go ahead and integrate it in the next revision. Either the `goto err_phy_stop` unwind or moving `phylink_start()` after the GDM VIP configuration so fewer error exits need teardown works for me — whichever you find cleaner. Happy to review the diff when you post v13. Best regards, Wayen ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net-next v12 00/12] net: pcs: Introduce support for fwnode PCS
@ 2026-08-09 20:30 Christian Marangi
2026-08-09 20:31 ` [PATCH net-next v12 12/12] net: airoha: add phylink support Christian Marangi
0 siblings, 1 reply; 5+ messages in thread
From: Christian Marangi @ 2026-08-09 20:30 UTC (permalink / raw)
To: Maxime Chevallier, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Simon Horman, Jonathan Corbet, Shuah Khan,
Christian Marangi, Lorenzo Bianconi, Heiner Kallweit,
Russell King, Philipp Zabel, Nathan Chancellor, Nick Desaulniers,
Bill Wendling, Justin Stitt, netdev, devicetree, linux-kernel,
linux-doc, linux-arm-kernel, linux-mediatek, llvm
This series introduce a most awaited feature that is correctly
provide PCS with fwnode without having to use specific export symbol
and additional handling of PCS in phylink.
At times there were 2 different implementation (this and the one
from Sean) but Sean agreed that this can be picked and used in favor
of his implementation as long as his case with race condition is
correctly handled.
---
First the PCS fwnode:
The concept is to implement a producer-consumer API similar to other
subsystem like clock or PHY.
That seems to be the best solution to the problem as PCS driver needs
to be detached from phylink and implement a simple way to provide a
PCS while maintaining support for probe defer or driver removal.
To keep the implementation simple, the PCS driver devs needs some
collaboration to correctly implement this. This is O.K. as helper
to correctly implement this are provided hence it's really a matter
of following a pattern to correct follow removal of a PCS driver.
A PCS provider have to implement and call fwnode_pcs_add_provider() in
probe function and define an xlate function to define how the PCS
should be provided based on the requested interface and phandle spec
defined in fwnode (based on the #pcs-cells)
fwnode_pcs_get() is provided to provide a specific PCS declared in
fwnode at index.
A simple xlate function is provided for simple single PCS
implementation, fwnode_pcs_simple_xlate.
A PCS provider on driver removal must call fwnode_pcs_del_provider()
to delete itself as a provider.
---
Second PCS handling in phylink:
We have the PCS problem for the only reason that in initial
implementation, we permitted way too much flexibility to MAC driver
and things started to deviate. At times we couldn't think SoC
would start to put PCS outside the MAC hence it was OK to assume
they would live in the same driver. With the introduction of
10g in more consumer devices, we are observing a rapid growth
of this pattern with multiple PCS external to MAC.
To put a stop on this, the only solution is to give back to phylink
control on PCS handling and enforce more robust supported interface
definition from both MAC and PCS side.
It's suggested to read patch 0003 of this series for more info, here
a brief explaination of the idea:
This series introduce handling of PCS in phylink and try to deprecate
.mac_select_pcs.
Phylink now might contain a linked list of available PCS and
those will be used for PCS selection on phylink_major_config.
MAC driver needs to define pcs_interfaces mask in phylink_config
for every interface that needs a dedicated PCS.
These PCS needs to be provided to phylink at phylink_create time
by setting the .fill_available_pcs and .num_possible_pcs in phylink_config.
Helpers to parse PCS from fwnode are provided
fwnode_phylink_pcs_count() that will return the count of PCS entries
described in the firmware node and fwnode_phylink_pcs_parse() that will
fill a preallocated array of PCS pointer with the actual available PCS
(ignoring the one that still needs to be probed).
phylink_create() will fill the internal PCS list with the passed
array of PCS. phylink_major_config and other user of .mac_select_pcs
are adapted to make use of this new PCS list.
The supported interface value is also moved internally to phylink
struct. This is to handle late removal and addition of PCS.
(the bonus effect to this is giving phylink a clear idea of what
is actually supported by the MAC and his constraint with PCS)
The supported interface mask in phylink is done by OR the
supported_interfaces in phylink_config with every PCS in PCS list.
PCS removal is supported by forcing a mac_config, refresh the
supported interfaces and run a phy_resolve().
PCS late addition is supported by introducing a global notifier
for PCS provider. If a phylink have the pcs_interfaces mask not
zero, it's registered to this notifier.
PCS provider will emit a global PCS add event to signal any
interface that a new PCS might be available.
The function will then check if the PCS is related to the MAC
fwnode and add it accordingly.
A user for this new implementation is provided as an Airoha PCS
driver. This was also tested downstream with the IPQ95xx QCOM SoC
and with the help of Daniel also on the various Mediatek MT7988
SoC with both SFP cage implementation and DSA attached.
Lots of tests were done with driver unbind/bind and with interface
up/down also by adding print to make sure major_config_fail gets
correctly triggered and reset once the PCS comes back.
The dedicated commits have longer description on the implementation
so it's suggested to also check there for additional info.
It's worth to mention that OpenWrt is currently using this on
Mediatek SoC and QCOM ipq807x/ipq60xx/ipq50xx and Airoha are
already ported in staging tree for testing.
---
Changes v12:
- Fix kdoc for function
- Rework PCS provider add and delete to be provider driven (instead of
relaying on scan of fwnode every time) (this also handle
multi PCS scenario)
- Even further rework state mutex locking for concurrent pcs list
- Restore MAC supported_interfaces validation in phylink_create()
wrongly dropped.
- Use get/put for fwnode reference
- Fix possible unment depndency for FWNODE_PCS
- Fix almost impossible problem for PCS calibration
- Hold rtnl with PCS deletion
Changes v11:
- Rework PCS release to notifier way (fix race as pointed out by bot)
- Add Ack from Lorenzo for Airoha Ethernet driver
- Introduce devm variant for pcs_provider_add
- Better support firmware node reference for PCS late attach
- Better protect list iteration with state mutex
- Minor fixup to airoha pcs driver (flow control fixup)
- Rebase on top of net-next
Changes v10:
- Minor code cleanup and fixes as suggested by bot
- Drop devlink patch
- Add reviewed by tag
- Configure old_link_state on PCS release
- Unlink PCS on error in phylink_create()
- Use list_add_tail
- Fix typo in Airoha PCS driver
- Update phylink migration guide
- Better handle late PCS attach (idempotent function and
add unser state_mutex)
- Use dedicated lock in Airoha ethernet driver
Changes v9:
- Rebase on top of net-next/main
- Drop early verification of supported_interface
(it can also be provided by get_capabilites MAC OP)
Changes v8:
- Back to RFC (net-next closed)
- Address additional bug reported by Sashiko bot
- Better handle priv interface for Airoha PCS driver
- Better handle locking for modifying the PCS list in
phylink code
- Improve fwnode_phylink_pcs_parse() parsing on -ENOENT
- Better handle error condition in phylink_create()
- Turn down the link when current PCS is released
- Fix compilation warning caused by copy paste error
Changes v7:
- Address all the bug from the Sashiko bot
- Rename .num_available_pcs to .num_possible_pcs
- Link PCS in phylink_create()
- Correctly unregister the notifier on phylink_destroy()
- Introduce fwnode_phylink_pcs_count()
- Better handle locking in phylink for PCS handling
- Better handle unavailable PCS at phylink_create() time
- Improve Documentation file
- Other minor fixes to address suggestion from bot
- Rebase on top of net-next
Changes v6:
- Rebase on top of net-next
- Add Documentation files
- Add fw_devlink patch
- Fix some comments typo
- Rework the airoha_eth.c implementation with new multi serdes code
- Extend PCS code with PCIe and USB support
- Align schema to new property
Changes v5:
- Rebase on top of net-next
- Use the new force_major_config
- Reword some comments and commit description
- Return -ENODEV instead of -EPROBE_DEFER to perevent race condition
- Drop phy_interface_copy patch (Russell pushed an equivalent version)
Changes v4:
- Move patch 0002 phy_interface_copy to 0002 (fix bisectability
problem)
- Address review from Lorenzo for Airoha ethernet driver
- Fix kdoc error with missing Return (actually missing : before Return)
- Fix UNMET dependency reported error for CONFIG_FWNODE_PCS
- Revert to pcs.c instead of core.c (due to name conflict with other kmod)
- Fix clang compilation error for Airoha PCS driver
- Add missing inline function to pcs.h function
Changes v3:
- Out of RFC
- Fix various spelling mistake
- Drop circular dependency patch
- Complete Airoha Ethernet phylink integration
- Introduce .pcs_link_down PCS OP
Changes v2:
- Switch to fwnode
- Implement PCS provider notifier
- Better split changes
- Move supported_interfaces to phylink
- Add circular dependency patch
- Rework handling with indirect addition/removal and
trigger of phylink_resolve()
Christian Marangi (12):
net: phylink: keep and use MAC supported_interfaces in phylink struct
net: phylink: introduce internal phylink PCS handling
net: pcs: implement Firmware node support for PCS driver
net: phylink: save phylink instance fwnode on phylink_create
net: phylink: support PCS provider release
net: phylink: support late PCS provider attach
net: Document PCS subsystem
MAINTAINERS: add myself as PCS subsystem maintainer
net: phylink: add .pcs_link_down PCS OP
dt-bindings: net: pcs: Document support for Airoha Ethernet PCS
net: pcs: airoha: add PCS driver for Airoha AN7581 SoC
net: airoha: add phylink support
.../bindings/net/pcs/airoha,pcs.yaml | 261 ++
Documentation/networking/index.rst | 1 +
Documentation/networking/pcs.rst | 234 ++
Documentation/networking/sfp-phylink.rst | 35 +-
MAINTAINERS | 9 +
drivers/net/ethernet/airoha/Kconfig | 2 +
drivers/net/ethernet/airoha/airoha_eth.c | 190 +-
drivers/net/ethernet/airoha/airoha_eth.h | 5 +
drivers/net/ethernet/airoha/airoha_regs.h | 12 +
drivers/net/pcs/Kconfig | 8 +
drivers/net/pcs/Makefile | 3 +
drivers/net/pcs/airoha/Kconfig | 12 +
drivers/net/pcs/airoha/Makefile | 7 +
drivers/net/pcs/airoha/pcs-airoha-common.c | 1303 ++++++++++
drivers/net/pcs/airoha/pcs-airoha.h | 1311 ++++++++++
drivers/net/pcs/airoha/pcs-an7581.c | 2100 +++++++++++++++++
drivers/net/pcs/pcs.c | 314 +++
drivers/net/phy/phylink.c | 397 +++-
include/linux/pcs/pcs-provider.h | 70 +
include/linux/pcs/pcs.h | 174 ++
include/linux/phylink.h | 28 +
21 files changed, 6421 insertions(+), 55 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/pcs/airoha,pcs.yaml
create mode 100644 Documentation/networking/pcs.rst
create mode 100644 drivers/net/pcs/airoha/Kconfig
create mode 100644 drivers/net/pcs/airoha/Makefile
create mode 100644 drivers/net/pcs/airoha/pcs-airoha-common.c
create mode 100644 drivers/net/pcs/airoha/pcs-airoha.h
create mode 100644 drivers/net/pcs/airoha/pcs-an7581.c
create mode 100644 drivers/net/pcs/pcs.c
create mode 100644 include/linux/pcs/pcs-provider.h
create mode 100644 include/linux/pcs/pcs.h
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH net-next v12 12/12] net: airoha: add phylink support 2026-08-09 20:30 [PATCH net-next v12 00/12] net: pcs: Introduce support for fwnode PCS Christian Marangi @ 2026-08-09 20:31 ` Christian Marangi 2026-08-10 14:53 ` win847 0 siblings, 1 reply; 5+ messages in thread From: Christian Marangi @ 2026-08-09 20:31 UTC (permalink / raw) To: Maxime Chevallier, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Simon Horman, Jonathan Corbet, Shuah Khan, Christian Marangi, Lorenzo Bianconi, Heiner Kallweit, Russell King, Philipp Zabel, Nathan Chancellor, Nick Desaulniers, Bill Wendling, Justin Stitt, netdev, devicetree, linux-kernel, linux-doc, linux-arm-kernel, linux-mediatek, llvm Add phylink support for each GDM port. For GDM1 add the internal interface mode as the only supported mode. For GDM2/3/4 add the required configuration of the PCS to make the external PHY or attached SFP cage work. These needs to be defined in the GDM port node using the pcs-handle property. Update and provide a .get/set_link_ksettings function that use phylink for ethtool OPs now that we fully support phylink. Acked-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> --- drivers/net/ethernet/airoha/Kconfig | 2 + drivers/net/ethernet/airoha/airoha_eth.c | 190 +++++++++++++++++++++- drivers/net/ethernet/airoha/airoha_eth.h | 5 + drivers/net/ethernet/airoha/airoha_regs.h | 12 ++ 4 files changed, 207 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/airoha/Kconfig b/drivers/net/ethernet/airoha/Kconfig index 1f6640a15fc9..5c54a07d2a76 100644 --- a/drivers/net/ethernet/airoha/Kconfig +++ b/drivers/net/ethernet/airoha/Kconfig @@ -20,6 +20,8 @@ config NET_AIROHA depends on NET_DSA || !NET_DSA select NET_AIROHA_NPU select PAGE_POOL + select PCS_AIROHA + select PHYLINK help This driver supports the gigabit ethernet MACs in the Airoha SoC family. diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c index 64619e9a704d..9fe8376aca0f 100644 --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c @@ -6,6 +6,7 @@ #include <linux/of.h> #include <linux/of_net.h> #include <linux/of_reserved_mem.h> +#include <linux/pcs/pcs.h> #include <linux/platform_device.h> #include <linux/tcp.h> #include <linux/u64_stats_sync.h> @@ -1915,6 +1916,14 @@ static int airoha_dev_open(struct net_device *netdev) struct airoha_qdma *qdma; int err; + err = phylink_of_phy_connect(dev->phylink, netdev->dev.of_node, 0); + if (err) { + netdev_err(netdev, "could not attach PHY: %d\n", err); + return err; + } + + phylink_start(dev->phylink); + netif_tx_start_all_queues(netdev); err = airoha_set_vip_for_gdm_port(dev, true); if (err) @@ -1945,6 +1954,8 @@ static int airoha_dev_stop(struct net_device *netdev) struct airoha_gdm_dev *dev = netdev_priv(netdev); struct airoha_gdm_port *port = dev->port; + phylink_stop(dev->phylink); + netif_tx_disable(netdev); airoha_set_vip_for_gdm_port(dev, false); @@ -1954,6 +1965,9 @@ static int airoha_dev_stop(struct net_device *netdev) airoha_set_gdm_port_fwd_cfg(dev->eth, REG_GDM_FWD_CFG(port->id), FE_PSE_PORT_DROP); + + phylink_disconnect_phy(dev->phylink); + return 0; } @@ -2509,6 +2523,24 @@ airoha_ethtool_get_rmon_stats(struct net_device *netdev, } while (u64_stats_fetch_retry(&dev->stats.syncp, start)); } +static int +airoha_ethtool_get_link_ksettings(struct net_device *netdev, + struct ethtool_link_ksettings *cmd) +{ + struct airoha_gdm_dev *dev = netdev_priv(netdev); + + return phylink_ethtool_ksettings_get(dev->phylink, cmd); +} + +static int +airoha_ethtool_set_link_ksettings(struct net_device *netdev, + const struct ethtool_link_ksettings *cmd) +{ + struct airoha_gdm_dev *dev = netdev_priv(netdev); + + return phylink_ethtool_ksettings_set(dev->phylink, cmd); +} + static int airoha_qdma_set_chan_tx_sched(struct net_device *netdev, int channel, enum tx_sched_mode mode, const u16 *weights, u8 n_weights) @@ -3353,7 +3385,8 @@ static const struct ethtool_ops airoha_ethtool_ops = { .get_drvinfo = airoha_ethtool_get_drvinfo, .get_eth_mac_stats = airoha_ethtool_get_mac_stats, .get_rmon_stats = airoha_ethtool_get_rmon_stats, - .get_link_ksettings = phy_ethtool_get_link_ksettings, + .get_link_ksettings = airoha_ethtool_get_link_ksettings, + .set_link_ksettings = airoha_ethtool_set_link_ksettings, .get_link = ethtool_op_get_link, }; @@ -3409,6 +3442,155 @@ bool airoha_is_valid_gdm_dev(struct airoha_eth *eth, return false; } +/* Nothing to do in MAC, everything is handled in PCS */ +static void airoha_mac_config(struct phylink_config *config, unsigned int mode, + const struct phylink_link_state *state) +{ +} + +static void airoha_mac_link_up(struct phylink_config *config, struct phy_device *phy, + unsigned int mode, phy_interface_t interface, + int speed, int duplex, bool tx_pause, bool rx_pause) +{ + struct airoha_gdm_dev *dev = container_of(config, struct airoha_gdm_dev, + phylink_config); + struct airoha_gdm_port *port = dev->port; + struct airoha_eth *eth = dev->eth; + u32 frag_size_tx, frag_size_rx; + + /* TX/RX frag is configured only for GDM4 */ + if (port->id != AIROHA_GDM4_IDX) + return; + + switch (speed) { + case SPEED_10000: + case SPEED_5000: + frag_size_tx = 8; + frag_size_rx = 8; + break; + case SPEED_2500: + frag_size_tx = 2; + frag_size_rx = 1; + break; + default: + frag_size_tx = 1; + frag_size_rx = 0; + break; + } + + mutex_lock(&port->link_lock); + + /* Configure TX/RX frag based on speed */ + if (dev->nbq == 1) { + airoha_fe_rmw(eth, REG_FE_GDM4_TMBI_FRAG, + GDM4_SGMII1_TX_FRAG_SIZE_MASK, + FIELD_PREP(GDM4_SGMII1_TX_FRAG_SIZE_MASK, + frag_size_tx)); + + airoha_fe_rmw(eth, REG_FE_GDM4_RMBI_FRAG, + GDM4_SGMII1_RX_FRAG_SIZE_MASK, + FIELD_PREP(GDM4_SGMII1_RX_FRAG_SIZE_MASK, + frag_size_rx)); + } else { + airoha_fe_rmw(eth, REG_FE_GDM4_TMBI_FRAG, + GDM4_SGMII0_TX_FRAG_SIZE_MASK, + FIELD_PREP(GDM4_SGMII0_TX_FRAG_SIZE_MASK, + frag_size_tx)); + + airoha_fe_rmw(eth, REG_FE_GDM4_RMBI_FRAG, + GDM4_SGMII0_RX_FRAG_SIZE_MASK, + FIELD_PREP(GDM4_SGMII0_RX_FRAG_SIZE_MASK, + frag_size_rx)); + } + + mutex_unlock(&port->link_lock); +} + +/* Nothing to do in MAC, everything is handled in PCS */ +static void airoha_mac_link_down(struct phylink_config *config, unsigned int mode, + phy_interface_t interface) +{ +} + +static const struct phylink_mac_ops airoha_phylink_ops = { + .mac_config = airoha_mac_config, + .mac_link_up = airoha_mac_link_up, + .mac_link_down = airoha_mac_link_down, +}; + +static int airoha_fill_available_pcs(struct phylink_config *config, + struct phylink_pcs **available_pcs, + unsigned int num_possible_pcs) +{ + struct device *dev = config->dev; + + return fwnode_phylink_pcs_parse(dev_fwnode(dev), available_pcs, + num_possible_pcs); +} + +static int airoha_setup_phylink(struct net_device *netdev) +{ + struct airoha_gdm_dev *dev = netdev_priv(netdev); + struct device_node *np = netdev->dev.of_node; + struct airoha_gdm_port *port = dev->port; + struct phylink_config *config; + phy_interface_t phy_mode; + struct phylink *phylink; + int err; + + err = of_get_phy_mode(np, &phy_mode); + if (err) { + dev_err(&netdev->dev, "incorrect phy-mode\n"); + return err; + } + + config = &dev->phylink_config; + config->dev = &netdev->dev; + config->type = PHYLINK_NETDEV; + + /* + * GDM1 only supports internal for Embedded Switch + * and doesn't require a PCS. + */ + if (port->id == AIROHA_GDM1_IDX) { + config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | + MAC_10000FD; + + __set_bit(PHY_INTERFACE_MODE_INTERNAL, + config->supported_interfaces); + } else { + config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | + MAC_10 | MAC_100 | MAC_1000 | + MAC_2500FD | MAC_5000FD | MAC_10000FD; + + config->num_possible_pcs = fwnode_phylink_pcs_count(dev_fwnode(config->dev)); + config->fill_available_pcs = airoha_fill_available_pcs; + + __set_bit(PHY_INTERFACE_MODE_SGMII, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_1000BASEX, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_2500BASEX, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_10GBASER, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_USXGMII, + config->supported_interfaces); + + phy_interface_copy(config->pcs_interfaces, + config->supported_interfaces); + } + + phylink = phylink_create(config, of_fwnode_handle(np), + phy_mode, &airoha_phylink_ops); + if (IS_ERR(phylink)) + return PTR_ERR(phylink); + + dev->phylink = phylink; + + return 0; +} + static int airoha_alloc_gdm_device(struct airoha_eth *eth, struct airoha_gdm_port *port, int nbq, struct device_node *np) @@ -3474,7 +3656,7 @@ static int airoha_alloc_gdm_device(struct airoha_eth *eth, dev->nbq = nbq; port->devs[index] = dev; - return 0; + return airoha_setup_phylink(netdev); } static int airoha_alloc_gdm_port(struct airoha_eth *eth, @@ -3510,6 +3692,7 @@ static int airoha_alloc_gdm_port(struct airoha_eth *eth, port->id = id; spin_lock_init(&port->stats_lock); + mutex_init(&port->link_lock); eth->ports[p] = port; err = airoha_metadata_dst_alloc(port); @@ -3706,6 +3889,8 @@ static int airoha_probe(struct platform_device *pdev) netdev = netdev_from_priv(dev); if (netdev->reg_state == NETREG_REGISTERED) unregister_netdev(netdev); + if (dev->phylink) + phylink_destroy(dev->phylink); of_node_put(netdev->dev.of_node); } airoha_metadata_dst_free(port); @@ -3744,6 +3929,7 @@ static void airoha_remove(struct platform_device *pdev) netdev = netdev_from_priv(dev); unregister_netdev(netdev); + phylink_destroy(dev->phylink); of_node_put(netdev->dev.of_node); } airoha_metadata_dst_free(port); diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h index fa9a8edce22f..83daec003257 100644 --- a/drivers/net/ethernet/airoha/airoha_eth.h +++ b/drivers/net/ethernet/airoha/airoha_eth.h @@ -595,6 +595,9 @@ struct airoha_gdm_dev { * QDMA migration. */ spinlock_t txq_lock[AIROHA_NUM_NETDEV_TX_RINGS]; + + struct phylink *phylink; + struct phylink_config phylink_config; }; struct airoha_gdm_port { @@ -604,6 +607,8 @@ struct airoha_gdm_port { /* protect concurrent hw_stats accesses */ spinlock_t stats_lock; + /* protect concurrent GDM4 register access */ + struct mutex link_lock; struct metadata_dst *dsa_meta[AIROHA_MAX_DSA_PORTS]; }; diff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h index 442b48c9b991..4ea89057b560 100644 --- a/drivers/net/ethernet/airoha/airoha_regs.h +++ b/drivers/net/ethernet/airoha/airoha_regs.h @@ -357,6 +357,18 @@ #define IP_FRAGMENT_PORT_MASK GENMASK(8, 5) #define IP_FRAGMENT_NBQ_MASK GENMASK(4, 0) +#define REG_FE_GDM4_TMBI_FRAG 0x2028 +#define GDM4_SGMII1_TX_WEIGHT_MASK GENMASK(31, 26) +#define GDM4_SGMII1_TX_FRAG_SIZE_MASK GENMASK(25, 16) +#define GDM4_SGMII0_TX_WEIGHT_MASK GENMASK(15, 10) +#define GDM4_SGMII0_TX_FRAG_SIZE_MASK GENMASK(9, 0) + +#define REG_FE_GDM4_RMBI_FRAG 0x202c +#define GDM4_SGMII1_RX_WEIGHT_MASK GENMASK(31, 26) +#define GDM4_SGMII1_RX_FRAG_SIZE_MASK GENMASK(25, 16) +#define GDM4_SGMII0_RX_WEIGHT_MASK GENMASK(15, 10) +#define GDM4_SGMII0_RX_FRAG_SIZE_MASK GENMASK(9, 0) + #define REG_MC_VLAN_EN 0x2100 #define MC_VLAN_EN_MASK BIT(0) -- 2.53.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net-next v12 12/12] net: airoha: add phylink support 2026-08-09 20:31 ` [PATCH net-next v12 12/12] net: airoha: add phylink support Christian Marangi @ 2026-08-10 14:53 ` win847 2026-08-10 14:57 ` Christian Marangi 0 siblings, 1 reply; 5+ messages in thread From: win847 @ 2026-08-10 14:53 UTC (permalink / raw) To: Christian Marangi; +Cc: netdev On Sun, 9 Aug 2026, Christian Marangi wrote: > Subject: [PATCH net-next v12 12/12] net: airoha: add phylink support Hi Christian, Thanks for the series. I have a question about the error path in `airoha_dev_open()` introduced in this patch, and a suggested cleanup. In the new code: err = phylink_of_phy_connect(dev->phylink, netdev->dev.of_node, 0); if (err) { netdev_err(netdev, "could not attach PHY: %d\n", err); return err; } phylink_start(dev->phylink); netif_tx_start_all_queues(netdev); err = airoha_set_vip_for_gdm_port(dev, true); if (err) return err; If `airoha_set_vip_for_gdm_port(dev, true)` fails after both `phylink_of_phy_connect()` and `phylink_start()` have already run, we return `err` directly without doing `phylink_stop()` or `phylink_disconnect_phy()`. That leaves the phylink in a started / PHY-connected state. On the next `ndo_open`, `phylink_of_phy_connect()` will be called again and may fail because the PHY is already connected, preventing the interface from ever coming back up again. I understand `airoha_set_vip_for_gdm_port()` currently always returns 0 (based on v12), so today this is a dead path, but it is easy to make the error handling correct and defensive so a future change to that helper does not silently break reopen. Suggested change: add an `err_phy_stop` error label and unwind phylink before returning: netif_tx_start_all_queues(netdev); err = airoha_set_vip_for_gdm_port(dev, true); if (err) goto err_phy_stop; return 0; err_phy_stop: netif_tx_stop_all_queues(netdev); phylink_stop(dev->phylink); phylink_disconnect_phy(dev->phylink); return err; Would you be open to folding this in (or reordering so `phylink_start()` runs after the VIP setup, leaving fewer error exits that need phylink teardown)? Happy to write it up as a proper patch if useful. Best regards, Wayen ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net-next v12 12/12] net: airoha: add phylink support 2026-08-10 14:53 ` win847 @ 2026-08-10 14:57 ` Christian Marangi 2026-08-10 15:32 ` win847 0 siblings, 1 reply; 5+ messages in thread From: Christian Marangi @ 2026-08-10 14:57 UTC (permalink / raw) To: win847; +Cc: netdev On Mon, Aug 10, 2026 at 10:53:13PM +0800, win847@gmail.com wrote: > On Sun, 9 Aug 2026, Christian Marangi wrote: > > Subject: [PATCH net-next v12 12/12] net: airoha: add phylink support > > Hi Christian, > > Thanks for the series. I have a question about the error path in > `airoha_dev_open()` introduced in this patch, and a suggested cleanup. > > In the new code: > > err = phylink_of_phy_connect(dev->phylink, netdev->dev.of_node, 0); > if (err) { > netdev_err(netdev, "could not attach PHY: %d\n", err); > return err; > } > > phylink_start(dev->phylink); > > netif_tx_start_all_queues(netdev); > err = airoha_set_vip_for_gdm_port(dev, true); > if (err) > return err; > > If `airoha_set_vip_for_gdm_port(dev, true)` fails after both > `phylink_of_phy_connect()` and `phylink_start()` have already run, we > return `err` directly without doing `phylink_stop()` or > `phylink_disconnect_phy()`. That leaves the phylink in a started / > PHY-connected state. On the next `ndo_open`, `phylink_of_phy_connect()` > will be called again and may fail because the PHY is already connected, > preventing the interface from ever coming back up again. > > I understand `airoha_set_vip_for_gdm_port()` currently always returns 0 > (based on v12), so today this is a dead path, but it is easy to make the > error handling correct and defensive so a future change to that helper > does not silently break reopen. > > Suggested change: add an `err_phy_stop` error label and unwind phylink > before returning: > > netif_tx_start_all_queues(netdev); > err = airoha_set_vip_for_gdm_port(dev, true); > if (err) > goto err_phy_stop; > > return 0; > > err_phy_stop: > netif_tx_stop_all_queues(netdev); > phylink_stop(dev->phylink); > phylink_disconnect_phy(dev->phylink); > return err; > > Would you be open to folding this in (or reordering so `phylink_start()` > runs after the VIP setup, leaving fewer error exits that need phylink > teardown)? Happy to write it up as a proper patch if useful. > If you are ok, I can integrate the change in the next revision. -- Ansuel ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net-next v12 12/12] net: airoha: add phylink support 2026-08-10 14:57 ` Christian Marangi @ 2026-08-10 15:32 ` win847 0 siblings, 0 replies; 5+ messages in thread From: win847 @ 2026-08-10 15:32 UTC (permalink / raw) To: Christian Marangi; +Cc: netdev On Mon, Aug 10, 2026 at 10:57:59PM +0800, Christian Marangi wrote: > If you are ok, I can integrate the change in the next revision. Thanks Christian, please go ahead and integrate it in the next revision. Either the `goto err_phy_stop` unwind or moving `phylink_start()` after the GDM VIP configuration so fewer error exits need teardown works for me — whichever you find cleaner. Happy to review the diff when you post v13. Best regards, Wayen ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-08-10 15:33 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <6a79e6fa.332d3c56.21a33c.b60f@mx.google.com>
2026-08-10 15:14 ` [PATCH net-next v12 12/12] net: airoha: add phylink support win847
2026-08-09 20:30 [PATCH net-next v12 00/12] net: pcs: Introduce support for fwnode PCS Christian Marangi
2026-08-09 20:31 ` [PATCH net-next v12 12/12] net: airoha: add phylink support Christian Marangi
2026-08-10 14:53 ` win847
2026-08-10 14:57 ` Christian Marangi
2026-08-10 15:32 ` win847
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox