* [PATCH net-next v8 1/5] net: dsa: microchip: ksz9477: Add Wake on Magic Packet support
2023-10-26 5:10 [PATCH net-next v8 0/5] net: dsa: microchip: provide Wake on LAN support (part 2) Oleksij Rempel
@ 2023-10-26 5:10 ` Oleksij Rempel
2023-10-26 9:58 ` Vladimir Oltean
2023-10-26 5:10 ` [PATCH net-next v8 2/5] net: dsa: microchip: Refactor comment for ksz_switch_macaddr_get() function Oleksij Rempel
` (5 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Oleksij Rempel @ 2023-10-26 5:10 UTC (permalink / raw)
To: David S. Miller, Andrew Lunn, Eric Dumazet, Florian Fainelli,
Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Woojung Huh,
Arun Ramadoss, Conor Dooley, Krzysztof Kozlowski, Rob Herring
Cc: Oleksij Rempel, Florian Fainelli, kernel, linux-kernel, netdev,
UNGLinuxDriver, Russell King (Oracle), devicetree
Introduce Wake on Magic Packet (WoL) functionality to the ksz9477
driver.
Major changes include:
1. Extending the `ksz9477_handle_wake_reason` function to identify Magic
Packet wake events alongside existing wake reasons.
2. Updating the `ksz9477_get_wol` and `ksz9477_set_wol` functions to
handle WAKE_MAGIC alongside the existing WAKE_PHY option, and to
program the switch's MAC address register accordingly when Magic
Packet wake-up is enabled. This change will prevent WAKE_MAGIC
activation if the related port has a different MAC address compared
to a MAC address already used by HSR or an already active WAKE_MAGIC
on another port.
3. Adding a restriction in `ksz_port_set_mac_address` to prevent MAC
address changes on ports with active Wake on Magic Packet, as the
switch's MAC address register is utilized for this feature.
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
---
drivers/net/dsa/microchip/ksz9477.c | 57 ++++++++++++++++++++++++--
drivers/net/dsa/microchip/ksz_common.c | 43 +++++++++++++++++--
drivers/net/dsa/microchip/ksz_common.h | 4 ++
3 files changed, 97 insertions(+), 7 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index 2534c3d122e4..441b4597ef27 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -81,7 +81,8 @@ static int ksz9477_handle_wake_reason(struct ksz_device *dev, int port)
if (!pme_status)
return 0;
- dev_dbg(dev->dev, "Wake event on port %d due to:%s%s\n", port,
+ dev_dbg(dev->dev, "Wake event on port %d due to:%s%s%s\n", port,
+ pme_status & PME_WOL_MAGICPKT ? " \"Magic Packet\"" : "",
pme_status & PME_WOL_LINKUP ? " \"Link Up\"" : "",
pme_status & PME_WOL_ENERGY ? " \"Enery detect\"" : "");
@@ -109,10 +110,19 @@ void ksz9477_get_wol(struct ksz_device *dev, int port,
wol->supported = WAKE_PHY;
+ /* Check if the current MAC address on this port can be set
+ * as global for WAKE_MAGIC support. The result may vary
+ * dynamically based on other ports configurations.
+ */
+ if (ksz_is_port_mac_global_usable(dev->ds, port))
+ wol->supported |= WAKE_MAGIC;
+
ret = ksz_pread8(dev, port, REG_PORT_PME_CTRL, &pme_ctrl);
if (ret)
return;
+ if (pme_ctrl & PME_WOL_MAGICPKT)
+ wol->wolopts |= WAKE_MAGIC;
if (pme_ctrl & (PME_WOL_LINKUP | PME_WOL_ENERGY))
wol->wolopts |= WAKE_PHY;
}
@@ -134,10 +144,12 @@ void ksz9477_get_wol(struct ksz_device *dev, int port,
int ksz9477_set_wol(struct ksz_device *dev, int port,
struct ethtool_wolinfo *wol)
{
- u8 pme_ctrl = 0;
+ u8 pme_ctrl = 0, pme_ctrl_old = 0;
+ bool magic_switched_off;
+ bool magic_switched_on;
int ret;
- if (wol->wolopts & ~WAKE_PHY)
+ if (wol->wolopts & ~(WAKE_PHY | WAKE_MAGIC))
return -EINVAL;
if (!dev->wakeup_source)
@@ -147,10 +159,42 @@ int ksz9477_set_wol(struct ksz_device *dev, int port,
if (ret)
return ret;
+ if (wol->wolopts & WAKE_MAGIC)
+ pme_ctrl |= PME_WOL_MAGICPKT;
if (wol->wolopts & WAKE_PHY)
pme_ctrl |= PME_WOL_LINKUP | PME_WOL_ENERGY;
- return ksz_pwrite8(dev, port, REG_PORT_PME_CTRL, pme_ctrl);
+ ret = ksz_pread8(dev, port, REG_PORT_PME_CTRL, &pme_ctrl_old);
+ if (ret)
+ return ret;
+
+ if (pme_ctrl_old == pme_ctrl)
+ return 0;
+
+ magic_switched_off = (pme_ctrl_old & PME_WOL_MAGICPKT) &&
+ !(pme_ctrl & PME_WOL_MAGICPKT);
+ magic_switched_on = !(pme_ctrl_old & PME_WOL_MAGICPKT) &&
+ (pme_ctrl & PME_WOL_MAGICPKT);
+
+ /* To keep reference count of MAC address, we should do this
+ * operation only on change of WOL settings.
+ */
+ if (magic_switched_on) {
+ ret = ksz_switch_macaddr_get(dev->ds, port, NULL);
+ if (ret)
+ return ret;
+ } else if (magic_switched_off) {
+ ksz_switch_macaddr_put(dev->ds);
+ }
+
+ ret = ksz_pwrite8(dev, port, REG_PORT_PME_CTRL, pme_ctrl);
+ if (ret) {
+ if (magic_switched_on)
+ ksz_switch_macaddr_put(dev->ds);
+ return ret;
+ }
+
+ return 0;
}
static int ksz9477_wait_vlan_ctrl_ready(struct ksz_device *dev)
@@ -1106,6 +1150,11 @@ void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
/* clear pending wake flags */
ksz9477_handle_wake_reason(dev, port);
+
+ /* Disable all WoL options by default. Otherwise
+ * ksz_switch_macaddr_get/put logic will not work properly.
+ */
+ ksz_pwrite8(dev, port, REG_PORT_PME_CTRL, 0);
}
void ksz9477_config_cpu_port(struct dsa_switch *ds)
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index de788f424a3f..8244204e177d 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -3569,6 +3569,7 @@ static int ksz_port_set_mac_address(struct dsa_switch *ds, int port,
const unsigned char *addr)
{
struct dsa_port *dp = dsa_to_port(ds, port);
+ struct ethtool_wolinfo wol;
if (dp->hsr_dev) {
dev_err(ds->dev,
@@ -3577,9 +3578,45 @@ static int ksz_port_set_mac_address(struct dsa_switch *ds, int port,
return -EBUSY;
}
+ ksz_get_wol(ds, dp->index, &wol);
+ if (wol.wolopts & WAKE_MAGIC) {
+ dev_err(ds->dev,
+ "Cannot change MAC address on port %d with active Wake on Magic Packet\n",
+ port);
+ return -EBUSY;
+ }
+
return 0;
}
+/**
+ * ksz_is_port_mac_global_usable - Check if the MAC address on a given port
+ * can be used as a global address.
+ * @ds: Pointer to the DSA switch structure.
+ * @port: The port number on which the MAC address is to be checked.
+ *
+ * This function examines the MAC address set on the specified port and
+ * determines if it can be used as a global address for the switch.
+ *
+ * Return: true if the port's MAC address can be used as a global address, false
+ * otherwise.
+ */
+bool ksz_is_port_mac_global_usable(struct dsa_switch *ds, int port)
+{
+ struct net_device *user = dsa_to_port(ds, port)->user;
+ const unsigned char *addr = user->dev_addr;
+ struct ksz_switch_macaddr *switch_macaddr;
+ struct ksz_device *dev = ds->priv;
+
+ ASSERT_RTNL();
+
+ switch_macaddr = dev->switch_macaddr;
+ if (switch_macaddr && !ether_addr_equal(switch_macaddr->addr, addr))
+ return false;
+
+ return true;
+}
+
/* Program the switch's MAC address register with the MAC address of the
* requesting user port. This single address is used by the switch for multiple
* features, like HSR self-address filtering and WoL. Other user ports are
@@ -3587,8 +3624,8 @@ static int ksz_port_set_mac_address(struct dsa_switch *ds, int port,
* the same. The user ports' MAC addresses must not change while they have
* ownership of the switch MAC address.
*/
-static int ksz_switch_macaddr_get(struct dsa_switch *ds, int port,
- struct netlink_ext_ack *extack)
+int ksz_switch_macaddr_get(struct dsa_switch *ds, int port,
+ struct netlink_ext_ack *extack)
{
struct net_device *user = dsa_to_port(ds, port)->user;
const unsigned char *addr = user->dev_addr;
@@ -3628,7 +3665,7 @@ static int ksz_switch_macaddr_get(struct dsa_switch *ds, int port,
return 0;
}
-static void ksz_switch_macaddr_put(struct dsa_switch *ds)
+void ksz_switch_macaddr_put(struct dsa_switch *ds)
{
struct ksz_switch_macaddr *switch_macaddr;
struct ksz_device *dev = ds->priv;
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index a7394175fcf6..06996813f9a8 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -390,12 +390,16 @@ int ksz_switch_register(struct ksz_device *dev);
void ksz_switch_remove(struct ksz_device *dev);
void ksz_init_mib_timer(struct ksz_device *dev);
+bool ksz_is_port_mac_global_usable(struct dsa_switch *ds, int port);
void ksz_r_mib_stats64(struct ksz_device *dev, int port);
void ksz88xx_r_mib_stats64(struct ksz_device *dev, int port);
void ksz_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
bool ksz_get_gbit(struct ksz_device *dev, int port);
phy_interface_t ksz_get_xmii(struct ksz_device *dev, int port, bool gbit);
extern const struct ksz_chip_data ksz_switch_chips[];
+int ksz_switch_macaddr_get(struct dsa_switch *ds, int port,
+ struct netlink_ext_ack *extack);
+void ksz_switch_macaddr_put(struct dsa_switch *ds);
/* Common register access functions */
static inline struct regmap *ksz_regmap_8(struct ksz_device *dev)
--
2.39.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH net-next v8 1/5] net: dsa: microchip: ksz9477: Add Wake on Magic Packet support
2023-10-26 5:10 ` [PATCH net-next v8 1/5] net: dsa: microchip: ksz9477: Add Wake on Magic Packet support Oleksij Rempel
@ 2023-10-26 9:58 ` Vladimir Oltean
0 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2023-10-26 9:58 UTC (permalink / raw)
To: Oleksij Rempel
Cc: David S. Miller, Andrew Lunn, Eric Dumazet, Florian Fainelli,
Jakub Kicinski, Paolo Abeni, Woojung Huh, Arun Ramadoss,
Conor Dooley, Krzysztof Kozlowski, Rob Herring, Florian Fainelli,
kernel, linux-kernel, netdev, UNGLinuxDriver,
Russell King (Oracle), devicetree
On Thu, Oct 26, 2023 at 07:10:47AM +0200, Oleksij Rempel wrote:
> Introduce Wake on Magic Packet (WoL) functionality to the ksz9477
> driver.
>
> Major changes include:
>
> 1. Extending the `ksz9477_handle_wake_reason` function to identify Magic
> Packet wake events alongside existing wake reasons.
>
> 2. Updating the `ksz9477_get_wol` and `ksz9477_set_wol` functions to
> handle WAKE_MAGIC alongside the existing WAKE_PHY option, and to
> program the switch's MAC address register accordingly when Magic
> Packet wake-up is enabled. This change will prevent WAKE_MAGIC
> activation if the related port has a different MAC address compared
> to a MAC address already used by HSR or an already active WAKE_MAGIC
> on another port.
>
> 3. Adding a restriction in `ksz_port_set_mac_address` to prevent MAC
> address changes on ports with active Wake on Magic Packet, as the
> switch's MAC address register is utilized for this feature.
>
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
> ---
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-next v8 2/5] net: dsa: microchip: Refactor comment for ksz_switch_macaddr_get() function
2023-10-26 5:10 [PATCH net-next v8 0/5] net: dsa: microchip: provide Wake on LAN support (part 2) Oleksij Rempel
2023-10-26 5:10 ` [PATCH net-next v8 1/5] net: dsa: microchip: ksz9477: Add Wake on Magic Packet support Oleksij Rempel
@ 2023-10-26 5:10 ` Oleksij Rempel
2023-10-26 5:10 ` [PATCH net-next v8 3/5] net: dsa: microchip: Add error handling for ksz_switch_macaddr_get() Oleksij Rempel
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Oleksij Rempel @ 2023-10-26 5:10 UTC (permalink / raw)
To: David S. Miller, Andrew Lunn, Eric Dumazet, Florian Fainelli,
Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Woojung Huh,
Arun Ramadoss, Conor Dooley, Krzysztof Kozlowski, Rob Herring
Cc: Oleksij Rempel, Florian Fainelli, Vladimir Oltean, kernel,
linux-kernel, netdev, UNGLinuxDriver, Russell King (Oracle),
devicetree
Update the comment to follow kernel-doc format.
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/dsa/microchip/ksz_common.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 8244204e177d..0c3adc389d0b 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -3617,12 +3617,20 @@ bool ksz_is_port_mac_global_usable(struct dsa_switch *ds, int port)
return true;
}
-/* Program the switch's MAC address register with the MAC address of the
- * requesting user port. This single address is used by the switch for multiple
- * features, like HSR self-address filtering and WoL. Other user ports are
- * allowed to share ownership of this address as long as their MAC address is
- * the same. The user ports' MAC addresses must not change while they have
- * ownership of the switch MAC address.
+/**
+ * ksz_switch_macaddr_get - Program the switch's MAC address register.
+ * @ds: DSA switch instance.
+ * @port: Port number.
+ * @extack: Netlink extended acknowledgment.
+ *
+ * This function programs the switch's MAC address register with the MAC address
+ * of the requesting user port. This single address is used by the switch for
+ * multiple features like HSR self-address filtering and WoL. Other user ports
+ * can share ownership of this address as long as their MAC address is the same.
+ * The MAC addresses of user ports must not change while they have ownership of
+ * the switch MAC address.
+ *
+ * Return: 0 on success, or other error codes on failure.
*/
int ksz_switch_macaddr_get(struct dsa_switch *ds, int port,
struct netlink_ext_ack *extack)
--
2.39.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH net-next v8 3/5] net: dsa: microchip: Add error handling for ksz_switch_macaddr_get()
2023-10-26 5:10 [PATCH net-next v8 0/5] net: dsa: microchip: provide Wake on LAN support (part 2) Oleksij Rempel
2023-10-26 5:10 ` [PATCH net-next v8 1/5] net: dsa: microchip: ksz9477: Add Wake on Magic Packet support Oleksij Rempel
2023-10-26 5:10 ` [PATCH net-next v8 2/5] net: dsa: microchip: Refactor comment for ksz_switch_macaddr_get() function Oleksij Rempel
@ 2023-10-26 5:10 ` Oleksij Rempel
2023-10-26 9:53 ` Vladimir Oltean
2023-10-26 5:10 ` [PATCH net-next v8 4/5] net: dsa: microchip: Refactor switch shutdown routine for WoL preparation Oleksij Rempel
` (3 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Oleksij Rempel @ 2023-10-26 5:10 UTC (permalink / raw)
To: David S. Miller, Andrew Lunn, Eric Dumazet, Florian Fainelli,
Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Woojung Huh,
Arun Ramadoss, Conor Dooley, Krzysztof Kozlowski, Rob Herring
Cc: Oleksij Rempel, Florian Fainelli, kernel, linux-kernel, netdev,
UNGLinuxDriver, Russell King (Oracle), devicetree
Enhance the ksz_switch_macaddr_get() function to handle errors that may
occur during the call to ksz_write8(). Specifically, this update checks
the return value of ksz_write8(), which may fail if regmap ranges
validation is not passed and returns the error code.
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
---
drivers/net/dsa/microchip/ksz_common.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 0c3adc389d0b..00be812bef40 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -3640,7 +3640,7 @@ int ksz_switch_macaddr_get(struct dsa_switch *ds, int port,
struct ksz_switch_macaddr *switch_macaddr;
struct ksz_device *dev = ds->priv;
const u16 *regs = dev->info->regs;
- int i;
+ int i, ret;
/* Make sure concurrent MAC address changes are blocked */
ASSERT_RTNL();
@@ -3667,10 +3667,20 @@ int ksz_switch_macaddr_get(struct dsa_switch *ds, int port,
dev->switch_macaddr = switch_macaddr;
/* Program the switch MAC address to hardware */
- for (i = 0; i < ETH_ALEN; i++)
- ksz_write8(dev, regs[REG_SW_MAC_ADDR] + i, addr[i]);
+ for (i = 0; i < ETH_ALEN; i++) {
+ ret = ksz_write8(dev, regs[REG_SW_MAC_ADDR] + i, addr[i]);
+ if (ret)
+ goto macaddr_drop;
+ }
return 0;
+
+macaddr_drop:
+ dev->switch_macaddr = NULL;
+ refcount_set(&switch_macaddr->refcount, 0);
+ kfree(switch_macaddr);
+
+ return ret;
}
void ksz_switch_macaddr_put(struct dsa_switch *ds)
--
2.39.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH net-next v8 3/5] net: dsa: microchip: Add error handling for ksz_switch_macaddr_get()
2023-10-26 5:10 ` [PATCH net-next v8 3/5] net: dsa: microchip: Add error handling for ksz_switch_macaddr_get() Oleksij Rempel
@ 2023-10-26 9:53 ` Vladimir Oltean
0 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2023-10-26 9:53 UTC (permalink / raw)
To: Oleksij Rempel
Cc: David S. Miller, Andrew Lunn, Eric Dumazet, Florian Fainelli,
Jakub Kicinski, Paolo Abeni, Woojung Huh, Arun Ramadoss,
Conor Dooley, Krzysztof Kozlowski, Rob Herring, Florian Fainelli,
kernel, linux-kernel, netdev, UNGLinuxDriver,
Russell King (Oracle), devicetree
On Thu, Oct 26, 2023 at 07:10:49AM +0200, Oleksij Rempel wrote:
> Enhance the ksz_switch_macaddr_get() function to handle errors that may
> occur during the call to ksz_write8(). Specifically, this update checks
> the return value of ksz_write8(), which may fail if regmap ranges
> validation is not passed and returns the error code.
>
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
> ---
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> drivers/net/dsa/microchip/ksz_common.c | 16 +++++++++++++---
> 1 file changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
> index 0c3adc389d0b..00be812bef40 100644
> --- a/drivers/net/dsa/microchip/ksz_common.c
> +++ b/drivers/net/dsa/microchip/ksz_common.c
> @@ -3640,7 +3640,7 @@ int ksz_switch_macaddr_get(struct dsa_switch *ds, int port,
> struct ksz_switch_macaddr *switch_macaddr;
> struct ksz_device *dev = ds->priv;
> const u16 *regs = dev->info->regs;
> - int i;
> + int i, ret;
>
> /* Make sure concurrent MAC address changes are blocked */
> ASSERT_RTNL();
> @@ -3667,10 +3667,20 @@ int ksz_switch_macaddr_get(struct dsa_switch *ds, int port,
> dev->switch_macaddr = switch_macaddr;
>
> /* Program the switch MAC address to hardware */
> - for (i = 0; i < ETH_ALEN; i++)
> - ksz_write8(dev, regs[REG_SW_MAC_ADDR] + i, addr[i]);
> + for (i = 0; i < ETH_ALEN; i++) {
> + ret = ksz_write8(dev, regs[REG_SW_MAC_ADDR] + i, addr[i]);
> + if (ret)
> + goto macaddr_drop;
> + }
>
> return 0;
> +
> +macaddr_drop:
> + dev->switch_macaddr = NULL;
> + refcount_set(&switch_macaddr->refcount, 0);
Nitpick: this line doesn't do any harm, but it doesn't do any good, either.
It can be removed in a follow-up patch.
> + kfree(switch_macaddr);
> +
> + return ret;
> }
>
> void ksz_switch_macaddr_put(struct dsa_switch *ds)
> --
> 2.39.2
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH net-next v8 4/5] net: dsa: microchip: Refactor switch shutdown routine for WoL preparation
2023-10-26 5:10 [PATCH net-next v8 0/5] net: dsa: microchip: provide Wake on LAN support (part 2) Oleksij Rempel
` (2 preceding siblings ...)
2023-10-26 5:10 ` [PATCH net-next v8 3/5] net: dsa: microchip: Add error handling for ksz_switch_macaddr_get() Oleksij Rempel
@ 2023-10-26 5:10 ` Oleksij Rempel
2023-10-26 5:10 ` [PATCH net-next v8 5/5] net: dsa: microchip: Ensure Stable PME Pin State for Wake-on-LAN Oleksij Rempel
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Oleksij Rempel @ 2023-10-26 5:10 UTC (permalink / raw)
To: David S. Miller, Andrew Lunn, Eric Dumazet, Florian Fainelli,
Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Woojung Huh,
Arun Ramadoss, Conor Dooley, Krzysztof Kozlowski, Rob Herring
Cc: Oleksij Rempel, Florian Fainelli, Vladimir Oltean, kernel,
linux-kernel, netdev, UNGLinuxDriver, Russell King (Oracle),
devicetree
Centralize the switch shutdown routine in a dedicated function,
ksz_switch_shutdown(), to enhance code maintainability and reduce
redundancy. This change abstracts the common shutdown operations
previously duplicated in ksz9477_i2c_shutdown() and ksz_spi_shutdown().
This refactoring is a preparatory step for an upcoming patch to avoid
reset on shutdown if Wake-on-LAN (WoL) is enabled.
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/dsa/microchip/ksz9477_i2c.c | 5 +----
drivers/net/dsa/microchip/ksz_common.c | 19 +++++++++++++++++++
drivers/net/dsa/microchip/ksz_common.h | 1 +
drivers/net/dsa/microchip/ksz_spi.c | 5 +----
4 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz9477_i2c.c b/drivers/net/dsa/microchip/ksz9477_i2c.c
index 2710afad4f3a..cac4a607e54a 100644
--- a/drivers/net/dsa/microchip/ksz9477_i2c.c
+++ b/drivers/net/dsa/microchip/ksz9477_i2c.c
@@ -66,10 +66,7 @@ static void ksz9477_i2c_shutdown(struct i2c_client *i2c)
if (!dev)
return;
- if (dev->dev_ops->reset)
- dev->dev_ops->reset(dev);
-
- dsa_switch_shutdown(dev->ds);
+ ksz_switch_shutdown(dev);
i2c_set_clientdata(i2c, NULL);
}
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 00be812bef40..3b48e42148a0 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -3845,6 +3845,25 @@ struct ksz_device *ksz_switch_alloc(struct device *base, void *priv)
}
EXPORT_SYMBOL(ksz_switch_alloc);
+/**
+ * ksz_switch_shutdown - Shutdown routine for the switch device.
+ * @dev: The switch device structure.
+ *
+ * This function is responsible for initiating a shutdown sequence for the
+ * switch device. It invokes the reset operation defined in the device
+ * operations, if available, to reset the switch. Subsequently, it calls the
+ * DSA framework's shutdown function to ensure a proper shutdown of the DSA
+ * switch.
+ */
+void ksz_switch_shutdown(struct ksz_device *dev)
+{
+ if (dev->dev_ops->reset)
+ dev->dev_ops->reset(dev);
+
+ dsa_switch_shutdown(dev->ds);
+}
+EXPORT_SYMBOL(ksz_switch_shutdown);
+
static void ksz_parse_rgmii_delay(struct ksz_device *dev, int port_num,
struct device_node *port_dn)
{
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index 06996813f9a8..14b4828f80a1 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -400,6 +400,7 @@ extern const struct ksz_chip_data ksz_switch_chips[];
int ksz_switch_macaddr_get(struct dsa_switch *ds, int port,
struct netlink_ext_ack *extack);
void ksz_switch_macaddr_put(struct dsa_switch *ds);
+void ksz_switch_shutdown(struct ksz_device *dev);
/* Common register access functions */
static inline struct regmap *ksz_regmap_8(struct ksz_device *dev)
diff --git a/drivers/net/dsa/microchip/ksz_spi.c b/drivers/net/dsa/microchip/ksz_spi.c
index 279338451621..6f6d878e742c 100644
--- a/drivers/net/dsa/microchip/ksz_spi.c
+++ b/drivers/net/dsa/microchip/ksz_spi.c
@@ -114,10 +114,7 @@ static void ksz_spi_shutdown(struct spi_device *spi)
if (!dev)
return;
- if (dev->dev_ops->reset)
- dev->dev_ops->reset(dev);
-
- dsa_switch_shutdown(dev->ds);
+ ksz_switch_shutdown(dev);
spi_set_drvdata(spi, NULL);
}
--
2.39.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH net-next v8 5/5] net: dsa: microchip: Ensure Stable PME Pin State for Wake-on-LAN
2023-10-26 5:10 [PATCH net-next v8 0/5] net: dsa: microchip: provide Wake on LAN support (part 2) Oleksij Rempel
` (3 preceding siblings ...)
2023-10-26 5:10 ` [PATCH net-next v8 4/5] net: dsa: microchip: Refactor switch shutdown routine for WoL preparation Oleksij Rempel
@ 2023-10-26 5:10 ` Oleksij Rempel
2023-10-26 9:40 ` [PATCH net-next v8 0/5] net: dsa: microchip: provide Wake on LAN support (part 2) Vladimir Oltean
2023-10-27 21:50 ` patchwork-bot+netdevbpf
6 siblings, 0 replies; 10+ messages in thread
From: Oleksij Rempel @ 2023-10-26 5:10 UTC (permalink / raw)
To: David S. Miller, Andrew Lunn, Eric Dumazet, Florian Fainelli,
Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Woojung Huh,
Arun Ramadoss, Conor Dooley, Krzysztof Kozlowski, Rob Herring
Cc: Oleksij Rempel, Vladimir Oltean, kernel, linux-kernel, netdev,
UNGLinuxDriver, Russell King (Oracle), devicetree
Ensures a stable PME (Power Management Event) pin state by disabling PME
on system start and enabling it on shutdown only if WoL (Wake-on-LAN) is
configured. This is needed to avoid issues with some PMICs (Power
Management ICs).
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
drivers/net/dsa/microchip/ksz9477.c | 46 ++++++++++++++++++++++++++
drivers/net/dsa/microchip/ksz9477.h | 1 +
drivers/net/dsa/microchip/ksz_common.c | 8 ++++-
drivers/net/dsa/microchip/ksz_common.h | 1 +
4 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index 441b4597ef27..f24181086e16 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -197,6 +197,46 @@ int ksz9477_set_wol(struct ksz_device *dev, int port,
return 0;
}
+/**
+ * ksz9477_wol_pre_shutdown - Prepares the switch device for shutdown while
+ * considering Wake-on-LAN (WoL) settings.
+ * @dev: The switch device structure.
+ * @wol_enabled: Pointer to a boolean which will be set to true if WoL is
+ * enabled on any port.
+ *
+ * This function prepares the switch device for a safe shutdown while taking
+ * into account the Wake-on-LAN (WoL) settings on the user ports. It updates
+ * the wol_enabled flag accordingly to reflect whether WoL is active on any
+ * port.
+ */
+void ksz9477_wol_pre_shutdown(struct ksz_device *dev, bool *wol_enabled)
+{
+ struct dsa_port *dp;
+ int ret;
+
+ *wol_enabled = false;
+
+ if (!dev->wakeup_source)
+ return;
+
+ dsa_switch_for_each_user_port(dp, dev->ds) {
+ u8 pme_ctrl = 0;
+
+ ret = ksz_pread8(dev, dp->index, REG_PORT_PME_CTRL, &pme_ctrl);
+ if (!ret && pme_ctrl)
+ *wol_enabled = true;
+
+ /* make sure there are no pending wake events which would
+ * prevent the device from going to sleep/shutdown.
+ */
+ ksz9477_handle_wake_reason(dev, dp->index);
+ }
+
+ /* Now we are save to enable PME pin. */
+ if (*wol_enabled)
+ ksz_write8(dev, REG_SW_PME_CTRL, PME_ENABLE);
+}
+
static int ksz9477_wait_vlan_ctrl_ready(struct ksz_device *dev)
{
unsigned int val;
@@ -1277,6 +1317,12 @@ int ksz9477_setup(struct dsa_switch *ds)
/* enable global MIB counter freeze function */
ksz_cfg(dev, REG_SW_MAC_CTRL_6, SW_MIB_COUNTER_FREEZE, true);
+ /* Make sure PME (WoL) is not enabled. If requested, it will be
+ * enabled by ksz9477_wol_pre_shutdown(). Otherwise, some PMICs do not
+ * like PME events changes before shutdown.
+ */
+ ksz_write8(dev, REG_SW_PME_CTRL, 0);
+
return 0;
}
diff --git a/drivers/net/dsa/microchip/ksz9477.h b/drivers/net/dsa/microchip/ksz9477.h
index fa8d0318b437..ce1e656b800b 100644
--- a/drivers/net/dsa/microchip/ksz9477.h
+++ b/drivers/net/dsa/microchip/ksz9477.h
@@ -62,6 +62,7 @@ void ksz9477_get_wol(struct ksz_device *dev, int port,
struct ethtool_wolinfo *wol);
int ksz9477_set_wol(struct ksz_device *dev, int port,
struct ethtool_wolinfo *wol);
+void ksz9477_wol_pre_shutdown(struct ksz_device *dev, bool *wol_enabled);
int ksz9477_port_acl_init(struct ksz_device *dev, int port);
void ksz9477_port_acl_free(struct ksz_device *dev, int port);
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 3b48e42148a0..3fed406fb46a 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -321,6 +321,7 @@ static const struct ksz_dev_ops ksz9477_dev_ops = {
.phylink_mac_link_up = ksz9477_phylink_mac_link_up,
.get_wol = ksz9477_get_wol,
.set_wol = ksz9477_set_wol,
+ .wol_pre_shutdown = ksz9477_wol_pre_shutdown,
.config_cpu_port = ksz9477_config_cpu_port,
.tc_cbs_set_cinc = ksz9477_tc_cbs_set_cinc,
.enable_stp_addr = ksz9477_enable_stp_addr,
@@ -3857,7 +3858,12 @@ EXPORT_SYMBOL(ksz_switch_alloc);
*/
void ksz_switch_shutdown(struct ksz_device *dev)
{
- if (dev->dev_ops->reset)
+ bool wol_enabled = false;
+
+ if (dev->dev_ops->wol_pre_shutdown)
+ dev->dev_ops->wol_pre_shutdown(dev, &wol_enabled);
+
+ if (dev->dev_ops->reset && !wol_enabled)
dev->dev_ops->reset(dev);
dsa_switch_shutdown(dev->ds);
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index 14b4828f80a1..b7e8a403a132 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -378,6 +378,7 @@ struct ksz_dev_ops {
struct ethtool_wolinfo *wol);
int (*set_wol)(struct ksz_device *dev, int port,
struct ethtool_wolinfo *wol);
+ void (*wol_pre_shutdown)(struct ksz_device *dev, bool *wol_enabled);
void (*config_cpu_port)(struct dsa_switch *ds);
int (*enable_stp_addr)(struct ksz_device *dev);
int (*reset)(struct ksz_device *dev);
--
2.39.2
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH net-next v8 0/5] net: dsa: microchip: provide Wake on LAN support (part 2)
2023-10-26 5:10 [PATCH net-next v8 0/5] net: dsa: microchip: provide Wake on LAN support (part 2) Oleksij Rempel
` (4 preceding siblings ...)
2023-10-26 5:10 ` [PATCH net-next v8 5/5] net: dsa: microchip: Ensure Stable PME Pin State for Wake-on-LAN Oleksij Rempel
@ 2023-10-26 9:40 ` Vladimir Oltean
2023-10-27 21:50 ` patchwork-bot+netdevbpf
6 siblings, 0 replies; 10+ messages in thread
From: Vladimir Oltean @ 2023-10-26 9:40 UTC (permalink / raw)
To: Oleksij Rempel
Cc: David S. Miller, Andrew Lunn, Eric Dumazet, Florian Fainelli,
Jakub Kicinski, Paolo Abeni, Woojung Huh, Arun Ramadoss,
Conor Dooley, Krzysztof Kozlowski, Rob Herring, kernel,
linux-kernel, netdev, UNGLinuxDriver, Russell King (Oracle),
devicetree
On Thu, Oct 26, 2023 at 07:10:46AM +0200, Oleksij Rempel wrote:
> This patch series introduces extensive Wake on LAN (WoL) support for the
> Microchip KSZ9477 family of switches, coupled with some code refactoring
> and error handling enhancements. The principal aim is to enable and
> manage Wake on Magic Packet and other PHY event triggers for waking up
> the system, whilst ensuring that the switch isn't reset during a
> shutdown if WoL is active.
>
> The Wake on LAN functionality is optional and is particularly beneficial
> if the PME pins are connected to the SoC as a wake source or to a PMIC
> that can enable or wake the SoC.
>
> changes v8:
> - rebase on top of net-next and s/slave/user/
I am stunned by what happened here. The timeline seems to be:
- On the 23rd of October, you sent a 9-patch series constituting v7.
- On the 25th of October, 4 of those patches were silently merged, as
follows:
93aa731e6133 Merge branch 'dsa-microchip-WoL-support'
d264f24409b8 net: dsa: microchip: ksz9477: add Wake on LAN support
aed7425d6510 net: dsa: microchip: use wakeup-source DT property to enable PME output
4e1799ae84fc dt-bindings: net: dsa: microchip: add wakeup-source property
02e987f52cf0 net: dsa: microchip: Add missing MAC address register offset for ksz8863
commit 93aa731e613399f5145166940b20224a8d116920
Merge: e43e6d9582e0 d264f24409b8
Author: David S. Miller <davem@davemloft.net>
Date: Wed Oct 25 08:47:33 2023 +0100
Merge branch 'dsa-microchip-WoL-support'
with no further details as usual (cover letter becomes merge commit
message), no patchwork bot notification, nothing.
- Today you are sending the rest of 5 unmerged patches.
- In parallel, Colin Ian King has sent a fixup for a review comment on
the first 4 patches from v7, which got silently applied without that
comment being addressed.
So, given the circumstances, I see that you did the right thing. It's
just that I'm starting to understand less and less of what the rules are
supposed to be.
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH net-next v8 0/5] net: dsa: microchip: provide Wake on LAN support (part 2)
2023-10-26 5:10 [PATCH net-next v8 0/5] net: dsa: microchip: provide Wake on LAN support (part 2) Oleksij Rempel
` (5 preceding siblings ...)
2023-10-26 9:40 ` [PATCH net-next v8 0/5] net: dsa: microchip: provide Wake on LAN support (part 2) Vladimir Oltean
@ 2023-10-27 21:50 ` patchwork-bot+netdevbpf
6 siblings, 0 replies; 10+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-10-27 21:50 UTC (permalink / raw)
To: Oleksij Rempel
Cc: davem, andrew, edumazet, f.fainelli, kuba, pabeni, olteanv,
woojung.huh, arun.ramadoss, conor+dt, krzysztof.kozlowski+dt,
robh+dt, kernel, linux-kernel, netdev, UNGLinuxDriver, linux,
devicetree
Hello:
This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 26 Oct 2023 07:10:46 +0200 you wrote:
> This patch series introduces extensive Wake on LAN (WoL) support for the
> Microchip KSZ9477 family of switches, coupled with some code refactoring
> and error handling enhancements. The principal aim is to enable and
> manage Wake on Magic Packet and other PHY event triggers for waking up
> the system, whilst ensuring that the switch isn't reset during a
> shutdown if WoL is active.
>
> [...]
Here is the summary with links:
- [net-next,v8,1/5] net: dsa: microchip: ksz9477: Add Wake on Magic Packet support
https://git.kernel.org/netdev/net-next/c/3b454b6390c3
- [net-next,v8,2/5] net: dsa: microchip: Refactor comment for ksz_switch_macaddr_get() function
https://git.kernel.org/netdev/net-next/c/78c21fca0b39
- [net-next,v8,3/5] net: dsa: microchip: Add error handling for ksz_switch_macaddr_get()
https://git.kernel.org/netdev/net-next/c/818cdb0f4b38
- [net-next,v8,4/5] net: dsa: microchip: Refactor switch shutdown routine for WoL preparation
https://git.kernel.org/netdev/net-next/c/77c819cb493a
- [net-next,v8,5/5] net: dsa: microchip: Ensure Stable PME Pin State for Wake-on-LAN
https://git.kernel.org/netdev/net-next/c/8afb91acc4a3
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 10+ messages in thread