* [PATCH] net: phy: dp83867: support Wake on LAN
@ 2019-10-22 11:11 Thomas Hämmerle
2019-10-22 12:34 ` Andrew Lunn
` (2 more replies)
0 siblings, 3 replies; 11+ messages in thread
From: Thomas Hämmerle @ 2019-10-22 11:11 UTC (permalink / raw)
To: netdev
Cc: andrew, f.fainelli, hkallweit1, davem, m.tretter, Thomas Hämmerle
From: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
This adds WoL support on TI DP83867 for magic, magic secure, unicast and
broadcast.
Signed-off-by: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
---
drivers/net/phy/dp83867.c | 131 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 130 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
index 37fceaf..a3b7ff7 100644
--- a/drivers/net/phy/dp83867.c
+++ b/drivers/net/phy/dp83867.c
@@ -12,6 +12,8 @@
#include <linux/of.h>
#include <linux/phy.h>
#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <dt-bindings/net/ti-dp83867.h>
@@ -21,8 +23,9 @@
#define MII_DP83867_PHYCTRL 0x10
#define MII_DP83867_MICR 0x12
#define MII_DP83867_ISR 0x13
-#define DP83867_CTRL 0x1f
+#define DP83867_CFG2 0x14
#define DP83867_CFG3 0x1e
+#define DP83867_CTRL 0x1f
/* Extended Registers */
#define DP83867_CFG4 0x0031
@@ -36,6 +39,13 @@
#define DP83867_STRAP_STS1 0x006E
#define DP83867_STRAP_STS2 0x006f
#define DP83867_RGMIIDCTL 0x0086
+#define DP83867_RXFCFG 0x0134
+#define DP83867_RXFPMD1 0x0136
+#define DP83867_RXFPMD2 0x0137
+#define DP83867_RXFPMD3 0x0138
+#define DP83867_RXFSOP1 0x0139
+#define DP83867_RXFSOP2 0x013A
+#define DP83867_RXFSOP3 0x013B
#define DP83867_IO_MUX_CFG 0x0170
#define DP83867_SGMIICTL 0x00D3
#define DP83867_10M_SGMII_CFG 0x016F
@@ -65,6 +75,13 @@
/* SGMIICTL bits */
#define DP83867_SGMII_TYPE BIT(14)
+/* RXFCFG bits*/
+#define DP83867_WOL_MAGIC_EN BIT(0)
+#define DP83867_WOL_BCAST_EN BIT(2)
+#define DP83867_WOL_UCAST_EN BIT(4)
+#define DP83867_WOL_SEC_EN BIT(5)
+#define DP83867_WOL_ENH_MAC BIT(7)
+
/* STRAP_STS1 bits */
#define DP83867_STRAP_STS1_RESERVED BIT(11)
@@ -126,6 +143,115 @@ static int dp83867_ack_interrupt(struct phy_device *phydev)
return 0;
}
+static int dp83867_set_wol(struct phy_device *phydev,
+ struct ethtool_wolinfo *wol)
+{
+ struct net_device *ndev = phydev->attached_dev;
+ u16 val_rxcfg, val_micr;
+ const u8 *mac;
+
+ val_rxcfg = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
+ val_micr = phy_read(phydev, MII_DP83867_MICR);
+
+ if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_UCAST |
+ WAKE_BCAST)) {
+ val_rxcfg |= DP83867_WOL_ENH_MAC;
+ val_micr |= MII_DP83867_MICR_WOL_INT_EN;
+
+ if (wol->wolopts & WAKE_MAGIC) {
+ mac = (const u8 *)ndev->dev_addr;
+
+ if (!is_valid_ether_addr(mac))
+ return -EINVAL;
+
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD1,
+ (mac[1] << 8 | mac[0]));
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD2,
+ (mac[3] << 8 | mac[2]));
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD3,
+ (mac[5] << 8 | mac[4]));
+
+ val_rxcfg |= DP83867_WOL_MAGIC_EN;
+ } else {
+ val_rxcfg &= ~DP83867_WOL_MAGIC_EN;
+ }
+
+ if (wol->wolopts & WAKE_MAGICSECURE) {
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
+ (wol->sopass[1] << 8) | wol->sopass[0]);
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
+ (wol->sopass[3] << 8) | wol->sopass[2]);
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
+ (wol->sopass[5] << 8) | wol->sopass[3]);
+
+ val_rxcfg |= DP83867_WOL_SEC_EN;
+ } else {
+ val_rxcfg &= ~DP83867_WOL_SEC_EN;
+ }
+
+ if (wol->wolopts & WAKE_UCAST)
+ val_rxcfg |= DP83867_WOL_UCAST_EN;
+ else
+ val_rxcfg &= ~DP83867_WOL_UCAST_EN;
+
+ if (wol->wolopts & WAKE_BCAST)
+ val_rxcfg |= DP83867_WOL_BCAST_EN;
+ else
+ val_rxcfg &= ~DP83867_WOL_BCAST_EN;
+ } else {
+ val_rxcfg &= ~DP83867_WOL_ENH_MAC;
+ val_micr &= ~MII_DP83867_MICR_WOL_INT_EN;
+ }
+
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG, val_rxcfg);
+ phy_write(phydev, MII_DP83867_MICR, val_micr);
+
+ return 0;
+}
+
+static void dp83867_get_wol(struct phy_device *phydev,
+ struct ethtool_wolinfo *wol)
+{
+ u16 value, sopass_val;
+
+ wol->supported = (WAKE_UCAST | WAKE_BCAST | WAKE_MAGIC |
+ WAKE_MAGICSECURE);
+ wol->wolopts = 0;
+
+ value = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
+
+ if (value & DP83867_WOL_UCAST_EN)
+ wol->wolopts |= WAKE_UCAST;
+
+ if (value & DP83867_WOL_BCAST_EN)
+ wol->wolopts |= WAKE_BCAST;
+
+ if (value & DP83867_WOL_MAGIC_EN)
+ wol->wolopts |= WAKE_MAGIC;
+
+ if (value & DP83867_WOL_SEC_EN) {
+ sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
+ DP83867_RXFSOP1);
+ wol->sopass[0] = (sopass_val & 0xff);
+ wol->sopass[1] = (sopass_val >> 8);
+
+ sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
+ DP83867_RXFSOP2);
+ wol->sopass[2] = (sopass_val & 0xff);
+ wol->sopass[3] = (sopass_val >> 8);
+
+ sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
+ DP83867_RXFSOP3);
+ wol->sopass[4] = (sopass_val & 0xff);
+ wol->sopass[5] = (sopass_val >> 8);
+
+ wol->wolopts |= WAKE_MAGICSECURE;
+ }
+
+ if (!(value & DP83867_WOL_ENH_MAC))
+ wol->wolopts = 0;
+}
+
static int dp83867_config_intr(struct phy_device *phydev)
{
int micr_status;
@@ -463,6 +589,9 @@ static struct phy_driver dp83867_driver[] = {
.config_init = dp83867_config_init,
.soft_reset = dp83867_phy_reset,
+ .get_wol = dp83867_get_wol,
+ .set_wol = dp83867_set_wol,
+
/* IRQ related */
.ack_interrupt = dp83867_ack_interrupt,
.config_intr = dp83867_config_intr,
--
2.7.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH] net: phy: dp83867: support Wake on LAN
2019-10-22 11:11 [PATCH] net: phy: dp83867: support Wake on LAN Thomas Hämmerle
@ 2019-10-22 12:34 ` Andrew Lunn
2019-10-22 13:06 ` [PATCH v2] " Thomas Hämmerle
2019-10-28 8:08 ` [PATCH v3] " Thomas Hämmerle
2 siblings, 0 replies; 11+ messages in thread
From: Andrew Lunn @ 2019-10-22 12:34 UTC (permalink / raw)
To: Thomas Hämmerle; +Cc: netdev, f.fainelli, hkallweit1, davem, m.tretter
On Tue, Oct 22, 2019 at 11:11:07AM +0000, Thomas Hämmerle wrote:
> + if (wol->wolopts & WAKE_MAGICSECURE) {
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
> + (wol->sopass[1] << 8) | wol->sopass[0]);
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
> + (wol->sopass[3] << 8) | wol->sopass[2]);
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
> + (wol->sopass[5] << 8) | wol->sopass[3]);
Hi Thomas
I see sopass[3] twice here. Is that a typo?
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2] net: phy: dp83867: support Wake on LAN
2019-10-22 11:11 [PATCH] net: phy: dp83867: support Wake on LAN Thomas Hämmerle
2019-10-22 12:34 ` Andrew Lunn
@ 2019-10-22 13:06 ` Thomas Hämmerle
2019-10-22 13:30 ` Michael Tretter
` (3 more replies)
2019-10-28 8:08 ` [PATCH v3] " Thomas Hämmerle
2 siblings, 4 replies; 11+ messages in thread
From: Thomas Hämmerle @ 2019-10-22 13:06 UTC (permalink / raw)
To: netdev
Cc: andrew, f.fainelli, hkallweit1, davem, m.tretter, Thomas Hämmerle
From: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
This adds WoL support on TI DP83867 for magic, magic secure, unicast and
broadcast.
Signed-off-by: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
---
drivers/net/phy/dp83867.c | 131 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 130 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
index 37fceaf..1a3f8f1 100644
--- a/drivers/net/phy/dp83867.c
+++ b/drivers/net/phy/dp83867.c
@@ -12,6 +12,8 @@
#include <linux/of.h>
#include <linux/phy.h>
#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <dt-bindings/net/ti-dp83867.h>
@@ -21,8 +23,9 @@
#define MII_DP83867_PHYCTRL 0x10
#define MII_DP83867_MICR 0x12
#define MII_DP83867_ISR 0x13
-#define DP83867_CTRL 0x1f
+#define DP83867_CFG2 0x14
#define DP83867_CFG3 0x1e
+#define DP83867_CTRL 0x1f
/* Extended Registers */
#define DP83867_CFG4 0x0031
@@ -36,6 +39,13 @@
#define DP83867_STRAP_STS1 0x006E
#define DP83867_STRAP_STS2 0x006f
#define DP83867_RGMIIDCTL 0x0086
+#define DP83867_RXFCFG 0x0134
+#define DP83867_RXFPMD1 0x0136
+#define DP83867_RXFPMD2 0x0137
+#define DP83867_RXFPMD3 0x0138
+#define DP83867_RXFSOP1 0x0139
+#define DP83867_RXFSOP2 0x013A
+#define DP83867_RXFSOP3 0x013B
#define DP83867_IO_MUX_CFG 0x0170
#define DP83867_SGMIICTL 0x00D3
#define DP83867_10M_SGMII_CFG 0x016F
@@ -65,6 +75,13 @@
/* SGMIICTL bits */
#define DP83867_SGMII_TYPE BIT(14)
+/* RXFCFG bits*/
+#define DP83867_WOL_MAGIC_EN BIT(0)
+#define DP83867_WOL_BCAST_EN BIT(2)
+#define DP83867_WOL_UCAST_EN BIT(4)
+#define DP83867_WOL_SEC_EN BIT(5)
+#define DP83867_WOL_ENH_MAC BIT(7)
+
/* STRAP_STS1 bits */
#define DP83867_STRAP_STS1_RESERVED BIT(11)
@@ -126,6 +143,115 @@ static int dp83867_ack_interrupt(struct phy_device *phydev)
return 0;
}
+static int dp83867_set_wol(struct phy_device *phydev,
+ struct ethtool_wolinfo *wol)
+{
+ struct net_device *ndev = phydev->attached_dev;
+ u16 val_rxcfg, val_micr;
+ const u8 *mac;
+
+ val_rxcfg = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
+ val_micr = phy_read(phydev, MII_DP83867_MICR);
+
+ if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_UCAST |
+ WAKE_BCAST)) {
+ val_rxcfg |= DP83867_WOL_ENH_MAC;
+ val_micr |= MII_DP83867_MICR_WOL_INT_EN;
+
+ if (wol->wolopts & WAKE_MAGIC) {
+ mac = (const u8 *)ndev->dev_addr;
+
+ if (!is_valid_ether_addr(mac))
+ return -EINVAL;
+
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD1,
+ (mac[1] << 8 | mac[0]));
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD2,
+ (mac[3] << 8 | mac[2]));
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD3,
+ (mac[5] << 8 | mac[4]));
+
+ val_rxcfg |= DP83867_WOL_MAGIC_EN;
+ } else {
+ val_rxcfg &= ~DP83867_WOL_MAGIC_EN;
+ }
+
+ if (wol->wolopts & WAKE_MAGICSECURE) {
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
+ (wol->sopass[1] << 8) | wol->sopass[0]);
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
+ (wol->sopass[3] << 8) | wol->sopass[2]);
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
+ (wol->sopass[5] << 8) | wol->sopass[4]);
+
+ val_rxcfg |= DP83867_WOL_SEC_EN;
+ } else {
+ val_rxcfg &= ~DP83867_WOL_SEC_EN;
+ }
+
+ if (wol->wolopts & WAKE_UCAST)
+ val_rxcfg |= DP83867_WOL_UCAST_EN;
+ else
+ val_rxcfg &= ~DP83867_WOL_UCAST_EN;
+
+ if (wol->wolopts & WAKE_BCAST)
+ val_rxcfg |= DP83867_WOL_BCAST_EN;
+ else
+ val_rxcfg &= ~DP83867_WOL_BCAST_EN;
+ } else {
+ val_rxcfg &= ~DP83867_WOL_ENH_MAC;
+ val_micr &= ~MII_DP83867_MICR_WOL_INT_EN;
+ }
+
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG, val_rxcfg);
+ phy_write(phydev, MII_DP83867_MICR, val_micr);
+
+ return 0;
+}
+
+static void dp83867_get_wol(struct phy_device *phydev,
+ struct ethtool_wolinfo *wol)
+{
+ u16 value, sopass_val;
+
+ wol->supported = (WAKE_UCAST | WAKE_BCAST | WAKE_MAGIC |
+ WAKE_MAGICSECURE);
+ wol->wolopts = 0;
+
+ value = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
+
+ if (value & DP83867_WOL_UCAST_EN)
+ wol->wolopts |= WAKE_UCAST;
+
+ if (value & DP83867_WOL_BCAST_EN)
+ wol->wolopts |= WAKE_BCAST;
+
+ if (value & DP83867_WOL_MAGIC_EN)
+ wol->wolopts |= WAKE_MAGIC;
+
+ if (value & DP83867_WOL_SEC_EN) {
+ sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
+ DP83867_RXFSOP1);
+ wol->sopass[0] = (sopass_val & 0xff);
+ wol->sopass[1] = (sopass_val >> 8);
+
+ sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
+ DP83867_RXFSOP2);
+ wol->sopass[2] = (sopass_val & 0xff);
+ wol->sopass[3] = (sopass_val >> 8);
+
+ sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
+ DP83867_RXFSOP3);
+ wol->sopass[4] = (sopass_val & 0xff);
+ wol->sopass[5] = (sopass_val >> 8);
+
+ wol->wolopts |= WAKE_MAGICSECURE;
+ }
+
+ if (!(value & DP83867_WOL_ENH_MAC))
+ wol->wolopts = 0;
+}
+
static int dp83867_config_intr(struct phy_device *phydev)
{
int micr_status;
@@ -463,6 +589,9 @@ static struct phy_driver dp83867_driver[] = {
.config_init = dp83867_config_init,
.soft_reset = dp83867_phy_reset,
+ .get_wol = dp83867_get_wol,
+ .set_wol = dp83867_set_wol,
+
/* IRQ related */
.ack_interrupt = dp83867_ack_interrupt,
.config_intr = dp83867_config_intr,
--
2.7.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2] net: phy: dp83867: support Wake on LAN
2019-10-22 13:06 ` [PATCH v2] " Thomas Hämmerle
@ 2019-10-22 13:30 ` Michael Tretter
2019-10-22 14:00 ` Andrew Lunn
` (2 subsequent siblings)
3 siblings, 0 replies; 11+ messages in thread
From: Michael Tretter @ 2019-10-22 13:30 UTC (permalink / raw)
To: Thomas Hämmerle
Cc: netdev, andrew, f.fainelli, hkallweit1, davem, kernel
On Tue, 22 Oct 2019 13:06:35 +0000, Thomas Hämmerle wrote:
> From: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
>
> This adds WoL support on TI DP83867 for magic, magic secure, unicast and
> broadcast.
>
> Signed-off-by: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
Reviewed-by: Michael Tretter <michael.tretter@pengutronix.de>
> ---
> drivers/net/phy/dp83867.c | 131 +++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 130 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
> index 37fceaf..1a3f8f1 100644
> --- a/drivers/net/phy/dp83867.c
> +++ b/drivers/net/phy/dp83867.c
> @@ -12,6 +12,8 @@
> #include <linux/of.h>
> #include <linux/phy.h>
> #include <linux/delay.h>
> +#include <linux/netdevice.h>
> +#include <linux/etherdevice.h>
>
> #include <dt-bindings/net/ti-dp83867.h>
>
> @@ -21,8 +23,9 @@
> #define MII_DP83867_PHYCTRL 0x10
> #define MII_DP83867_MICR 0x12
> #define MII_DP83867_ISR 0x13
> -#define DP83867_CTRL 0x1f
> +#define DP83867_CFG2 0x14
> #define DP83867_CFG3 0x1e
> +#define DP83867_CTRL 0x1f
>
> /* Extended Registers */
> #define DP83867_CFG4 0x0031
> @@ -36,6 +39,13 @@
> #define DP83867_STRAP_STS1 0x006E
> #define DP83867_STRAP_STS2 0x006f
> #define DP83867_RGMIIDCTL 0x0086
> +#define DP83867_RXFCFG 0x0134
> +#define DP83867_RXFPMD1 0x0136
> +#define DP83867_RXFPMD2 0x0137
> +#define DP83867_RXFPMD3 0x0138
> +#define DP83867_RXFSOP1 0x0139
> +#define DP83867_RXFSOP2 0x013A
> +#define DP83867_RXFSOP3 0x013B
> #define DP83867_IO_MUX_CFG 0x0170
> #define DP83867_SGMIICTL 0x00D3
> #define DP83867_10M_SGMII_CFG 0x016F
> @@ -65,6 +75,13 @@
> /* SGMIICTL bits */
> #define DP83867_SGMII_TYPE BIT(14)
>
> +/* RXFCFG bits*/
> +#define DP83867_WOL_MAGIC_EN BIT(0)
> +#define DP83867_WOL_BCAST_EN BIT(2)
> +#define DP83867_WOL_UCAST_EN BIT(4)
> +#define DP83867_WOL_SEC_EN BIT(5)
> +#define DP83867_WOL_ENH_MAC BIT(7)
> +
> /* STRAP_STS1 bits */
> #define DP83867_STRAP_STS1_RESERVED BIT(11)
>
> @@ -126,6 +143,115 @@ static int dp83867_ack_interrupt(struct phy_device *phydev)
> return 0;
> }
>
> +static int dp83867_set_wol(struct phy_device *phydev,
> + struct ethtool_wolinfo *wol)
> +{
> + struct net_device *ndev = phydev->attached_dev;
> + u16 val_rxcfg, val_micr;
> + const u8 *mac;
> +
> + val_rxcfg = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
> + val_micr = phy_read(phydev, MII_DP83867_MICR);
> +
> + if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_UCAST |
> + WAKE_BCAST)) {
> + val_rxcfg |= DP83867_WOL_ENH_MAC;
> + val_micr |= MII_DP83867_MICR_WOL_INT_EN;
> +
> + if (wol->wolopts & WAKE_MAGIC) {
> + mac = (const u8 *)ndev->dev_addr;
> +
> + if (!is_valid_ether_addr(mac))
> + return -EINVAL;
> +
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD1,
> + (mac[1] << 8 | mac[0]));
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD2,
> + (mac[3] << 8 | mac[2]));
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD3,
> + (mac[5] << 8 | mac[4]));
> +
> + val_rxcfg |= DP83867_WOL_MAGIC_EN;
> + } else {
> + val_rxcfg &= ~DP83867_WOL_MAGIC_EN;
> + }
> +
> + if (wol->wolopts & WAKE_MAGICSECURE) {
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
> + (wol->sopass[1] << 8) | wol->sopass[0]);
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
> + (wol->sopass[3] << 8) | wol->sopass[2]);
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
> + (wol->sopass[5] << 8) | wol->sopass[4]);
> +
> + val_rxcfg |= DP83867_WOL_SEC_EN;
> + } else {
> + val_rxcfg &= ~DP83867_WOL_SEC_EN;
> + }
> +
> + if (wol->wolopts & WAKE_UCAST)
> + val_rxcfg |= DP83867_WOL_UCAST_EN;
> + else
> + val_rxcfg &= ~DP83867_WOL_UCAST_EN;
> +
> + if (wol->wolopts & WAKE_BCAST)
> + val_rxcfg |= DP83867_WOL_BCAST_EN;
> + else
> + val_rxcfg &= ~DP83867_WOL_BCAST_EN;
> + } else {
> + val_rxcfg &= ~DP83867_WOL_ENH_MAC;
> + val_micr &= ~MII_DP83867_MICR_WOL_INT_EN;
> + }
> +
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG, val_rxcfg);
> + phy_write(phydev, MII_DP83867_MICR, val_micr);
> +
> + return 0;
> +}
> +
> +static void dp83867_get_wol(struct phy_device *phydev,
> + struct ethtool_wolinfo *wol)
> +{
> + u16 value, sopass_val;
> +
> + wol->supported = (WAKE_UCAST | WAKE_BCAST | WAKE_MAGIC |
> + WAKE_MAGICSECURE);
> + wol->wolopts = 0;
> +
> + value = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
> +
> + if (value & DP83867_WOL_UCAST_EN)
> + wol->wolopts |= WAKE_UCAST;
> +
> + if (value & DP83867_WOL_BCAST_EN)
> + wol->wolopts |= WAKE_BCAST;
> +
> + if (value & DP83867_WOL_MAGIC_EN)
> + wol->wolopts |= WAKE_MAGIC;
> +
> + if (value & DP83867_WOL_SEC_EN) {
> + sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
> + DP83867_RXFSOP1);
> + wol->sopass[0] = (sopass_val & 0xff);
> + wol->sopass[1] = (sopass_val >> 8);
> +
> + sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
> + DP83867_RXFSOP2);
> + wol->sopass[2] = (sopass_val & 0xff);
> + wol->sopass[3] = (sopass_val >> 8);
> +
> + sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
> + DP83867_RXFSOP3);
> + wol->sopass[4] = (sopass_val & 0xff);
> + wol->sopass[5] = (sopass_val >> 8);
> +
> + wol->wolopts |= WAKE_MAGICSECURE;
> + }
> +
> + if (!(value & DP83867_WOL_ENH_MAC))
> + wol->wolopts = 0;
> +}
> +
> static int dp83867_config_intr(struct phy_device *phydev)
> {
> int micr_status;
> @@ -463,6 +589,9 @@ static struct phy_driver dp83867_driver[] = {
> .config_init = dp83867_config_init,
> .soft_reset = dp83867_phy_reset,
>
> + .get_wol = dp83867_get_wol,
> + .set_wol = dp83867_set_wol,
> +
> /* IRQ related */
> .ack_interrupt = dp83867_ack_interrupt,
> .config_intr = dp83867_config_intr,
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] net: phy: dp83867: support Wake on LAN
2019-10-22 13:06 ` [PATCH v2] " Thomas Hämmerle
2019-10-22 13:30 ` Michael Tretter
@ 2019-10-22 14:00 ` Andrew Lunn
2019-10-22 18:40 ` Heiner Kallweit
2019-10-24 22:16 ` David Miller
3 siblings, 0 replies; 11+ messages in thread
From: Andrew Lunn @ 2019-10-22 14:00 UTC (permalink / raw)
To: Thomas Hämmerle; +Cc: netdev, f.fainelli, hkallweit1, davem, m.tretter
On Tue, Oct 22, 2019 at 01:06:35PM +0000, Thomas Hämmerle wrote:
> From: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
>
> This adds WoL support on TI DP83867 for magic, magic secure, unicast and
> broadcast.
>
> Signed-off-by: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] net: phy: dp83867: support Wake on LAN
2019-10-22 13:06 ` [PATCH v2] " Thomas Hämmerle
2019-10-22 13:30 ` Michael Tretter
2019-10-22 14:00 ` Andrew Lunn
@ 2019-10-22 18:40 ` Heiner Kallweit
2019-10-22 19:15 ` Andrew Lunn
2019-10-24 22:16 ` David Miller
3 siblings, 1 reply; 11+ messages in thread
From: Heiner Kallweit @ 2019-10-22 18:40 UTC (permalink / raw)
To: Thomas Hämmerle, netdev; +Cc: andrew, f.fainelli, davem, m.tretter
On 22.10.2019 15:06, Thomas Hämmerle wrote:
> From: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
>
> This adds WoL support on TI DP83867 for magic, magic secure, unicast and
> broadcast.
>
> Signed-off-by: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
> ---
> drivers/net/phy/dp83867.c | 131 +++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 130 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
> index 37fceaf..1a3f8f1 100644
> --- a/drivers/net/phy/dp83867.c
> +++ b/drivers/net/phy/dp83867.c
> @@ -12,6 +12,8 @@
> #include <linux/of.h>
> #include <linux/phy.h>
> #include <linux/delay.h>
> +#include <linux/netdevice.h>
> +#include <linux/etherdevice.h>
>
> #include <dt-bindings/net/ti-dp83867.h>
>
> @@ -21,8 +23,9 @@
> #define MII_DP83867_PHYCTRL 0x10
> #define MII_DP83867_MICR 0x12
> #define MII_DP83867_ISR 0x13
> -#define DP83867_CTRL 0x1f
> +#define DP83867_CFG2 0x14
> #define DP83867_CFG3 0x1e
> +#define DP83867_CTRL 0x1f
>
> /* Extended Registers */
> #define DP83867_CFG4 0x0031
> @@ -36,6 +39,13 @@
> #define DP83867_STRAP_STS1 0x006E
> #define DP83867_STRAP_STS2 0x006f
> #define DP83867_RGMIIDCTL 0x0086
> +#define DP83867_RXFCFG 0x0134
> +#define DP83867_RXFPMD1 0x0136
> +#define DP83867_RXFPMD2 0x0137
> +#define DP83867_RXFPMD3 0x0138
> +#define DP83867_RXFSOP1 0x0139
> +#define DP83867_RXFSOP2 0x013A
> +#define DP83867_RXFSOP3 0x013B
> #define DP83867_IO_MUX_CFG 0x0170
> #define DP83867_SGMIICTL 0x00D3
> #define DP83867_10M_SGMII_CFG 0x016F
> @@ -65,6 +75,13 @@
> /* SGMIICTL bits */
> #define DP83867_SGMII_TYPE BIT(14)
>
> +/* RXFCFG bits*/
> +#define DP83867_WOL_MAGIC_EN BIT(0)
> +#define DP83867_WOL_BCAST_EN BIT(2)
> +#define DP83867_WOL_UCAST_EN BIT(4)
> +#define DP83867_WOL_SEC_EN BIT(5)
> +#define DP83867_WOL_ENH_MAC BIT(7)
> +
> /* STRAP_STS1 bits */
> #define DP83867_STRAP_STS1_RESERVED BIT(11)
>
> @@ -126,6 +143,115 @@ static int dp83867_ack_interrupt(struct phy_device *phydev)
> return 0;
> }
>
> +static int dp83867_set_wol(struct phy_device *phydev,
> + struct ethtool_wolinfo *wol)
> +{
> + struct net_device *ndev = phydev->attached_dev;
> + u16 val_rxcfg, val_micr;
> + const u8 *mac;
> +
> + val_rxcfg = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
> + val_micr = phy_read(phydev, MII_DP83867_MICR);
> +
> + if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_UCAST |
> + WAKE_BCAST)) {
> + val_rxcfg |= DP83867_WOL_ENH_MAC;
> + val_micr |= MII_DP83867_MICR_WOL_INT_EN;
> +
> + if (wol->wolopts & WAKE_MAGIC) {
> + mac = (const u8 *)ndev->dev_addr;
Using a cast to add/remove a const qualifier usually isn't too nice.
Why not simply declare mac w/o const?
Also PHY might not be attached. I think ndev should be checked for NULL.
> +
> + if (!is_valid_ether_addr(mac))
> + return -EINVAL;
> +
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD1,
> + (mac[1] << 8 | mac[0]));
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD2,
> + (mac[3] << 8 | mac[2]));
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD3,
> + (mac[5] << 8 | mac[4]));
> +
> + val_rxcfg |= DP83867_WOL_MAGIC_EN;
> + } else {
> + val_rxcfg &= ~DP83867_WOL_MAGIC_EN;
> + }
> +
> + if (wol->wolopts & WAKE_MAGICSECURE) {
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
> + (wol->sopass[1] << 8) | wol->sopass[0]);
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
> + (wol->sopass[3] << 8) | wol->sopass[2]);
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
> + (wol->sopass[5] << 8) | wol->sopass[4]);
> +
> + val_rxcfg |= DP83867_WOL_SEC_EN;
> + } else {
> + val_rxcfg &= ~DP83867_WOL_SEC_EN;
> + }
> +
> + if (wol->wolopts & WAKE_UCAST)
> + val_rxcfg |= DP83867_WOL_UCAST_EN;
> + else
> + val_rxcfg &= ~DP83867_WOL_UCAST_EN;
> +
> + if (wol->wolopts & WAKE_BCAST)
> + val_rxcfg |= DP83867_WOL_BCAST_EN;
> + else
> + val_rxcfg &= ~DP83867_WOL_BCAST_EN;
> + } else {
> + val_rxcfg &= ~DP83867_WOL_ENH_MAC;
> + val_micr &= ~MII_DP83867_MICR_WOL_INT_EN;
> + }
> +
> + phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG, val_rxcfg);
> + phy_write(phydev, MII_DP83867_MICR, val_micr);
> +
> + return 0;
> +}
> +
> +static void dp83867_get_wol(struct phy_device *phydev,
> + struct ethtool_wolinfo *wol)
> +{
> + u16 value, sopass_val;
> +
> + wol->supported = (WAKE_UCAST | WAKE_BCAST | WAKE_MAGIC |
> + WAKE_MAGICSECURE);
> + wol->wolopts = 0;
> +
> + value = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
> +
> + if (value & DP83867_WOL_UCAST_EN)
> + wol->wolopts |= WAKE_UCAST;
> +
> + if (value & DP83867_WOL_BCAST_EN)
> + wol->wolopts |= WAKE_BCAST;
> +
> + if (value & DP83867_WOL_MAGIC_EN)
> + wol->wolopts |= WAKE_MAGIC;
> +
> + if (value & DP83867_WOL_SEC_EN) {
> + sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
> + DP83867_RXFSOP1);
> + wol->sopass[0] = (sopass_val & 0xff);
> + wol->sopass[1] = (sopass_val >> 8);
> +
> + sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
> + DP83867_RXFSOP2);
> + wol->sopass[2] = (sopass_val & 0xff);
> + wol->sopass[3] = (sopass_val >> 8);
> +
> + sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
> + DP83867_RXFSOP3);
> + wol->sopass[4] = (sopass_val & 0xff);
> + wol->sopass[5] = (sopass_val >> 8);
> +
> + wol->wolopts |= WAKE_MAGICSECURE;
> + }
> +
> + if (!(value & DP83867_WOL_ENH_MAC))
> + wol->wolopts = 0;
> +}
> +
> static int dp83867_config_intr(struct phy_device *phydev)
> {
> int micr_status;
> @@ -463,6 +589,9 @@ static struct phy_driver dp83867_driver[] = {
> .config_init = dp83867_config_init,
> .soft_reset = dp83867_phy_reset,
>
> + .get_wol = dp83867_get_wol,
> + .set_wol = dp83867_set_wol,
> +
> /* IRQ related */
> .ack_interrupt = dp83867_ack_interrupt,
> .config_intr = dp83867_config_intr,
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] net: phy: dp83867: support Wake on LAN
2019-10-22 18:40 ` Heiner Kallweit
@ 2019-10-22 19:15 ` Andrew Lunn
0 siblings, 0 replies; 11+ messages in thread
From: Andrew Lunn @ 2019-10-22 19:15 UTC (permalink / raw)
To: Heiner Kallweit
Cc: Thomas Hämmerle, netdev, f.fainelli, davem, m.tretter
> > +static int dp83867_set_wol(struct phy_device *phydev,
> > + struct ethtool_wolinfo *wol)
> > +{
> > + struct net_device *ndev = phydev->attached_dev;
> > + u16 val_rxcfg, val_micr;
> > + const u8 *mac;
> > +
> > + val_rxcfg = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
> > + val_micr = phy_read(phydev, MII_DP83867_MICR);
> > +
> > + if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_UCAST |
> > + WAKE_BCAST)) {
> > + val_rxcfg |= DP83867_WOL_ENH_MAC;
> > + val_micr |= MII_DP83867_MICR_WOL_INT_EN;
> > +
> > + if (wol->wolopts & WAKE_MAGIC) {
> > + mac = (const u8 *)ndev->dev_addr;
>
> Using a cast to add/remove a const qualifier usually isn't too nice.
> Why not simply declare mac w/o const?
>
> Also PHY might not be attached. I think ndev should be checked for NULL.
Hi Heiner
I thought about that as well. But the ethtool API is invoked using a
network interface name. It would be odd to call into the PHY driver if
the PHY was not attached. And the resulting Oops would help us
identify the bug.
Plus all the other PHY drivers which implement magic packet WoL assume
the PHY is attached. It could be they are all broken i suppose...
Andrew
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] net: phy: dp83867: support Wake on LAN
2019-10-22 13:06 ` [PATCH v2] " Thomas Hämmerle
` (2 preceding siblings ...)
2019-10-22 18:40 ` Heiner Kallweit
@ 2019-10-24 22:16 ` David Miller
2019-10-25 7:55 ` Thomas Hämmerle
3 siblings, 1 reply; 11+ messages in thread
From: David Miller @ 2019-10-24 22:16 UTC (permalink / raw)
To: Thomas.Haemmerle; +Cc: netdev, andrew, f.fainelli, hkallweit1, m.tretter
From: Thomas Hämmerle <Thomas.Haemmerle@wolfvision.net>
Date: Tue, 22 Oct 2019 13:06:35 +0000
> + const u8 *mac;
> +
> + val_rxcfg = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
> + val_micr = phy_read(phydev, MII_DP83867_MICR);
> +
> + if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_UCAST |
> + WAKE_BCAST)) {
> + val_rxcfg |= DP83867_WOL_ENH_MAC;
> + val_micr |= MII_DP83867_MICR_WOL_INT_EN;
> +
> + if (wol->wolopts & WAKE_MAGIC) {
> + mac = (const u8 *)ndev->dev_addr;
Please declare 'mac' non-const and get rid of this cast, as suggested by Heiner.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2] net: phy: dp83867: support Wake on LAN
2019-10-24 22:16 ` David Miller
@ 2019-10-25 7:55 ` Thomas Hämmerle
0 siblings, 0 replies; 11+ messages in thread
From: Thomas Hämmerle @ 2019-10-25 7:55 UTC (permalink / raw)
To: David Miller; +Cc: netdev, andrew, f.fainelli, hkallweit1, m.tretter
Hi David,
On 25.10.19 00:17, David Miller wrote:
> From: Thomas Hämmerle <Thomas.Haemmerle@wolfvision.net>
> Date: Tue, 22 Oct 2019 13:06:35 +0000
>
>> + const u8 *mac;
>> +
>> + val_rxcfg = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
>> + val_micr = phy_read(phydev, MII_DP83867_MICR);
>> +
>> + if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_UCAST |
>> + WAKE_BCAST)) {
>> + val_rxcfg |= DP83867_WOL_ENH_MAC;
>> + val_micr |= MII_DP83867_MICR_WOL_INT_EN;
>> +
>> + if (wol->wolopts & WAKE_MAGIC) {
>> + mac = (const u8 *)ndev->dev_addr;
>
> Please declare 'mac' non-const and get rid of this cast, as suggested by Heiner.
>
I agree with Heiner and you, however since I first took a into other phy
drivers (at803x, dp83822, dp83tc811) and how set_wol() is done there,
I've implemented it the same way.
So maybe we should also change it in the other drivers.
Thomas
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v3] net: phy: dp83867: support Wake on LAN
2019-10-22 11:11 [PATCH] net: phy: dp83867: support Wake on LAN Thomas Hämmerle
2019-10-22 12:34 ` Andrew Lunn
2019-10-22 13:06 ` [PATCH v2] " Thomas Hämmerle
@ 2019-10-28 8:08 ` Thomas Hämmerle
2019-10-29 23:43 ` David Miller
2 siblings, 1 reply; 11+ messages in thread
From: Thomas Hämmerle @ 2019-10-28 8:08 UTC (permalink / raw)
To: netdev
Cc: andrew, f.fainelli, hkallweit1, davem, m.tretter, Thomas Hämmerle
From: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
This adds WoL support on TI DP83867 for magic, magic secure, unicast and
broadcast.
Signed-off-by: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
---
drivers/net/phy/dp83867.c | 131 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 130 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
index 37fceaf..7874271 100644
--- a/drivers/net/phy/dp83867.c
+++ b/drivers/net/phy/dp83867.c
@@ -12,6 +12,8 @@
#include <linux/of.h>
#include <linux/phy.h>
#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
#include <dt-bindings/net/ti-dp83867.h>
@@ -21,8 +23,9 @@
#define MII_DP83867_PHYCTRL 0x10
#define MII_DP83867_MICR 0x12
#define MII_DP83867_ISR 0x13
-#define DP83867_CTRL 0x1f
+#define DP83867_CFG2 0x14
#define DP83867_CFG3 0x1e
+#define DP83867_CTRL 0x1f
/* Extended Registers */
#define DP83867_CFG4 0x0031
@@ -36,6 +39,13 @@
#define DP83867_STRAP_STS1 0x006E
#define DP83867_STRAP_STS2 0x006f
#define DP83867_RGMIIDCTL 0x0086
+#define DP83867_RXFCFG 0x0134
+#define DP83867_RXFPMD1 0x0136
+#define DP83867_RXFPMD2 0x0137
+#define DP83867_RXFPMD3 0x0138
+#define DP83867_RXFSOP1 0x0139
+#define DP83867_RXFSOP2 0x013A
+#define DP83867_RXFSOP3 0x013B
#define DP83867_IO_MUX_CFG 0x0170
#define DP83867_SGMIICTL 0x00D3
#define DP83867_10M_SGMII_CFG 0x016F
@@ -65,6 +75,13 @@
/* SGMIICTL bits */
#define DP83867_SGMII_TYPE BIT(14)
+/* RXFCFG bits*/
+#define DP83867_WOL_MAGIC_EN BIT(0)
+#define DP83867_WOL_BCAST_EN BIT(2)
+#define DP83867_WOL_UCAST_EN BIT(4)
+#define DP83867_WOL_SEC_EN BIT(5)
+#define DP83867_WOL_ENH_MAC BIT(7)
+
/* STRAP_STS1 bits */
#define DP83867_STRAP_STS1_RESERVED BIT(11)
@@ -126,6 +143,115 @@ static int dp83867_ack_interrupt(struct phy_device *phydev)
return 0;
}
+static int dp83867_set_wol(struct phy_device *phydev,
+ struct ethtool_wolinfo *wol)
+{
+ struct net_device *ndev = phydev->attached_dev;
+ u16 val_rxcfg, val_micr;
+ u8 *mac;
+
+ val_rxcfg = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
+ val_micr = phy_read(phydev, MII_DP83867_MICR);
+
+ if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_UCAST |
+ WAKE_BCAST)) {
+ val_rxcfg |= DP83867_WOL_ENH_MAC;
+ val_micr |= MII_DP83867_MICR_WOL_INT_EN;
+
+ if (wol->wolopts & WAKE_MAGIC) {
+ mac = (u8 *)ndev->dev_addr;
+
+ if (!is_valid_ether_addr(mac))
+ return -EINVAL;
+
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD1,
+ (mac[1] << 8 | mac[0]));
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD2,
+ (mac[3] << 8 | mac[2]));
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD3,
+ (mac[5] << 8 | mac[4]));
+
+ val_rxcfg |= DP83867_WOL_MAGIC_EN;
+ } else {
+ val_rxcfg &= ~DP83867_WOL_MAGIC_EN;
+ }
+
+ if (wol->wolopts & WAKE_MAGICSECURE) {
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
+ (wol->sopass[1] << 8) | wol->sopass[0]);
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
+ (wol->sopass[3] << 8) | wol->sopass[2]);
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
+ (wol->sopass[5] << 8) | wol->sopass[4]);
+
+ val_rxcfg |= DP83867_WOL_SEC_EN;
+ } else {
+ val_rxcfg &= ~DP83867_WOL_SEC_EN;
+ }
+
+ if (wol->wolopts & WAKE_UCAST)
+ val_rxcfg |= DP83867_WOL_UCAST_EN;
+ else
+ val_rxcfg &= ~DP83867_WOL_UCAST_EN;
+
+ if (wol->wolopts & WAKE_BCAST)
+ val_rxcfg |= DP83867_WOL_BCAST_EN;
+ else
+ val_rxcfg &= ~DP83867_WOL_BCAST_EN;
+ } else {
+ val_rxcfg &= ~DP83867_WOL_ENH_MAC;
+ val_micr &= ~MII_DP83867_MICR_WOL_INT_EN;
+ }
+
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG, val_rxcfg);
+ phy_write(phydev, MII_DP83867_MICR, val_micr);
+
+ return 0;
+}
+
+static void dp83867_get_wol(struct phy_device *phydev,
+ struct ethtool_wolinfo *wol)
+{
+ u16 value, sopass_val;
+
+ wol->supported = (WAKE_UCAST | WAKE_BCAST | WAKE_MAGIC |
+ WAKE_MAGICSECURE);
+ wol->wolopts = 0;
+
+ value = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
+
+ if (value & DP83867_WOL_UCAST_EN)
+ wol->wolopts |= WAKE_UCAST;
+
+ if (value & DP83867_WOL_BCAST_EN)
+ wol->wolopts |= WAKE_BCAST;
+
+ if (value & DP83867_WOL_MAGIC_EN)
+ wol->wolopts |= WAKE_MAGIC;
+
+ if (value & DP83867_WOL_SEC_EN) {
+ sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
+ DP83867_RXFSOP1);
+ wol->sopass[0] = (sopass_val & 0xff);
+ wol->sopass[1] = (sopass_val >> 8);
+
+ sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
+ DP83867_RXFSOP2);
+ wol->sopass[2] = (sopass_val & 0xff);
+ wol->sopass[3] = (sopass_val >> 8);
+
+ sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
+ DP83867_RXFSOP3);
+ wol->sopass[4] = (sopass_val & 0xff);
+ wol->sopass[5] = (sopass_val >> 8);
+
+ wol->wolopts |= WAKE_MAGICSECURE;
+ }
+
+ if (!(value & DP83867_WOL_ENH_MAC))
+ wol->wolopts = 0;
+}
+
static int dp83867_config_intr(struct phy_device *phydev)
{
int micr_status;
@@ -463,6 +589,9 @@ static struct phy_driver dp83867_driver[] = {
.config_init = dp83867_config_init,
.soft_reset = dp83867_phy_reset,
+ .get_wol = dp83867_get_wol,
+ .set_wol = dp83867_set_wol,
+
/* IRQ related */
.ack_interrupt = dp83867_ack_interrupt,
.config_intr = dp83867_config_intr,
--
2.7.4
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v3] net: phy: dp83867: support Wake on LAN
2019-10-28 8:08 ` [PATCH v3] " Thomas Hämmerle
@ 2019-10-29 23:43 ` David Miller
0 siblings, 0 replies; 11+ messages in thread
From: David Miller @ 2019-10-29 23:43 UTC (permalink / raw)
To: Thomas.Haemmerle; +Cc: netdev, andrew, f.fainelli, hkallweit1, m.tretter
From: Thomas Hämmerle <Thomas.Haemmerle@wolfvision.net>
Date: Mon, 28 Oct 2019 08:08:14 +0000
> From: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
>
> This adds WoL support on TI DP83867 for magic, magic secure, unicast and
> broadcast.
>
> Signed-off-by: Thomas Haemmerle <thomas.haemmerle@wolfvision.net>
Applied to net-next, thanks Thomas.
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2019-10-29 23:43 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-22 11:11 [PATCH] net: phy: dp83867: support Wake on LAN Thomas Hämmerle
2019-10-22 12:34 ` Andrew Lunn
2019-10-22 13:06 ` [PATCH v2] " Thomas Hämmerle
2019-10-22 13:30 ` Michael Tretter
2019-10-22 14:00 ` Andrew Lunn
2019-10-22 18:40 ` Heiner Kallweit
2019-10-22 19:15 ` Andrew Lunn
2019-10-24 22:16 ` David Miller
2019-10-25 7:55 ` Thomas Hämmerle
2019-10-28 8:08 ` [PATCH v3] " Thomas Hämmerle
2019-10-29 23:43 ` David Miller
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.