From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-yw1-f174.google.com (mail-yw1-f174.google.com [209.85.128.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 04F8839D6FF for ; Sat, 30 May 2026 10:52:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.174 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780138324; cv=none; b=l3W8F5wWoF/sh3CZL6HeqY+Jr5x5J6/etVGeChqpT2AVXaNOkDZVSjDVCJSnD7nQen1ETxB1Vf7Sc6hO0+KgSTseCnudeWoAjC4ijjW72QdodsW7M/Z/OfN2rs3crAoSRzPYx+FKAk+HZP8f0f0pRmQRyez9QZDy5sISs72Xi1w= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780138324; c=relaxed/simple; bh=YE8yAci25sZxPGcV1uGvCIx8UtQWcWaIps8F73J1ZbY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XccghauJnckehhqntqj/lZ3LXbGeVayVVWfsDaX46kU00f0ojK1l36tBs0n3wq3xJSSofHR1Gwcn+dzEr9q24kjg+KCWef8oHhovQbOZohTwmIDQ+U3Gj4h0xMk5V641yyiz0tC85GeXwHR/Jl51C+hH0E+ntOHWBenYtFlKxuU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=et94EE7z; arc=none smtp.client-ip=209.85.128.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="et94EE7z" Received: by mail-yw1-f174.google.com with SMTP id 00721157ae682-7dc6d090381so32286477b3.2 for ; Sat, 30 May 2026 03:52:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780138322; x=1780743122; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=IEznufSV9FiyZUofh6eH1tSidWmVGDG7OZcTFQAh4VI=; b=et94EE7zApNZ3vIkTw9NCqXiUJJBegZAiCwum1ReXq17Zbpy9QViVPU1uI4HwHXoWF LffcxAP1gfs0QrPdMp8EP1ZV32hJfWXWYleFUXlmgo0DpF/7Ov4jKtW7Osj5faE2nUmZ Dv5PSTKuwz8vXlk4qVVI7r4ujw2kOrJH1uGS1OSE+fyn+KKQp/2qLFGb4vKwtWGXv34K mvFYdp9ZUBR+3fXUeR/YXM9FEXZlO5MGYm8W0HXMuCYRIVlTYlN4W0qEIsVisLpl/IVt A7+gkzc6lMVeOnRScsJR7hbjZDAc9cJ34VG4l7qeacMEyJXE3UbA6iDIWSDTAdaNHcIS Gd0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780138322; x=1780743122; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=IEznufSV9FiyZUofh6eH1tSidWmVGDG7OZcTFQAh4VI=; b=cHd6uqAEIgwmhm56Aclk4A1Pz5Iu+nF25BLsZxJ9D4aukUWlpnjAcC1EkL9pL7lXKE 7ntuCKba/cGNLBnRnOLy8uwHZx0dSwZgk5gXXLFP1Yfnm0uPWdi1Xmy8epK4RRvvAjZL pRd35wIiC6wYQ50n9jK+hedpZoV9mVe/mLkTQrVygFezQOAZqm1Mhqm9jBSc7kqrZ15O NyUlI3wGAK9GEXFHOhnzlLCfMKNh2esUk+mlPZpO40Tdy3MaTPACJdvqI9mmW4ERhcT9 eIl1chZiechFqI71bIqnz8RPWGYXDm/55IR6X3osUa0TgF07Uy851kHb4vLDVgClFKdN lfRQ== X-Forwarded-Encrypted: i=1; AFNElJ9vIPErAj5I9t1ZcEyL0bJlykwPjFjA11ELdBtGNdJLGmnK05cYkQ1g2twkZjdA97e4Lz3ML1LQ37zkIM8=@vger.kernel.org X-Gm-Message-State: AOJu0YxcUzX0I4xLK6JPqKYObr2Qh9xIssS2hkb3AKHVq4kwP3INqW8U diu2y0jz9TTkvYXJ7kjAy+xhFHPwVzA2jyb/BLKNMjp1kcoy+vRooZp5 X-Gm-Gg: Acq92OHzsNzDF1Nb9ynP28V83cU17Lk8gLb2TZY2dQK6OsfuQizFieetIRs2ibuKdyl zI+yqtk1ZkP9GZYBcbbdePtsjCE9D9T0Y/bhMSoXmW5JnKqWgZLPJnsWO4Xvy5OgopqFpgvq0kF qC4PCQbMGQ3qrZ03LJR/AZSow9bzjrDOJWd4Gb/kUzye19R9t8srhOuJHJlF/KjXbvUEePvyYjW A+JX+87n/YCyjCACBG2MEbgnNdVj02fv+wBVCoNyvMkq/YH9dWax4R3FXUxjQN+WIYFs6M18TPh WdzkPCoCVRCkazDfT5wKkZ2vqddnnY/uC9Pq4f7hAQydD9p95WAF8sVvJn1tYSYF25iuvv4W/aJ B7LFzOh6H+JSxrcgbwo+EU3AAHbry5AJIkkFZN3H6PYa6uQcCRAcG0VXCpoLw/pHdkfZ8sd3iNr XZq9CO05s6Ep6PRVjCeorAFwwgrRU2n2/JLLzQhRTU1fh3it78P0YzWoCMJMp9 X-Received: by 2002:a05:690c:dc2:b0:7dc:a5a8:8b9 with SMTP id 00721157ae682-7e058d3094amr31058287b3.10.1780138321887; Sat, 30 May 2026 03:52:01 -0700 (PDT) Received: from tresc054937.tre-sc.gov.br ([187.65.210.13]) by smtp.gmail.com with ESMTPSA id 00721157ae682-7e176d6ff86sm5579357b3.16.2026.05.30.03.51.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 30 May 2026 03:52:01 -0700 (PDT) From: Luiz Angelo Daros de Luca Date: Sat, 30 May 2026 07:51:08 -0300 Subject: [net-next PATCH v10 3/9] net: dsa: realtek: rtl8365mb: use dsa helpers for port iteration Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260530-realtek_forward-v10-3-d14b51e6a69d@gmail.com> References: <20260530-realtek_forward-v10-0-d14b51e6a69d@gmail.com> In-Reply-To: <20260530-realtek_forward-v10-0-d14b51e6a69d@gmail.com> To: Andrew Lunn , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Simon Horman , Linus Walleij , =?utf-8?q?Alvin_=C5=A0ipraga?= , Yury Norov , Rasmus Villemoes , Russell King Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Abdulkader Alrezej , Mieczyslaw Nalewaj , Luiz Angelo Daros de Luca X-Mailer: b4 0.15.2 Convert open-coded port iteration loops to use the DSA helpers and restructure rtl8365mb_setup() into clear blocking, user, and CPU port phases. As part of this refactoring, unused ports are no longer initialized and no longer receive a virtual IRQ mapping. To accommodate this, a guard check is added to the interrupt handler (rtl8365mb_irq) to safely skip ports without a valid IRQ mapping Furthermore, since the new initialization loop starts with all ports administratively isolated by default, CPU port forwarding and isolation masks are explicitly configured at the end of the setup phase to prevent egress traffic from being blocked. Suggested-by: Abdulkader Alrezej Reviewed-by: Linus Walleij Reviewed-by: Mieczyslaw Nalewaj Signed-off-by: Luiz Angelo Daros de Luca --- drivers/net/dsa/realtek/rtl8365mb.c | 160 ++++++++++++++++++++++-------------- 1 file changed, 100 insertions(+), 60 deletions(-) diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c index a1641378fcbb..fe7e0f0a66b7 100644 --- a/drivers/net/dsa/realtek/rtl8365mb.c +++ b/drivers/net/dsa/realtek/rtl8365mb.c @@ -1554,18 +1554,15 @@ static void rtl8365mb_stats_setup(struct realtek_priv *priv) { struct rtl8365mb *mb = priv->chip_data; struct dsa_switch *ds = &priv->ds; - int i; + struct dsa_port *dp; /* Per-chip global mutex to protect MIB counter access, since doing * so requires accessing a series of registers in a particular order. */ mutex_init(&mb->mib_lock); - for (i = 0; i < priv->num_ports; i++) { - struct rtl8365mb_port *p = &mb->ports[i]; - - if (dsa_is_unused_port(ds, i)) - continue; + dsa_switch_for_each_available_port(dp, ds) { + struct rtl8365mb_port *p = &mb->ports[dp->index]; /* Per-port spinlock to protect the stats64 data */ spin_lock_init(&p->stats_lock); @@ -1581,13 +1578,10 @@ static void rtl8365mb_stats_teardown(struct realtek_priv *priv) { struct rtl8365mb *mb = priv->chip_data; struct dsa_switch *ds = &priv->ds; - int i; - - for (i = 0; i < priv->num_ports; i++) { - struct rtl8365mb_port *p = &mb->ports[i]; + struct dsa_port *dp; - if (dsa_is_unused_port(ds, i)) - continue; + dsa_switch_for_each_available_port(dp, ds) { + struct rtl8365mb_port *p = &mb->ports[dp->index]; cancel_delayed_work_sync(&p->mib_work); } @@ -1646,6 +1640,9 @@ static irqreturn_t rtl8365mb_irq(int irq, void *data) for_each_set_bit(line, &line_changes, priv->num_ports) { int child_irq = irq_find_mapping(priv->irqdomain, line); + if (!child_irq) + continue; + handle_nested_irq(child_irq); } @@ -1709,13 +1706,14 @@ static int rtl8365mb_irq_disable(struct realtek_priv *priv) static int rtl8365mb_irq_setup(struct realtek_priv *priv) { struct rtl8365mb *mb = priv->chip_data; + struct dsa_switch *ds = &priv->ds; struct device_node *intc; + struct dsa_port *dp; u32 irq_trig; int virq; int irq; u32 val; int ret; - int i; intc = of_get_child_by_name(priv->dev->of_node, "interrupt-controller"); if (!intc) { @@ -1744,8 +1742,8 @@ static int rtl8365mb_irq_setup(struct realtek_priv *priv) goto out_put_node; } - for (i = 0; i < priv->num_ports; i++) { - virq = irq_create_mapping(priv->irqdomain, i); + dsa_switch_for_each_available_port(dp, ds) { + virq = irq_create_mapping(priv->irqdomain, dp->index); if (!virq) { dev_err(priv->dev, "failed to create irq domain mapping\n"); @@ -1815,9 +1813,11 @@ static int rtl8365mb_irq_setup(struct realtek_priv *priv) mb->irq = 0; out_remove_irqdomain: - for (i = 0; i < priv->num_ports; i++) { - virq = irq_find_mapping(priv->irqdomain, i); - irq_dispose_mapping(virq); + dsa_switch_for_each_port(dp, ds) { + virq = irq_find_mapping(priv->irqdomain, dp->index); + + if (virq) + irq_dispose_mapping(virq); } irq_domain_remove(priv->irqdomain); @@ -1832,8 +1832,9 @@ static int rtl8365mb_irq_setup(struct realtek_priv *priv) static void rtl8365mb_irq_teardown(struct realtek_priv *priv) { struct rtl8365mb *mb = priv->chip_data; + struct dsa_switch *ds = &priv->ds; + struct dsa_port *dp; int virq; - int i; if (mb->irq) { free_irq(mb->irq, priv); @@ -1841,9 +1842,15 @@ static void rtl8365mb_irq_teardown(struct realtek_priv *priv) } if (priv->irqdomain) { - for (i = 0; i < priv->num_ports; i++) { - virq = irq_find_mapping(priv->irqdomain, i); - irq_dispose_mapping(virq); + /* Unused ports with a linked PHY still have an active IRQ + * mapping that must be disposed of during teardown. Loop + * through all ports. + */ + dsa_switch_for_each_port(dp, ds) { + virq = irq_find_mapping(priv->irqdomain, dp->index); + + if (virq) + irq_dispose_mapping(virq); } irq_domain_remove(priv->irqdomain); @@ -1961,10 +1968,11 @@ static int rtl8365mb_setup(struct dsa_switch *ds) { struct realtek_priv *priv = ds->priv; struct rtl8365mb_cpu *cpu; - struct dsa_port *cpu_dp; + u32 downports_mask = 0; + u32 upports_mask = 0; struct rtl8365mb *mb; + struct dsa_port *dp; int ret; - int i; mb = priv->chip_data; cpu = &mb->cpu; @@ -1991,33 +1999,11 @@ static int rtl8365mb_setup(struct dsa_switch *ds) else if (ret) dev_info(priv->dev, "no interrupt support\n"); - /* Configure CPU tagging */ - dsa_switch_for_each_cpu_port(cpu_dp, ds) { - cpu->mask |= BIT(cpu_dp->index); - - if (cpu->trap_port == RTL8365MB_MAX_NUM_PORTS) - cpu->trap_port = cpu_dp->index; - } - cpu->enable = cpu->mask > 0; + /* Start with all ports blocked, including unused ports */ + dsa_switch_for_each_port(dp, ds) { + struct rtl8365mb_port *p = &mb->ports[dp->index]; - if (!cpu->enable) { - dev_err(priv->dev, "no upstream (CPU, Link) port defined\n"); - ret = -EINVAL; - goto out_teardown_irq; - } - - ret = rtl8365mb_cpu_config(priv); - if (ret) - goto out_teardown_irq; - - /* Configure ports */ - for (i = 0; i < priv->num_ports; i++) { - struct rtl8365mb_port *p = &mb->ports[i]; - - if (dsa_is_unused_port(ds, i)) - continue; - - if (dsa_is_dsa_port(ds, i)) { + if (dsa_port_is_dsa(dp)) { /* Cascading (DSA links) is not supported yet. * Historically, the driver has always been broken * without a dedicated CPU port because CPU tagging @@ -2029,27 +2015,81 @@ static int rtl8365mb_setup(struct dsa_switch *ds) goto out_teardown_irq; } - /* Forward only to the CPU */ - ret = rtl8365mb_port_set_isolation(priv, i, cpu->mask); + /* Set the initial STP state of all ports to DISABLED, otherwise + * ports will still forward frames to the CPU despite being + * administratively down by default. + */ + rtl8365mb_port_stp_state_set(ds, dp->index, BR_STATE_DISABLED); + + /* Start with all port completely isolated */ + ret = rtl8365mb_port_set_isolation(priv, dp->index, 0); if (ret) goto out_teardown_irq; /* Disable learning */ - ret = rtl8365mb_port_set_learning(priv, i, false); + ret = rtl8365mb_port_set_learning(priv, dp->index, false); if (ret) goto out_teardown_irq; - /* Set the initial STP state of all ports to DISABLED, otherwise - * ports will still forward frames to the CPU despite being - * administratively down by default. - */ - rtl8365mb_port_stp_state_set(ds, i, BR_STATE_DISABLED); - /* Set up per-port private data */ p->priv = priv; - p->index = i; + p->index = dp->index; + + /* Collect CPU ports. If we support cascade switches, it should + * also include the upstream DSA ports. + */ + if (!dsa_port_is_cpu(dp)) + continue; + + upports_mask |= BIT(dp->index); + } + + /* Configure user ports */ + dsa_switch_for_each_port(dp, ds) { + if (!dsa_port_is_user(dp)) + continue; + + /* Forward only to the CPU */ + ret = rtl8365mb_port_set_isolation(priv, dp->index, + upports_mask); + if (ret) + goto out_teardown_irq; + + /* If we support cascade switches, it should also include the + * downstream DSA ports. + */ + downports_mask |= BIT(dp->index); } + /* Configure CPU tagging */ + /* If we support cascade switches, it should also include the upstream + * DSA ports. + */ + dsa_switch_for_each_cpu_port(dp, ds) { + /* Use the first CPU port as trap_port */ + if (cpu->trap_port == RTL8365MB_MAX_NUM_PORTS) + cpu->trap_port = dp->index; + + /* Forward to all user ports */ + ret = rtl8365mb_port_set_isolation(priv, dp->index, + downports_mask); + if (ret) + goto out_teardown_irq; + } + + cpu->mask = upports_mask; + cpu->enable = cpu->mask > 0; + + if (!cpu->enable) { + dev_err(priv->dev, "no upstream (CPU, Link) port defined\n"); + ret = -EINVAL; + goto out_teardown_irq; + } + + ret = rtl8365mb_cpu_config(priv); + if (ret) + goto out_teardown_irq; + ret = rtl8365mb_port_change_mtu(ds, cpu->trap_port, ETH_DATA_LEN); if (ret) goto out_teardown_irq; -- 2.54.0