From: netdev-bot+sashiko@kernel.org
To: linusw@kernel.org
Cc: woojung.huh@microchip.com, UNGLinuxDriver@microchip.com,
andrew@lunn.ch, olteanv@gmail.com, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
marex@denx.de, horms@kernel.org, linux@armlinux.org.uk,
nb@tipi-net.de, netdev@vger.kernel.org,
devicetree@vger.kernel.org
Subject: Re: [PATCH net-next v11 3/4] net: dsa: microchip: Support Microchip KSZ8995XA / KS8995XA
Date: Thu, 10 Sep 2026 20:02:01 +0000 [thread overview]
Message-ID: <178907052148.219967.6703395266184682965@kernel.org> (raw)
In-Reply-To: <20260909-ks8995-to-ksz8-v11-3-0e04411a559d@kernel.org>
Thank you for your contribution! Sashiko AI review found 2 potential
issue(s) to consider:
Critical: 0 · High: 0 · Medium: 2 · Low: 0
- [Medium] ksz8_reset_switch() (drivers/net/dsa/microchip/ksz8.c:266 and
:275) iterates `port < dev->info->port_cnt` (5 for KSZ8995XA) for both…
- [Medium] In ksz8_port_setup()
(drivers/net/dsa/microchip/ksz8.c:2140-2153) the new KSZ8995XA block…
--
net: dsa: microchip: Support Microchip KSZ8995XA / KS8995XA
Adds KSZ8995XA (Micrel KS8995XA) support to the KSZ driver with a reduced
set of dev/switch ops, a per-port PHY reset with poll, header-tag handling
instead of tail tags, and a KSZ8995XA-specific DSCP register layout in the
DCB helpers. The legacy KS8995 driver is made mutually exclusive via
Kconfig and the Micrel compatibles are moved to the KSZ SPI driver.
> diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
> index 941ae9f66f70..c3871d5d6d36 100644
> --- a/drivers/net/dsa/microchip/ksz8.c
> +++ b/drivers/net/dsa/microchip/ksz8.c
[ ... ]
> @@ -253,7 +255,35 @@ static int ksz8463_reset_switch(struct ksz_device *dev)
>
> static int ksz8_reset_switch(struct ksz_device *dev)
> {
> - if (ksz_is_ksz88x3(dev)) {
> + if (ksz_is_ksz8995xa(dev)) {
> + unsigned int port, reg, val;
> + int ret;
> +
> + /* The KSZ8995XA switch itself cannot be reset by software, but
> + * often boot loaders have fun with ports, so reset them. This
> + * reset bit is self-clearing.
> + */
> + for (port = 0; port < dev->info->port_cnt; port++) {
> + ret = ksz_prmw8(dev, port, REG_PORT_STATUS_3,
> + PORT_PHY_SOFT_RESET,
> + PORT_PHY_SOFT_RESET);
> + if (ret)
> + return ret;
> + }
> +
> + /* IEEE 802.3 allows up to 500 ms for a PHY reset. */
> + for (port = 0; port < dev->info->port_cnt; port++) {
> + reg = dev->dev_ops->get_port_addr(port, REG_PORT_STATUS_3);
> + ret = regmap_read_poll_timeout(ksz_regmap_8(dev), reg, val,
> + !(val & PORT_PHY_SOFT_RESET),
> + 1000, 600000);
> + if (ret)
> + return ret;
> + }
[Severity: Medium]
Should these two loops be bounded by dev->phy_port_cnt instead of
dev->info->port_cnt?
port_cnt is 5 for KSZ8995XA, so port index 4 is included, and the chip
data added by this patch declares that port as having no internal PHY:
[KSZ8995XA] = {
...
.port_cnt = 5, /* total cpu and user ports */
...
.internal_phy = {true, true, true, true, false},
ksz8_get_port_addr(4, REG_PORT_STATUS_3) lands on register 0x5F, and
ksz8_reg.h only defines PHY Status 3 for the four PHY ports:
#define REG_PORT_1_STATUS_3 0x1F
#define REG_PORT_2_STATUS_3 0x2F
#define REG_PORT_3_STATUS_3 0x3F
#define REG_PORT_4_STATUS_3 0x4F
The first loop therefore does a read-modify-write of bit 4 in the MII/CPU
port bank where no PHY reset is documented.
The second loop has no per-port skip and its only success condition is
!(val & PORT_PHY_SOFT_RESET). If that bit at 0x5F is a plain writable or
reserved bit that never self-clears, does probe fail here?
ksz_switch_register() -> dsa_register_switch() -> ksz8_setup()
-> ksz8_reset_switch()
regmap_read_poll_timeout() would return -ETIMEDOUT after 600 ms, and
ksz8_setup() propagates that after printing "failed to reset switch".
Every other per-PHY loop in this file uses dev->phy_port_cnt, for example
ksz8_config_cpu_port():
for (i = 0; i < dev->phy_port_cnt; i++) {
> +
> + /* Some PHYs need additional settling time after reset. */
> + usleep_range(1000, 2000);
> + } else if (ksz_is_ksz88x3(dev)) {
> /* reset switch */
> ksz_cfg(dev, KSZ8863_REG_SW_RESET,
> KSZ8863_GLOBAL_SOFTWARE_RESET | KSZ8863_PCS_RESET, true);
[ ... ]
> @@ -2057,6 +2137,21 @@ static void ksz8_port_setup(struct ksz_device *dev, int port, bool cpu_port)
>
> ksz8_cfg_port_member(dev, port, member);
>
> + if (ksz_is_ksz8995xa(dev)) {
> + /* Use VID 0 to identify untagged frames in the special tag */
> + ksz_pwrite16(dev, port, REG_PORT_CTRL_VID, 0);
> +
> + /* The KSZ8995XA has a special tag format in the front of the frame
> + * that need to be inserted by the CPU and then removed by each
> + * port. PORT_REMOVE_TAG simply means "remove tags coming from the
> + * CPU port" it does not affect ingress packets.
> + */
> + if (cpu_port)
> + ksz_port_cfg(dev, port, REG_PORT_CTRL_0, PORT_INSERT_TAG, true);
> + else
> + ksz_port_cfg(dev, port, REG_PORT_CTRL_0, PORT_REMOVE_TAG, true);
> + }
[Severity: Medium]
Can the opposite tag bit stay set here? Both bits live in
REG_PORT_CTRL_0:
#define PORT_INSERT_TAG BIT(2)
#define PORT_REMOVE_TAG BIT(1)
and ksz_port_cfg(..., true) can only set bits, never clear them:
static void ksz_port_cfg(struct ksz_device *dev, int port, int offset,
u8 bits, bool set)
{
ksz_rmw8(dev, dev->dev_ops->get_port_addr(port, offset), bits,
set ? bits : 0);
}
So a user port that comes up with PORT_INSERT_TAG already set keeps it,
and a CPU port that comes up with PORT_REMOVE_TAG already set keeps that.
For this chip ksz8_reset_switch() intentionally performs no global reset,
and its own comment says the prior state cannot be trusted:
/* The KSZ8995XA switch itself cannot be reset by software, but
* often boot loaders have fun with ports, so reset them. This
* reset bit is self-clearing.
*/
No other path clears these bits for KSZ8995XA either: the VLAN writer
ksz_port_cfg(dev, port, P_TAG_CTRL, PORT_REMOVE_TAG, untagged) is not
reachable through ksz8995xa_switch_ops, and ksz8_port_queue_split() masks
only KSZ8795_PORT_2QUEUE_SPLIT_EN.
Would a single read-modify-write with mask PORT_INSERT_TAG |
PORT_REMOVE_TAG, setting one and clearing the other, be more robust? As
written, a stale PORT_INSERT_TAG on a user port emits the private tag onto
the wire, and a stale PORT_REMOVE_TAG on the CPU port strips the tag that
tag_ks8995 expects on receive, both without any error being reported.
> /* Disable all WoL options by default. Otherwise
> * ksz_switch_macaddr_get/put logic will not work properly.
> * CPU port 4 has no WoL functionality.
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260909-ks8995-to-ksz8-v11-0-0e04411a559d%40kernel.org
next prev parent reply other threads:[~2026-09-10 20:02 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-09 17:00 [PATCH net-next v11 0/4] net: dsa: microchip: Add support for KSZ8995XA/KS8995XA Linus Walleij
2026-09-09 17:00 ` [PATCH net-next v11 1/4] dt-bindings: net: dsa: microchip: Add KSZ8995XA Linus Walleij
2026-09-10 20:01 ` netdev-bot+sashiko
2026-09-10 20:29 ` Linus Walleij
2026-09-09 17:00 ` [PATCH net-next v11 2/4] net: dsa: tag_ks8995: Add the KS8995 tag handling Linus Walleij
2026-09-10 20:01 ` netdev-bot+sashiko
2026-09-09 17:00 ` [PATCH net-next v11 3/4] net: dsa: microchip: Support Microchip KSZ8995XA / KS8995XA Linus Walleij
2026-09-10 20:02 ` netdev-bot+sashiko [this message]
2026-09-10 20:53 ` Linus Walleij
2026-09-09 17:00 ` [PATCH net-next v11 4/4] net: dsa: ks8995: Delete surplus driver Linus Walleij
2026-09-10 20:02 ` netdev-bot+sashiko
2026-09-10 20:40 ` Linus Walleij
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178907052148.219967.6703395266184682965@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=UNGLinuxDriver@microchip.com \
--cc=andrew@lunn.ch \
--cc=conor+dt@kernel.org \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=linusw@kernel.org \
--cc=linux@armlinux.org.uk \
--cc=marex@denx.de \
--cc=nb@tipi-net.de \
--cc=netdev@vger.kernel.org \
--cc=olteanv@gmail.com \
--cc=pabeni@redhat.com \
--cc=robh@kernel.org \
--cc=woojung.huh@microchip.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox