From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-vk1-f182.google.com (mail-vk1-f182.google.com [209.85.221.182]) (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 27A3B304BDF for ; Fri, 22 May 2026 02:31:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.182 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779417111; cv=none; b=mkWAXDzL+sSX38paDmUY4fdV1dlmjDEkU9aLvxEnqOxZF8VZzBY3HHfRl8ZKdwFIdGW2n0ewY+crX01soodZMfDVZ3k0Nr4jiOugWjxVtE01Sd0W0/LB5KAVRjaRhv+l3Ug0fDmiEwCIZsfx/AhP92D82wMw+Z78YECZed8RI04= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779417111; c=relaxed/simple; bh=BdMH/BgGU7WHFSaYxaEQN+JaBpyK0vsKPK0W3SiAL7c=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=eQZt9b1CXfa/XDBmdQ0Gw7yZJSfNaEVzeGhFOFVyDrSsiYEwY3IojCkaeuMD95fA0oH5IXpPY7o2aJVYNHVmPlgs2yDw7wim7dWF98mp4t7NgJVkexOdQfuSszOmBsGl1/4Y4mOsvP7y7RpvNyyCMWYxA1EG5T2murDaFZS6oOY= 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=PAuZJvM0; arc=none smtp.client-ip=209.85.221.182 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="PAuZJvM0" Received: by mail-vk1-f182.google.com with SMTP id 71dfb90a1353d-57524e52a3dso5610822e0c.2 for ; Thu, 21 May 2026 19:31:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779417109; x=1780021909; 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=vuLdr8L+mBInuxTG1VO3TjPKQaXuApsCz15DjDY3WDU=; b=PAuZJvM0zHVv9NRHtCV/FeT+hLwwbx2AVxR67wa8kJE2ufuF85ECO5j84Rc4//mFcB oaRtnF2Bp9tzALCYNKo1m9hB4HVM9L4+IjTNEwC8CPvJQRp0ru77np0tL2kUHWeLoLih RIzP4RrAm2wCAzLucaxZvfdC8JYks2NNMNbi4sd7fnBFjZZ3PmIGP2ufjy9qbw7vimf5 3vmbMeEdUk2J9d3jMbCn7yvvk+s3p+rlIKuEKxwZaaYxPMgnTCDFNSwzeyGsT3fIJUnH LMKqgksxzzTn09Y6OixbxZx0WVOrCrdoL0++x6sYf/k9Nzs+sIfvuSpsNF03hSbIYSef +ASw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779417109; x=1780021909; 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=vuLdr8L+mBInuxTG1VO3TjPKQaXuApsCz15DjDY3WDU=; b=NLvNxi+ko3uawKd4GAazfCRljlRLY+cXetjv0fhYLlAKIg95iGqGl436t49shLZQXD 9gs0ULqbAcNvOjkNAw9LqyjjeDKPvUGD3374D7Eny6a13Wqk8Zb48FQkamYEtZI9l8OR ZnfBjU8noNgWal6KBZnz4brc8Y2pl3gWYb6/97lxl9gLBOnNmUoJyEkDD3rkhO4PuP4t MP5xqD/FG0ZCb5+1koJghdupsBnUiryMKtpjGO7tvypVKXM12wHxhK6wdUcB/+QsxE3e f8t/ysbuQkkBL/8CZnpDcqhEVNbTaexs6Ohn/3tNZah5xBBr9vkXwv337aYLiGccoBbK JE7g== X-Forwarded-Encrypted: i=1; AFNElJ+YkjY9tlqukssFFeOWthctCuiUNbYvooASszghU3ogBSW2MJuKlSPmiCycerEYmzSXhnoLGrwWA6tR/t0=@vger.kernel.org X-Gm-Message-State: AOJu0YxSNXzsoGLsSHeYw/FetmTQRAY9t53A1RzyX8S5HgWjPTkCKede HlWSWC5Ui0FHHQIH02K2BIHY2xahFj470YD0l7wbxWSsNwpHUzt1OG9G X-Gm-Gg: Acq92OFGQUby69BF8engxDkXZiW2E43OiQ2Mmvil2kCCUTRXuLs14WbYot7ut8Wk8Ig v+BEYxNzQybDH5a05C0ga26NwkYO2ubdwVitu9TnsRe4O0pWN1xwp0ImBxq+/IUefJqIWT95zRl I0hd3Ja8jLCke9Bluppzl1hgubLnEGRXiMWXCdTS5ThRia07WehL3hxlzVx83AmCKe6s/OTee7W BeU5OO60Ea9+VgjQjj3gsGbnikUHhkTcVVg4AvVMk73eN/uevQbhFRTmTBJFCfIgiCjrDk4OXzE 60jtJR+bnA2DDEy+6IOd39UHpqIvz3DZ5HE93z3+mSaTrG7+0Vuq4+Rra9wvr4Z/QvSNgvPXEbH e2Wf7o1yWLuGz+nPDjDXypesxaJ88KRSXEG1/lbT3NtdKnxPUhDTTYwN6DpEp/UEKTh1TfME5q+ J/9r9pUUIbbehQMRgaPrFYoq2JsKg4Sc7sG8qmQlE7o4fzyKxn5w== X-Received: by 2002:a05:6122:c93:b0:56b:579c:82e with SMTP id 71dfb90a1353d-586606b79a4mr1146149e0c.5.1779417108774; Thu, 21 May 2026 19:31:48 -0700 (PDT) Received: from tresc054937.tre-sc.gov.br ([187.65.210.13]) by smtp.gmail.com with ESMTPSA id 71dfb90a1353d-586f2f791d1sm640709e0c.5.2026.05.21.19.31.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 May 2026 19:31:48 -0700 (PDT) From: Luiz Angelo Daros de Luca Date: Thu, 21 May 2026 23:31:11 -0300 Subject: [net-next PATCH v6 2/8] 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: <20260521-realtek_forward-v6-2-d391bbad38c3@gmail.com> References: <20260521-realtek_forward-v6-0-d391bbad38c3@gmail.com> In-Reply-To: <20260521-realtek_forward-v6-0-d391bbad38c3@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 Use dsa_switch_for_each_*() whenever possible. For port setup(), a new blocking setup phase was added for all ports, including unused ones, before the user and CPU port setup. CPU isolation includes all user ports as traffic was being blocked in some scenarios (suggested by Abdulkader Alrezej). The driver bails out if a DSA port is detected as the driver was not tested in a cascading setup. 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 | 148 ++++++++++++++++++++++++------------ 1 file changed, 99 insertions(+), 49 deletions(-) diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c index 2637884fe472..c29a09883d1c 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_available_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,11 @@ 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); + dsa_switch_for_each_available_port(dp, ds) { + virq = irq_find_mapping(priv->irqdomain, dp->index); + + if (virq) + irq_dispose_mapping(virq); } irq_domain_remove(priv->irqdomain); @@ -1961,10 +1964,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,44 +1995,90 @@ 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); + /* 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->trap_port == RTL8365MB_MAX_NUM_PORTS) - cpu->trap_port = cpu_dp->index; - } - cpu->enable = cpu->mask > 0; - ret = rtl8365mb_cpu_config(priv); - if (ret) - goto out_teardown_irq; + if (dsa_port_is_dsa(dp)) { + dev_err(ds->dev, + "Cascading (DSA link) not supported\n"); + ret = -EOPNOTSUPP; + 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, dp->index, BR_STATE_DISABLED); - /* Configure ports */ - for (i = 0; i < priv->num_ports; i++) { - struct rtl8365mb_port *p = &mb->ports[i]; + /* 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, dp->index, false); + if (ret) + goto out_teardown_irq; + + /* Set up per-port private data */ + p->priv = priv; + p->index = dp->index; - if (dsa_is_unused_port(ds, i)) + /* 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, i, cpu->mask); + ret = rtl8365mb_port_set_isolation(priv, dp->index, + upports_mask); if (ret) goto out_teardown_irq; - /* Disable learning */ - ret = rtl8365mb_port_set_learning(priv, i, false); + /* 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; + } - /* 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); + cpu->mask = upports_mask; + cpu->enable = cpu->mask > 0; - /* Set up per-port private data */ - p->priv = priv; - p->index = i; + ret = rtl8365mb_cpu_config(priv); + if (ret) + goto out_teardown_irq; + + if (!cpu->enable) { + dev_err(priv->dev, "no upstream (CPU, Link) port defined\n"); + ret = -EINVAL; + goto out_teardown_irq; } ret = rtl8365mb_port_change_mtu(ds, cpu->trap_port, ETH_DATA_LEN); -- 2.54.0