* [PATCH net-next v5 1/2] net: ti: icssg-prueth: Add Frame Preemption MAC Merge support
From: Meghana Malladi @ 2026-04-30 11:17 UTC (permalink / raw)
To: vadim.fedorenko, haokexin, jacob.e.keller, horms, m-malladi, arnd,
parvathi, afd, basharath, vladimir.oltean, rogerq, danishanwar,
pabeni, kuba, edumazet, davem, andrew+netdev
Cc: linux-arm-kernel, netdev, linux-kernel, srk, Vignesh Raghavendra
In-Reply-To: <20260430111723.497113-1-m-malladi@ti.com>
From: MD Danish Anwar <danishanwar@ti.com>
Introduce QoS infrastructure for Frame Preemption (FPE) support in
the ICSSG Ethernet driver.
prueth_qos_iet tracks FPE enable/active state and verify state machine
status via firmware-reported enum icssg_ietfpe_verify_states.
icssg_config_ietfpe() configures IET FPE in firmware, triggers
verify state machine based on ethtool MAC Merge parameters.
Polls firmware verify status up to 3 times with verify_time_ms intervals
and driver handles timeout by logging error and returning.
For MQPRIO qdisc support all queues are express by default later
gets override by user-provided preemptible_tcs bitmask via tc qdisc mask
Preempt mask configuration: Maps traffic classes to queue express/preemptible
state and applied only when FPE is active (Tx enabled)
Verify state machine re-triggers on link up/down events based on
fpe_enabled and fpe_active flags, and for memory protection, fpe_lock
serializes all FPE state mutations, preventing races between ethtool
config, qdisc setup, and link events
Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
Signed-off-by: Meghana Malladi <m-malladi@ti.com>
---
changes from v4(v5-v4):
- preemptible TCs are committed to hardware only when FPE is active
- Removed workqueue implementation with direct call to configure FPE
- Changed MAC verification logic to poll at verify_time_ms intervals
instead of 5 seconds.
- Used mutex_lock whenever necessary to ensure proper synchronization
All the above changes are addressed as part of Vladimir Oltean <vladimir.oltean@nxp.com>
comments for this patch
drivers/net/ethernet/ti/Makefile | 3 +-
drivers/net/ethernet/ti/icssg/icssg_config.h | 9 -
drivers/net/ethernet/ti/icssg/icssg_prueth.c | 7 +
drivers/net/ethernet/ti/icssg/icssg_prueth.h | 2 +
drivers/net/ethernet/ti/icssg/icssg_qos.c | 232 +++++++++++++++++++
drivers/net/ethernet/ti/icssg/icssg_qos.h | 68 ++++++
6 files changed, 311 insertions(+), 10 deletions(-)
create mode 100644 drivers/net/ethernet/ti/icssg/icssg_qos.c
create mode 100644 drivers/net/ethernet/ti/icssg/icssg_qos.h
diff --git a/drivers/net/ethernet/ti/Makefile b/drivers/net/ethernet/ti/Makefile
index f4276c9a77620..d19bcd25c9d07 100644
--- a/drivers/net/ethernet/ti/Makefile
+++ b/drivers/net/ethernet/ti/Makefile
@@ -46,6 +46,7 @@ icssg-y := icssg/icssg_common.o \
icssg/icssg_config.o \
icssg/icssg_mii_cfg.o \
icssg/icssg_stats.o \
- icssg/icssg_ethtool.o
+ icssg/icssg_ethtool.o \
+ icssg/icssg_qos.o
obj-$(CONFIG_TI_ICSS_IEP) += icssg/icss_iep.o
diff --git a/drivers/net/ethernet/ti/icssg/icssg_config.h b/drivers/net/ethernet/ti/icssg/icssg_config.h
index 60d69744ffae2..1ac202f855ed4 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_config.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_config.h
@@ -323,13 +323,4 @@ struct prueth_fdb_slot {
u8 fid;
u8 fid_c2;
} __packed;
-
-enum icssg_ietfpe_verify_states {
- ICSSG_IETFPE_STATE_UNKNOWN = 0,
- ICSSG_IETFPE_STATE_INITIAL,
- ICSSG_IETFPE_STATE_VERIFYING,
- ICSSG_IETFPE_STATE_SUCCEEDED,
- ICSSG_IETFPE_STATE_FAILED,
- ICSSG_IETFPE_STATE_DISABLED
-};
#endif /* __NET_TI_ICSSG_CONFIG_H */
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index 591be5c8056b4..7657dc1015f0a 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -392,6 +392,8 @@ static void emac_adjust_link(struct net_device *ndev)
} else {
icssg_set_port_state(emac, ICSSG_EMAC_PORT_DISABLE);
}
+
+ icssg_qos_link_state_update(ndev);
}
if (emac->link) {
@@ -1652,6 +1654,7 @@ static const struct net_device_ops emac_netdev_ops = {
.ndo_hwtstamp_get = icssg_ndo_get_ts_config,
.ndo_hwtstamp_set = icssg_ndo_set_ts_config,
.ndo_xsk_wakeup = prueth_xsk_wakeup,
+ .ndo_setup_tc = icssg_qos_ndo_setup_tc,
};
static int prueth_netdev_init(struct prueth *prueth,
@@ -1686,6 +1689,8 @@ static int prueth_netdev_init(struct prueth *prueth,
INIT_DELAYED_WORK(&emac->stats_work, icssg_stats_work_handler);
+ icssg_qos_init(ndev);
+
ret = pruss_request_mem_region(prueth->pruss,
port == PRUETH_PORT_MII0 ?
PRUSS_MEM_DRAM0 : PRUSS_MEM_DRAM1,
@@ -2461,6 +2466,7 @@ static int prueth_probe(struct platform_device *pdev)
}
unregister_netdev(prueth->registered_netdevs[i]);
disable_work_sync(&prueth->emac[i]->rx_mode_work);
+ mutex_destroy(&prueth->emac[i]->qos.iet.fpe_lock);
}
netdev_exit:
@@ -2521,6 +2527,7 @@ static void prueth_remove(struct platform_device *pdev)
prueth->emac[i]->ndev->phydev = NULL;
unregister_netdev(prueth->registered_netdevs[i]);
disable_work_sync(&prueth->emac[i]->rx_mode_work);
+ mutex_destroy(&prueth->emac[i]->qos.iet.fpe_lock);
}
for (i = 0; i < PRUETH_NUM_MACS; i++) {
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index df93d15c5b786..85f7017d2c8e7 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -44,6 +44,7 @@
#include "icssg_config.h"
#include "icss_iep.h"
#include "icssg_switch_map.h"
+#include "icssg_qos.h"
#define PRUETH_MAX_MTU (2000 - ETH_HLEN - ETH_FCS_LEN)
#define PRUETH_MIN_PKT_SIZE (VLAN_ETH_ZLEN)
@@ -254,6 +255,7 @@ struct prueth_emac {
struct bpf_prog *xdp_prog;
struct xdp_attachment_info xdpi;
int xsk_qid;
+ struct prueth_qos qos;
};
/* The buf includes headroom compatible with both skb and xdpf */
diff --git a/drivers/net/ethernet/ti/icssg/icssg_qos.c b/drivers/net/ethernet/ti/icssg/icssg_qos.c
new file mode 100644
index 0000000000000..fc4b0ebc7d683
--- /dev/null
+++ b/drivers/net/ethernet/ti/icssg/icssg_qos.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Texas Instruments ICSSG PRUETH QoS submodule
+ * Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#include "icssg_prueth.h"
+#include "icssg_switch_map.h"
+
+static void icssg_iet_set_preempt_mask(struct prueth_emac *emac)
+{
+ void __iomem *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
+ struct prueth_qos_mqprio *p_mqprio = &emac->qos.mqprio;
+ struct tc_mqprio_qopt *qopt = &p_mqprio->mqprio.qopt;
+ u8 preemptible_tcs = p_mqprio->preemptible_tcs;
+ struct prueth_qos_iet *iet = &emac->qos.iet;
+ int prempt_mask = 0, i;
+ u8 tc;
+
+ /* The preemptible traffic classes should only be committed to hardware
+ * once TX is active.
+ */
+ if (!iet->fpe_active) {
+ netdev_dbg(emac->ndev, "FPE not active, skipping preempt mask config\n");
+ return;
+ }
+
+ /* Configure the queues based on the preemptible tc map set by the user */
+ for (tc = 0; tc < p_mqprio->mqprio.qopt.num_tc; tc++) {
+ /* check if the tc is preemptive or not */
+ if (preemptible_tcs & BIT(tc)) {
+ for (i = qopt->offset[tc]; i < qopt->offset[tc] + qopt->count[tc]; i++) {
+ /* Set all the queues in this tc as preemptive queues */
+ writeb(BIT(4), config + EXPRESS_PRE_EMPTIVE_Q_MAP + i);
+ prempt_mask &= ~BIT(i);
+ }
+ } else {
+ /* Set all the queues in this tc as express queues */
+ for (i = qopt->offset[tc]; i < qopt->offset[tc] + qopt->count[tc]; i++) {
+ writeb(0, config + EXPRESS_PRE_EMPTIVE_Q_MAP + i);
+ prempt_mask |= BIT(i);
+ }
+ }
+ netdev_set_tc_queue(emac->ndev, tc, qopt->count[tc], qopt->offset[tc]);
+ }
+ writeb(prempt_mask, config + EXPRESS_PRE_EMPTIVE_Q_MASK);
+}
+
+static int icssg_iet_verify_wait(struct prueth_emac *emac)
+{
+ void __iomem *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
+ struct prueth_qos_iet *iet = &emac->qos.iet;
+ int try = 3;
+
+ do {
+ msleep(iet->verify_time_ms);
+ iet->verify_status = readb(config + PRE_EMPTION_VERIFY_STATUS);
+ if (iet->verify_status == ICSSG_IETFPE_STATE_SUCCEEDED)
+ return 0;
+ } while (--try > 0);
+
+ netdev_err(emac->ndev, "MAC Verify timeout\n");
+ return -ETIMEDOUT;
+}
+
+/* Direct synchronous configuration of IET FPE.
+ * Caller must hold iet->fpe_lock.
+ */
+void icssg_config_ietfpe(struct prueth_emac *emac, bool enable)
+{
+ void __iomem *config = emac->dram.va + ICSSG_CONFIG_OFFSET;
+ struct prueth_qos_iet *iet = &emac->qos.iet;
+ int ret;
+ u8 val;
+
+ /* return early if FPE is not active and need not be enabled */
+ if (!iet->fpe_enabled && !iet->fpe_active)
+ return;
+
+ if (!netif_running(emac->ndev)) {
+ netdev_dbg(emac->ndev, "cannot change IET/FPE state when interface is down\n");
+ return;
+ }
+
+ /* Update FPE Tx enable bit (PRE_EMPTION_ENABLE_TX) if
+ * fpe_enabled is set to enable MM in Tx direction
+ */
+ writeb(enable ? 1 : 0, config + PRE_EMPTION_ENABLE_TX);
+
+ /* If FPE is to be enabled, first configure MAC Verify state
+ * machine in firmware as firmware kicks the Verify process
+ * as soon as ICSSG_EMAC_PORT_PREMPT_TX_ENABLE command is
+ * received.
+ */
+ if (enable && iet->mac_verify_configure) {
+ writeb(1, config + PRE_EMPTION_ENABLE_VERIFY);
+ writew(iet->tx_min_frag_size, config + PRE_EMPTION_ADD_FRAG_SIZE_LOCAL);
+ writel(iet->verify_time_ms, config + PRE_EMPTION_VERIFY_TIME);
+ } else {
+ iet->verify_status = ICSSG_IETFPE_STATE_DISABLED;
+ }
+
+ /* Send command to enable FPE Tx side. Rx is always enabled */
+ ret = icssg_set_port_state(emac,
+ enable ? ICSSG_EMAC_PORT_PREMPT_TX_ENABLE :
+ ICSSG_EMAC_PORT_PREMPT_TX_DISABLE);
+ if (ret) {
+ netdev_err(emac->ndev, "TX preempt %s command failed\n",
+ str_enable_disable(enable));
+ writeb(0, config + PRE_EMPTION_ENABLE_VERIFY);
+ iet->verify_status = ICSSG_IETFPE_STATE_DISABLED;
+ return;
+ }
+
+ if (enable && iet->mac_verify_configure) {
+ ret = icssg_iet_verify_wait(emac);
+ if (ret) {
+ netdev_err(emac->ndev, "MAC Verification failed with timeout\n");
+ return;
+ }
+ } else if (enable) {
+ /* Give firmware some time to update PRE_EMPTION_ACTIVE_TX state */
+ usleep_range(100, 200);
+ }
+
+ if (enable) {
+ val = readb(config + PRE_EMPTION_ACTIVE_TX);
+ if (val != 1) {
+ netdev_err(emac->ndev,
+ "Firmware fails to activate IET/FPE\n");
+ return;
+ }
+ iet->fpe_active = true;
+ } else {
+ iet->fpe_active = false;
+ }
+
+ icssg_iet_set_preempt_mask(emac);
+ netdev_err(emac->ndev, "IET FPE %s successfully\n",
+ str_enable_disable(iet->fpe_active));
+}
+EXPORT_SYMBOL_GPL(icssg_config_ietfpe);
+
+void icssg_qos_init(struct net_device *ndev)
+{
+ struct prueth_emac *emac = netdev_priv(ndev);
+ struct prueth_qos_iet *iet = &emac->qos.iet;
+
+ iet->emac = emac;
+ mutex_init(&iet->fpe_lock);
+}
+
+static void icssg_iet_change_preemptible_tcs(struct prueth_emac *emac)
+{
+ struct prueth_qos_iet *iet = &emac->qos.iet;
+
+ mutex_lock(&iet->fpe_lock);
+ icssg_config_ietfpe(emac, iet->fpe_enabled);
+ mutex_unlock(&iet->fpe_lock);
+}
+
+static int emac_tc_query_caps(struct net_device *ndev, void *type_data)
+{
+ struct tc_query_caps_base *base = type_data;
+
+ switch (base->type) {
+ case TC_SETUP_QDISC_MQPRIO: {
+ struct tc_mqprio_caps *caps = base->caps;
+
+ caps->validate_queue_counts = true;
+ return 0;
+ }
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int emac_tc_setup_mqprio(struct net_device *ndev, void *type_data)
+{
+ struct tc_mqprio_qopt_offload *mqprio = type_data;
+ struct prueth_emac *emac = netdev_priv(ndev);
+ struct tc_mqprio_qopt *qopt = &mqprio->qopt;
+ struct prueth_qos_mqprio *p_mqprio;
+ u8 num_tc = mqprio->qopt.num_tc;
+ int tc, offset, count;
+
+ p_mqprio = &emac->qos.mqprio;
+
+ if (!num_tc) {
+ netdev_reset_tc(ndev);
+ p_mqprio->preemptible_tcs = 0;
+ p_mqprio->mqprio.qopt.num_tc = 0;
+ goto reset_tcs;
+ }
+
+ memcpy(&p_mqprio->mqprio, mqprio, sizeof(*mqprio));
+ p_mqprio->preemptible_tcs = mqprio->preemptible_tcs;
+ netdev_set_num_tc(ndev, mqprio->qopt.num_tc);
+
+ for (tc = 0; tc < num_tc; tc++) {
+ count = qopt->count[tc];
+ offset = qopt->offset[tc];
+ netdev_set_tc_queue(ndev, tc, count, offset);
+ }
+
+reset_tcs:
+ icssg_iet_change_preemptible_tcs(emac);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(icssg_qos_init);
+
+int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type,
+ void *type_data)
+{
+ switch (type) {
+ case TC_QUERY_CAPS:
+ return emac_tc_query_caps(ndev, type_data);
+ case TC_SETUP_QDISC_MQPRIO:
+ return emac_tc_setup_mqprio(ndev, type_data);
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+EXPORT_SYMBOL_GPL(icssg_qos_ndo_setup_tc);
+
+void icssg_qos_link_state_update(struct net_device *ndev)
+{
+ struct prueth_emac *emac = netdev_priv(ndev);
+
+ icssg_iet_change_preemptible_tcs(emac);
+}
+EXPORT_SYMBOL_GPL(icssg_qos_link_state_update);
diff --git a/drivers/net/ethernet/ti/icssg/icssg_qos.h b/drivers/net/ethernet/ti/icssg/icssg_qos.h
new file mode 100644
index 0000000000000..083f248c557de
--- /dev/null
+++ b/drivers/net/ethernet/ti/icssg/icssg_qos.h
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2023 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#ifndef __NET_TI_ICSSG_QOS_H
+#define __NET_TI_ICSSG_QOS_H
+
+#include <linux/atomic.h>
+#include <linux/netdevice.h>
+#include <net/pkt_sched.h>
+
+/**
+ * enum icssg_ietfpe_verify_states - status of MAC Merge Verify returned by firmware
+ * @ICSSG_IETFPE_STATE_UNKNOWN:
+ * verification status is unknown
+ * @ICSSG_IETFPE_STATE_INITIAL:
+ * Firmware returns this if verify state diagram is idle
+ * @ICSSG_IETFPE_STATE_VERIFYING:
+ * Firmware returns this if verification is ongoing
+ * @ICSSG_IETFPE_STATE_SUCCEEDED:
+ * Firmware returns this if verify state diagram completes verification
+ * @ICSSG_IETFPE_STATE_FAILED:
+ * Firmware returns this if verify state diagram fails during verification
+ * @ICSSG_IETFPE_STATE_DISABLED:
+ * verification is disabled by the driver
+ */
+enum icssg_ietfpe_verify_states {
+ ICSSG_IETFPE_STATE_UNKNOWN = 0,
+ ICSSG_IETFPE_STATE_INITIAL,
+ ICSSG_IETFPE_STATE_VERIFYING,
+ ICSSG_IETFPE_STATE_SUCCEEDED,
+ ICSSG_IETFPE_STATE_FAILED,
+ ICSSG_IETFPE_STATE_DISABLED
+};
+
+struct prueth_qos_mqprio {
+ struct tc_mqprio_qopt_offload mqprio;
+ u8 preemptible_tcs;
+};
+
+struct prueth_qos_iet {
+ struct prueth_emac *emac;
+
+ /* Configuration state - protected by fpe_lock */
+ bool fpe_enabled;
+ bool mac_verify_configure;
+ u32 tx_min_frag_size;
+ u32 verify_time_ms;
+
+ /* Runtime state - protected by fpe_lock */
+ bool fpe_active;
+ enum icssg_ietfpe_verify_states verify_status;
+
+ /* Synchronization: single mutex protects all FPE operations */
+ struct mutex fpe_lock;
+};
+
+struct prueth_qos {
+ struct prueth_qos_iet iet;
+ struct prueth_qos_mqprio mqprio;
+};
+
+void icssg_qos_init(struct net_device *ndev);
+void icssg_qos_link_state_update(struct net_device *ndev);
+int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type,
+ void *type_data);
+void icssg_config_ietfpe(struct prueth_emac *emac, bool enable);
+#endif /* __NET_TI_ICSSG_QOS_H */
--
2.43.0
^ permalink raw reply related
* [PATCH net-next v5 2/2] net: ti: icssg-prueth: Add ethtool ops for Frame Preemption MAC Merge
From: Meghana Malladi @ 2026-04-30 11:17 UTC (permalink / raw)
To: vadim.fedorenko, haokexin, jacob.e.keller, horms, m-malladi, arnd,
parvathi, afd, basharath, vladimir.oltean, rogerq, danishanwar,
pabeni, kuba, edumazet, davem, andrew+netdev
Cc: linux-arm-kernel, netdev, linux-kernel, srk, Vignesh Raghavendra
In-Reply-To: <20260430111723.497113-1-m-malladi@ti.com>
From: MD Danish Anwar <danishanwar@ti.com>
Add driver support for viewing and changing the MAC Merge sublayer
parameters via ethtool ops: .set_mm(), .get_mm() and .get_mm_stats().
The minimum size of non-final mPacket fragments supported by the firmware
without leading errors is 64 Bytes (including FCS). Verify time bounded to
1-128 ms per 802.3-2018 clause 30.14.1.6. Add a check to ensure
user passed tx_min_frag_size argument via ethtool, honors this.
Add pa stats registers to check statistics for preemption, which can be
dumped using ethtool ops.
Fix emac_get_stat_by_name() to return u64 instead of int and return 0 on
error instead of -EINVAL. This prevents invalid stat lookups from corrupting
output stats with signed error codes cast to u64. Error conditions are still
logged via netdev_err().
Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
Signed-off-by: Meghana Malladi <m-malladi@ti.com>
---
Changes from v4(v5-v4):
- Fix the naming conventiion for icssg_qos_frag_size_min_to_add()
- Change the logic to include FCS while validating and accepting
values from the userspace
All the above changes are addressed as part of Vladimir Oltean <vladimir.oltean@nxp.com>
comments for this patch
- Handle all verify_status values in emac_get_mm() based on what
all states are supported by the firmware.
This change is addressed based on AI-generated review and highlighted by
Simon Horman <horms@kernel.org>
drivers/net/ethernet/ti/icssg/icssg_ethtool.c | 107 +++++++++++++++++-
drivers/net/ethernet/ti/icssg/icssg_prueth.h | 7 +-
drivers/net/ethernet/ti/icssg/icssg_qos.h | 38 +++++++
drivers/net/ethernet/ti/icssg/icssg_stats.c | 5 +-
drivers/net/ethernet/ti/icssg/icssg_stats.h | 5 +
.../net/ethernet/ti/icssg/icssg_switch_map.h | 5 +
6 files changed, 160 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c
index b715af21d23ac..6a08c40adde54 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_ethtool.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_ethtool.c
@@ -6,7 +6,6 @@
*/
#include "icssg_prueth.h"
-#include "icssg_stats.h"
static void emac_get_drvinfo(struct net_device *ndev,
struct ethtool_drvinfo *info)
@@ -294,6 +293,109 @@ static int emac_set_per_queue_coalesce(struct net_device *ndev, u32 queue,
return 0;
}
+static int emac_get_mm(struct net_device *ndev, struct ethtool_mm_state *state)
+{
+ struct prueth_emac *emac = netdev_priv(ndev);
+ struct prueth_qos_iet *iet = &emac->qos.iet;
+ enum icssg_ietfpe_verify_states verify_status;
+
+ if (emac->is_sr1)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&iet->fpe_lock);
+ state->tx_enabled = iet->fpe_enabled;
+ state->tx_min_frag_size = iet->tx_min_frag_size - ETH_FCS_LEN;
+ state->tx_active = iet->fpe_active;
+ state->verify_enabled = iet->mac_verify_configure;
+ state->verify_time = iet->verify_time_ms;
+ verify_status = iet->verify_status;
+ mutex_unlock(&iet->fpe_lock);
+
+ state->pmac_enabled = true;
+ /* 64Bytes is the minimum fragment size supported
+ * by the firmware. <64B leads to min frame errors
+ */
+ state->rx_min_frag_size = 64;
+
+ switch (verify_status) {
+ case ICSSG_IETFPE_STATE_DISABLED:
+ state->verify_status = ETHTOOL_MM_VERIFY_STATUS_DISABLED;
+ break;
+ case ICSSG_IETFPE_STATE_INITIAL:
+ state->verify_status = ETHTOOL_MM_VERIFY_STATUS_INITIAL;
+ break;
+ case ICSSG_IETFPE_STATE_VERIFYING:
+ state->verify_status = ETHTOOL_MM_VERIFY_STATUS_VERIFYING;
+ break;
+ case ICSSG_IETFPE_STATE_SUCCEEDED:
+ state->verify_status = ETHTOOL_MM_VERIFY_STATUS_SUCCEEDED;
+ break;
+ case ICSSG_IETFPE_STATE_FAILED:
+ state->verify_status = ETHTOOL_MM_VERIFY_STATUS_FAILED;
+ break;
+ default:
+ state->verify_status = ETHTOOL_MM_VERIFY_STATUS_UNKNOWN;
+ break;
+ }
+
+ /* 802.3-2018 clause 30.14.1.6, says that the aMACMergeVerifyTime
+ * variable has a range between 1 and 128 ms inclusive. Limit to that.
+ */
+ state->max_verify_time = ETHTOOL_MM_MAX_VERIFY_TIME_MS;
+
+ return 0;
+}
+
+static int emac_set_mm(struct net_device *ndev, struct ethtool_mm_cfg *cfg,
+ struct netlink_ext_ack *extack)
+{
+ struct prueth_emac *emac = netdev_priv(ndev);
+ struct prueth_qos_iet *iet = &emac->qos.iet;
+ int err;
+
+ if (emac->is_sr1)
+ return -EOPNOTSUPP;
+
+ if (!cfg->pmac_enabled)
+ NL_SET_ERR_MSG_MOD(extack, "preemptible MAC is always enabled");
+
+ err = icssg_qos_validate_tx_min_frag_size(cfg->tx_min_frag_size, extack);
+ if (err)
+ return err;
+
+ err = icssg_qos_validate_verify_time(cfg->verify_time, extack);
+ if (err)
+ return err;
+
+ mutex_lock(&iet->fpe_lock);
+ iet->verify_time_ms = cfg->verify_time;
+ iet->tx_min_frag_size = cfg->tx_min_frag_size + ETH_FCS_LEN;
+ iet->fpe_enabled = cfg->tx_enabled;
+ iet->mac_verify_configure = cfg->verify_enabled;
+ icssg_config_ietfpe(emac, cfg->tx_enabled);
+ mutex_unlock(&iet->fpe_lock);
+
+ return err;
+}
+
+static void emac_get_mm_stats(struct net_device *ndev,
+ struct ethtool_mm_stats *s)
+{
+ struct prueth_emac *emac = netdev_priv(ndev);
+
+ if (emac->is_sr1)
+ return;
+
+ if (!emac->prueth->pa_stats)
+ return;
+
+ s->MACMergeFrameAssOkCount = emac_get_stat_by_name(emac, "FW_PREEMPT_ASSEMBLY_OK");
+ s->MACMergeFrameAssErrorCount = emac_get_stat_by_name(emac, "FW_PREEMPT_ASSEMBLY_ERR");
+ s->MACMergeFragCountRx = emac_get_stat_by_name(emac, "FW_PREEMPT_FRAG_CNT_RX");
+ s->MACMergeFragCountTx = emac_get_stat_by_name(emac, "FW_PREEMPT_FRAG_CNT_TX");
+ s->MACMergeFrameSmdErrorCount = emac_get_stat_by_name(emac, "FW_PREEMPT_BAD_FRAG");
+}
+
const struct ethtool_ops icssg_ethtool_ops = {
.get_drvinfo = emac_get_drvinfo,
.get_msglevel = emac_get_msglevel,
@@ -317,5 +419,8 @@ const struct ethtool_ops icssg_ethtool_ops = {
.set_eee = emac_set_eee,
.nway_reset = emac_nway_reset,
.get_rmon_stats = emac_get_rmon_stats,
+ .get_mm = emac_get_mm,
+ .set_mm = emac_set_mm,
+ .get_mm_stats = emac_get_mm_stats,
};
EXPORT_SYMBOL_GPL(icssg_ethtool_ops);
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.h b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
index 85f7017d2c8e7..61320c252bec2 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.h
@@ -45,6 +45,7 @@
#include "icss_iep.h"
#include "icssg_switch_map.h"
#include "icssg_qos.h"
+#include "icssg_stats.h"
#define PRUETH_MAX_MTU (2000 - ETH_HLEN - ETH_FCS_LEN)
#define PRUETH_MIN_PKT_SIZE (VLAN_ETH_ZLEN)
@@ -58,8 +59,8 @@
#define ICSSG_MAX_RFLOWS 8 /* per slice */
-#define ICSSG_NUM_PA_STATS 32
-#define ICSSG_NUM_MIIG_STATS 60
+#define ICSSG_NUM_PA_STATS ARRAY_SIZE(icssg_all_pa_stats)
+#define ICSSG_NUM_MIIG_STATS ARRAY_SIZE(icssg_all_miig_stats)
/* Number of ICSSG related stats */
#define ICSSG_NUM_STATS (ICSSG_NUM_MIIG_STATS + ICSSG_NUM_PA_STATS)
#define ICSSG_NUM_STANDARD_STATS 31
@@ -460,7 +461,7 @@ int emac_fdb_flow_id_updated(struct prueth_emac *emac);
void icssg_stats_work_handler(struct work_struct *work);
void emac_update_hardware_stats(struct prueth_emac *emac);
-int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name);
+u64 emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name);
/* Common functions */
void prueth_cleanup_rx_chns(struct prueth_emac *emac,
diff --git a/drivers/net/ethernet/ti/icssg/icssg_qos.h b/drivers/net/ethernet/ti/icssg/icssg_qos.h
index 083f248c557de..104910516d966 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_qos.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_qos.h
@@ -65,4 +65,42 @@ void icssg_qos_link_state_update(struct net_device *ndev);
int icssg_qos_ndo_setup_tc(struct net_device *ndev, enum tc_setup_type type,
void *type_data);
void icssg_config_ietfpe(struct prueth_emac *emac, bool enable);
+static inline int icssg_qos_validate_tx_min_frag_size(u32 min_frag_size,
+ struct netlink_ext_ack *extack)
+{
+ /* Firmware takes min_frag_size including FCS length */
+ min_frag_size += ETH_FCS_LEN;
+
+ /* The minimum size of the non-final mPacket supported
+ * by the firmware is 64B and multiples of 64B.
+ */
+ if (min_frag_size < 64) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "tx_min_frag_size must be at least 64 bytes");
+ return -EINVAL;
+ }
+
+ if (min_frag_size % (ETH_ZLEN + ETH_FCS_LEN)) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "tx_min_frag_size must be a multiple of 64 bytes");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline int icssg_qos_validate_verify_time(u32 verify_time_ms,
+ struct netlink_ext_ack *extack)
+{
+ /* 802.3-2018 clause 30.14.1.6: aMACMergeVerifyTime must be
+ * between 1 and 128 ms inclusive
+ */
+ if (verify_time_ms < 1 || verify_time_ms > 128) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "verify_time must be between 1 and 128 ms");
+ return -EINVAL;
+ }
+
+ return 0;
+}
#endif /* __NET_TI_ICSSG_QOS_H */
diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.c b/drivers/net/ethernet/ti/icssg/icssg_stats.c
index 7159baa0155cf..950d58d8183eb 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_stats.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_stats.c
@@ -6,7 +6,6 @@
*/
#include "icssg_prueth.h"
-#include "icssg_stats.h"
#include <linux/regmap.h>
#define ICSSG_TX_PACKET_OFFSET 0xA0
@@ -74,7 +73,7 @@ void icssg_stats_work_handler(struct work_struct *work)
}
EXPORT_SYMBOL_GPL(icssg_stats_work_handler);
-int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name)
+u64 emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name)
{
int i;
@@ -91,5 +90,5 @@ int emac_get_stat_by_name(struct prueth_emac *emac, char *stat_name)
}
netdev_err(emac->ndev, "Invalid stats %s\n", stat_name);
- return -EINVAL;
+ return 0;
}
diff --git a/drivers/net/ethernet/ti/icssg/icssg_stats.h b/drivers/net/ethernet/ti/icssg/icssg_stats.h
index 5ec0b38e0c67d..f35ae1b4f8460 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_stats.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_stats.h
@@ -189,6 +189,11 @@ static const struct icssg_pa_stats icssg_all_pa_stats[] = {
ICSSG_PA_STATS(FW_INF_DROP_PRIOTAGGED),
ICSSG_PA_STATS(FW_INF_DROP_NOTAG),
ICSSG_PA_STATS(FW_INF_DROP_NOTMEMBER),
+ ICSSG_PA_STATS(FW_PREEMPT_BAD_FRAG),
+ ICSSG_PA_STATS(FW_PREEMPT_ASSEMBLY_ERR),
+ ICSSG_PA_STATS(FW_PREEMPT_FRAG_CNT_TX),
+ ICSSG_PA_STATS(FW_PREEMPT_ASSEMBLY_OK),
+ ICSSG_PA_STATS(FW_PREEMPT_FRAG_CNT_RX),
ICSSG_PA_STATS(FW_RX_EOF_SHORT_FRMERR),
ICSSG_PA_STATS(FW_RX_B0_DROP_EARLY_EOF),
ICSSG_PA_STATS(FW_TX_JUMBO_FRM_CUTOFF),
diff --git a/drivers/net/ethernet/ti/icssg/icssg_switch_map.h b/drivers/net/ethernet/ti/icssg/icssg_switch_map.h
index 7e053b8af3ece..855fd4ed0b3f6 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_switch_map.h
+++ b/drivers/net/ethernet/ti/icssg/icssg_switch_map.h
@@ -256,6 +256,11 @@
#define FW_INF_DROP_PRIOTAGGED 0x0148
#define FW_INF_DROP_NOTAG 0x0150
#define FW_INF_DROP_NOTMEMBER 0x0158
+#define FW_PREEMPT_BAD_FRAG 0x0160
+#define FW_PREEMPT_ASSEMBLY_ERR 0x0168
+#define FW_PREEMPT_FRAG_CNT_TX 0x0170
+#define FW_PREEMPT_ASSEMBLY_OK 0x0178
+#define FW_PREEMPT_FRAG_CNT_RX 0x0180
#define FW_RX_EOF_SHORT_FRMERR 0x0188
#define FW_RX_B0_DROP_EARLY_EOF 0x0190
#define FW_TX_JUMBO_FRM_CUTOFF 0x0198
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v2 3/3] arm64: dts: imx8dxl: Add SolidRun SoM and HummingBoard
From: Josua Mayer @ 2026-04-30 11:17 UTC (permalink / raw)
To: Andrew Lunn
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Yazan Shhady, Mikhail Anikin, Alexander Dahl,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
Vladimir Oltean, Conor Dooley, Krzysztof Kozlowski,
netdev@vger.kernel.org
In-Reply-To: <8efbafe3-0a8a-4005-960c-e8fe62cee719@lunn.ch>
Am 09.04.26 um 14:46 schrieb Andrew Lunn:
>> +&eqos {
>> + /* delays are added by connected ethernet-switch cpu port */
>> + phy-mode = "rgmii";
>> + pinctrl-0 = <&eqos_pins>;
>> + pinctrl-names = "default";
>> + status = "okay";
>> +
>> + fixed-link {
>> + full-duplex;
>> + speed = <1000>;
>> + };
>> +};
>
>> + ethernet-switch@0 {
>> + compatible = "nxp,sja1110a";
>> + reg = <0>;
>> + reset-gpios = <&lsio_gpio4 3 GPIO_ACTIVE_LOW>;
>> + spi-max-frequency = <4000000>;
>> +
>> + ethernet-ports {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> +
>> + /* 100Base-TX on connector J26 */
>> + port@1 {
>> + reg = <0x1>;
>> + label = "lan1";
>> + phy-handle = <&switch_port1_base_tx_phy>;
>> + phy-mode = "internal";
>> + status = "okay";
dropping unnecessary status okay for v3
>> + };
>> +
>> + /* CPU */
>> + port@2 {
>> + reg = <0x2>;
>> + ethernet = <&eqos>;
>> + label = "cpu";
>> + phy-mode = "rgmii-id";
>> + rx-internal-delay-ps = <2000>;
>> + tx-internal-delay-ps = <2000>;
>> + status = "okay";
dropping unnecessary status okay for v3
>> +
>> + fixed-link {
>> + full-duplex;
>> + speed = <1000>;
>> + };
>> + };
>> +
>> + /* sgmii on addon board connector J21 */
>> + port@3 {
>> + reg = <0x3>;
>> + label = "lan3";
>> + status = "disabled";
>> + };
>> +
>> + /* sgmii on addon board connector J21 */
>> + port@4 {
>> + reg = <0x4>;
>> + label = "lan4";
>> + status = "disabled";
>> + };
>> +
>> + /* 100base-t1 on addon board connector J21 */
>> + port@5 {
>> + reg = <0x5>;
>> + label = "trx1";
>> + phy-handle = <&switch_port5_base_t1_phy>;
>> + phy-mode = "internal";
>> + status = "disabled";
>> + };
>> +
>> + /* 100base-t1 on addon board connector J21 */
>> + port@6 {
>> + reg = <0x6>;
>> + label = "trx2";
>> + phy-handle = <&switch_port6_base_t1_phy>;
>> + phy-mode = "internal";
>> + status = "disabled";
>> + };
>> +
>> + /* 100base-t1 on addon board connector J21 */
>> + port@7 {
>> + reg = <0x7>;
>> + label = "trx3";
>> + phy-handle = <&switch_port7_base_t1_phy>;
>> + phy-mode = "internal";
>> + status = "disabled";
>> + };
>> +
>> + /* 100base-t1 on addon board connector J21 */
>> + port@8 {
>> + reg = <0x8>;
>> + label = "trx4";
>> + phy-handle = <&switch_port8_base_t1_phy>;
>> + phy-mode = "internal";
>> + status = "disabled";
>> + };
>> +
>> + /* 100base-t1 on addon board connector J21 */
>> + port@9 {
>> + reg = <0x9>;
>> + label = "trx5";
>> + phy-handle = <&switch_port9_base_t1_phy>;
>> + phy-mode = "internal";
>> + status = "disabled";
>> + };
>> +
>> + /* 100Base-T1 on connector J26 */
>> + port@a {
>> + reg = <0xa>;
>> + label = "trx6";
>> + phy-handle = <&switch_port10_base_t1_phy>;
>> + phy-mode = "internal";
>> + status = "okay";
dropping unnecessary status okay for v3
>> + };
>> + };
>> +
>> + mdios {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> +
>> + mdio@0 {
>> + compatible = "nxp,sja1110-base-t1-mdio";
>> + reg = <0>;
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> +
>> + /* 100base-t1 on addon board connector J21 */
>> + switch_port5_base_t1_phy: ethernet-phy@1 {
>> + compatible = "ethernet-phy-ieee802.3-c45";
>> + reg = <0x1>;
>> + status = "disabled";
>> + };
>> +
>> + /* 100base-t1 on addon board connector J21 */
>> + switch_port6_base_t1_phy: ethernet-phy@2 {
>> + compatible = "ethernet-phy-ieee802.3-c45";
>> + reg = <0x2>;
>> + status = "disabled";
>> + };
>> +
>> + /* 100base-t1 on addon board connector J21 */
>> + switch_port7_base_t1_phy: ethernet-phy@3 {
>> + compatible = "ethernet-phy-ieee802.3-c45";
>> + reg = <0x3>;
>> + status = "disabled";
>> + };
>> +
>> + /* 100base-t1 on addon board connector J21 */
>> + switch_port8_base_t1_phy: ethernet-phy@4 {
>> + compatible = "ethernet-phy-ieee802.3-c45";
>> + reg = <0x4>;
>> + status = "disabled";
>> + };
>> +
>> + /* 100base-t1 on addon board connector J21 */
>> + switch_port9_base_t1_phy: ethernet-phy@5 {
>> + compatible = "ethernet-phy-ieee802.3-c45";
>> + reg = <0x5>;
>> + status = "disabled";
>> + };
>> +
>> + /* 100Base-T1 on connector J26 */
>> + switch_port10_base_t1_phy: ethernet-phy@6 {
>> + compatible = "ethernet-phy-ieee802.3-c45";
>> + reg = <0x6>;
>> + };
>> + };
>> +
>> + mdio@1 {
>> + compatible = "nxp,sja1110-base-tx-mdio";
>> + reg = <1>;
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> +
>> + /* 100Base-TX on connector J26 */
>> + switch_port1_base_tx_phy: ethernet-phy@1 {
>> + reg = <0x1>;
>> + };
>> + };
> For these nodes only:
>
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
>
> Andrew
Thanks!
I don't know how to keep this partial review for v3, so I will send it without.
^ permalink raw reply
* [GIT PULL] wireless-2026-04-30
From: Johannes Berg @ 2026-04-30 11:17 UTC (permalink / raw)
To: netdev; +Cc: linux-wireless
Hi,
So the LLM floodgates are starting to open ;-) But I'm somewhat
happy that so far we haven't gotten any really critical reports.
Here's a couple of first fixes though.
Please pull and let us know if there's any problem.
Thanks,
johannes
The following changes since commit 254f49634ee16a731174d2ae34bc50bd5f45e731:
Linux 7.1-rc1 (2026-04-26 14:19:00 -0700)
are available in the Git repository at:
https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless.git tags/wireless-2026-04-30
for you to fetch changes up to d997c32157d2ca06e9f3f00ba6c4bf06593b49e7:
Merge tag 'ath-current-20260427' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath (2026-04-28 10:41:51 +0200)
----------------------------------------------------------------
Couple of initial fixes:
- mac80211
- remove HT NSS validation to work with broken APs
- remove 'static' that could cause races
- check station link lookup before further processing
- ath12k
- fix OF node refcount imbalance
- fix queue flush ("REO update") in MLO
- fix RCU assert
- ath12k: fix Kconfig with POWER_SEQUENCING
- rsi: fix thread lifetime race
- brcmfmac: fix potential UAF
- nl80211: require admin permissions for PMK management
- various fixes to not trust values from firmware
----------------------------------------------------------------
Aaradhana Sahu (1):
wifi: ath12k: fix OF node refcount imbalance in WSI graph traversal
Amir Mohammad Jahangirzad (1):
wifi: libertas: fix integer underflow in process_cmdrequest()
Baochen Qiang (1):
wifi: ath12k: prepare REO update element only for primary link
Catherine (1):
wifi: mac80211: drop stray 'static' from fast-RX rx_result
Dmitry Baryshkov (1):
wifi: ath10k: snoc: select POWER_SEQUENCING
Jeongjun Park (1):
wifi: rsi: fix kthread lifetime race between self-exit and external-stop
Johannes Berg (1):
Merge tag 'ath-current-20260427' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath
Marek Szyprowski (1):
wifi: brcmfmac: Fix potential use-after-free issue when stopping watchdog task
Michael Bommarito (2):
wifi: nl80211: require admin perm on SET_PMK / DEL_PMK
wifi: mac80211: check ieee80211_rx_data_set_link return in pubsta MLO path
Rio Liu (1):
wifi: mac80211: skip ieee80211_verify_sta_ht_mcs_support check in non-strict mode
Tristan Madani (2):
wifi: b43: enforce bounds check on firmware key index in b43_rx()
wifi: b43legacy: enforce bounds check on firmware key index in RX path
Yu-Hsiang Tseng (1):
wifi: ath12k: use lockdep_assert_in_rcu_read_lock() for RCU assertions
drivers/net/wireless/ath/ath10k/Kconfig | 1 +
drivers/net/wireless/ath/ath12k/core.c | 77 ++++++++++++++--------
drivers/net/wireless/ath/ath12k/dp_rx.c | 3 +
drivers/net/wireless/ath/ath12k/mac.c | 2 +-
drivers/net/wireless/ath/ath12k/p2p.c | 2 +-
drivers/net/wireless/broadcom/b43/xmit.c | 3 +-
drivers/net/wireless/broadcom/b43legacy/xmit.c | 3 +-
.../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 6 +-
drivers/net/wireless/marvell/libertas/if_usb.c | 5 +-
drivers/net/wireless/rsi/rsi_common.h | 5 +-
net/mac80211/mlme.c | 9 +++
net/mac80211/rx.c | 6 +-
net/wireless/nl80211.c | 2 +
13 files changed, 82 insertions(+), 42 deletions(-)
^ permalink raw reply
* Re: [PATCH v2 3/3] arm64: dts: imx8dxl: Add SolidRun SoM and HummingBoard
From: Vladimir Oltean @ 2026-04-30 11:19 UTC (permalink / raw)
To: Josua Mayer
Cc: Andrew Lunn, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Shawn Guo, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Vladimir Oltean, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Yazan Shhady, Mikhail Anikin,
Alexander Dahl, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org, Conor Dooley,
Krzysztof Kozlowski, netdev@vger.kernel.org
In-Reply-To: <bd2e73c5-2e61-4ea1-ab3b-42a6573b31f8@solid-run.com>
On Thu, Apr 30, 2026 at 11:17:36AM +0000, Josua Mayer wrote:
> Am 09.04.26 um 14:46 schrieb Andrew Lunn:
> >> +&eqos {
> >> + /* delays are added by connected ethernet-switch cpu port */
> >> + phy-mode = "rgmii";
> >> + pinctrl-0 = <&eqos_pins>;
> >> + pinctrl-names = "default";
> >> + status = "okay";
> >> +
> >> + fixed-link {
> >> + full-duplex;
> >> + speed = <1000>;
> >> + };
> >> +};
> >
> >> + ethernet-switch@0 {
> >> + compatible = "nxp,sja1110a";
> >> + reg = <0>;
> >> + reset-gpios = <&lsio_gpio4 3 GPIO_ACTIVE_LOW>;
> >> + spi-max-frequency = <4000000>;
> >> +
> >> + ethernet-ports {
> >> + #address-cells = <1>;
> >> + #size-cells = <0>;
> >> +
> >> + /* 100Base-TX on connector J26 */
> >> + port@1 {
> >> + reg = <0x1>;
> >> + label = "lan1";
> >> + phy-handle = <&switch_port1_base_tx_phy>;
> >> + phy-mode = "internal";
> >> + status = "okay";
> dropping unnecessary status okay for v3
> >> + };
> >> +
> >> + /* CPU */
> >> + port@2 {
> >> + reg = <0x2>;
> >> + ethernet = <&eqos>;
> >> + label = "cpu";
Please drop unused label = "cpu". Also, can you use udev for user
interface naming?
> >> + phy-mode = "rgmii-id";
> >> + rx-internal-delay-ps = <2000>;
> >> + tx-internal-delay-ps = <2000>;
> >> + status = "okay";
> dropping unnecessary status okay for v3
> >> +
> >> + fixed-link {
> >> + full-duplex;
> >> + speed = <1000>;
> >> + };
> >> + };
> >> +
> >> + /* sgmii on addon board connector J21 */
> >> + port@3 {
> >> + reg = <0x3>;
> >> + label = "lan3";
> >> + status = "disabled";
> >> + };
> >> +
> >> + /* sgmii on addon board connector J21 */
> >> + port@4 {
> >> + reg = <0x4>;
> >> + label = "lan4";
> >> + status = "disabled";
> >> + };
> >> +
> >> + /* 100base-t1 on addon board connector J21 */
> >> + port@5 {
> >> + reg = <0x5>;
> >> + label = "trx1";
> >> + phy-handle = <&switch_port5_base_t1_phy>;
> >> + phy-mode = "internal";
> >> + status = "disabled";
> >> + };
> >> +
> >> + /* 100base-t1 on addon board connector J21 */
> >> + port@6 {
> >> + reg = <0x6>;
> >> + label = "trx2";
> >> + phy-handle = <&switch_port6_base_t1_phy>;
> >> + phy-mode = "internal";
> >> + status = "disabled";
> >> + };
> >> +
> >> + /* 100base-t1 on addon board connector J21 */
> >> + port@7 {
> >> + reg = <0x7>;
> >> + label = "trx3";
> >> + phy-handle = <&switch_port7_base_t1_phy>;
> >> + phy-mode = "internal";
> >> + status = "disabled";
> >> + };
> >> +
> >> + /* 100base-t1 on addon board connector J21 */
> >> + port@8 {
> >> + reg = <0x8>;
> >> + label = "trx4";
> >> + phy-handle = <&switch_port8_base_t1_phy>;
> >> + phy-mode = "internal";
> >> + status = "disabled";
> >> + };
> >> +
> >> + /* 100base-t1 on addon board connector J21 */
> >> + port@9 {
> >> + reg = <0x9>;
> >> + label = "trx5";
> >> + phy-handle = <&switch_port9_base_t1_phy>;
> >> + phy-mode = "internal";
> >> + status = "disabled";
> >> + };
> >> +
> >> + /* 100Base-T1 on connector J26 */
> >> + port@a {
> >> + reg = <0xa>;
> >> + label = "trx6";
> >> + phy-handle = <&switch_port10_base_t1_phy>;
> >> + phy-mode = "internal";
> >> + status = "okay";
> dropping unnecessary status okay for v3
> >> + };
> >> + };
> >> +
> >> + mdios {
> >> + #address-cells = <1>;
> >> + #size-cells = <0>;
> >> +
> >> + mdio@0 {
> >> + compatible = "nxp,sja1110-base-t1-mdio";
> >> + reg = <0>;
> >> + #address-cells = <1>;
> >> + #size-cells = <0>;
> >> +
> >> + /* 100base-t1 on addon board connector J21 */
> >> + switch_port5_base_t1_phy: ethernet-phy@1 {
> >> + compatible = "ethernet-phy-ieee802.3-c45";
> >> + reg = <0x1>;
> >> + status = "disabled";
> >> + };
> >> +
> >> + /* 100base-t1 on addon board connector J21 */
> >> + switch_port6_base_t1_phy: ethernet-phy@2 {
> >> + compatible = "ethernet-phy-ieee802.3-c45";
> >> + reg = <0x2>;
> >> + status = "disabled";
> >> + };
> >> +
> >> + /* 100base-t1 on addon board connector J21 */
> >> + switch_port7_base_t1_phy: ethernet-phy@3 {
> >> + compatible = "ethernet-phy-ieee802.3-c45";
> >> + reg = <0x3>;
> >> + status = "disabled";
> >> + };
> >> +
> >> + /* 100base-t1 on addon board connector J21 */
> >> + switch_port8_base_t1_phy: ethernet-phy@4 {
> >> + compatible = "ethernet-phy-ieee802.3-c45";
> >> + reg = <0x4>;
> >> + status = "disabled";
> >> + };
> >> +
> >> + /* 100base-t1 on addon board connector J21 */
> >> + switch_port9_base_t1_phy: ethernet-phy@5 {
> >> + compatible = "ethernet-phy-ieee802.3-c45";
> >> + reg = <0x5>;
> >> + status = "disabled";
> >> + };
> >> +
> >> + /* 100Base-T1 on connector J26 */
> >> + switch_port10_base_t1_phy: ethernet-phy@6 {
> >> + compatible = "ethernet-phy-ieee802.3-c45";
> >> + reg = <0x6>;
> >> + };
> >> + };
> >> +
> >> + mdio@1 {
> >> + compatible = "nxp,sja1110-base-tx-mdio";
> >> + reg = <1>;
> >> + #address-cells = <1>;
> >> + #size-cells = <0>;
> >> +
> >> + /* 100Base-TX on connector J26 */
> >> + switch_port1_base_tx_phy: ethernet-phy@1 {
> >> + reg = <0x1>;
> >> + };
> >> + };
> > For these nodes only:
> >
> > Reviewed-by: Andrew Lunn <andrew@lunn.ch>
> >
> > Andrew
>
> Thanks!
>
> I don't know how to keep this partial review for v3, so I will send it without.
^ permalink raw reply
* Re: [PATCH net] net: phy: micrel: fix LAN8814 QSGMII soft reset
From: Paolo Abeni @ 2026-04-30 11:27 UTC (permalink / raw)
To: Robert Marko, andrew, hkallweit1, linux, davem, edumazet, kuba,
Divya.Koppera, horatiu.vultur, netdev, linux-kernel
In-Reply-To: <20260428134138.1741253-1-robert.marko@sartura.hr>
On 4/28/26 3:41 PM, Robert Marko wrote:
> LAN8814 QSGMII soft reset was moved into the probe function to avoid
> triggering it for each of 4 PHY-s in the package.
>
> However, that broke QSGMII link between the MAC and PHY on most LAN8814
> PHY-s, specificaly for us on the Microchip LAN969x switch.
> Reading the QSGMII status registers it was visible that lanes were only
> partially synced.
>
> It looks like the reset timing is crucial, so lets move the reset back
> into the .config_init function but guard it with phy_package_init_once()
> to avoid it being triggered on each of 4 PHY-s in the package.
> Change the probe function to use phy_package_probe_once() for coma and PtP
> setup.
>
> Fixes: 96a9178a29a6 ("net: phy: micrel: lan8814 fix reset of the QSGMII interface")
> Signed-off-by: Robert Marko <robert.marko@sartura.hr>
> ---
> drivers/net/phy/micrel.c | 15 ++++++++-------
> 1 file changed, 8 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
> index 2aa1dedd21b8..e211a523c258 100644
> --- a/drivers/net/phy/micrel.c
> +++ b/drivers/net/phy/micrel.c
> @@ -4548,6 +4548,13 @@ static int lan8814_config_init(struct phy_device *phydev)
> struct kszphy_priv *lan8814 = phydev->priv;
> int ret;
>
> + if (phy_package_init_once(phydev))
> + /* Reset the PHY */
> + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
> + LAN8814_QSGMII_SOFT_RESET,
> + LAN8814_QSGMII_SOFT_RESET_BIT,
> + LAN8814_QSGMII_SOFT_RESET_BIT)
Sashiko says:
---
Could this introduce a race condition if multiple ports are brought up
concurrently?
Because phy_package_init_once() does not provide a synchronization
barrier for followers, they might proceed immediately to configure their
registers while the leader is still performing the reset.
---
on top of my head IDK if such race is possible at all.
/P
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH v7 net-next 7/8] ice: add Tx reference clock index handling to AN restart command
From: Loktionov, Aleksandr @ 2026-04-30 11:29 UTC (permalink / raw)
To: Nitka, Grzegorz, netdev@vger.kernel.org
Cc: Vecera, Ivan, vadim.fedorenko@linux.dev, kuba@kernel.org,
jiri@resnulli.us, edumazet@google.com, Kitszel, Przemyslaw,
richardcochran@gmail.com, donald.hunter@gmail.com,
linux-kernel@vger.kernel.org, Kubalewski, Arkadiusz,
andrew+netdev@lunn.ch, intel-wired-lan@lists.osuosl.org,
horms@kernel.org, Prathosh.Satish@microchip.com,
Nguyen, Anthony L, pabeni@redhat.com, davem@davemloft.net
In-Reply-To: <20260430094238.987976-8-grzegorz.nitka@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Grzegorz Nitka
> Sent: Thursday, April 30, 2026 11:43 AM
> To: netdev@vger.kernel.org
> Cc: Vecera, Ivan <ivecera@redhat.com>; vadim.fedorenko@linux.dev;
> kuba@kernel.org; jiri@resnulli.us; edumazet@google.com; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; richardcochran@gmail.com;
> donald.hunter@gmail.com; linux-kernel@vger.kernel.org; Kubalewski,
> Arkadiusz <arkadiusz.kubalewski@intel.com>; andrew+netdev@lunn.ch;
> intel-wired-lan@lists.osuosl.org; horms@kernel.org;
> Prathosh.Satish@microchip.com; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; pabeni@redhat.com; davem@davemloft.net
> Subject: [Intel-wired-lan] [PATCH v7 net-next 7/8] ice: add Tx
> reference clock index handling to AN restart command
>
> Extend the Restart Auto-Negotiation (AN) AdminQ command with a new
> parameter allowing software to specify the Tx reference clock index to
> be used during link restart.
>
> This patch:
> - adds REFCLK field definitions to ice_aqc_restart_an
> - updates ice_aq_set_link_restart_an() to take a new refclk parameter
> and properly encode it into the command
> - keeps legacy behavior by passing REFCLK_NOCHANGE where appropriate
>
> This prepares the driver for configurations requiring dynamic
> selection of the Tx reference clock as part of the AN flow.
>
> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
> ---
> drivers/net/ethernet/intel/ice/ice_adminq_cmd.h | 2 ++
> drivers/net/ethernet/intel/ice/ice_common.c | 5 ++++-
> drivers/net/ethernet/intel/ice/ice_common.h | 2 +-
> drivers/net/ethernet/intel/ice/ice_lib.c | 3 ++-
> 4 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
> b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
> index 3cbb1b0582e3..42878abac9eb 100644
> --- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
> +++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
> @@ -1169,6 +1169,8 @@ struct ice_aqc_restart_an {
> u8 cmd_flags;
> #define ICE_AQC_RESTART_AN_LINK_RESTART BIT(1)
> #define ICE_AQC_RESTART_AN_LINK_ENABLE BIT(2)
> +#define ICE_AQC_RESTART_AN_REFCLK_M GENMASK(4, 3)
> +#define ICE_AQC_RESTART_AN_REFCLK_NOCHANGE 0
> u8 reserved2[13];
> };
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_common.c
> b/drivers/net/ethernet/intel/ice/ice_common.c
> index ce11fea122d0..de88aec9137c 100644
> --- a/drivers/net/ethernet/intel/ice/ice_common.c
> +++ b/drivers/net/ethernet/intel/ice/ice_common.c
> @@ -4126,12 +4126,13 @@ int ice_get_link_status(struct ice_port_info
> *pi, bool *link_up)
> * @pi: pointer to the port information structure
> * @ena_link: if true: enable link, if false: disable link
> * @cd: pointer to command details structure or NULL
> + * @refclk: the new TX reference clock, 0 if no change
> *
> * Sets up the link and restarts the Auto-Negotiation over the link.
> */
> int
> ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link,
> - struct ice_sq_cd *cd)
> + struct ice_sq_cd *cd, u8 refclk)
> {
> struct ice_aqc_restart_an *cmd;
> struct libie_aq_desc desc;
> @@ -4147,6 +4148,8 @@ ice_aq_set_link_restart_an(struct ice_port_info
> *pi, bool ena_link,
> else
> cmd->cmd_flags &= ~ICE_AQC_RESTART_AN_LINK_ENABLE;
>
> + cmd->cmd_flags |= FIELD_PREP(ICE_AQC_RESTART_AN_REFCLK_M,
> refclk);
> +
> return ice_aq_send_cmd(pi->hw, &desc, NULL, 0, cd); }
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_common.h
> b/drivers/net/ethernet/intel/ice/ice_common.h
> index e700ac0dc347..9f5344212195 100644
> --- a/drivers/net/ethernet/intel/ice/ice_common.h
> +++ b/drivers/net/ethernet/intel/ice/ice_common.h
> @@ -215,7 +215,7 @@ ice_cfg_phy_fec(struct ice_port_info *pi, struct
> ice_aqc_set_phy_cfg_data *cfg,
> enum ice_fec_mode fec);
> int
> ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link,
> - struct ice_sq_cd *cd);
> + struct ice_sq_cd *cd, u8 refclk);
> int
> ice_aq_set_mac_cfg(struct ice_hw *hw, u16 max_frame_size, struct
> ice_sq_cd *cd); int diff --git
> a/drivers/net/ethernet/intel/ice/ice_lib.c
> b/drivers/net/ethernet/intel/ice/ice_lib.c
> index 837b71b7b2b7..8cdc4fda89e9 100644
> --- a/drivers/net/ethernet/intel/ice/ice_lib.c
> +++ b/drivers/net/ethernet/intel/ice/ice_lib.c
> @@ -3769,7 +3769,8 @@ int ice_set_link(struct ice_vsi *vsi, bool ena)
> if (vsi->type != ICE_VSI_PF)
> return -EINVAL;
>
> - status = ice_aq_set_link_restart_an(pi, ena, NULL);
> + status = ice_aq_set_link_restart_an(pi, ena, NULL,
> +
> ICE_AQC_RESTART_AN_REFCLK_NOCHANGE);
>
> /* if link is owned by manageability, FW will return
> LIBIE_AQ_RC_EMODE.
> * this is not a fatal error, so print a warning message and
> return
> --
> 2.39.3
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH v7 net-next 8/8] ice: implement E825 TX ref clock control and TXC hardware sync status
From: Loktionov, Aleksandr @ 2026-04-30 11:33 UTC (permalink / raw)
To: Nitka, Grzegorz, netdev@vger.kernel.org
Cc: Vecera, Ivan, vadim.fedorenko@linux.dev, kuba@kernel.org,
jiri@resnulli.us, edumazet@google.com, Kitszel, Przemyslaw,
richardcochran@gmail.com, donald.hunter@gmail.com,
linux-kernel@vger.kernel.org, Kubalewski, Arkadiusz,
andrew+netdev@lunn.ch, intel-wired-lan@lists.osuosl.org,
horms@kernel.org, Prathosh.Satish@microchip.com,
Nguyen, Anthony L, pabeni@redhat.com, davem@davemloft.net
In-Reply-To: <20260430094238.987976-9-grzegorz.nitka@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Grzegorz Nitka
> Sent: Thursday, April 30, 2026 11:43 AM
> To: netdev@vger.kernel.org
> Cc: Vecera, Ivan <ivecera@redhat.com>; vadim.fedorenko@linux.dev;
> kuba@kernel.org; jiri@resnulli.us; edumazet@google.com; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; richardcochran@gmail.com;
> donald.hunter@gmail.com; linux-kernel@vger.kernel.org; Kubalewski,
> Arkadiusz <arkadiusz.kubalewski@intel.com>; andrew+netdev@lunn.ch;
> intel-wired-lan@lists.osuosl.org; horms@kernel.org;
> Prathosh.Satish@microchip.com; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; pabeni@redhat.com; davem@davemloft.net
> Subject: [Intel-wired-lan] [PATCH v7 net-next 8/8] ice: implement E825
> TX ref clock control and TXC hardware sync status
>
> Build on the previously introduced TXC DPLL framework and implement
> full TX reference clock control and hardware-backed synchronization
> status reporting for E825 devices.
>
> E825 firmware may accept or override TX reference clock requests based
> on device-wide routing constraints and link conditions. For this
> reason, TX reference selection and synchronization status must be
> observed from hardware rather than inferred from user intent.
>
> This change implements TX reference switching using a deferred worker,
> triggered by DPLL TXCLK pin operations. Pin set callbacks express
> selection intent and schedule the operation asynchronously; firmware
> commands and autonegotiation restarts are executed outside of DPLL
> context.
>
> After link-up, the effective TX reference clock is read back from
> hardware and software state is reconciled accordingly. TXCLK pin state
> reflects only the selected reference clock topology:
> - External references (SYNCE, EREF0) are represented as TXCLK pins
> - The internal ENET/TXCO clock has no pin representation; when
> selected,
> all TXCLK pins are reported DISCONNECTED
>
> Actual hardware synchronization result is reported exclusively via the
> TXC DPLL lock status:
> - LOCKED when an external TX reference is in use
> - UNLOCKED when falling back to ENET/TXCO
>
> This separation allows userspace to distinguish between TX reference
> selection and successful synchronization, matching the DPLL subsystem
> model where pin state describes topology and device lock status
> describes signal quality.
>
> With this change, TX reference clocks on E825 devices can be reliably
> selected, verified against hardware state, and monitored for effective
> synchronization via standard DPLL interfaces.
>
> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
> ---
> drivers/net/ethernet/intel/ice/Makefile | 2 +-
> drivers/net/ethernet/intel/ice/ice.h | 12 +
> drivers/net/ethernet/intel/ice/ice_dpll.c | 110 ++++++++-
> drivers/net/ethernet/intel/ice/ice_dpll.h | 4 +
> drivers/net/ethernet/intel/ice/ice_ptp.c | 26 +-
> drivers/net/ethernet/intel/ice/ice_ptp.h | 7 +
> drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 37 +++
> drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 27 +++
> drivers/net/ethernet/intel/ice/ice_txclk.c | 255 ++++++++++++++++++++
> drivers/net/ethernet/intel/ice/ice_txclk.h | 38 +++
> 10 files changed, 499 insertions(+), 19 deletions(-) create mode
> 100644 drivers/net/ethernet/intel/ice/ice_txclk.c
> create mode 100644 drivers/net/ethernet/intel/ice/ice_txclk.h
>
> diff --git a/drivers/net/ethernet/intel/ice/Makefile
> b/drivers/net/ethernet/intel/ice/Makefile
> index 38db476ab2ec..95fd0c49800f 100644
> --- a/drivers/net/ethernet/intel/ice/Makefile
> +++ b/drivers/net/ethernet/intel/ice/Makefile
> @@ -54,7 +54,7 @@ ice-$(CONFIG_PCI_IOV) += \
> ice_vf_mbx.o \
> ice_vf_vsi_vlan_ops.o \
> ice_vf_lib.o
> -ice-$(CONFIG_PTP_1588_CLOCK) += ice_ptp.o ice_ptp_hw.o ice_dpll.o
> ice_tspll.o ice_cpi.o
> +ice-$(CONFIG_PTP_1588_CLOCK) += ice_ptp.o ice_ptp_hw.o ice_dpll.o
> +ice_tspll.o ice_cpi.o ice_txclk.o
> ice-$(CONFIG_DCB) += ice_dcb.o ice_dcb_nl.o ice_dcb_lib.o
> ice-$(CONFIG_RFS_ACCEL) += ice_arfs.o
> ice-$(CONFIG_XDP_SOCKETS) += ice_xsk.o
> diff --git a/drivers/net/ethernet/intel/ice/ice.h
> b/drivers/net/ethernet/intel/ice/ice.h
> index 725b130dd3a2..f72bb1aa4067 100644
> --- a/drivers/net/ethernet/intel/ice/ice.h
> +++ b/drivers/net/ethernet/intel/ice/ice.h
> @@ -1155,4 +1155,16 @@ static inline struct ice_hw
> *ice_get_primary_hw(struct ice_pf *pf)
> else
> return &pf->adapter->ctrl_pf->hw;
> }
...
> * * negative - failure
> */
> static int
> @@ -2547,11 +2586,29 @@ ice_dpll_txclk_state_on_dpll_set(const struct
> dpll_pin *pin, void *pin_priv,
> void *dpll_priv, enum dpll_pin_state
> state,
> struct netlink_ext_ack *extack)
> {
> - /*
> - * TODO: set HW accordingly to selected TX reference clock.
> - * To be added in the follow up patches.
> - */
> - return -EOPNOTSUPP;
> + struct ice_dpll_pin *p = pin_priv;
> + struct ice_pf *pf = p->pf;
> + enum ice_e825c_ref_clk new_clk;
> +
> + if (ice_dpll_is_reset(pf, extack))
> + return -EBUSY;
> +
> + mutex_lock(&pf->dplls.lock);
> + new_clk = (state == DPLL_PIN_STATE_DISCONNECTED) ?
> ICE_REF_CLK_ENET :
> + p->tx_ref_src;
> + if (new_clk == pf->ptp.port.tx_clk_req) {
> + NL_SET_ERR_MSG_FMT(extack,
> + "pin:%u state:%u on parent device
> already set",
> + p->idx, state);
> + goto unlock;
extack message attached, but ...
> + }
> +
> + pf->ptp.port.tx_clk_req = new_clk;
> + pf->dplls.txclk_switch_requested = true;
> + queue_work(pf->dplls.wq, &pf->dplls.txclk_work);
> +unlock:
> + mutex_unlock(&pf->dplls.lock);
> + return 0;
... function returns success.
IMHO either drop the message or return -EALREADY/-EBUSY.
Or I missed something?
> }
>
> /**
> @@ -2563,10 +2620,21 @@ ice_dpll_txclk_state_on_dpll_set(const struct
> dpll_pin *pin, void *pin_priv,
> * @state: on success holds pin state on parent pin
> * @extack: error reporting
> *
...
> --
> 2.39.3
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH v7 net-next 8/8] ice: implement E825 TX ref clock control and TXC hardware sync status
From: Loktionov, Aleksandr @ 2026-04-30 11:37 UTC (permalink / raw)
To: Nitka, Grzegorz, netdev@vger.kernel.org
Cc: Vecera, Ivan, vadim.fedorenko@linux.dev, kuba@kernel.org,
jiri@resnulli.us, edumazet@google.com, Kitszel, Przemyslaw,
richardcochran@gmail.com, donald.hunter@gmail.com,
linux-kernel@vger.kernel.org, Kubalewski, Arkadiusz,
andrew+netdev@lunn.ch, intel-wired-lan@lists.osuosl.org,
horms@kernel.org, Prathosh.Satish@microchip.com,
Nguyen, Anthony L, pabeni@redhat.com, davem@davemloft.net
In-Reply-To: <20260430094238.987976-9-grzegorz.nitka@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Grzegorz Nitka
> Sent: Thursday, April 30, 2026 11:43 AM
> To: netdev@vger.kernel.org
> Cc: Vecera, Ivan <ivecera@redhat.com>; vadim.fedorenko@linux.dev;
> kuba@kernel.org; jiri@resnulli.us; edumazet@google.com; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; richardcochran@gmail.com;
> donald.hunter@gmail.com; linux-kernel@vger.kernel.org; Kubalewski,
> Arkadiusz <arkadiusz.kubalewski@intel.com>; andrew+netdev@lunn.ch;
> intel-wired-lan@lists.osuosl.org; horms@kernel.org;
> Prathosh.Satish@microchip.com; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; pabeni@redhat.com; davem@davemloft.net
> Subject: [Intel-wired-lan] [PATCH v7 net-next 8/8] ice: implement E825
> TX ref clock control and TXC hardware sync status
>
> Build on the previously introduced TXC DPLL framework and implement
> full TX reference clock control and hardware-backed synchronization
> status reporting for E825 devices.
>
> E825 firmware may accept or override TX reference clock requests based
> on device-wide routing constraints and link conditions. For this
> reason, TX reference selection and synchronization status must be
> observed from hardware rather than inferred from user intent.
>
> This change implements TX reference switching using a deferred worker,
> triggered by DPLL TXCLK pin operations. Pin set callbacks express
> selection intent and schedule the operation asynchronously; firmware
> commands and autonegotiation restarts are executed outside of DPLL
> context.
>
> After link-up, the effective TX reference clock is read back from
> hardware and software state is reconciled accordingly. TXCLK pin state
> reflects only the selected reference clock topology:
> - External references (SYNCE, EREF0) are represented as TXCLK pins
> - The internal ENET/TXCO clock has no pin representation; when
> selected,
> all TXCLK pins are reported DISCONNECTED
>
> Actual hardware synchronization result is reported exclusively via the
> TXC DPLL lock status:
> - LOCKED when an external TX reference is in use
> - UNLOCKED when falling back to ENET/TXCO
>
> This separation allows userspace to distinguish between TX reference
> selection and successful synchronization, matching the DPLL subsystem
> model where pin state describes topology and device lock status
> describes signal quality.
>
> With this change, TX reference clocks on E825 devices can be reliably
> selected, verified against hardware state, and monitored for effective
> synchronization via standard DPLL interfaces.
>
> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
> ---
> drivers/net/ethernet/intel/ice/Makefile | 2 +-
> drivers/net/ethernet/intel/ice/ice.h | 12 +
> drivers/net/ethernet/intel/ice/ice_dpll.c | 110 ++++++++-
> drivers/net/ethernet/intel/ice/ice_dpll.h | 4 +
> drivers/net/ethernet/intel/ice/ice_ptp.c | 26 +-
> drivers/net/ethernet/intel/ice/ice_ptp.h | 7 +
> drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 37 +++
> drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 27 +++
> drivers/net/ethernet/intel/ice/ice_txclk.c | 255 ++++++++++++++++++++
> drivers/net/ethernet/intel/ice/ice_txclk.h | 38 +++
> 10 files changed, 499 insertions(+), 19 deletions(-) create mode
> 100644 drivers/net/ethernet/intel/ice/ice_txclk.c
> create mode 100644 drivers/net/ethernet/intel/ice/ice_txclk.h
>
> diff --git a/drivers/net/ethernet/intel/ice/Makefile
> b/drivers/net/ethernet/intel/ice/Makefile
> index 38db476ab2ec..95fd0c49800f 100644
> --- a/drivers/net/ethernet/intel/ice/Makefile
> +++ b/drivers/net/ethernet/intel/ice/Makefile
> @@ -54,7 +54,7 @@ ice-$(CONFIG_PCI_IOV) += \
> ice_vf_mbx.o \
> ice_vf_vsi_vlan_ops.o \
> ice_vf_lib.o
...
>
> +/**
> + * ice_dpll_txclk_work - apply a pending TX reference clock change
> + * @work: work_struct embedded in struct ice_dplls
> + *
> + * This worker executes an outstanding TX reference clock switch
> +request
> + * that was previously queued via the DPLL TXCLK pin set callback.
> + *
> + * The worker performs only the operational part of the switch,
> issuing
> + * the necessary firmware commands to request a new TX reference
> clock
> + * selection (e.g. triggering an AN restart). It does not verify
> +whether
> + * the requested clock was ultimately accepted by the hardware.
> + *
> + * Hardware verification, software state reconciliation, pin state
> + * notification, and TXC DPLL lock-status updates are performed
> later,
> + * after link-up, by ice_txclk_update_and_notify().
> + *
> + * Context:
> + * - Runs in process context on pf->dplls.wq and may sleep.
> + * - Serializes access to shared TXCLK state using pf->dplls.lock.
> + */
> +static void ice_dpll_txclk_work(struct work_struct *work) {
> + struct ice_dplls *dplls =
> + container_of(work, struct ice_dplls, txclk_work);
> + struct ice_pf *pf = container_of(dplls, struct ice_pf, dplls);
> + enum ice_e825c_ref_clk clk;
> + bool do_switch;
> +
> + mutex_lock(&pf->dplls.lock);
> + do_switch = pf->dplls.txclk_switch_requested;
Two stray spaces.
> + clk = pf->ptp.port.tx_clk_req;
> + pf->dplls.txclk_switch_requested = false;
Two stray spaces.
> + mutex_unlock(&pf->dplls.lock);
> +
> + if (do_switch)
> + ice_txclk_set_clk(pf, clk);
> +}
> +
...
> --
> 2.39.3
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH v6 net-next 6/8] ice: implement CPI support for E825C
From: Loktionov, Aleksandr @ 2026-04-30 11:40 UTC (permalink / raw)
To: Nitka, Grzegorz, netdev@vger.kernel.org
Cc: Vecera, Ivan, vadim.fedorenko@linux.dev, kuba@kernel.org,
jiri@resnulli.us, edumazet@google.com, Kitszel, Przemyslaw,
richardcochran@gmail.com, donald.hunter@gmail.com,
linux-kernel@vger.kernel.org, Kubalewski, Arkadiusz,
andrew+netdev@lunn.ch, intel-wired-lan@lists.osuosl.org,
horms@kernel.org, Prathosh.Satish@microchip.com,
Nguyen, Anthony L, pabeni@redhat.com, davem@davemloft.net
In-Reply-To: <20260409235122.436749-7-grzegorz.nitka@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Grzegorz Nitka
> Sent: Friday, April 10, 2026 1:51 AM
> To: netdev@vger.kernel.org
> Cc: Vecera, Ivan <ivecera@redhat.com>; vadim.fedorenko@linux.dev;
> kuba@kernel.org; jiri@resnulli.us; edumazet@google.com; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; richardcochran@gmail.com;
> donald.hunter@gmail.com; linux-kernel@vger.kernel.org; Kubalewski,
> Arkadiusz <arkadiusz.kubalewski@intel.com>; andrew+netdev@lunn.ch;
> intel-wired-lan@lists.osuosl.org; horms@kernel.org;
> Prathosh.Satish@microchip.com; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; pabeni@redhat.com; davem@davemloft.net
> Subject: [Intel-wired-lan] [PATCH v6 net-next 6/8] ice: implement CPI
> support for E825C
>
> Add full CPI (Converged PHY Interface) command handling required for
> E825C devices. The CPI interface allows the driver to interact with
> PHY-side control logic through the LM/PHY command registers, including
> enabling/disabling/selection of PHY reference clock.
>
> This patch introduces:
> - a new CPI subsystem (ice_cpi.c / ice_cpi.h) implementing the CPI
> request/acknowledge state machine, including REQ/ACK protocol,
> command execution, and response handling
> - helper functions for reading/writing PHY registers over Sideband
> Queue
> - CPI command execution API (ice_cpi_exec) and a helper for enabling
> or
> disabling Tx reference clocks (CPI 0xF1 opcode 'Config PHY
> clocking')
> - assurance of CPI transaction serialization into the CPI core.
> CPI REQ/ACK is a multi-step handshake and must be executed
> atomically per PHY. Centralize the lock in ice_cpi_exec() and
> use adapter-scoped per-PHY mutexes, which match the hardware
> sharing
> model across PFs.
> - addition of the non-posted write opcode (wr_np) to SBQ
> - Makefile integration to build CPI support together with the PTP
> stack
>
> This provides the infrastructure necessary to support PHY-side
> configuration flows on E825C and is required for advanced link control
> and Tx reference clock management.
>
> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
> ---
> drivers/net/ethernet/intel/ice/Makefile | 2 +-
> drivers/net/ethernet/intel/ice/ice_adapter.c | 4 +
> drivers/net/ethernet/intel/ice/ice_adapter.h | 7 +
> drivers/net/ethernet/intel/ice/ice_cpi.c | 364
> +++++++++++++++++++
> drivers/net/ethernet/intel/ice/ice_cpi.h | 61 ++++
> drivers/net/ethernet/intel/ice/ice_sbq_cmd.h | 5 +-
> drivers/net/ethernet/intel/ice/ice_type.h | 2 +
> 7 files changed, 442 insertions(+), 3 deletions(-) create mode
> 100644 drivers/net/ethernet/intel/ice/ice_cpi.c
> create mode 100644 drivers/net/ethernet/intel/ice/ice_cpi.h
>
> diff --git a/drivers/net/ethernet/intel/ice/Makefile
> b/drivers/net/ethernet/intel/ice/Makefile
> index 5b2c666496e7..38db476ab2ec 100644
> --- a/drivers/net/ethernet/intel/ice/Makefile
> +++ b/drivers/net/ethernet/intel/ice/Makefile
> @@ -54,7 +54,7 @@ ice-$(CONFIG_PCI_IOV) += \
> ice_vf_mbx.o \
> ice_vf_vsi_vlan_ops.o \
> ice_vf_lib.o
...
> diff --git a/drivers/net/ethernet/intel/ice/ice_cpi.h
> b/drivers/net/ethernet/intel/ice/ice_cpi.h
> new file mode 100644
> index 000000000000..932fe0c0824a
> --- /dev/null
> +++ b/drivers/net/ethernet/intel/ice/ice_cpi.h
> @@ -0,0 +1,61 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/* Copyright (C) 2018-2025 Intel Corporation */
Shouldn't the 2025 year be updated to 2026?
> +
> +#ifndef _ICE_CPI_H_
> +#define _ICE_CPI_H_
> +
> +#define CPI0_PHY1_CMD_DATA 0x7FD028
> +#define CPI0_LM1_CMD_DATA 0x7FD024
> +#define CPI_RETRIES_COUNT 10
> +#define CPI_RETRIES_CADENCE_MS 100
> +
> +/* CPI PHY CMD DATA register (CPI0_PHY1_CMD_DATA) */
> +#define CPI_PHY_CMD_DATA_M GENMASK(15, 0)
> +#define CPI_PHY_CMD_OPCODE_M GENMASK(23, 16)
> +#define CPI_PHY_CMD_PORTLANE_M GENMASK(26, 24)
> +#define CPI_PHY_CMD_RSVD_M GENMASK(29, 27)
> +#define CPI_PHY_CMD_ERROR_M BIT(30)
> +#define CPI_PHY_CMD_ACK_M BIT(31)
> +
> +/* CPI LM CMD DATA register (CPI0_LM1_CMD_DATA) */
> +#define CPI_LM_CMD_DATA_M GENMASK(15, 0)
> +#define CPI_LM_CMD_OPCODE_M GENMASK(23, 16)
> +#define CPI_LM_CMD_PORTLANE_M GENMASK(26, 24)
> +#define CPI_LM_CMD_RSVD_M GENMASK(28, 27)
> +#define CPI_LM_CMD_GET_SET_M BIT(29)
> +#define CPI_LM_CMD_RESET_M BIT(30)
> +#define CPI_LM_CMD_REQ_M BIT(31)
> +
> +#define CPI_OPCODE_PHY_CLK 0xF1
> +#define CPI_OPCODE_PHY_CLK_PHY_SEL_M GENMASK(9, 6)
> +#define CPI_OPCODE_PHY_CLK_REF_CTRL_M GENMASK(5, 4)
> +#define CPI_OPCODE_PHY_CLK_PORT_SEL 0
> +#define CPI_OPCODE_PHY_CLK_DISABLE 1
> +#define CPI_OPCODE_PHY_CLK_ENABLE 2
> +#define CPI_OPCODE_PHY_CLK_REF_SEL_M GENMASK(3, 0)
> +
> +#define CPI_OPCODE_PHY_PCS_RESET 0xF0
> +#define CPI_OPCODE_PHY_PCS_ONPI_RESET_VAL 0x3F
> +
> +#define CPI_LM_CMD_REQ 1
> +#define CPI_LM_CMD_SET 1
CPI_LM_CMD_SET is defined but not used in the patches
> +
...
> /* Port hardware description */
> struct ice_hw {
> u8 __iomem *hw_addr;
> --
> 2.39.3
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH v6 net-next 7/8] ice: add Tx reference clock index handling to AN restart command
From: Loktionov, Aleksandr @ 2026-04-30 11:44 UTC (permalink / raw)
To: Nitka, Grzegorz, netdev@vger.kernel.org
Cc: Vecera, Ivan, vadim.fedorenko@linux.dev, kuba@kernel.org,
jiri@resnulli.us, edumazet@google.com, Kitszel, Przemyslaw,
richardcochran@gmail.com, donald.hunter@gmail.com,
linux-kernel@vger.kernel.org, Kubalewski, Arkadiusz,
andrew+netdev@lunn.ch, intel-wired-lan@lists.osuosl.org,
horms@kernel.org, Prathosh.Satish@microchip.com,
Nguyen, Anthony L, pabeni@redhat.com, davem@davemloft.net
In-Reply-To: <20260409235122.436749-8-grzegorz.nitka@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Grzegorz Nitka
> Sent: Friday, April 10, 2026 1:51 AM
> To: netdev@vger.kernel.org
> Cc: Vecera, Ivan <ivecera@redhat.com>; vadim.fedorenko@linux.dev;
> kuba@kernel.org; jiri@resnulli.us; edumazet@google.com; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; richardcochran@gmail.com;
> donald.hunter@gmail.com; linux-kernel@vger.kernel.org; Kubalewski,
> Arkadiusz <arkadiusz.kubalewski@intel.com>; andrew+netdev@lunn.ch;
> intel-wired-lan@lists.osuosl.org; horms@kernel.org;
> Prathosh.Satish@microchip.com; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; pabeni@redhat.com; davem@davemloft.net
> Subject: [Intel-wired-lan] [PATCH v6 net-next 7/8] ice: add Tx
> reference clock index handling to AN restart command
>
> Extend the Restart Auto-Negotiation (AN) AdminQ command with a new
> parameter allowing software to specify the Tx reference clock index to
> be used during link restart.
>
> This patch:
> - adds REFCLK field definitions to ice_aqc_restart_an
> - updates ice_aq_set_link_restart_an() to take a new refclk parameter
> and properly encode it into the command
> - keeps legacy behavior by passing REFCLK_NOCHANGE where appropriate
>
> This prepares the driver for configurations requiring dynamic
> selection of the Tx reference clock as part of the AN flow.
>
> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
> ---
> drivers/net/ethernet/intel/ice/ice_adminq_cmd.h | 2 ++
> drivers/net/ethernet/intel/ice/ice_common.c | 5 ++++-
> drivers/net/ethernet/intel/ice/ice_common.h | 2 +-
> drivers/net/ethernet/intel/ice/ice_lib.c | 3 ++-
> 4 files changed, 9 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
> b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
> index 859e9c66f3e7..a24a0613d887 100644
> --- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
> +++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
> @@ -1169,6 +1169,8 @@ struct ice_aqc_restart_an {
> u8 cmd_flags;
> #define ICE_AQC_RESTART_AN_LINK_RESTART BIT(1)
> #define ICE_AQC_RESTART_AN_LINK_ENABLE BIT(2)
> +#define ICE_AQC_RESTART_AN_REFCLK_M GENMASK(4, 3)
> +#define ICE_AQC_RESTART_AN_REFCLK_NOCHANGE 0
> u8 reserved2[13];
> };
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_common.c
> b/drivers/net/ethernet/intel/ice/ice_common.c
> index ce11fea122d0..de88aec9137c 100644
> --- a/drivers/net/ethernet/intel/ice/ice_common.c
> +++ b/drivers/net/ethernet/intel/ice/ice_common.c
> @@ -4126,12 +4126,13 @@ int ice_get_link_status(struct ice_port_info
> *pi, bool *link_up)
> * @pi: pointer to the port information structure
> * @ena_link: if true: enable link, if false: disable link
> * @cd: pointer to command details structure or NULL
> + * @refclk: the new TX reference clock, 0 if no change
0 is not a magic number, but kdoc should better
mention the ICE_AQC_RESTART_AN_REFCLK_NOCHANGE
What do you think?
> *
> * Sets up the link and restarts the Auto-Negotiation over the link.
> */
> int
> ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link,
> - struct ice_sq_cd *cd)
> + struct ice_sq_cd *cd, u8 refclk)
Double-space after ,
> {
> struct ice_aqc_restart_an *cmd;
> struct libie_aq_desc desc;
> @@ -4147,6 +4148,8 @@ ice_aq_set_link_restart_an(struct ice_port_info
> *pi, bool ena_link,
> else
> cmd->cmd_flags &= ~ICE_AQC_RESTART_AN_LINK_ENABLE;
>
> + cmd->cmd_flags |= FIELD_PREP(ICE_AQC_RESTART_AN_REFCLK_M,
> refclk);
> +
> return ice_aq_send_cmd(pi->hw, &desc, NULL, 0, cd); }
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_common.h
> b/drivers/net/ethernet/intel/ice/ice_common.h
> index e700ac0dc347..9f5344212195 100644
> --- a/drivers/net/ethernet/intel/ice/ice_common.h
> +++ b/drivers/net/ethernet/intel/ice/ice_common.h
> @@ -215,7 +215,7 @@ ice_cfg_phy_fec(struct ice_port_info *pi, struct
> ice_aqc_set_phy_cfg_data *cfg,
> enum ice_fec_mode fec);
> int
> ice_aq_set_link_restart_an(struct ice_port_info *pi, bool ena_link,
> - struct ice_sq_cd *cd);
> + struct ice_sq_cd *cd, u8 refclk);
> int
> ice_aq_set_mac_cfg(struct ice_hw *hw, u16 max_frame_size, struct
> ice_sq_cd *cd); int diff --git
> a/drivers/net/ethernet/intel/ice/ice_lib.c
> b/drivers/net/ethernet/intel/ice/ice_lib.c
> index 689c6025ea82..c2c7f186bcc7 100644
> --- a/drivers/net/ethernet/intel/ice/ice_lib.c
> +++ b/drivers/net/ethernet/intel/ice/ice_lib.c
> @@ -3769,7 +3769,8 @@ int ice_set_link(struct ice_vsi *vsi, bool ena)
> if (vsi->type != ICE_VSI_PF)
> return -EINVAL;
>
> - status = ice_aq_set_link_restart_an(pi, ena, NULL);
> + status = ice_aq_set_link_restart_an(pi, ena, NULL,
> +
> ICE_AQC_RESTART_AN_REFCLK_NOCHANGE);
>
> /* if link is owned by manageability, FW will return
> LIBIE_AQ_RC_EMODE.
> * this is not a fatal error, so print a warning message and
> return
> --
> 2.39.3
^ permalink raw reply
* [PATCH net-next v6 0/3] net: dsa: yt921x: Add port police support
From: David Yang @ 2026-04-30 11:45 UTC (permalink / raw)
To: netdev
Cc: David Yang, Vladimir Oltean, UNGLinuxDriver, Andrew Lunn,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-kernel, Vladimir Oltean
v5: https://lore.kernel.org/r/20260428112606.1917230-1-mmyangfl@gmail.com
- remove new line chars in extact messages
v4: https://lore.kernel.org/r/20260409171209.2575583-1-mmyangfl@gmail.com
- split series and drop patch for qdisc tbf
v3: https://lore.kernel.org/r/20260407160559.1747616-1-mmyangfl@gmail.com
- explain long registers more accurately
- fix missing packet mode flag
- rearrange function layout, in preparation for further patches
v2: https://lore.kernel.org/r/20260402223437.109097-1-mmyangfl@gmail.com
- refine commit messages and code styles, no functional changes
v1: https://lore.kernel.org/r/20260225090853.2021140-1-mmyangfl@gmail.com
- pass extack to user tc policers
- keep reg64 helpers along with reg96
- avoid macros in favor of functions
- adjust log messages
David Yang (3):
net: dsa: pass extack to dsa_switch_ops :: port_policer_add()
net: dsa: yt921x: Refactor long register helpers
net: dsa: yt921x: Add port police support
drivers/net/dsa/ocelot/felix.c | 3 +-
drivers/net/dsa/sja1105/sja1105_main.c | 3 +-
drivers/net/dsa/yt921x.c | 485 ++++++++++++++++++++++---
drivers/net/dsa/yt921x.h | 87 ++++-
include/net/dsa.h | 3 +-
net/dsa/user.c | 2 +-
6 files changed, 509 insertions(+), 74 deletions(-)
--
2.53.0
^ permalink raw reply
* [PATCH net-next v6 1/3] net: dsa: pass extack to dsa_switch_ops :: port_policer_add()
From: David Yang @ 2026-04-30 11:45 UTC (permalink / raw)
To: netdev
Cc: David Yang, Andrew Lunn, Vladimir Oltean, UNGLinuxDriver,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, linux-kernel
In-Reply-To: <20260430114529.3536911-1-mmyangfl@gmail.com>
Drivers might have error messages to propagate to user space. Propagate
the netlink extack so that they can inform user space in a verbal way of
their limitations.
Make the according transformations to the two users (sja1105 and felix).
Signed-off-by: David Yang <mmyangfl@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/ocelot/felix.c | 3 ++-
drivers/net/dsa/sja1105/sja1105_main.c | 3 ++-
include/net/dsa.h | 3 ++-
net/dsa/user.c | 2 +-
4 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index 84cf8e7fb17a..4272ea6e9ca8 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -2001,7 +2001,8 @@ static int felix_cls_flower_stats(struct dsa_switch *ds, int port,
}
static int felix_port_policer_add(struct dsa_switch *ds, int port,
- const struct flow_action_police *policer)
+ const struct flow_action_police *policer,
+ struct netlink_ext_ack *extack)
{
struct ocelot *ocelot = ds->priv;
struct ocelot_policer pol = {
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index c72c2bfdcffb..dbfa45064747 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -2847,7 +2847,8 @@ static void sja1105_mirror_del(struct dsa_switch *ds, int port,
}
static int sja1105_port_policer_add(struct dsa_switch *ds, int port,
- const struct flow_action_police *policer)
+ const struct flow_action_police *policer,
+ struct netlink_ext_ack *extack)
{
struct sja1105_l2_policing_entry *policing;
struct sja1105_private *priv = ds->priv;
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 8b6d34e8a6f0..4cc67469cf2e 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -1122,7 +1122,8 @@ struct dsa_switch_ops {
void (*port_mirror_del)(struct dsa_switch *ds, int port,
struct dsa_mall_mirror_tc_entry *mirror);
int (*port_policer_add)(struct dsa_switch *ds, int port,
- const struct flow_action_police *policer);
+ const struct flow_action_police *policer,
+ struct netlink_ext_ack *extack);
void (*port_policer_del)(struct dsa_switch *ds, int port);
int (*port_setup_tc)(struct dsa_switch *ds, int port,
enum tc_setup_type type, void *type_data);
diff --git a/net/dsa/user.c b/net/dsa/user.c
index c4bd6fe90b45..8704c1a3a5b7 100644
--- a/net/dsa/user.c
+++ b/net/dsa/user.c
@@ -1499,7 +1499,7 @@ dsa_user_add_cls_matchall_police(struct net_device *dev,
policer = &mall_tc_entry->policer;
*policer = act->police;
- err = ds->ops->port_policer_add(ds, dp->index, policer);
+ err = ds->ops->port_policer_add(ds, dp->index, policer, extack);
if (err) {
kfree(mall_tc_entry);
return err;
--
2.53.0
^ permalink raw reply related
* [PATCH net-next v6 2/3] net: dsa: yt921x: Refactor long register helpers
From: David Yang @ 2026-04-30 11:45 UTC (permalink / raw)
To: netdev
Cc: David Yang, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, linux-kernel
In-Reply-To: <20260430114529.3536911-1-mmyangfl@gmail.com>
Dealing long registers with u64 is good, until you realize there are
longer 96-bit registers.
Refactor reg64 helpers to use u32 arrays instead of u64 values, in
preparation for 96-bit registers. We do not keep the separate u64
version for reg64 to avoid duplicated wrappers, although it looks better
when dealing with reg64 *only*.
Helpers for reg96 should be added when they are actually used to avoid
function unused warnings.
Signed-off-by: David Yang <mmyangfl@gmail.com>
---
drivers/net/dsa/yt921x.c | 162 +++++++++++++++++++++++++++------------
drivers/net/dsa/yt921x.h | 36 ++++-----
2 files changed, 129 insertions(+), 69 deletions(-)
diff --git a/drivers/net/dsa/yt921x.c b/drivers/net/dsa/yt921x.c
index 87139448bec3..0c07b903fd68 100644
--- a/drivers/net/dsa/yt921x.c
+++ b/drivers/net/dsa/yt921x.c
@@ -255,63 +255,122 @@ yt921x_reg_toggle_bits(struct yt921x_priv *priv, u32 reg, u32 mask, bool set)
return yt921x_reg_update_bits(priv, reg, mask, !set ? 0 : mask);
}
-/* Some registers, like VLANn_CTRL, should always be written in 64-bit, even if
- * you are to write only the lower / upper 32 bits.
+/* Some multi-word registers, like VLANn_CTRL, should be treated as a single
+ * long register. More specifically, writes to parts of its words won't become
+ * visible, until the last word is written.
*
- * There is no such restriction for reading, but we still provide 64-bit read
- * wrappers so that we always handle u64 values.
+ * Here we require full read and write operations over these registers to
+ * eliminate potential issues, although partial reads/writes are also possible.
*/
-static int yt921x_reg64_read(struct yt921x_priv *priv, u32 reg, u64 *valp)
+static int
+yt921x_regs_read(struct yt921x_priv *priv, u32 reg, u32 *vals,
+ unsigned int num_regs)
{
- u32 lo;
- u32 hi;
int res;
- res = yt921x_reg_read(priv, reg, &lo);
- if (res)
- return res;
- res = yt921x_reg_read(priv, reg + 4, &hi);
- if (res)
- return res;
+ for (unsigned int i = 0; i < num_regs; i++) {
+ res = yt921x_reg_read(priv, reg + 4 * i, &vals[i]);
+ if (res)
+ return res;
+ }
+
+ return 0;
+}
+
+static int
+yt921x_regs_write(struct yt921x_priv *priv, u32 reg, const u32 *vals,
+ unsigned int num_regs)
+{
+ int res;
+
+ for (unsigned int i = 0; i < num_regs; i++) {
+ res = yt921x_reg_write(priv, reg + 4 * i, vals[i]);
+ if (res)
+ return res;
+ }
- *valp = ((u64)hi << 32) | lo;
return 0;
}
-static int yt921x_reg64_write(struct yt921x_priv *priv, u32 reg, u64 val)
+static int
+yt921x_regs_update_bits(struct yt921x_priv *priv, u32 reg, const u32 *masks,
+ const u32 *vals, unsigned int num_regs)
{
+ bool changed = false;
+ u32 vs[4];
int res;
- res = yt921x_reg_write(priv, reg, (u32)val);
+ BUILD_BUG_ON(num_regs > ARRAY_SIZE(vs));
+
+ res = yt921x_regs_read(priv, reg, vs, num_regs);
if (res)
return res;
- return yt921x_reg_write(priv, reg + 4, (u32)(val >> 32));
+
+ for (unsigned int i = 0; i < num_regs; i++) {
+ u32 u = vs[i];
+
+ u &= ~masks[i];
+ u |= vals[i];
+ if (u != vs[i])
+ changed = true;
+
+ vs[i] = u;
+ }
+
+ if (!changed)
+ return 0;
+
+ return yt921x_regs_write(priv, reg, vs, num_regs);
}
static int
-yt921x_reg64_update_bits(struct yt921x_priv *priv, u32 reg, u64 mask, u64 val)
+yt921x_regs_clear_bits(struct yt921x_priv *priv, u32 reg, const u32 *masks,
+ unsigned int num_regs)
{
+ bool changed = false;
+ u32 vs[4];
int res;
- u64 v;
- u64 u;
- res = yt921x_reg64_read(priv, reg, &v);
+ BUILD_BUG_ON(num_regs > ARRAY_SIZE(vs));
+
+ res = yt921x_regs_read(priv, reg, vs, num_regs);
if (res)
return res;
- u = v;
- u &= ~mask;
- u |= val;
- if (u == v)
+ for (unsigned int i = 0; i < num_regs; i++) {
+ u32 u = vs[i];
+
+ u &= ~masks[i];
+ if (u != vs[i])
+ changed = true;
+
+ vs[i] = u;
+ }
+
+ if (!changed)
return 0;
- return yt921x_reg64_write(priv, reg, u);
+ return yt921x_regs_write(priv, reg, vs, num_regs);
+}
+
+static int
+yt921x_reg64_write(struct yt921x_priv *priv, u32 reg, const u32 *vals)
+{
+ return yt921x_regs_write(priv, reg, vals, 2);
}
-static int yt921x_reg64_clear_bits(struct yt921x_priv *priv, u32 reg, u64 mask)
+static int
+yt921x_reg64_update_bits(struct yt921x_priv *priv, u32 reg, const u32 *masks,
+ const u32 *vals)
{
- return yt921x_reg64_update_bits(priv, reg, mask, 0);
+ return yt921x_regs_update_bits(priv, reg, masks, vals, 2);
+}
+
+static int
+yt921x_reg64_clear_bits(struct yt921x_priv *priv, u32 reg, const u32 *masks)
+{
+ return yt921x_regs_clear_bits(priv, reg, masks, 2);
}
static int yt921x_reg_mdio_read(void *context, u32 reg, u32 *valp)
@@ -1844,33 +1903,31 @@ yt921x_vlan_filtering(struct yt921x_priv *priv, int port, bool vlan_filtering)
return 0;
}
-static int
-yt921x_vlan_del(struct yt921x_priv *priv, int port, u16 vid)
+static int yt921x_vlan_del(struct yt921x_priv *priv, int port, u16 vid)
{
- u64 mask64;
+ u32 masks[2];
- mask64 = YT921X_VLAN_CTRL_PORTS(port) |
- YT921X_VLAN_CTRL_UNTAG_PORTn(port);
+ masks[0] = YT921X_VLAN_CTRLa_PORTn(port);
+ masks[1] = YT921X_VLAN_CTRLb_UNTAG_PORTn(port);
- return yt921x_reg64_clear_bits(priv, YT921X_VLANn_CTRL(vid), mask64);
+ return yt921x_reg64_clear_bits(priv, YT921X_VLANn_CTRL(vid), masks);
}
static int
yt921x_vlan_add(struct yt921x_priv *priv, int port, u16 vid, bool untagged)
{
- u64 mask64;
- u64 ctrl64;
+ u32 masks[2];
+ u32 ctrls[2];
- mask64 = YT921X_VLAN_CTRL_PORTn(port) |
- YT921X_VLAN_CTRL_PORTS(priv->cpu_ports_mask);
- ctrl64 = mask64;
+ masks[0] = YT921X_VLAN_CTRLa_PORTn(port) |
+ YT921X_VLAN_CTRLa_PORTS(priv->cpu_ports_mask);
+ ctrls[0] = masks[0];
- mask64 |= YT921X_VLAN_CTRL_UNTAG_PORTn(port);
- if (untagged)
- ctrl64 |= YT921X_VLAN_CTRL_UNTAG_PORTn(port);
+ masks[1] = YT921X_VLAN_CTRLb_UNTAG_PORTn(port);
+ ctrls[1] = untagged ? masks[1] : 0;
return yt921x_reg64_update_bits(priv, YT921X_VLANn_CTRL(vid),
- mask64, ctrl64);
+ masks, ctrls);
}
static int
@@ -2318,8 +2375,8 @@ yt921x_dsa_vlan_msti_set(struct dsa_switch *ds, struct dsa_bridge bridge,
const struct switchdev_vlan_msti *msti)
{
struct yt921x_priv *priv = to_yt921x_priv(ds);
- u64 mask64;
- u64 ctrl64;
+ u32 masks[2];
+ u32 ctrls[2];
int res;
if (!msti->vid)
@@ -2327,12 +2384,14 @@ yt921x_dsa_vlan_msti_set(struct dsa_switch *ds, struct dsa_bridge bridge,
if (!msti->msti || msti->msti >= YT921X_MSTI_NUM)
return -EINVAL;
- mask64 = YT921X_VLAN_CTRL_STP_ID_M;
- ctrl64 = YT921X_VLAN_CTRL_STP_ID(msti->msti);
+ masks[0] = 0;
+ ctrls[0] = 0;
+ masks[1] = YT921X_VLAN_CTRLb_STP_ID_M;
+ ctrls[1] = YT921X_VLAN_CTRLb_STP_ID(msti->msti);
mutex_lock(&priv->reg_lock);
res = yt921x_reg64_update_bits(priv, YT921X_VLANn_CTRL(msti->vid),
- mask64, ctrl64);
+ masks, ctrls);
mutex_unlock(&priv->reg_lock);
return res;
@@ -3084,7 +3143,7 @@ static int yt921x_chip_setup_dsa(struct yt921x_priv *priv)
{
struct dsa_switch *ds = &priv->ds;
unsigned long cpu_ports_mask;
- u64 ctrl64;
+ u32 ctrls[2];
u32 ctrl;
int port;
int res;
@@ -3145,8 +3204,9 @@ static int yt921x_chip_setup_dsa(struct yt921x_priv *priv)
/* Tagged VID 0 should be treated as untagged, which confuses the
* hardware a lot
*/
- ctrl64 = YT921X_VLAN_CTRL_LEARN_DIS | YT921X_VLAN_CTRL_PORTS_M;
- res = yt921x_reg64_write(priv, YT921X_VLANn_CTRL(0), ctrl64);
+ ctrls[0] = YT921X_VLAN_CTRLa_LEARN_DIS | YT921X_VLAN_CTRLa_PORTS_M;
+ ctrls[1] = 0;
+ res = yt921x_reg64_write(priv, YT921X_VLANn_CTRL(0), ctrls);
if (res)
return res;
diff --git a/drivers/net/dsa/yt921x.h b/drivers/net/dsa/yt921x.h
index 3f129b8d403f..4989d87c2492 100644
--- a/drivers/net/dsa/yt921x.h
+++ b/drivers/net/dsa/yt921x.h
@@ -429,24 +429,24 @@ enum yt921x_app_selector {
#define YT921X_FDB_HW_FLUSH_ON_LINKDOWN BIT(0)
#define YT921X_VLANn_CTRL(vlan) (0x188000 + 8 * (vlan))
-#define YT921X_VLAN_CTRL_UNTAG_PORTS_M GENMASK_ULL(50, 40)
-#define YT921X_VLAN_CTRL_UNTAG_PORTS(x) FIELD_PREP(YT921X_VLAN_CTRL_UNTAG_PORTS_M, (x))
-#define YT921X_VLAN_CTRL_UNTAG_PORTn(port) BIT_ULL((port) + 40)
-#define YT921X_VLAN_CTRL_STP_ID_M GENMASK_ULL(39, 36)
-#define YT921X_VLAN_CTRL_STP_ID(x) FIELD_PREP(YT921X_VLAN_CTRL_STP_ID_M, (x))
-#define YT921X_VLAN_CTRL_SVLAN_EN BIT_ULL(35)
-#define YT921X_VLAN_CTRL_FID_M GENMASK_ULL(34, 23)
-#define YT921X_VLAN_CTRL_FID(x) FIELD_PREP(YT921X_VLAN_CTRL_FID_M, (x))
-#define YT921X_VLAN_CTRL_LEARN_DIS BIT_ULL(22)
-#define YT921X_VLAN_CTRL_PRIO_EN BIT_ULL(21)
-#define YT921X_VLAN_CTRL_PRIO_M GENMASK_ULL(20, 18)
-#define YT921X_VLAN_CTRL_PRIO(x) FIELD_PREP(YT921X_VLAN_CTRL_PRIO_M, (x))
-#define YT921X_VLAN_CTRL_PORTS_M GENMASK_ULL(17, 7)
-#define YT921X_VLAN_CTRL_PORTS(x) FIELD_PREP(YT921X_VLAN_CTRL_PORTS_M, (x))
-#define YT921X_VLAN_CTRL_PORTn(port) BIT_ULL((port) + 7)
-#define YT921X_VLAN_CTRL_BYPASS_1X_AC BIT_ULL(6)
-#define YT921X_VLAN_CTRL_METER_EN BIT_ULL(5)
-#define YT921X_VLAN_CTRL_METER_ID_M GENMASK_ULL(4, 0)
+#define YT921X_VLAN_CTRLb_UNTAG_PORTS_M GENMASK(18, 8)
+#define YT921X_VLAN_CTRLb_UNTAG_PORTS(x) FIELD_PREP(YT921X_VLAN_CTRLb_UNTAG_PORTS_M, (x))
+#define YT921X_VLAN_CTRLb_UNTAG_PORTn(port) BIT((port) + 8)
+#define YT921X_VLAN_CTRLb_STP_ID_M GENMASK(7, 4)
+#define YT921X_VLAN_CTRLb_STP_ID(x) FIELD_PREP(YT921X_VLAN_CTRLb_STP_ID_M, (x))
+#define YT921X_VLAN_CTRLb_SVLAN_EN BIT(3)
+#define YT921X_VLAN_CTRLab_FID_M GENMASK_ULL(34, 23)
+#define YT921X_VLAN_CTRLab_FID(x) FIELD_PREP(YT921X_VLAN_CTRLab_FID_M, (x))
+#define YT921X_VLAN_CTRLa_LEARN_DIS BIT(22)
+#define YT921X_VLAN_CTRLa_PRIO_EN BIT(21)
+#define YT921X_VLAN_CTRLa_PRIO_M GENMASK(20, 18)
+#define YT921X_VLAN_CTRLa_PRIO(x) FIELD_PREP(YT921X_VLAN_CTRLa_PRIO_M, (x))
+#define YT921X_VLAN_CTRLa_PORTS_M GENMASK(17, 7)
+#define YT921X_VLAN_CTRLa_PORTS(x) FIELD_PREP(YT921X_VLAN_CTRLa_PORTS_M, (x))
+#define YT921X_VLAN_CTRLa_PORTn(port) BIT((port) + 7)
+#define YT921X_VLAN_CTRLa_BYPASS_1X_AC BIT(6)
+#define YT921X_VLAN_CTRLa_METER_EN BIT(5)
+#define YT921X_VLAN_CTRLa_METER_ID_M GENMASK(4, 0)
#define YT921X_TPID_IGRn(x) (0x210000 + 4 * (x)) /* [0, 3] */
#define YT921X_TPID_IGR_TPID_M GENMASK(15, 0)
--
2.53.0
^ permalink raw reply related
* [PATCH net-next v6 3/3] net: dsa: yt921x: Add port police support
From: David Yang @ 2026-04-30 11:45 UTC (permalink / raw)
To: netdev
Cc: David Yang, Andrew Lunn, Vladimir Oltean, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, linux-kernel
In-Reply-To: <20260430114529.3536911-1-mmyangfl@gmail.com>
Enable rate meter ability and support limiting the rate of incoming
traffic.
Signed-off-by: David Yang <mmyangfl@gmail.com>
---
drivers/net/dsa/yt921x.c | 323 ++++++++++++++++++++++++++++++++++++++-
drivers/net/dsa/yt921x.h | 51 +++++++
2 files changed, 373 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/yt921x.c b/drivers/net/dsa/yt921x.c
index 0c07b903fd68..fd1fdcd5f9a3 100644
--- a/drivers/net/dsa/yt921x.c
+++ b/drivers/net/dsa/yt921x.c
@@ -263,6 +263,14 @@ yt921x_reg_toggle_bits(struct yt921x_priv *priv, u32 reg, u32 mask, bool set)
* eliminate potential issues, although partial reads/writes are also possible.
*/
+static void update_ctrls_unaligned(u32 *lo, u32 *hi, u64 mask, u64 val)
+{
+ *lo &= ~lower_32_bits(mask);
+ *hi &= ~upper_32_bits(mask);
+ *lo |= lower_32_bits(val);
+ *hi |= upper_32_bits(val);
+}
+
static int
yt921x_regs_read(struct yt921x_priv *priv, u32 reg, u32 *vals,
unsigned int num_regs)
@@ -373,6 +381,12 @@ yt921x_reg64_clear_bits(struct yt921x_priv *priv, u32 reg, const u32 *masks)
return yt921x_regs_clear_bits(priv, reg, masks, 2);
}
+static int
+yt921x_reg96_write(struct yt921x_priv *priv, u32 reg, const u32 *vals)
+{
+ return yt921x_regs_write(priv, reg, vals, 3);
+}
+
static int yt921x_reg_mdio_read(void *context, u32 reg, u32 *valp)
{
struct yt921x_reg_mdio *mdio = context;
@@ -1066,6 +1080,13 @@ yt921x_dsa_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_keee *e)
return res;
}
+static int yt921x_mtu_fetch(struct yt921x_priv *priv, int port)
+{
+ struct dsa_port *dp = dsa_to_port(&priv->ds, port);
+
+ return dp->user ? READ_ONCE(dp->user->mtu) : ETH_DATA_LEN;
+}
+
static int
yt921x_dsa_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
{
@@ -1097,6 +1118,266 @@ static int yt921x_dsa_port_max_mtu(struct dsa_switch *ds, int port)
return YT921X_FRAME_SIZE_MAX - ETH_HLEN - ETH_FCS_LEN - YT921X_TAG_LEN;
}
+/* v * 2^e */
+static u64 ldexpu64(u64 v, int e)
+{
+ return e >= 0 ? v << e : v >> -e;
+}
+
+/* slot (ns) * rate (/s) / 10^9 (ns/s) = 2^C * token * 4^unit */
+static u32 rate2token(u64 rate, unsigned int slot_ns, int unit, int C)
+{
+ int e = 2 * unit + C + YT921X_TOKEN_RATE_C;
+
+ return div_u64(ldexpu64(slot_ns * rate, -e), 1000000000);
+}
+
+static u64 token2rate(u32 token, unsigned int slot_ns, int unit, int C)
+{
+ int e = 2 * unit + C + YT921X_TOKEN_RATE_C;
+
+ return div_u64(ldexpu64(mul_u32_u32(1000000000, token), e), slot_ns);
+}
+
+/* burst = 2^C * token * 4^unit */
+static u32 burst2token(u64 burst, int unit, int C)
+{
+ return ldexpu64(burst, -(2 * unit + C));
+}
+
+static u64 token2burst(u32 token, int unit, int C)
+{
+ return ldexpu64(token, 2 * unit + C);
+}
+
+struct yt921x_marker {
+ u32 cir;
+ u32 cbs;
+ u32 ebs;
+ int unit;
+ bool pkt_mode;
+};
+
+#define YT921X_MARKER_PKT_MODE BIT(0)
+#define YT921X_MARKER_SINGLE_BUCKET BIT(1)
+
+static int
+yt921x_marker_tfm(struct yt921x_marker *marker, u64 rate, u64 burst,
+ unsigned int flags, unsigned int slot_ns, u32 cir_max,
+ u32 cbs_max, int unit_max, struct yt921x_priv *priv, int port,
+ struct netlink_ext_ack *extack)
+{
+ const int C = flags & YT921X_MARKER_PKT_MODE ? YT921X_TOKEN_PKT_C :
+ YT921X_TOKEN_BYTE_C;
+ struct device *dev = to_device(priv);
+ struct yt921x_marker m;
+ u64 burst_est;
+ u64 burst_sug;
+ u64 burst_max;
+ u64 rate_max;
+
+ m.unit = unit_max;
+ rate_max = token2rate(cir_max, slot_ns, m.unit, C);
+ burst_max = token2burst(cbs_max, m.unit, C);
+
+ /* Check for unusual values */
+ if (rate > rate_max || burst > burst_max) {
+ NL_SET_ERR_MSG_MOD(extack, "Unexpected tremendous rate");
+ return -ERANGE;
+ }
+
+ /* Check for matching burst */
+ burst_est = div_u64(slot_ns * rate, 1000000000);
+ burst_sug = burst_est;
+ if (flags & YT921X_MARKER_PKT_MODE)
+ burst_sug++;
+ else
+ burst_sug += ETH_HLEN + yt921x_mtu_fetch(priv, port) +
+ ETH_FCS_LEN;
+ if (burst_sug > burst)
+ NL_SET_ERR_MSG_FMT_MOD(extack,
+ "Consider match rate %llu with burst at least %llu",
+ rate, burst_sug);
+
+ /* Select unit */
+ for (; m.unit > 0; m.unit--) {
+ if (rate > (rate_max >> 2) || burst > (burst_max >> 2))
+ break;
+ rate_max >>= 2;
+ burst_max >>= 2;
+ }
+
+ /* Calculate information rate and bucket size */
+ m.cir = rate2token(rate, slot_ns, m.unit, C);
+ if (!m.cir)
+ m.cir = 1;
+ else if (WARN_ON(m.cir > cir_max))
+ m.cir = cir_max;
+ m.cbs = burst2token(burst, m.unit, C);
+ if (!m.cbs)
+ m.cbs = 1;
+ else if (WARN_ON(m.cbs > cbs_max))
+ m.cbs = cbs_max;
+
+ /* Cut EBS */
+ m.ebs = 0;
+ if (!(flags & YT921X_MARKER_SINGLE_BUCKET)) {
+ /* We don't have a chance to adjust rate when MTU is changed */
+ if (flags & YT921X_MARKER_PKT_MODE)
+ burst_est++;
+ else
+ burst_est += YT921X_FRAME_SIZE_MAX;
+
+ if (burst_est < burst) {
+ u32 pbs = m.cbs;
+
+ m.cbs = burst2token(burst_est, m.unit, C);
+ if (!m.cbs)
+ m.cbs = 1;
+ else if (WARN_ON(m.cbs > cbs_max))
+ m.cbs = cbs_max;
+
+ if (pbs > m.cbs)
+ m.ebs = pbs - m.cbs;
+ }
+ }
+
+ dev_dbg(dev,
+ "slot %u ns, rate %llu, burst %llu -> unit %d, cir %u, cbs %u, ebs %u\n",
+ slot_ns, rate, burst, m.unit, m.cir, m.cbs, m.ebs);
+
+ m.pkt_mode = flags & YT921X_MARKER_PKT_MODE;
+ *marker = m;
+ return 0;
+}
+
+static int
+yt921x_marker_tfm_police(struct yt921x_marker *marker,
+ const struct flow_action_police *police,
+ unsigned int flags, struct yt921x_priv *priv, int port,
+ struct netlink_ext_ack *extack)
+{
+ bool pkt_mode = !!police->rate_pkt_ps;
+ u64 burst;
+ u64 rate;
+
+ rate = pkt_mode ? police->rate_pkt_ps : police->rate_bytes_ps;
+ burst = pkt_mode ? police->burst_pkt : police->burst;
+ if (pkt_mode)
+ flags |= YT921X_MARKER_PKT_MODE;
+
+ return yt921x_marker_tfm(marker, rate, burst, flags,
+ priv->meter_slot_ns, YT921X_METER_CIR_MAX,
+ YT921X_METER_CBS_MAX, YT921X_METER_UNIT_MAX,
+ priv, port, extack);
+}
+
+static int
+yt921x_police_validate(const struct flow_action_police *police,
+ const struct flow_action *action,
+ const struct flow_action_entry *act,
+ struct netlink_ext_ack *extack)
+{
+ if (police->exceed.act_id != FLOW_ACTION_DROP) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Offload not supported when exceed action is not drop");
+ return -EOPNOTSUPP;
+ }
+
+ if (police->notexceed.act_id != FLOW_ACTION_PIPE &&
+ police->notexceed.act_id != FLOW_ACTION_ACCEPT) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Offload not supported when conform action is not pipe or ok");
+ return -EOPNOTSUPP;
+ }
+
+ if (police->notexceed.act_id == FLOW_ACTION_ACCEPT && action && act &&
+ !flow_action_is_last_entry(action, act)) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Offload not supported when conform action is ok, but action is not last");
+ return -EOPNOTSUPP;
+ }
+
+ /* mtu defaults to unlimited but we got 2040 here, don't know why */
+ if (police->peakrate_bytes_ps || police->avrate || police->overhead) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Offload not supported when peakrate/avrate/overhead is configured");
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static int
+yt921x_meter_config(struct yt921x_priv *priv, unsigned int id,
+ const struct yt921x_marker *marker)
+{
+ u32 ctrls[3];
+
+ ctrls[0] = 0;
+ ctrls[1] = YT921X_METER_CTRLb_CIR(marker->cir);
+ ctrls[2] = YT921X_METER_CTRLc_UNIT(marker->unit) |
+ YT921X_METER_CTRLc_DROP_R |
+ YT921X_METER_CTRLc_TOKEN_OVERFLOW_EN |
+ YT921X_METER_CTRLc_METER_EN;
+ if (marker->pkt_mode)
+ ctrls[2] |= YT921X_METER_CTRLc_PKT_MODE;
+ update_ctrls_unaligned(&ctrls[0], &ctrls[1],
+ YT921X_METER_CTRLab_EBS_M,
+ YT921X_METER_CTRLab_EBS(marker->ebs));
+ update_ctrls_unaligned(&ctrls[1], &ctrls[2],
+ YT921X_METER_CTRLbc_CBS_M,
+ YT921X_METER_CTRLbc_CBS(marker->cbs));
+
+ return yt921x_reg96_write(priv, YT921X_METERn_CTRL(id), ctrls);
+}
+
+static void yt921x_dsa_port_policer_del(struct dsa_switch *ds, int port)
+{
+ struct yt921x_priv *priv = to_yt921x_priv(ds);
+ struct device *dev = to_device(priv);
+ int res;
+
+ mutex_lock(&priv->reg_lock);
+ res = yt921x_reg_write(priv, YT921X_PORTn_METER(port), 0);
+ mutex_unlock(&priv->reg_lock);
+
+ if (res)
+ dev_err(dev, "Failed to %s port %d: %i\n", "delete policer on",
+ port, res);
+}
+
+static int
+yt921x_dsa_port_policer_add(struct dsa_switch *ds, int port,
+ const struct flow_action_police *police,
+ struct netlink_ext_ack *extack)
+{
+ struct yt921x_priv *priv = to_yt921x_priv(ds);
+ struct yt921x_marker marker;
+ u32 ctrl;
+ int res;
+
+ res = yt921x_police_validate(police, NULL, NULL, extack);
+ if (res)
+ return res;
+
+ res = yt921x_marker_tfm_police(&marker, police, 0, priv, port, extack);
+ if (res)
+ return res;
+
+ mutex_lock(&priv->reg_lock);
+ res = yt921x_meter_config(priv, port + YT921X_METER_NUM, &marker);
+ if (res)
+ goto end;
+
+ ctrl = YT921X_PORT_METER_ID(port) | YT921X_PORT_METER_EN;
+ res = yt921x_reg_write(priv, YT921X_PORTn_METER(port), ctrl);
+end:
+ mutex_unlock(&priv->reg_lock);
+
+ return res;
+}
+
static int
yt921x_mirror_del(struct yt921x_priv *priv, int port, bool ingress)
{
@@ -3052,6 +3333,7 @@ static int yt921x_chip_detect(struct yt921x_priv *priv)
u32 chipid;
u32 major;
u32 mode;
+ u32 val;
int res;
res = yt921x_reg_read(priv, YT921X_CHIP_ID, &chipid);
@@ -3086,12 +3368,27 @@ static int yt921x_chip_detect(struct yt921x_priv *priv)
return -ENODEV;
}
+ res = yt921x_reg_read(priv, YT921X_SYS_CLK, &val);
+ if (res)
+ return res;
+ switch (FIELD_GET(YT921X_SYS_CLK_SEL_M, val)) {
+ case 0:
+ priv->cycle_ns = info->major == YT9215_MAJOR ? 8 : 6;
+ break;
+ case YT921X_SYS_CLK_143M:
+ priv->cycle_ns = 7;
+ break;
+ default:
+ priv->cycle_ns = 8;
+ }
+
/* Print chipid here since we are interested in lower 16 bits */
dev_info(dev,
"Motorcomm %s ethernet switch, chipid: 0x%x, chipmode: 0x%x 0x%x\n",
info->name, chipid, mode, extmode);
priv->info = info;
+
return 0;
}
@@ -3213,6 +3510,23 @@ static int yt921x_chip_setup_dsa(struct yt921x_priv *priv)
return 0;
}
+static int yt921x_chip_setup_tc(struct yt921x_priv *priv)
+{
+ unsigned int op_ns;
+ u32 ctrl;
+ int res;
+
+ op_ns = 8 * priv->cycle_ns;
+
+ ctrl = max(priv->meter_slot_ns / op_ns, YT921X_METER_SLOT_MIN);
+ res = yt921x_reg_write(priv, YT921X_METER_SLOT, ctrl);
+ if (res)
+ return res;
+ priv->meter_slot_ns = ctrl * op_ns;
+
+ return 0;
+}
+
static int __maybe_unused yt921x_chip_setup_qos(struct yt921x_priv *priv)
{
u32 ctrl;
@@ -3259,7 +3573,7 @@ static int yt921x_chip_setup(struct yt921x_priv *priv)
u32 ctrl;
int res;
- ctrl = YT921X_FUNC_MIB;
+ ctrl = YT921X_FUNC_MIB | YT921X_FUNC_METER;
res = yt921x_reg_set_bits(priv, YT921X_FUNC, ctrl);
if (res)
return res;
@@ -3268,6 +3582,10 @@ static int yt921x_chip_setup(struct yt921x_priv *priv)
if (res)
return res;
+ res = yt921x_chip_setup_tc(priv);
+ if (res)
+ return res;
+
#if IS_ENABLED(CONFIG_DCB)
res = yt921x_chip_setup_qos(priv);
if (res)
@@ -3359,6 +3677,9 @@ static const struct dsa_switch_ops yt921x_dsa_switch_ops = {
/* mtu */
.port_change_mtu = yt921x_dsa_port_change_mtu,
.port_max_mtu = yt921x_dsa_port_max_mtu,
+ /* rate */
+ .port_policer_del = yt921x_dsa_port_policer_del,
+ .port_policer_add = yt921x_dsa_port_policer_add,
/* hsr */
.port_hsr_leave = dsa_port_simple_hsr_leave,
.port_hsr_join = dsa_port_simple_hsr_join,
diff --git a/drivers/net/dsa/yt921x.h b/drivers/net/dsa/yt921x.h
index 4989d87c2492..546b12a8994a 100644
--- a/drivers/net/dsa/yt921x.h
+++ b/drivers/net/dsa/yt921x.h
@@ -23,6 +23,7 @@
#define YT921X_RST_HW BIT(31)
#define YT921X_RST_SW BIT(1)
#define YT921X_FUNC 0x80004
+#define YT921X_FUNC_METER BIT(4)
#define YT921X_FUNC_MIB BIT(1)
#define YT921X_CHIP_ID 0x80008
#define YT921X_CHIP_ID_MAJOR GENMASK(31, 16)
@@ -239,6 +240,11 @@
#define YT921X_EDATA_DATA_STATUS_M GENMASK(3, 0)
#define YT921X_EDATA_DATA_STATUS(x) FIELD_PREP(YT921X_EDATA_DATA_STATUS_M, (x))
#define YT921X_EDATA_DATA_IDLE YT921X_EDATA_DATA_STATUS(3)
+#define YT921X_SYS_CLK 0xe0040
+#define YT921X_SYS_CLK_SEL_M GENMASK(1, 0) /* unknown: 167M */
+#define YT9215_SYS_CLK_125M 0
+#define YT9218_SYS_CLK_167M 0
+#define YT921X_SYS_CLK_143M 1
#define YT921X_EXT_MBUS_OP 0x6a000
#define YT921X_INT_MBUS_OP 0xf0000
@@ -465,6 +471,39 @@ enum yt921x_app_selector {
#define YT921X_LAG_HASH_MAC_DA BIT(1)
#define YT921X_LAG_HASH_SRC_PORT BIT(0)
+#define YT921X_PORTn_RATE(port) (0x220000 + 4 * (port))
+#define YT921X_PORT_RATE_GAP_VALUE GENMASK(4, 0) /* default 20 */
+#define YT921X_METER_SLOT 0x220104
+#define YT921X_METER_SLOT_SLOT_M GENMASK(11, 0)
+#define YT921X_PORTn_METER(port) (0x220108 + 4 * (port))
+#define YT921X_PORT_METER_EN BIT(4)
+#define YT921X_PORT_METER_ID_M GENMASK(3, 0)
+#define YT921X_PORT_METER_ID(x) FIELD_PREP(YT921X_PORT_METER_ID_M, (x))
+#define YT921X_METERn_CTRL(x) (0x220800 + 0x10 * (x))
+#define YT921X_METER_CTRLc_METER_EN BIT(14)
+#define YT921X_METER_CTRLc_TOKEN_OVERFLOW_EN BIT(13) /* RFC4115: yellow use unused green bw */
+#define YT921X_METER_CTRLc_DROP_M GENMASK(12, 11)
+#define YT921X_METER_CTRLc_DROP(x) FIELD_PREP(YT921X_METER_CTRLc_DROP_M, (x))
+#define YT921X_METER_CTRLc_DROP_GYR YT921X_METER_CTRLc_DROP(0)
+#define YT921X_METER_CTRLc_DROP_YR YT921X_METER_CTRLc_DROP(1)
+#define YT921X_METER_CTRLc_DROP_R YT921X_METER_CTRLc_DROP(2)
+#define YT921X_METER_CTRLc_DROP_NONE YT921X_METER_CTRLc_DROP(3)
+#define YT921X_METER_CTRLc_COLOR_BLIND BIT(10)
+#define YT921X_METER_CTRLc_UNIT_M GENMASK(9, 7)
+#define YT921X_METER_CTRLc_UNIT(x) FIELD_PREP(YT921X_METER_CTRLc_UNIT_M, (x))
+#define YT921X_METER_CTRLc_BYTE_MODE_INCLUDE_GAP BIT(6) /* +GAP_VALUE bytes each packet */
+#define YT921X_METER_CTRLc_PKT_MODE BIT(5) /* 0: byte rate mode */
+#define YT921X_METER_CTRLc_RFC2698 BIT(4) /* 0: RFC4115 */
+#define YT921X_METER_CTRLbc_CBS_M GENMASK_ULL(35, 20)
+#define YT921X_METER_CTRLbc_CBS(x) FIELD_PREP(YT921X_METER_CTRLbc_CBS_M, (x))
+#define YT921X_METER_CTRLb_CIR_M GENMASK(19, 2)
+#define YT921X_METER_CTRLb_CIR(x) FIELD_PREP(YT921X_METER_CTRLb_CIR_M, (x))
+#define YT921X_METER_CTRLab_EBS_M GENMASK_ULL(33, 18)
+#define YT921X_METER_CTRLab_EBS(x) FIELD_PREP(YT921X_METER_CTRLab_EBS_M, (x))
+#define YT921X_METER_CTRLa_EIR_M GENMASK(17, 0)
+#define YT921X_METER_CTRLa_EIR(x) FIELD_PREP(YT921X_METER_CTRLa_EIR_M, (x))
+#define YT921X_METERn_STAT(x) (0x221000 + 8 * (x))
+
#define YT921X_PORTn_VLAN_CTRL(port) (0x230010 + 4 * (port))
#define YT921X_PORT_VLAN_CTRL_SVLAN_PRIO_EN BIT(31)
#define YT921X_PORT_VLAN_CTRL_CVLAN_PRIO_EN BIT(30)
@@ -508,6 +547,16 @@ enum yt921x_fdb_entry_status {
#define YT921X_MSTI_NUM 16
+#define YT921X_TOKEN_BYTE_C 1 /* 1 token = 2^1 byte */
+#define YT921X_TOKEN_PKT_C -6 /* 1 token = 2^-6 packets */
+#define YT921X_TOKEN_RATE_C -15
+/* Custom meters only, not including dedicated port meters (11) */
+#define YT921X_METER_NUM 64
+#define YT921X_METER_SLOT_MIN 80
+#define YT921X_METER_UNIT_MAX ((1 << 3) - 1)
+#define YT921X_METER_CIR_MAX ((1 << 18) - 1)
+#define YT921X_METER_CBS_MAX ((1 << 16) - 1)
+
#define YT921X_LAG_NUM 2
#define YT921X_LAG_PORT_NUM 4
@@ -602,8 +651,10 @@ struct yt921x_priv {
struct dsa_switch ds;
const struct yt921x_info *info;
+ unsigned int meter_slot_ns;
/* cache of dsa_cpu_ports(ds) */
u16 cpu_ports_mask;
+ unsigned char cycle_ns;
/* protect the access to the switch registers */
struct mutex reg_lock;
--
2.53.0
^ permalink raw reply related
* RE: [Intel-wired-lan] [PATCH v7 net-next 5/8] ice: introduce TXC DPLL device and TX ref clock pin framework for E825
From: Loktionov, Aleksandr @ 2026-04-30 11:46 UTC (permalink / raw)
To: Nitka, Grzegorz, netdev@vger.kernel.org
Cc: Vecera, Ivan, vadim.fedorenko@linux.dev, kuba@kernel.org,
jiri@resnulli.us, edumazet@google.com, Kitszel, Przemyslaw,
richardcochran@gmail.com, donald.hunter@gmail.com,
linux-kernel@vger.kernel.org, Kubalewski, Arkadiusz,
andrew+netdev@lunn.ch, intel-wired-lan@lists.osuosl.org,
horms@kernel.org, Prathosh.Satish@microchip.com,
Nguyen, Anthony L, pabeni@redhat.com, davem@davemloft.net
In-Reply-To: <20260430094238.987976-6-grzegorz.nitka@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Grzegorz Nitka
> Sent: Thursday, April 30, 2026 11:43 AM
> To: netdev@vger.kernel.org
> Cc: Vecera, Ivan <ivecera@redhat.com>; vadim.fedorenko@linux.dev;
> kuba@kernel.org; jiri@resnulli.us; edumazet@google.com; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; richardcochran@gmail.com;
> donald.hunter@gmail.com; linux-kernel@vger.kernel.org; Kubalewski,
> Arkadiusz <arkadiusz.kubalewski@intel.com>; andrew+netdev@lunn.ch;
> intel-wired-lan@lists.osuosl.org; horms@kernel.org;
> Prathosh.Satish@microchip.com; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; pabeni@redhat.com; davem@davemloft.net
> Subject: [Intel-wired-lan] [PATCH v7 net-next 5/8] ice: introduce TXC
> DPLL device and TX ref clock pin framework for E825
>
> E825 devices provide a dedicated TX clock (TXC) domain which may be
> driven by multiple reference clock sources, including external board
> references and port-derived SyncE. To support future TX clock control
> and observability through the Linux DPLL subsystem, introduce a
> separate TXC DPLL device (of DPLL_TYPE_GENERIC) and a framework for
> representing TX reference clock inputs.
>
> This change adds a new internal DPLL pin type (TXCLK) and registers TX
> reference clock pins for E825-based devices:
> - EXT_EREF0: a board-level external electrical reference
> - SYNCE: a port-derived SyncE reference described via firmware nodes
>
> The TXC DPLL device is created and managed alongside the existing PPS
> and EEC DPLL instances. TXCLK pins are registered directly or deferred
> via a notifier when backed by fwnode-described pins.
> A per-pin attribute encodes the TX reference source associated with
> each TXCLK pin.
>
> At this stage, TXCLK pin state callbacks and TXC DPLL lock status
> reporting are implemented as placeholders. Pin state getters always
> return DISCONNECTED, and the TXC DPLL is initialized in the UNLOCKED
> state. No hardware configuration or TX reference switching is
> performed yet.
>
> This patch establishes the structural groundwork required for
> hardware-backed TX reference selection, verification, and
> synchronization status reporting, which will be implemented in
> subsequent patches.
>
> Reviewed-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
> Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
> ---
> drivers/net/ethernet/intel/ice/ice_dpll.c | 296 ++++++++++++++++++-
> -
> drivers/net/ethernet/intel/ice/ice_dpll.h | 6 +
> drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 7 +
> 3 files changed, 286 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c
> b/drivers/net/ethernet/intel/ice/ice_dpll.c
> index 62f75701d652..d839b50187ba 100644
> --- a/drivers/net/ethernet/intel/ice/ice_dpll.c
> +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
> @@ -19,6 +19,11 @@
> #define ICE_DPLL_SW_PIN_INPUT_BASE_QSFP 6
> #define ICE_DPLL_SW_PIN_OUTPUT_BASE 0
>
> +#define E825_EXT_EREF_PIN_IDX 0
> +#define E825_EXT_SYNCE_PIN_IDX 1
> +#define E825_RCLK_PARENT_0_PIN_IDX 0
> +#define E825_RCLK_PARENT_1_PIN_IDX 1
> +
> #define ICE_DPLL_PIN_SW_INPUT_ABS(in_idx) \
> (ICE_DPLL_SW_PIN_INPUT_BASE_SFP + (in_idx))
>
> @@ -57,6 +62,7 @@
> * @ICE_DPLL_PIN_TYPE_OUTPUT: output pin
> * @ICE_DPLL_PIN_TYPE_RCLK_INPUT: recovery clock input pin
> * @ICE_DPLL_PIN_TYPE_SOFTWARE: software controlled SMA/U.FL pins
...
> /**
> @@ -3199,19 +3276,40 @@ static bool ice_dpll_is_fwnode_pin(struct
> ice_dpll_pin *pin)
> return !IS_ERR_OR_NULL(pin->fwnode);
> }
>
> +static bool ice_dpll_fwnode_eq(const struct fwnode_handle *a,
> + const struct fwnode_handle *b) {
> + return a && b && a == b;
I'm pretty sure that return a && a == b; is enough instead.
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
> +}
> +
...
> #define E810C_QSFP_C827_0_HANDLE 2
> #define E810C_QSFP_C827_1_HANDLE 3
>
> --
> 2.39.3
^ permalink raw reply
* Re: [PATCH v2 3/3] arm64: dts: imx8dxl: Add SolidRun SoM and HummingBoard
From: Josua Mayer @ 2026-04-30 11:48 UTC (permalink / raw)
To: Vladimir Oltean
Cc: Andrew Lunn, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Shawn Guo, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Vladimir Oltean, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Yazan Shhady, Mikhail Anikin,
Alexander Dahl, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org, Conor Dooley,
Krzysztof Kozlowski, netdev@vger.kernel.org
In-Reply-To: <20260430111924.nvwohy4nexzyiyyl@skbuf>
Am 30.04.26 um 13:19 schrieb Vladimir Oltean:
> On Thu, Apr 30, 2026 at 11:17:36AM +0000, Josua Mayer wrote:
>> Am 09.04.26 um 14:46 schrieb Andrew Lunn:
>>>> +&eqos {
>>>> + /* delays are added by connected ethernet-switch cpu port */
>>>> + phy-mode = "rgmii";
>>>> + pinctrl-0 = <&eqos_pins>;
>>>> + pinctrl-names = "default";
>>>> + status = "okay";
>>>> +
>>>> + fixed-link {
>>>> + full-duplex;
>>>> + speed = <1000>;
>>>> + };
>>>> +};
>>>> + ethernet-switch@0 {
>>>> + compatible = "nxp,sja1110a";
>>>> + reg = <0>;
>>>> + reset-gpios = <&lsio_gpio4 3 GPIO_ACTIVE_LOW>;
>>>> + spi-max-frequency = <4000000>;
>>>> +
>>>> + ethernet-ports {
>>>> + #address-cells = <1>;
>>>> + #size-cells = <0>;
>>>> +
>>>> + /* 100Base-TX on connector J26 */
>>>> + port@1 {
>>>> + reg = <0x1>;
>>>> + label = "lan1";
>>>> + phy-handle = <&switch_port1_base_tx_phy>;
>>>> + phy-mode = "internal";
>>>> + status = "okay";
>> dropping unnecessary status okay for v3
>>>> + };
>>>> +
>>>> + /* CPU */
>>>> + port@2 {
>>>> + reg = <0x2>;
>>>> + ethernet = <&eqos>;
>>>> + label = "cpu";
> Please drop unused label = "cpu".
Okay.
> Also, can you use udev for user
> interface naming?
Possibly .... I am aware of systemd (udev) based default behaviour
for network interface aliases (eth0, eth1, ...).
However I have not seen it for dsa switch ports.
It has been common practice for switch ports to be named lan[0-9]+,
and I'd prefer to keep it that way here too.
Predictable names are important for users in particular when interfaces
are of different types and at different connectors.
Re. the T1 ports names I didn't know whether to use "lan" or "trx".
For those if "lan" is preferred, I can change them.
>
>>>> + phy-mode = "rgmii-id";
>>>> + rx-internal-delay-ps = <2000>;
>>>> + tx-internal-delay-ps = <2000>;
>>>> + status = "okay";
>> dropping unnecessary status okay for v3
>>>> +
>>>> + fixed-link {
>>>> + full-duplex;
>>>> + speed = <1000>;
>>>> + };
>>>> + };
>>>> +
>>>> + /* sgmii on addon board connector J21 */
>>>> + port@3 {
>>>> + reg = <0x3>;
>>>> + label = "lan3";
>>>> + status = "disabled";
>>>> + };
>>>> +
>>>> + /* sgmii on addon board connector J21 */
>>>> + port@4 {
>>>> + reg = <0x4>;
>>>> + label = "lan4";
>>>> + status = "disabled";
>>>> + };
>>>> +
>>>> + /* 100base-t1 on addon board connector J21 */
>>>> + port@5 {
>>>> + reg = <0x5>;
>>>> + label = "trx1";
>>>> + phy-handle = <&switch_port5_base_t1_phy>;
>>>> + phy-mode = "internal";
>>>> + status = "disabled";
>>>> + };
>>>> +
>>>> + /* 100base-t1 on addon board connector J21 */
>>>> + port@6 {
>>>> + reg = <0x6>;
>>>> + label = "trx2";
>>>> + phy-handle = <&switch_port6_base_t1_phy>;
>>>> + phy-mode = "internal";
>>>> + status = "disabled";
>>>> + };
>>>> +
>>>> + /* 100base-t1 on addon board connector J21 */
>>>> + port@7 {
>>>> + reg = <0x7>;
>>>> + label = "trx3";
>>>> + phy-handle = <&switch_port7_base_t1_phy>;
>>>> + phy-mode = "internal";
>>>> + status = "disabled";
>>>> + };
>>>> +
>>>> + /* 100base-t1 on addon board connector J21 */
>>>> + port@8 {
>>>> + reg = <0x8>;
>>>> + label = "trx4";
>>>> + phy-handle = <&switch_port8_base_t1_phy>;
>>>> + phy-mode = "internal";
>>>> + status = "disabled";
>>>> + };
>>>> +
>>>> + /* 100base-t1 on addon board connector J21 */
>>>> + port@9 {
>>>> + reg = <0x9>;
>>>> + label = "trx5";
>>>> + phy-handle = <&switch_port9_base_t1_phy>;
>>>> + phy-mode = "internal";
>>>> + status = "disabled";
>>>> + };
>>>> +
>>>> + /* 100Base-T1 on connector J26 */
>>>> + port@a {
>>>> + reg = <0xa>;
>>>> + label = "trx6";
>>>> + phy-handle = <&switch_port10_base_t1_phy>;
>>>> + phy-mode = "internal";
>>>> + status = "okay";
>> dropping unnecessary status okay for v3
>>>> + };
>>>> + };
>>>> +
>>>> + mdios {
>>>> + #address-cells = <1>;
>>>> + #size-cells = <0>;
>>>> +
>>>> + mdio@0 {
>>>> + compatible = "nxp,sja1110-base-t1-mdio";
>>>> + reg = <0>;
>>>> + #address-cells = <1>;
>>>> + #size-cells = <0>;
>>>> +
>>>> + /* 100base-t1 on addon board connector J21 */
>>>> + switch_port5_base_t1_phy: ethernet-phy@1 {
>>>> + compatible = "ethernet-phy-ieee802.3-c45";
>>>> + reg = <0x1>;
>>>> + status = "disabled";
>>>> + };
>>>> +
>>>> + /* 100base-t1 on addon board connector J21 */
>>>> + switch_port6_base_t1_phy: ethernet-phy@2 {
>>>> + compatible = "ethernet-phy-ieee802.3-c45";
>>>> + reg = <0x2>;
>>>> + status = "disabled";
>>>> + };
>>>> +
>>>> + /* 100base-t1 on addon board connector J21 */
>>>> + switch_port7_base_t1_phy: ethernet-phy@3 {
>>>> + compatible = "ethernet-phy-ieee802.3-c45";
>>>> + reg = <0x3>;
>>>> + status = "disabled";
>>>> + };
>>>> +
>>>> + /* 100base-t1 on addon board connector J21 */
>>>> + switch_port8_base_t1_phy: ethernet-phy@4 {
>>>> + compatible = "ethernet-phy-ieee802.3-c45";
>>>> + reg = <0x4>;
>>>> + status = "disabled";
>>>> + };
>>>> +
>>>> + /* 100base-t1 on addon board connector J21 */
>>>> + switch_port9_base_t1_phy: ethernet-phy@5 {
>>>> + compatible = "ethernet-phy-ieee802.3-c45";
>>>> + reg = <0x5>;
>>>> + status = "disabled";
>>>> + };
>>>> +
>>>> + /* 100Base-T1 on connector J26 */
>>>> + switch_port10_base_t1_phy: ethernet-phy@6 {
>>>> + compatible = "ethernet-phy-ieee802.3-c45";
>>>> + reg = <0x6>;
>>>> + };
>>>> + };
>>>> +
>>>> + mdio@1 {
>>>> + compatible = "nxp,sja1110-base-tx-mdio";
>>>> + reg = <1>;
>>>> + #address-cells = <1>;
>>>> + #size-cells = <0>;
>>>> +
>>>> + /* 100Base-TX on connector J26 */
>>>> + switch_port1_base_tx_phy: ethernet-phy@1 {
>>>> + reg = <0x1>;
>>>> + };
>>>> + };
>>> For these nodes only:
>>>
>>> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
>>>
>>> Andrew
>> Thanks!
>>
>> I don't know how to keep this partial review for v3, so I will send it without.
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH v7 net-next 1/8] dpll: add generic DPLL type
From: Loktionov, Aleksandr @ 2026-04-30 11:49 UTC (permalink / raw)
To: Nitka, Grzegorz, netdev@vger.kernel.org
Cc: Vecera, Ivan, vadim.fedorenko@linux.dev, kuba@kernel.org,
jiri@resnulli.us, edumazet@google.com, Kitszel, Przemyslaw,
richardcochran@gmail.com, donald.hunter@gmail.com,
linux-kernel@vger.kernel.org, Kubalewski, Arkadiusz,
andrew+netdev@lunn.ch, intel-wired-lan@lists.osuosl.org,
horms@kernel.org, Prathosh.Satish@microchip.com,
Nguyen, Anthony L, pabeni@redhat.com, davem@davemloft.net
In-Reply-To: <20260430094238.987976-2-grzegorz.nitka@intel.com>
> -----Original Message-----
> From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf
> Of Grzegorz Nitka
> Sent: Thursday, April 30, 2026 11:43 AM
> To: netdev@vger.kernel.org
> Cc: Vecera, Ivan <ivecera@redhat.com>; vadim.fedorenko@linux.dev;
> kuba@kernel.org; jiri@resnulli.us; edumazet@google.com; Kitszel,
> Przemyslaw <przemyslaw.kitszel@intel.com>; richardcochran@gmail.com;
> donald.hunter@gmail.com; linux-kernel@vger.kernel.org; Kubalewski,
> Arkadiusz <arkadiusz.kubalewski@intel.com>; andrew+netdev@lunn.ch;
> intel-wired-lan@lists.osuosl.org; horms@kernel.org;
> Prathosh.Satish@microchip.com; Nguyen, Anthony L
> <anthony.l.nguyen@intel.com>; pabeni@redhat.com; davem@davemloft.net
> Subject: [Intel-wired-lan] [PATCH v7 net-next 1/8] dpll: add generic
> DPLL type
>
> Add DPLL_TYPE_GENERIC to represent DPLL devices which do not fit the
> existing PPS or EEC classes.
>
> The UAPI type is intentionally generic. During netdev discussion,
> maintainers pointed out that introducing identifiers tied to a
> specific placement or single design does not scale across ASICs and
> vendors.
> The role of a DPLL is already inferable from the spawning driver, bus
> device, and pin topology, without encoding additional purpose-specific
> taxonomy in the type name.
>
> Using a generic type keeps the UAPI extensible and avoids premature
> naming that may become incorrect as new hardware topologies are
> exposed through the DPLL subsystem.
>
> Expose the new type through UAPI and netlink specification as
> "generic".
>
> Signed-off-by: Grzegorz Nitka <grzegorz.nitka@intel.com>
> ---
> Documentation/netlink/specs/dpll.yaml | 3 +++
> drivers/dpll/dpll_nl.c | 2 +-
> include/uapi/linux/dpll.h | 2 ++
> 3 files changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/netlink/specs/dpll.yaml
> b/Documentation/netlink/specs/dpll.yaml
> index 40465a3d7fc2..572cf7ae5f36 100644
> --- a/Documentation/netlink/specs/dpll.yaml
> +++ b/Documentation/netlink/specs/dpll.yaml
> @@ -138,6 +138,9 @@ definitions:
> -
> name: eec
> doc: dpll drives the Ethernet Equipment Clock
> + -
> + name: generic
> + doc: generic dpll type for devices outside PPS/EEC classes
> render-max: true
> -
> type: enum
> diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c index
> 1e652340a5d7..9a3b70ea3ae0 100644
> --- a/drivers/dpll/dpll_nl.c
> +++ b/drivers/dpll/dpll_nl.c
> @@ -34,7 +34,7 @@ const struct nla_policy
> dpll_reference_sync_nl_policy[DPLL_A_PIN_STATE + 1] = { static const
> struct nla_policy dpll_device_id_get_nl_policy[DPLL_A_TYPE + 1] = {
> [DPLL_A_MODULE_NAME] = { .type = NLA_NUL_STRING, },
> [DPLL_A_CLOCK_ID] = { .type = NLA_U64, },
> - [DPLL_A_TYPE] = NLA_POLICY_RANGE(NLA_U32, 1, 2),
> + [DPLL_A_TYPE] = NLA_POLICY_RANGE(NLA_U32, 1, 3),
I think you need especial note if you manually edit "do not edit directly" file.
Isn't it ?
> };
>
> /* DPLL_CMD_DEVICE_GET - do */
> diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h
> index 871685f7c353..648553053cd8 100644
> --- a/include/uapi/linux/dpll.h
> +++ b/include/uapi/linux/dpll.h
> @@ -109,10 +109,12 @@ enum dpll_clock_quality_level {
> * enum dpll_type - type of dpll, valid values for DPLL_A_TYPE
> attribute
> * @DPLL_TYPE_PPS: dpll produces Pulse-Per-Second signal
> * @DPLL_TYPE_EEC: dpll drives the Ethernet Equipment Clock
> + * @DPLL_TYPE_GENERIC: generic dpll type for devices outside PPS/EEC
> + classes
> */
> enum dpll_type {
> DPLL_TYPE_PPS = 1,
> DPLL_TYPE_EEC,
> + DPLL_TYPE_GENERIC,
>
> /* private: */
> __DPLL_TYPE_MAX,
> --
> 2.39.3
^ permalink raw reply
* Re: [PATCH v2 net] sfc: fix error code in efx_devlink_info_running_versions()
From: patchwork-bot+netdevbpf @ 2026-04-30 11:50 UTC (permalink / raw)
To: Dan Carpenter
Cc: alejandro.lucero-palau, ecree.xilinx, andrew+netdev, davem,
edumazet, kuba, pabeni, habetsm.xilinx, jiri, netdev,
linux-net-drivers, linux-kernel, kernel-janitors
In-Reply-To: <afGpsbLRHL4_H0KS@stanley.mountain>
Hello:
This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Wed, 29 Apr 2026 09:48:17 +0300 you wrote:
> Return -EIO if efx_mcdi_rpc() doesn't return enough space.
>
> Fixes: 14743ddd2495 ("sfc: add devlink info support for ef100")
> Signed-off-by: Dan Carpenter <error27@gmail.com>
> ---
> v2: Originally I returned -EINVAL but -EIO is the usual error code
> when 'MC response was too short'
>
> [...]
Here is the summary with links:
- [v2,net] sfc: fix error code in efx_devlink_info_running_versions()
https://git.kernel.org/netdev/net/c/051ffb001b8a
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH net] net: tls: fix strparser anchor skb leak on offload RX setup failure
From: patchwork-bot+netdevbpf @ 2026-04-30 11:50 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms,
john.fastabend, sd
In-Reply-To: <20260428231559.1358502-1-kuba@kernel.org>
Hello:
This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Tue, 28 Apr 2026 16:15:59 -0700 you wrote:
> When tls_set_device_offload_rx() fails at tls_dev_add(), the error path
> calls tls_sw_free_resources_rx() to clean up the SW context that was
> initialized by tls_set_sw_offload(). This function calls
> tls_sw_release_resources_rx() (which stops the strparser via
> tls_strp_stop()) and tls_sw_free_ctx_rx() (which kfrees the context),
> but never frees the anchor skb that was allocated by alloc_skb(0) in
> tls_strp_init().
>
> [...]
Here is the summary with links:
- [net] net: tls: fix strparser anchor skb leak on offload RX setup failure
https://git.kernel.org/netdev/net/c/58689498ca33
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH 2/2] pinctrl: qcom: Add Shikra pinctrl driver
From: Linus Walleij @ 2026-04-30 11:51 UTC (permalink / raw)
To: Komal Bajaj
Cc: Bjorn Andersson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Richard Cochran, linux-arm-msm, linux-gpio, devicetree,
linux-kernel, netdev
In-Reply-To: <20260429-shikra-pinctrl-v1-2-1b4bb2b3a8d6@oss.qualcomm.com>
On Wed, Apr 29, 2026 at 3:12 PM Komal Bajaj
<komal.bajaj@oss.qualcomm.com> wrote:
> Add pinctrl driver for TLMM block found in Shikra SoC.
>
> Signed-off-by: Komal Bajaj <komal.bajaj@oss.qualcomm.com>
(...)
> +config PINCTRL_SHIKRA
> + tristate "Qualcomm Technologies Inc Shikra pin controller driver"
Those descriptions are changed in my devel branch, should be something
like "Qualcomm Shikra pin controller driver".
Yours,
Linus Walleij
^ permalink raw reply
* Re: [PATCH net-next 1/2] dpll: add pin operational state
From: Petr Oros @ 2026-04-30 11:58 UTC (permalink / raw)
To: Ivan Vecera, netdev
Cc: Arkadiusz Kubalewski, David S. Miller, Donald Hunter,
Eric Dumazet, Jakub Kicinski, Jiri Pirko, Jonathan Corbet,
Michal Schmidt, Paolo Abeni, Pasi Vaananen, Prathosh Satish,
Shuah Khan, Simon Horman, Vadim Fedorenko, linux-doc,
linux-kernel
In-Reply-To: <20260428154907.2820654-2-ivecera@redhat.com>
On 4/28/26 17:49, Ivan Vecera wrote:
> Add pin-operstate enum and operstate_on_dpll_get callback to report
> the actual hardware status of a pin with respect to its parent DPLL
> device. Unlike pin-state (which reflects administrative intent set
> by the user), operstate reflects what the hardware is actually doing.
>
> Defined operational states:
> - active: pin is qualified and actively used by the DPLL
> - standby: pin is qualified but not actively used by the DPLL
> - no-signal: pin does not have a valid signal
> - qual-failed: pin signal failed qualification
>
> The operstate is reported inside the pin-parent-device nested
> attribute alongside the existing state and phase-offset attributes.
>
> Signed-off-by: Ivan Vecera <ivecera@redhat.com>
> ---
> Documentation/driver-api/dpll.rst | 38 ++++++++++++++++-----------
> Documentation/netlink/specs/dpll.yaml | 31 ++++++++++++++++++++++
> drivers/dpll/dpll_netlink.c | 27 +++++++++++++++++++
> drivers/dpll/dpll_nl.c | 3 ++-
> drivers/dpll/dpll_nl.h | 2 +-
> include/linux/dpll.h | 6 +++++
> include/uapi/linux/dpll.h | 23 ++++++++++++++++
> 7 files changed, 113 insertions(+), 17 deletions(-)
>
> diff --git a/Documentation/driver-api/dpll.rst b/Documentation/driver-api/dpll.rst
> index 93c191b2d0898..37eaef785e304 100644
> --- a/Documentation/driver-api/dpll.rst
> +++ b/Documentation/driver-api/dpll.rst
> @@ -65,35 +65,43 @@ request, where user provides attributes that result in single pin match.
> Pin selection
> =============
>
> -In general, selected pin (the one which signal is driving the dpll
> -device) can be obtained from ``DPLL_A_PIN_STATE`` attribute, and only
> -one pin shall be in ``DPLL_PIN_STATE_CONNECTED`` state for any dpll
> -device.
> +Pin state (``DPLL_A_PIN_STATE``) reflects the administrative intent set
> +by the user. Pin operational state (``DPLL_A_PIN_OPERSTATE``) reflects
> +what the hardware is actually doing with the pin.
>
> Pin selection can be done either manually or automatically, depending
> on hardware capabilities and active dpll device work mode
> (``DPLL_A_MODE`` attribute). The consequence is that there are
> -differences for each mode in terms of available pin states, as well as
> -for the states the user can request for a dpll device.
> +differences for each mode in terms of available pin states the user can
> +request for a dpll device.
>
> -In manual mode (``DPLL_MODE_MANUAL``) the user can request or receive
> -one of following pin states:
> +In manual mode (``DPLL_MODE_MANUAL``) the user can request one of
> +following pin states:
>
> -- ``DPLL_PIN_STATE_CONNECTED`` - the pin is used to drive dpll device
> -- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin is not used to drive dpll
> +- ``DPLL_PIN_STATE_CONNECTED`` - the pin is selected to drive dpll
> device
> +- ``DPLL_PIN_STATE_DISCONNECTED`` - the pin is not selected to drive
> + dpll device
>
> -In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can request or
> -receive one of following pin states:
> +In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can request one of
> +following pin states:
>
> - ``DPLL_PIN_STATE_SELECTABLE`` - the pin shall be considered as valid
> input for automatic selection algorithm
> - ``DPLL_PIN_STATE_DISCONNECTED`` - the pin shall be not considered as
> a valid input for automatic selection algorithm
>
> -In automatic mode (``DPLL_MODE_AUTOMATIC``) the user can only receive
> -pin state ``DPLL_PIN_STATE_CONNECTED`` once automatic selection
> -algorithm locks a dpll device with one of the inputs.
> +The actual hardware status of a pin is reported via the operational
> +state (``DPLL_A_PIN_OPERSTATE``) attribute nested under the parent
> +device:
> +
> +- ``DPLL_PIN_OPERSTATE_ACTIVE`` - pin is qualified and actively used
> + by the DPLL
> +- ``DPLL_PIN_OPERSTATE_STANDBY`` - pin is qualified but not actively
> + used by the DPLL
> +- ``DPLL_PIN_OPERSTATE_NO_SIGNAL`` - pin does not have a valid signal
> +- ``DPLL_PIN_OPERSTATE_QUAL_FAILED`` - pin signal failed qualification
> + checks
>
> Shared pins
> ===========
> diff --git a/Documentation/netlink/specs/dpll.yaml b/Documentation/netlink/specs/dpll.yaml
> index 40465a3d7fc20..c45de70a47ce6 100644
> --- a/Documentation/netlink/specs/dpll.yaml
> +++ b/Documentation/netlink/specs/dpll.yaml
> @@ -212,6 +212,27 @@ definitions:
> name: selectable
> doc: pin enabled for automatic input selection
> render-max: true
> + -
> + type: enum
> + name: pin-operstate
> + doc: |
> + defines possible operational states of a pin with respect to its
> + parent DPLL device, valid values for DPLL_A_PIN_OPERSTATE attribute
> + entries:
> + -
> + name: active
> + doc: pin is qualified and actively used by the DPLL
> + value: 1
> + -
> + name: standby
> + doc: pin is qualified but not actively used by the DPLL
> + -
> + name: no-signal
> + doc: pin does not have a valid signal
> + -
> + name: qual-failed
> + doc: pin signal failed qualification (e.g. frequency or phase monitor)
> + render-max: true
> -
> type: flags
> name: pin-capabilities
> @@ -488,6 +509,14 @@ attribute-sets:
> Value of (DPLL_A_PIN_MEASURED_FREQUENCY %
> DPLL_PIN_MEASURED_FREQUENCY_DIVIDER) is a fractional part
> of a measured frequency value.
> + -
> + name: operstate
> + type: u32
> + enum: pin-operstate
> + doc: |
> + Operational state of the pin with respect to its parent DPLL
> + device. Unlike state (which reflects the administrative intent),
> + operstate reflects the actual hardware status.
>
> -
> name: pin-parent-device
> @@ -501,6 +530,8 @@ attribute-sets:
> name: prio
> -
> name: state
> + -
> + name: operstate
> -
> name: phase-offset
> -
> diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c
> index af7ce62ec55ca..05cf946b4be5e 100644
> --- a/drivers/dpll/dpll_netlink.c
> +++ b/drivers/dpll/dpll_netlink.c
> @@ -324,6 +324,30 @@ dpll_msg_add_pin_on_dpll_state(struct sk_buff *msg, struct dpll_pin *pin,
> return 0;
> }
>
> +static int
> +dpll_msg_add_pin_operstate(struct sk_buff *msg, struct dpll_pin *pin,
> + struct dpll_pin_ref *ref,
> + struct netlink_ext_ack *extack)
> +{
> + const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
> + struct dpll_device *dpll = ref->dpll;
> + enum dpll_pin_operstate operstate;
> + int ret;
> +
> + if (!ops->operstate_on_dpll_get)
> + return 0;
> + ret = ops->operstate_on_dpll_get(pin,
> + dpll_pin_on_dpll_priv(dpll, pin),
> + dpll, dpll_priv(dpll),
> + &operstate, extack);
> + if (ret)
> + return ret;
> + if (nla_put_u32(msg, DPLL_A_PIN_OPERSTATE, operstate))
> + return -EMSGSIZE;
> +
> + return 0;
> +}
> +
> static int
> dpll_msg_add_pin_direction(struct sk_buff *msg, struct dpll_pin *pin,
> struct dpll_pin_ref *ref,
> @@ -650,6 +674,9 @@ dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll_pin *pin,
> if (ret)
> goto nest_cancel;
> ret = dpll_msg_add_pin_on_dpll_state(msg, pin, ref, extack);
> + if (ret)
> + goto nest_cancel;
> + ret = dpll_msg_add_pin_operstate(msg, pin, ref, extack);
> if (ret)
> goto nest_cancel;
> ret = dpll_msg_add_pin_prio(msg, pin, ref, extack);
> diff --git a/drivers/dpll/dpll_nl.c b/drivers/dpll/dpll_nl.c
> index 1e652340a5d73..58235845fa3d5 100644
> --- a/drivers/dpll/dpll_nl.c
> +++ b/drivers/dpll/dpll_nl.c
> @@ -12,11 +12,12 @@
> #include <uapi/linux/dpll.h>
>
> /* Common nested types */
> -const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_PHASE_OFFSET + 1] = {
> +const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_OPERSTATE + 1] = {
> [DPLL_A_PIN_PARENT_ID] = { .type = NLA_U32, },
> [DPLL_A_PIN_DIRECTION] = NLA_POLICY_RANGE(NLA_U32, 1, 2),
> [DPLL_A_PIN_PRIO] = { .type = NLA_U32, },
> [DPLL_A_PIN_STATE] = NLA_POLICY_RANGE(NLA_U32, 1, 3),
> + [DPLL_A_PIN_OPERSTATE] = NLA_POLICY_RANGE(NLA_U32, 1, 4),
> [DPLL_A_PIN_PHASE_OFFSET] = { .type = NLA_S64, },
> };
>
> diff --git a/drivers/dpll/dpll_nl.h b/drivers/dpll/dpll_nl.h
> index 7419679b69779..fa8280e3dd14c 100644
> --- a/drivers/dpll/dpll_nl.h
> +++ b/drivers/dpll/dpll_nl.h
> @@ -13,7 +13,7 @@
> #include <uapi/linux/dpll.h>
>
> /* Common nested types */
> -extern const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_PHASE_OFFSET + 1];
> +extern const struct nla_policy dpll_pin_parent_device_nl_policy[DPLL_A_PIN_OPERSTATE + 1];
> extern const struct nla_policy dpll_pin_parent_pin_nl_policy[DPLL_A_PIN_STATE + 1];
> extern const struct nla_policy dpll_reference_sync_nl_policy[DPLL_A_PIN_STATE + 1];
>
> diff --git a/include/linux/dpll.h b/include/linux/dpll.h
> index b7277a8b484d2..b6f16c884b99e 100644
> --- a/include/linux/dpll.h
> +++ b/include/linux/dpll.h
> @@ -85,6 +85,12 @@ struct dpll_pin_ops {
> const struct dpll_device *dpll,
> void *dpll_priv, enum dpll_pin_state *state,
> struct netlink_ext_ack *extack);
> + int (*operstate_on_dpll_get)(const struct dpll_pin *pin,
> + void *pin_priv,
> + const struct dpll_device *dpll,
> + void *dpll_priv,
> + enum dpll_pin_operstate *operstate,
> + struct netlink_ext_ack *extack);
> int (*state_on_pin_set)(const struct dpll_pin *pin, void *pin_priv,
> const struct dpll_pin *parent_pin,
> void *parent_pin_priv,
> diff --git a/include/uapi/linux/dpll.h b/include/uapi/linux/dpll.h
> index 871685f7c353b..cb363cccf2e2a 100644
> --- a/include/uapi/linux/dpll.h
> +++ b/include/uapi/linux/dpll.h
> @@ -178,6 +178,28 @@ enum dpll_pin_state {
> DPLL_PIN_STATE_MAX = (__DPLL_PIN_STATE_MAX - 1)
> };
>
> +/**
> + * enum dpll_pin_operstate - defines possible operational states of a pin with
> + * respect to its parent DPLL device, valid values for DPLL_A_PIN_OPERSTATE
> + * attribute
> + * @DPLL_PIN_OPERSTATE_ACTIVE: pin is qualified and actively used by the DPLL
> + * @DPLL_PIN_OPERSTATE_STANDBY: pin is qualified but not actively used by the
> + * DPLL
> + * @DPLL_PIN_OPERSTATE_NO_SIGNAL: pin does not have a valid signal
> + * @DPLL_PIN_OPERSTATE_QUAL_FAILED: pin signal failed qualification (e.g.
> + * frequency or phase monitor)
> + */
> +enum dpll_pin_operstate {
> + DPLL_PIN_OPERSTATE_ACTIVE = 1,
> + DPLL_PIN_OPERSTATE_STANDBY,
> + DPLL_PIN_OPERSTATE_NO_SIGNAL,
> + DPLL_PIN_OPERSTATE_QUAL_FAILED,
> +
> + /* private: */
> + __DPLL_PIN_OPERSTATE_MAX,
> + DPLL_PIN_OPERSTATE_MAX = (__DPLL_PIN_OPERSTATE_MAX - 1)
> +};
> +
> /**
> * enum dpll_pin_capabilities - defines possible capabilities of a pin, valid
> * flags on DPLL_A_PIN_CAPABILITIES attribute
> @@ -257,6 +279,7 @@ enum dpll_a_pin {
> DPLL_A_PIN_PHASE_ADJUST_GRAN,
> DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET_PPT,
> DPLL_A_PIN_MEASURED_FREQUENCY,
> + DPLL_A_PIN_OPERSTATE,
>
> __DPLL_A_PIN_MAX,
> DPLL_A_PIN_MAX = (__DPLL_A_PIN_MAX - 1)
Reviewed-by: Petr Oros <poros@redhat.com>
^ permalink raw reply
* Re: [PATCH net-next 2/2] dpll: zl3073x: implement pin operational state reporting
From: Petr Oros @ 2026-04-30 11:58 UTC (permalink / raw)
To: Ivan Vecera, netdev
Cc: Arkadiusz Kubalewski, David S. Miller, Donald Hunter,
Eric Dumazet, Jakub Kicinski, Jiri Pirko, Jonathan Corbet,
Michal Schmidt, Paolo Abeni, Pasi Vaananen, Prathosh Satish,
Shuah Khan, Simon Horman, Vadim Fedorenko, linux-doc,
linux-kernel
In-Reply-To: <20260428154907.2820654-3-ivecera@redhat.com>
On 4/28/26 17:49, Ivan Vecera wrote:
> Implement operstate_on_dpll_get callback for input pins to report
> the actual hardware status:
>
> - active: pin is the currently locked reference
> - standby: signal is valid but pin is not actively used
> - no-signal: reference monitor reports Loss of Signal (LOS)
> - qual-failed: reference monitor reports a qualification failure
> (SCM, CFM, GST, PFM, eSync or Split-XO)
>
> Separate administrative state (state_on_dpll_get) from operational
> state: admin state now reports purely the user-requested intent
> (connected in reflock mode, selectable in auto mode).
>
> Switch periodic monitoring to track operstate changes instead of
> the mixed admin/oper state that was previously reported.
>
> Add ref_mon_status bit definitions to regs.h.
>
> Signed-off-by: Ivan Vecera <ivecera@redhat.com>
> ---
> drivers/dpll/zl3073x/dpll.c | 108 ++++++++++++++++++++++++------------
> drivers/dpll/zl3073x/regs.h | 9 ++-
> 2 files changed, 79 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c
> index c95e93ef3ab04..6fd718696de0d 100644
> --- a/drivers/dpll/zl3073x/dpll.c
> +++ b/drivers/dpll/zl3073x/dpll.c
> @@ -38,7 +38,7 @@
> * @prio: pin priority <0, 14>
> * @esync_control: embedded sync is controllable
> * @phase_gran: phase adjustment granularity
> - * @pin_state: last saved pin state
> + * @operstate: last saved operational state
> * @phase_offset: last saved pin phase offset
> * @freq_offset: last saved fractional frequency offset
> * @measured_freq: last saved measured frequency
> @@ -55,7 +55,7 @@ struct zl3073x_dpll_pin {
> u8 prio;
> bool esync_control;
> s32 phase_gran;
> - enum dpll_pin_state pin_state;
> + enum dpll_pin_operstate operstate;
> s64 phase_offset;
> s64 freq_offset;
> u32 measured_freq;
> @@ -500,46 +500,41 @@ zl3073x_dpll_input_pin_phase_adjust_set(const struct dpll_pin *dpll_pin,
> }
>
> /**
> - * zl3073x_dpll_ref_state_get - get status for given input pin
> + * zl3073x_dpll_ref_operstate_get - get operational state for input pin
> * @pin: pointer to pin
> - * @state: place to store status
> + * @operstate: place to store operational state
> *
> - * Checks current status for the given input pin and stores the value
> - * to @state.
> + * Returns the actual hardware state of the pin: whether it is actively
> + * used by the DPLL, has no signal, failed qualification, or is simply
> + * not in use.
> *
> * Return: 0 on success, <0 on error
> */
> static int
> -zl3073x_dpll_ref_state_get(struct zl3073x_dpll_pin *pin,
> - enum dpll_pin_state *state)
> +zl3073x_dpll_ref_operstate_get(struct zl3073x_dpll_pin *pin,
> + enum dpll_pin_operstate *operstate)
> {
> struct zl3073x_dpll *zldpll = pin->dpll;
> struct zl3073x_dev *zldev = zldpll->dev;
> - const struct zl3073x_chan *chan;
> - u8 ref;
> -
> - chan = zl3073x_chan_state_get(zldev, zldpll->id);
> - ref = zl3073x_input_pin_ref_get(pin->id);
> + const struct zl3073x_ref *ref;
> + u8 ref_id;
>
> - /* Check if the pin reference is connected */
> - if (ref == zl3073x_dpll_connected_ref_get(zldpll)) {
> - *state = DPLL_PIN_STATE_CONNECTED;
> - return 0;
> - }
> + ref_id = zl3073x_input_pin_ref_get(pin->id);
>
> - /* If the DPLL is running in automatic mode and the reference is
> - * selectable and its monitor does not report any error then report
> - * pin as selectable.
> - */
> - if (zl3073x_chan_mode_get(chan) == ZL_DPLL_MODE_REFSEL_MODE_AUTO &&
> - zl3073x_dev_ref_is_status_ok(zldev, ref) &&
> - zl3073x_chan_ref_is_selectable(chan, ref)) {
> - *state = DPLL_PIN_STATE_SELECTABLE;
> + /* Check if this pin is the currently locked reference */
> + if (ref_id == zl3073x_dpll_connected_ref_get(zldpll)) {
> + *operstate = DPLL_PIN_OPERSTATE_ACTIVE;
> return 0;
> }
>
> - /* Otherwise report the pin as disconnected */
> - *state = DPLL_PIN_STATE_DISCONNECTED;
> + /* Check reference monitor status */
> + ref = zl3073x_ref_state_get(zldev, ref_id);
> + if (ref->mon_status & ZL_REF_MON_STATUS_LOS)
> + *operstate = DPLL_PIN_OPERSTATE_NO_SIGNAL;
> + else if (!zl3073x_ref_is_status_ok(ref))
> + *operstate = DPLL_PIN_OPERSTATE_QUAL_FAILED;
> + else
> + *operstate = DPLL_PIN_OPERSTATE_STANDBY;
>
> return 0;
> }
> @@ -551,10 +546,48 @@ zl3073x_dpll_input_pin_state_on_dpll_get(const struct dpll_pin *dpll_pin,
> void *dpll_priv,
> enum dpll_pin_state *state,
> struct netlink_ext_ack *extack)
> +{
> + struct zl3073x_dpll *zldpll = dpll_priv;
> + struct zl3073x_dpll_pin *pin = pin_priv;
> + const struct zl3073x_chan *chan;
> + u8 mode, ref;
> +
> + chan = zl3073x_chan_state_get(zldpll->dev, zldpll->id);
> + ref = zl3073x_input_pin_ref_get(pin->id);
> + mode = zl3073x_chan_mode_get(chan);
> +
> + switch (mode) {
> + case ZL_DPLL_MODE_REFSEL_MODE_REFLOCK:
> + if (ref == zl3073x_chan_ref_get(chan))
> + *state = DPLL_PIN_STATE_CONNECTED;
> + else
> + *state = DPLL_PIN_STATE_DISCONNECTED;
> + break;
> + case ZL_DPLL_MODE_REFSEL_MODE_AUTO:
> + if (zl3073x_chan_ref_is_selectable(chan, ref))
> + *state = DPLL_PIN_STATE_SELECTABLE;
> + else
> + *state = DPLL_PIN_STATE_DISCONNECTED;
> + break;
> + default:
> + *state = DPLL_PIN_STATE_DISCONNECTED;
> + break;
> + }
> +
> + return 0;
> +}
> +
> +static int
> +zl3073x_dpll_input_pin_operstate_on_dpll_get(const struct dpll_pin *dpll_pin,
> + void *pin_priv,
> + const struct dpll_device *dpll,
> + void *dpll_priv,
> + enum dpll_pin_operstate *operstate,
> + struct netlink_ext_ack *extack)
> {
> struct zl3073x_dpll_pin *pin = pin_priv;
>
> - return zl3073x_dpll_ref_state_get(pin, state);
> + return zl3073x_dpll_ref_operstate_get(pin, operstate);
> }
>
> static int
> @@ -1248,6 +1281,7 @@ static const struct dpll_pin_ops zl3073x_dpll_input_pin_ops = {
> .frequency_get = zl3073x_dpll_input_pin_frequency_get,
> .frequency_set = zl3073x_dpll_input_pin_frequency_set,
> .measured_freq_get = zl3073x_dpll_input_pin_measured_freq_get,
> + .operstate_on_dpll_get = zl3073x_dpll_input_pin_operstate_on_dpll_get,
> .phase_offset_get = zl3073x_dpll_input_pin_phase_offset_get,
> .phase_adjust_get = zl3073x_dpll_input_pin_phase_adjust_get,
> .phase_adjust_set = zl3073x_dpll_input_pin_phase_adjust_set,
> @@ -1663,7 +1697,7 @@ zl3073x_dpll_pin_phase_offset_check(struct zl3073x_dpll_pin *pin)
> * 2) For other pins use appropriate ref_phase register if the phase
> * monitor feature is enabled.
> */
> - if (pin->pin_state == DPLL_PIN_STATE_CONNECTED)
> + if (pin->operstate == DPLL_PIN_OPERSTATE_ACTIVE)
> reg = ZL_REG_DPLL_PHASE_ERR_DATA(zldpll->id);
> else if (zldpll->phase_monitor)
> reg = ZL_REG_REF_PHASE(ref_id);
> @@ -1828,7 +1862,7 @@ zl3073x_dpll_changes_check(struct zl3073x_dpll *zldpll)
> }
>
> list_for_each_entry(pin, &zldpll->pins, list) {
> - enum dpll_pin_state state;
> + enum dpll_pin_operstate operstate;
> bool pin_changed = false;
>
> /* Output pins change checks are not necessary because output
> @@ -1837,18 +1871,18 @@ zl3073x_dpll_changes_check(struct zl3073x_dpll *zldpll)
> if (!zl3073x_dpll_is_input_pin(pin))
> continue;
>
> - rc = zl3073x_dpll_ref_state_get(pin, &state);
> + rc = zl3073x_dpll_ref_operstate_get(pin, &operstate);
> if (rc) {
> dev_err(dev,
> - "Failed to get %s on DPLL%u state: %pe\n",
> + "Failed to get %s on DPLL%u oper state: %pe\n",
> pin->label, zldpll->id, ERR_PTR(rc));
> return;
> }
>
> - if (state != pin->pin_state) {
> - dev_dbg(dev, "%s state changed: %u->%u\n", pin->label,
> - pin->pin_state, state);
> - pin->pin_state = state;
> + if (operstate != pin->operstate) {
> + dev_dbg(dev, "%s oper state changed: %u->%u\n",
> + pin->label, pin->operstate, operstate);
> + pin->operstate = operstate;
> pin_changed = true;
> }
>
> diff --git a/drivers/dpll/zl3073x/regs.h b/drivers/dpll/zl3073x/regs.h
> index d425dc67250fe..8015808bdf548 100644
> --- a/drivers/dpll/zl3073x/regs.h
> +++ b/drivers/dpll/zl3073x/regs.h
> @@ -98,7 +98,14 @@
>
> #define ZL_REG_REF_MON_STATUS(_idx) \
> ZL_REG_IDX(_idx, 2, 0x02, 1, ZL3073X_NUM_REFS, 1)
> -#define ZL_REF_MON_STATUS_OK 0 /* all bits zeroed */
> +#define ZL_REF_MON_STATUS_OK 0
> +#define ZL_REF_MON_STATUS_LOS BIT(0)
> +#define ZL_REF_MON_STATUS_SCM BIT(1)
> +#define ZL_REF_MON_STATUS_CFM BIT(2)
> +#define ZL_REF_MON_STATUS_GST BIT(3)
> +#define ZL_REF_MON_STATUS_PFM BIT(4)
> +#define ZL_REF_MON_STATUS_ESYNC BIT(6)
> +#define ZL_REF_MON_STATUS_SPLIT_XO BIT(7)
>
> #define ZL_REG_DPLL_MON_STATUS(_idx) \
> ZL_REG_IDX(_idx, 2, 0x10, 1, ZL3073X_MAX_CHANNELS, 1)
Reviewed-by: Petr Oros <poros@redhat.com>
^ permalink raw reply
* Re: [PATCH net] net/sched: cls_flower: revert unintended changes
From: patchwork-bot+netdevbpf @ 2026-04-30 12:00 UTC (permalink / raw)
To: Paolo Abeni; +Cc: netdev, jhs, jiri, davem, edumazet, kuba, horms, william, jk
In-Reply-To: <043026a53ff84da88b17648c4b0d17f0331749cb.1777447863.git.pabeni@redhat.com>
Hello:
This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Wed, 29 Apr 2026 09:39:11 +0200 you wrote:
> While applying the blamed commit 4ca07b9239bd ("net: mctp i2c: check
> length before marking flow active"), I unintentionally included
> unrelated and unacceptable changes.
>
> Revert them.
>
> Fixes: 4ca07b9239bd ("net: mctp i2c: check length before marking flow active")
> Reported-by: Jeremy Kerr <jk@codeconstruct.com.au>
> Closes: https://lore.kernel.org/netdev/bd8704fe0bd53e278add5cde4873256656623e2e.camel@codeconstruct.com.au/
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
>
> [...]
Here is the summary with links:
- [net] net/sched: cls_flower: revert unintended changes
https://git.kernel.org/netdev/net/c/1e01abec8565
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* [GIT PULL] wireless-next-2026-04-30
From: Johannes Berg @ 2026-04-30 12:02 UTC (permalink / raw)
To: netdev; +Cc: linux-wireless
Hi,
Looks like 7.2 is going to be interesting with NAN and UHR
both getting major work, but for now we have some (relatively)
minor things - the biggest is the station bandwidth rework,
which is needed en route to UHR.
Please pull and let us know if there's any problem.
Thanks,
johannes
The following changes since commit 254f49634ee16a731174d2ae34bc50bd5f45e731:
Linux 7.1-rc1 (2026-04-26 14:19:00 -0700)
are available in the Git repository at:
https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next.git tags/wireless-next-2026-04-30
for you to fetch changes up to 7baf5857e15d722776898510a10546d6b2f18645:
wifi: brcmsmac: phy_lcn: Remove dead code in wlc_lcnphy_radio_2064_channel_tune_4313() (2026-04-28 10:43:27 +0200)
----------------------------------------------------------------
Some new content already, notably:
- mac80211: major rework of station bandwidth handling,
fixing issues with lower capability than AP
- general: cleanups for EMLSR spec issues (drafts differed)
- ath9k: GPIO interface improvements
- ath12k: replace dynamic memory allocation in WMI RX path
----------------------------------------------------------------
Aaradhana Sahu (1):
wifi: ath12k: Fix invalid IRQ requests during AHB probe
Chelsy Ratnawat (1):
wifi: brcmsmac: phy_lcn: Remove dead code in wlc_lcnphy_radio_2064_channel_tune_4313()
Daniel Gabay (1):
wifi: cfg80211: validate cipher suite for NAN Data keys
Dmitry Antipov (1):
wifi: mac80211: use kstrtobool_from_user() in debugfs callbacks
Jeff Johnson (3):
wifi: ath12k: Fix HTC prototype ath12k_base parameters
wifi: ath12k: Fix ath12k_dp_htt_tlv_iter()'s iter() signature
wifi: ath12k: Remove macro HAL_RX_EHT_SIG_OFDMA_EB2_MCS
Johannes Berg (24):
wifi: mac80211: remove NAN guards on ieee80211_sta_cur_vht_bw() calls
wifi: mac80211: set cur_max_bandwidth to maximum
wifi: mac80211: use max BW for HT channel width update
wifi: mac80211: use chandef in ieee80211_get_sta_bw()
wifi: mac80211: use chandef in TDLS chanctx handling
wifi: mac80211: remove ieee80211_sta_cap_chan_bw()
wifi: nl80211: document channel opmode change channel width
wifi: mac80211: simplify ieee80211_sta_rx_bw_to_chan_width()
wifi: mac80211: clean up STA NSS handling
wifi: mac80211: clean up initial STA NSS/bandwidth handling
wifi: mac80211: clean up ieee80211_sta_cap_rx_bw()
wifi: mac80211: remove ieee80211_sta_cur_vht_bw()
wifi: cfg80211: remove HE/SAE H2E required fields
wifi: nl80211: reject beacons with bad HE operation
wifi: cfg80211: move AP HT/VHT/... operation to beacon info
wifi: nl80211: reject too short HT/VHT/HE/EHT capability/operation
wifi: cfg80211: provide HT/VHT operation for AP beacon
wifi: nl80211: always validate AP operation/PHY regulatory
wifi: mac80211: clarify per-STA bandwidth handling
wifi: mac80211: fix per-station PHY capability bandwidth
wifi: mac80211: clarify an 802.11 VHT spec reference
wifi: nl80211: check link is beaconing for color change
wifi: mac80211: always allow transmitting null-data on TXQs
Merge tag 'ath-next-20260427' of git://git.kernel.org/pub/scm/linux/kernel/git/ath/ath
Linus Walleij (1):
wifi: ath9k: Obtain system GPIOS from descriptors
Louis Kotze (1):
wifi: cfg80211: fix grammar in MLO group key error message
Nicolas Escande (1):
wifi: ath12k: avoid dynamic alloc when parsing wmi tb
Pablo Martin-Gomez (4):
wifi: Remove invalid 128TU transition timeout constant
wifi: Remove EMLMR Delay subfield definitions
wifi: Rename EMLSR delay constants and add EMLMR helpers and definitions
wifi: Update EML function documentation to remove EMLSR-specific references
Ping-Ke Shih (1):
wifi: mac80211: add __packed to union members of struct ieee80211_rx_status
Yuqi Xu (1):
wifi: cfg80211: reject duplicate wiphy cipher suite entries
drivers/gpio/gpio-ath79.c | 57 +++-
drivers/net/wireless/ath/ath12k/ahb.c | 25 +-
drivers/net/wireless/ath/ath12k/core.c | 6 +
drivers/net/wireless/ath/ath12k/dp_htt.c | 2 +-
drivers/net/wireless/ath/ath12k/dp_htt.h | 2 +-
drivers/net/wireless/ath/ath12k/htc.h | 8 +-
drivers/net/wireless/ath/ath12k/wifi7/hal_rx.h | 1 -
drivers/net/wireless/ath/ath12k/wmi.c | 217 +++++--------
drivers/net/wireless/ath/ath12k/wmi.h | 3 +
drivers/net/wireless/ath/ath9k/hw.c | 33 +-
drivers/net/wireless/ath/ath9k/hw.h | 3 +-
.../broadcom/brcm80211/brcmsmac/phy/phy_lcn.c | 13 +-
drivers/net/wireless/intel/iwlwifi/mld/iface.c | 2 +-
drivers/net/wireless/intel/iwlwifi/mld/mac80211.c | 6 +-
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 +-
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c | 4 +-
drivers/net/wireless/quantenna/qtnfmac/commands.c | 4 +-
drivers/net/wireless/realtek/rtw89/fw.c | 2 +-
include/linux/ieee80211-eht.h | 115 +++++--
include/net/cfg80211.h | 25 +-
include/net/mac80211.h | 10 +-
include/uapi/linux/nl80211.h | 10 +-
net/mac80211/cfg.c | 136 +++++++-
net/mac80211/chan.c | 66 ++--
net/mac80211/debugfs.c | 47 +--
net/mac80211/eht.c | 11 +-
net/mac80211/he.c | 9 +-
net/mac80211/ht.c | 59 +---
net/mac80211/ibss.c | 3 +
net/mac80211/ieee80211_i.h | 28 +-
net/mac80211/mesh_plink.c | 3 +
net/mac80211/mlme.c | 25 +-
net/mac80211/ocb.c | 5 +-
net/mac80211/rate.c | 4 +-
net/mac80211/sta_info.c | 294 ++++++++++++++++-
net/mac80211/sta_info.h | 16 +-
net/mac80211/tdls.c | 24 +-
net/mac80211/tx.c | 2 +-
net/mac80211/util.c | 23 +-
net/mac80211/vht.c | 350 +--------------------
net/wireless/core.c | 21 ++
net/wireless/core.h | 3 +-
net/wireless/nl80211.c | 260 +++++++++------
net/wireless/util.c | 10 +
net/wireless/wext-compat.c | 3 +-
45 files changed, 1097 insertions(+), 859 deletions(-)
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox