All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jay Monkman <jtm@lopingdog.com>
To: devicetree@vger.kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Piergiorgio Beruto <piergiorgio.beruto@gmail.com>,
	Arndt Schuebel <Arndt.Schuebel@onsemi.com>
Subject: [PATCH 3/4] net: phy: Add GPIO and DT support to NCN26000
Date: Mon, 18 Sep 2023 01:59:03 -0500	[thread overview]
Message-ID: <ZQf1Nx+2amtUZulX@lopingdog.com> (raw)


This adds GPIO support and devicetree configuration for
the NCN26000 PHY.

Signed-off-by: Jay Monkman <jtm@lopingdog.com>
---
 drivers/net/phy/ncn26000.c | 467 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 459 insertions(+), 8 deletions(-)

diff --git a/drivers/net/phy/ncn26000.c b/drivers/net/phy/ncn26000.c
index 5680584f659e..d89cbac6f8e3 100644
--- a/drivers/net/phy/ncn26000.c
+++ b/drivers/net/phy/ncn26000.c
@@ -7,17 +7,32 @@
 #include <linux/kernel.h>
 #include <linux/bitfield.h>
 #include <linux/errno.h>
+#include <linux/gpio/driver.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
+#include <linux/property.h>
 
 #include "mdio-open-alliance.h"
 
 #define PHY_ID_NCN26000			0x180FF5A1
 
+#define TO_TMR_DEFAULT			32
+
 #define NCN26000_REG_IRQ_CTL            16
 #define NCN26000_REG_IRQ_STATUS         17
+#define NCN26000_REG_DIO_CONFIG         18
+
+// clause 45 vendor specific registers
+#define NCN26000_REG_PHYCFG1_MMD	MDIO_MMD_VEND2
+#define NCN26000_REG_PHYCFG1		0x8001
+
+#define NCN26000_REG_PLCAEXT_MMD	MDIO_MMD_VEND2
+#define NCN26000_REG_PLCAEXT		0x8002
+
+#define NCN26000_REG_TWEAKS_MMD		MDIO_MMD_VEND1
+#define NCN26000_REG_TWEAKS		0x1001
 
 // the NCN26000 maps link_ctrl to BMCR_ANENABLE
 #define NCN26000_BCMR_LINK_CTRL_BIT	BMCR_ANENABLE
@@ -33,17 +48,392 @@
 #define NCN26000_IRQ_PHYSCOL_BIT	BIT(5)
 #define NCN26000_IRQ_RESET_BIT		BIT(15)
 
-#define TO_TMR_DEFAULT			32
+#define NCN26000_DIO_FN_DISABLE		0x0
+#define NCN26000_DIO_FN_GPIO		0x1
+#define NCN26000_DIO_FN_SFD_TX		0x2
+#define NCN26000_DIO_FN_SFD_RX		0x3
+#define NCN26000_DIO_FN_LED_LINK	0x4
+#define NCN26000_DIO_FN_LED_PLCA	0x5
+#define NCN26000_DIO_FN_LED_TX		0x6
+#define NCN26000_DIO_FN_LED_RX		0x7
+#define NCN26000_DIO_FN_CLK25M		0x8
+#define NCN26000_DIO_FN_SFD_RXTX	0xb
+#define NCN26000_DIO_FN_LED_RXTX	0xf
+
+#define NCN26000_DIO_CFG_SLEW_RATE1	BIT(15)
+#define NCN26000_DIO_CFG_PULL_EN1	BIT(14)
+#define NCN26000_DIO_CFG_PULL_DIR1	BIT(13)
+#define NCN26000_DIO_CFG_FN1(x)		((x) << 9)
+#define NCN26000_DIO_CFG_VAL1		BIT(8)
+#define NCN26000_DIO_CFG_SLEW_RATE0	BIT(7)
+#define NCN26000_DIO_CFG_PULL_EN0	BIT(6)
+#define NCN26000_DIO_CFG_PULL_DIR0	BIT(5)
+#define NCN26000_DIO_CFG_FN0(x)		((x) << 1)
+#define NCN26000_DIO_CFG_VAL0		BIT(0)
+
+#define NCN26000_PHYCFG1_PKT_LOOP	BIT(15)
+#define NCN26000_PHYCFG1_ENI		BIT(7)
+#define NCN26000_PHYCFG1_UNJAB_TMR	BIT(6)
+#define NCN26000_PHYCFG1_NO_COL_MASK	BIT(1)
+#define NCN26000_PHYCFG1_RX_DLY		BIT(0)
+
+#define NCN26000_PLCAEXT_PRECEDENCE	BIT(15)
+#define NCN26000_PLCAEXT_MIIEXTDIS	BIT(11)
+
+#define NCN26000_TWEAKS_TX_GAIN(x)	((x) << 14)
+#define NCN26000_TWEAKS_CD_THRESH(x)	((x) << 10)
+#define NCN26000_TWEAKS_ED_THRESH(x)	((x) << 6)
+#define NCN26000_TWEAKS_DIG_SLEW	BIT(5)
+#define NCN26000_TWEAKS_CMC_COMP(x)	((x) << 3)
+#define NCN26000_TWEAKS_TX_SLEW		BIT(2)
+
+#define NCN26000_TX_GAIN_1V0		0
+#define NCN26000_TX_GAIN_1V1		1
+#define NCN26000_TX_GAIN_0V9		2
+#define NCN26000_TX_GAIN_0V8		3
+#define NCN26000_CD_THRESH_DEFAULT	11
+#define NCN26000_ED_THRESH_DEFAULT	2
+#define NCN26000_DIG_SLEW_FAST		1
+#define NCN26000_DIG_SLEW_SLOW		0
+#define NCN26000_CMC_COMP_0P25		0
+#define NCN26000_CMC_COMP_1P37		1
+#define NCN26000_CMC_COMP_3P00		2
+#define NCN26000_CMC_COMP_4P37		3
+#define NCN26000_TX_SLEW_FAST		1
+#define NCN26000_TX_SLEW_SLOW		0
+
+struct ncn26000_priv {
+	struct device *dev;
+	struct phy_device *phydev;
+	struct gpio_chip gpio_chip;
+	unsigned int gpiomask;
+	u16 diocfg;
+	u16 phycfg0;
+	u16 plcaext;
+	u16 tweaks;
+
+	enum {
+		ENI_AUTO = 0,
+		ENI_FORCE_ON = 1,
+		ENI_FORCE_OFF = 2
+	} eni_mode;
+};
+
+static int ncn26000_gpio_request(struct gpio_chip *gc, unsigned int offset)
+{
+	struct ncn26000_priv *priv = gpiochip_get_data(gc);
+
+	if (offset > 2)
+		return -ENODEV;
+
+	if (priv->gpiomask & (1 << offset))
+		return 0;
+
+	return -EBUSY;
+}
+
+static void ncn26000_gpio_set(struct gpio_chip *gc, unsigned int offset, int val)
+{
+	struct ncn26000_priv *priv = gpiochip_get_data(gc);
+	u32 dio_reg;
+
+	dio_reg = phy_read(priv->phydev, NCN26000_REG_DIO_CONFIG);
+
+	switch (offset) {
+	case 0:
+		if (!val == !(priv->diocfg & NCN26000_DIO_CFG_VAL0))
+			dio_reg |= NCN26000_DIO_CFG_VAL0;
+		else
+			dio_reg &= ~NCN26000_DIO_CFG_VAL0;
+		break;
+
+	case 1:
+		if (!val == !(priv->diocfg & NCN26000_DIO_CFG_VAL1))
+			dio_reg |= NCN26000_DIO_CFG_VAL1;
+		else
+			dio_reg &= ~NCN26000_DIO_CFG_VAL1;
+		break;
+
+	default:
+		dev_err(priv->dev, "invalid GPIO offset: %d\n", offset);
+		return;
+	}
+
+	phy_write(priv->phydev, NCN26000_REG_DIO_CONFIG, dio_reg);
+}
+
+static int ncn26000_gpio_get_dir(struct gpio_chip *gc, unsigned int offset)
+{
+	return GPIO_LINE_DIRECTION_OUT;
+}
+
+static int ncn26000_gpio_dir_out(struct gpio_chip *gc, unsigned int offset,
+				 int val)
+{
+	ncn26000_gpio_set(gc, offset, val);
+	return 0;
+}
+
+static int ncn26000_gpio_setup(struct ncn26000_priv *priv)
+{
+	struct gpio_chip *gc = &priv->gpio_chip;
+
+	gc->request            = ncn26000_gpio_request;
+	gc->get_direction      = ncn26000_gpio_get_dir;
+	gc->direction_output   = ncn26000_gpio_dir_out;
+	gc->set                = ncn26000_gpio_set;
+	gc->label              = "ncn26000-gpio";
+	gc->base               = -1;
+	gc->ngpio              = 2;
+	gc->parent             = priv->dev;
+	gc->owner              = THIS_MODULE;
+
+	return devm_gpiochip_add_data(priv->dev, gc, priv);
+}
+
+static void ncn26000_tweaks_config(struct ncn26000_priv *priv)
+{
+	u16 val = NCN26000_TWEAKS_CD_THRESH(NCN26000_CD_THRESH_DEFAULT) |
+		  NCN26000_TWEAKS_ED_THRESH(NCN26000_ED_THRESH_DEFAULT) |
+		  NCN26000_DIG_SLEW_FAST;
+
+	struct device *dev = &priv->phydev->mdio.dev;
+	const char *s;
+	int ret;
+
+	ret = device_property_read_string(dev, "tx-gain", &s);
+	if (!ret) {
+		dev_info(dev, "tx-gain = %s\n", s);
+		if (strcmp(s, "1v1") == 0)
+			val |= NCN26000_TWEAKS_TX_GAIN(NCN26000_TX_GAIN_1V1);
+		else if (strcmp(s, "0v9") == 0)
+			val |= NCN26000_TWEAKS_TX_GAIN(NCN26000_TX_GAIN_0V9);
+		else if (strcmp(s, "0v8") == 0)
+			val |= NCN26000_TWEAKS_TX_GAIN(NCN26000_TX_GAIN_0V8);
+		else if (strcmp(s, "1v0") != 0)
+			dev_err(dev, "tx-gain is invalid: %s\n", s);
+	}
+
+	ret = device_property_read_string(dev, "tx-slew", &s);
+	if (!ret) {
+		dev_info(dev, "tx-slew = %s\n", s);
+		if (strcmp(s, "fast") == 0)
+			val |= NCN26000_TX_SLEW_FAST;
+		else if (strcmp(s, "slow") != 0)
+			dev_err(dev, "tx-slew is invalid: %s\n", s);
+	}
+
+	ret = device_property_read_string(dev, "dig-slew", &s);
+	if (!ret) {
+		dev_info(dev, "dig-slew = %s\n", s);
+		if (strcmp(s, "slow") == 0)
+			val &= ~NCN26000_DIG_SLEW_FAST;
+		else if (strcmp(s, "fast") != 0)
+			dev_err(dev, "dig-slew is invalid: %s\n", s);
+	}
+
+	ret = device_property_read_string(dev, "cmc-comp", &s);
+	if (!ret) {
+		dev_info(dev, "cmc-comp = %s\n", s);
+		if (strcmp(s, "1p37") == 0)
+			val |= NCN26000_TWEAKS_CMC_COMP(NCN26000_CMC_COMP_1P37);
+		else if (strcmp(s, "3p00") == 0)
+			val |= NCN26000_TWEAKS_CMC_COMP(NCN26000_CMC_COMP_3P00);
+		else if (strcmp(s, "4p37") == 0)
+			val |= NCN26000_TWEAKS_CMC_COMP(NCN26000_CMC_COMP_4P37);
+		else if (strcmp(s, "0p25") != 0)
+			dev_err(dev, "cmc-comp is invalid: %s\n", s);
+	}
+
+	priv->tweaks = val;
+}
+
+static void ncn26000_plcaext_config(struct ncn26000_priv *priv)
+{
+	u16 val = NCN26000_PLCAEXT_MIIEXTDIS;
+
+	if (device_property_read_bool(priv->dev, "plca-precedence")) {
+		dev_info(priv->dev, "PLCA precedence mode enabled\n");
+		val |= NCN26000_PLCAEXT_PRECEDENCE;
+	}
+
+	priv->plcaext = val;
+}
+
+static void ncn26000_phycfg0_config(struct ncn26000_priv *priv)
+{
+	u16 val = NCN26000_PHYCFG1_RX_DLY | NCN26000_PHYCFG1_NO_COL_MASK |
+		  NCN26000_PHYCFG1_UNJAB_TMR;
+
+	struct device *dev = &priv->phydev->mdio.dev;
+	const char *s;
+	int ret;
+
+	priv->eni_mode = ENI_AUTO;
+	ret = device_property_read_string(dev, "eni-mode", &s);
+	if (!ret) {
+		dev_info(dev, "eni-mode = %s\n", s);
+		if (strcmp(s, "force-on") == 0) {
+			priv->eni_mode = ENI_FORCE_ON;
+			val |= NCN26000_PHYCFG1_ENI;
+		} else if (strcmp(s, "force-off") == 0) {
+			priv->eni_mode = ENI_FORCE_OFF;
+		} else if (strcmp(s, "auto") != 0) {
+			dev_err(dev, "eni-mode is invalid: %s\n", s);
+		}
+	}
+
+	if (device_property_read_bool(priv->dev, "tx-pkt-loop")) {
+		dev_info(priv->dev, "TX packet loop enabled\n");
+		val |= NCN26000_PHYCFG1_PKT_LOOP;
+	}
+
+	if (device_property_read_bool(priv->dev, "unjab-tmr-disable")) {
+		dev_info(priv->dev, "unjab timer disabled\n");
+		val &= ~NCN26000_PHYCFG1_UNJAB_TMR;
+	}
+
+	if (device_property_read_bool(priv->dev, "col-disable")) {
+		dev_info(priv->dev, "ENI collision detect disabled\n");
+		val &= ~NCN26000_PHYCFG1_NO_COL_MASK;
+	}
+
+	if (device_property_read_bool(priv->dev, "no-rx-delay")) {
+		dev_info(priv->dev, "RX delay disabled\n");
+		val &= ~NCN26000_PHYCFG1_RX_DLY;
+	}
+
+	priv->phycfg0 = val;
+}
+
+static void ncn26000_dio_config(struct ncn26000_priv *priv)
+{
+	struct device *dev = &priv->phydev->mdio.dev;
+	const char *s;
+	u16 val = 0;
+	int ret;
+
+	ret = device_property_read_string(dev, "dio0-fn", &s);
+	if (!ret) {
+		dev_info(dev, "dio0-fn = %s\n", s);
+		if (strcmp(s, "sfd-tx") == 0)
+			val |= NCN26000_DIO_CFG_FN0(NCN26000_DIO_FN_SFD_TX);
+		else if (strcmp(s, "sfd-rx") == 0)
+			val |= NCN26000_DIO_CFG_FN0(NCN26000_DIO_FN_SFD_RX);
+		else if (strcmp(s, "sfd-rxtx") == 0)
+			val |= NCN26000_DIO_CFG_FN0(NCN26000_DIO_FN_SFD_RXTX);
+		else if (strcmp(s, "led-link") == 0)
+			val |= NCN26000_DIO_CFG_FN0(NCN26000_DIO_FN_LED_LINK);
+		else if (strcmp(s, "led-plca") == 0)
+			val |= NCN26000_DIO_CFG_FN0(NCN26000_DIO_FN_LED_PLCA);
+		else if (strcmp(s, "led-tx") == 0)
+			val |= NCN26000_DIO_CFG_FN0(NCN26000_DIO_FN_LED_TX);
+		else if (strcmp(s, "led-rx") == 0)
+			val |= NCN26000_DIO_CFG_FN0(NCN26000_DIO_FN_LED_RX);
+		else if (strcmp(s, "led-rxtx") == 0)
+			val |= NCN26000_DIO_CFG_FN0(NCN26000_DIO_FN_LED_RXTX);
+		else if (strcmp(s, "clk25m") == 0)
+			val |= NCN26000_DIO_CFG_FN0(NCN26000_DIO_FN_CLK25M);
+		else
+			dev_err(dev, "dio0-fn is invalid: %s\n", s);
+	}
+
+	if (device_property_read_bool(dev, "dio0-pullup"))
+		val |= NCN26000_DIO_CFG_PULL_EN0;
+
+	if (device_property_read_bool(dev, "dio0-active-high"))
+		val |= NCN26000_DIO_CFG_VAL0;
+
+	ret = device_property_read_string(dev, "dio0-slew", &s);
+	if (!ret) {
+		dev_info(dev, "dio0-slew = %s\n", s);
+		if (strcmp(s, "slow") == 0)
+			val |= NCN26000_DIO_CFG_SLEW_RATE0;
+		else if (strcmp(s, "fast") != 0)
+			dev_err(dev, "dio0-slew is invalid: %s\n", s);
+	}
+
+	ret = device_property_read_string(dev, "dio1-fn", &s);
+	if (!ret) {
+		dev_info(dev, "dio1-fn = %s\n", s);
+		if (strcmp(s, "sfd-tx") == 0)
+			val |= NCN26000_DIO_CFG_FN1(NCN26000_DIO_FN_SFD_TX);
+		else if (strcmp(s, "sfd-rx") == 0)
+			val |= NCN26000_DIO_CFG_FN1(NCN26000_DIO_FN_SFD_RX);
+		else if (strcmp(s, "sfd-rxtx") == 0)
+			val |= NCN26000_DIO_CFG_FN1(NCN26000_DIO_FN_SFD_RXTX);
+		else if (strcmp(s, "led-link") == 0)
+			val |= NCN26000_DIO_CFG_FN1(NCN26000_DIO_FN_LED_LINK);
+		else if (strcmp(s, "led-plca") == 0)
+			val |= NCN26000_DIO_CFG_FN1(NCN26000_DIO_FN_LED_PLCA);
+		else if (strcmp(s, "led-tx") == 0)
+			val |= NCN26000_DIO_CFG_FN1(NCN26000_DIO_FN_LED_TX);
+		else if (strcmp(s, "led-rx") == 0)
+			val |= NCN26000_DIO_CFG_FN1(NCN26000_DIO_FN_LED_RX);
+		else if (strcmp(s, "led-rxtx") == 0)
+			val |= NCN26000_DIO_CFG_FN1(NCN26000_DIO_FN_LED_RXTX);
+		else if (strcmp(s, "clk25m") == 0)
+			val |= NCN26000_DIO_CFG_FN1(NCN26000_DIO_FN_CLK25M);
+		else
+			dev_err(dev, "dio1-fn is invalid: %s\n", s);
+	}
+
+	if (device_property_read_bool(dev, "dio1-pullup"))
+		val |= NCN26000_DIO_CFG_PULL_EN1;
+
+	if (device_property_read_bool(dev, "dio1-active-high"))
+		val |= NCN26000_DIO_CFG_VAL1;
+
+	ret = device_property_read_string(dev, "dio1-slew", &s);
+	if (!ret) {
+		dev_info(dev, "dio1-slew = %s\n", s);
+		if (strcmp(s, "slow") == 0)
+			val |= NCN26000_DIO_CFG_SLEW_RATE1;
+		else if (strcmp(s, "fast") != 0)
+			dev_err(dev, "dio1-slew is invalid: %s\n", s);
+	}
+
+	priv->diocfg = val;
+}
 
 static int ncn26000_config_init(struct phy_device *phydev)
 {
+	struct ncn26000_priv *priv = phydev->priv;
+	int ret;
+
+	// configure the DIOx function
+	ret = phy_write(phydev, NCN26000_REG_DIO_CONFIG, priv->diocfg);
+	if (ret)
+		goto out;
+
+	// configure proprietary PHY features
+	ret = phy_write_mmd(phydev, NCN26000_REG_PHYCFG1_MMD,
+			    NCN26000_REG_PHYCFG1, priv->phycfg0);
+	if (ret)
+		goto out;
+
+	// configure the PLCA extensions
+	ret = phy_write_mmd(phydev, NCN26000_REG_PLCAEXT_MMD,
+			    NCN26000_REG_PLCAEXT, priv->plcaext);
+	if (ret)
+		goto out;
+
+	// configure additional PHY tweaks
+	ret = phy_write_mmd(phydev, NCN26000_REG_TWEAKS_MMD,
+			    NCN26000_REG_TWEAKS, priv->tweaks);
+	if (ret)
+		goto out;
+
 	/* HW bug workaround: the default value of the PLCA TO_TIMER should be
 	 * 32, where the current version of NCN26000 reports 24. This will be
 	 * fixed in future PHY versions. For the time being, we force the
 	 * correct default here.
 	 */
-	return phy_write_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_PLCA_TOTMR,
-			     TO_TMR_DEFAULT);
+	ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, MDIO_OATC14_PLCA_TOTMR,
+			    TO_TMR_DEFAULT);
+
+out:
+	return ret;
 }
 
 static int ncn26000_config_aneg(struct phy_device *phydev)
@@ -100,6 +490,36 @@ static int ncn26000_read_status(struct phy_device *phydev)
 	return 0;
 }
 
+static int ncn26000_plca_set_cfg(struct phy_device *phydev,
+				 const struct phy_plca_cfg *plca_cfg)
+{
+	struct ncn26000_priv *priv = phydev->priv;
+	int ret;
+
+	/* We capture calls to PLCA set config to intercept PLCA enable/disable
+	 * requests and set the proprietary ENI mode accordingly
+	 */
+	ret = genphy_c45_plca_set_cfg(phydev, plca_cfg);
+	if (ret || plca_cfg->enabled < 0 || priv->eni_mode != ENI_AUTO)
+		goto out;
+
+	ret = phy_read_mmd(phydev, NCN26000_REG_PHYCFG1_MMD,
+			   NCN26000_REG_PHYCFG1);
+
+	if (ret < 0)
+		goto out;
+
+	if (plca_cfg->enabled)
+		ret |= NCN26000_PHYCFG1_ENI;
+	else
+		ret &= ~NCN26000_PHYCFG1_ENI;
+
+	ret = phy_write_mmd(phydev, NCN26000_REG_PHYCFG1_MMD,
+			    NCN26000_REG_PHYCFG1, ret);
+out:
+	return ret;
+}
+
 static irqreturn_t ncn26000_handle_interrupt(struct phy_device *phydev)
 {
 	int ret;
@@ -140,20 +560,51 @@ static int ncn26000_config_intr(struct phy_device *phydev)
 	return 0;
 }
 
+static int ncn26000_probe(struct phy_device *phydev)
+{
+	struct device *dev = &phydev->mdio.dev;
+	struct ncn26000_priv *priv;
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = dev;
+	priv->phydev = phydev;
+	phydev->priv = priv;
+
+	ncn26000_dio_config(priv);
+	if (priv->gpiomask)
+		ncn26000_gpio_setup(priv);
+
+	ncn26000_phycfg0_config(priv);
+	ncn26000_plcaext_config(priv);
+	ncn26000_tweaks_config(priv);
+
+	return 0;
+}
+
+static void ncn26000_remove(struct phy_device *phydev)
+{
+	kfree(phydev->priv);
+}
+
 static struct phy_driver ncn26000_driver[] = {
 	{
 		PHY_ID_MATCH_MODEL(PHY_ID_NCN26000),
 		.name			= "NCN26000",
 		.features		= PHY_BASIC_T1S_P2MP_FEATURES,
-		.config_init            = ncn26000_config_init,
-		.config_intr            = ncn26000_config_intr,
+		.probe			= ncn26000_probe,
+		.remove			= ncn26000_remove,
+		.config_init		= ncn26000_config_init,
+		.config_intr		= ncn26000_config_intr,
 		.config_aneg		= ncn26000_config_aneg,
 		.read_status		= ncn26000_read_status,
-		.handle_interrupt       = ncn26000_handle_interrupt,
+		.handle_interrupt	= ncn26000_handle_interrupt,
+		.set_plca_cfg		= ncn26000_plca_set_cfg,
 		.get_plca_cfg		= genphy_c45_plca_get_cfg,
-		.set_plca_cfg		= genphy_c45_plca_set_cfg,
 		.get_plca_status	= genphy_c45_plca_get_status,
-		.soft_reset             = genphy_soft_reset,
+		.soft_reset		= genphy_soft_reset,
 	},
 };
 
-- 
2.40.1


             reply	other threads:[~2023-09-18  7:09 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-18  6:59 Jay Monkman [this message]
2023-09-18 10:40 ` [PATCH 3/4] net: phy: Add GPIO and DT support to NCN26000 Vadim Fedorenko
2023-09-18 16:19   ` Andrew Lunn
2023-09-18 16:18 ` Andrew Lunn

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=ZQf1Nx+2amtUZulX@lopingdog.com \
    --to=jtm@lopingdog.com \
    --cc=Arndt.Schuebel@onsemi.com \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=piergiorgio.beruto@gmail.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 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.