xenomai.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* fec driver needs care
@ 2023-04-05  6:30 Jan Kiszka
  2023-04-25  9:08 ` [PATCH 0/1] " Gunter Grau
  0 siblings, 1 reply; 4+ messages in thread
From: Jan Kiszka @ 2023-04-05  6:30 UTC (permalink / raw)
  To: Gunter Grau, Jean-Baptiste Trédez, Xenomai

Hi all,

kernel 6.3 created separate MII callbacks for C22 and C45. This breaks
kernel/drivers/net/drivers/freescale/fec_main.c, see e.g. [1]. We
basically need [2], but with backward compatibility for 6.2 and older.
Could someone have a look, and specifically test that the result still 
works?

Thanks,
Jan

[1] https://source.denx.de/Xenomai/xenomai/-/jobs/608467
[2] https://github.com/torvalds/linux/commit/8d03ad1ab0b052f1f992a52fb80a31b7540b61f6

-- 
Siemens AG, Technology
Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 0/1] Re: fec driver needs care
  2023-04-05  6:30 fec driver needs care Jan Kiszka
@ 2023-04-25  9:08 ` Gunter Grau
  2023-04-25  9:08   ` [PATCH 1/1] rtnet_fec: Get build working with linux 6.3 Gunter Grau
  0 siblings, 1 reply; 4+ messages in thread
From: Gunter Grau @ 2023-04-25  9:08 UTC (permalink / raw)
  To: Xenomai

From: Gunter Grau <gunter.grau@philips.com>

Hi,

we are interested to keep this driver active and so I could spend some
time for porting. 
The patch applies on origin/next and was tested with kernel 5.4 on imx6
and imx7.
With some tweaking also the new c22 path was tested on 5.4 and imx6 and
imx7.
Due to lack of HW I could not test the c45 path.
Also with kernel 6.3 only the build was tested.

Regards,
Gunter

Gunter Grau (1):
  rtnet_fec: Get build working with linux 6.3

 kernel/drivers/net/drivers/freescale/fec.h    |   5 +
 .../drivers/net/drivers/freescale/fec_main.c  | 197 +++++++++++++++++-
 2 files changed, 193 insertions(+), 9 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/1] rtnet_fec: Get build working with linux 6.3
  2023-04-25  9:08 ` [PATCH 0/1] " Gunter Grau
@ 2023-04-25  9:08   ` Gunter Grau
  2023-04-25 11:47     ` Jan Kiszka
  0 siblings, 1 reply; 4+ messages in thread
From: Gunter Grau @ 2023-04-25  9:08 UTC (permalink / raw)
  To: Xenomai

From: Gunter Grau <gunter.grau@philips.com>

Due to separation of C22 and C45 phy access in kernel 6.3 the built
broke. This is the port from the regular freescale fec driver of
following commits:
	8d03ad1ab0b0 net: fec: Separate C22 and C45 transactions
	abc33494ddd5 net: fec: make use of MDIO C45 quirk

In case of older kernels then 6.3 the old implementation will be
used.

Signed-off-by: Gunter Grau <gunter.grau@philips.com>
---
 kernel/drivers/net/drivers/freescale/fec.h    |   5 +
 .../drivers/net/drivers/freescale/fec_main.c  | 197 +++++++++++++++++-
 2 files changed, 193 insertions(+), 9 deletions(-)

diff --git a/kernel/drivers/net/drivers/freescale/fec.h b/kernel/drivers/net/drivers/freescale/fec.h
index 0e2566296..e5c08b349 100644
--- a/kernel/drivers/net/drivers/freescale/fec.h
+++ b/kernel/drivers/net/drivers/freescale/fec.h
@@ -469,6 +469,11 @@ struct bufdesc_ex {
  */
 #define FEC_QUIRK_DELAYED_CLKS_SUPPORT	(1 << 18)
 
+/* Not all FEC hardware block MDIOs support accesses in C45 mode.
+ * Older blocks in the ColdFire parts do not support it.
+ */
+#define FEC_QUIRK_HAS_MDIO_C45		BIT(24)
+
 struct bufdesc_prop {
 	int qid;
 	/* Address of Rx and Tx buffers */
diff --git a/kernel/drivers/net/drivers/freescale/fec_main.c b/kernel/drivers/net/drivers/freescale/fec_main.c
index 5abf5e822..63285bf1b 100644
--- a/kernel/drivers/net/drivers/freescale/fec_main.c
+++ b/kernel/drivers/net/drivers/freescale/fec_main.c
@@ -92,28 +92,32 @@ struct fec_devinfo {
 
 static const struct fec_devinfo fec_imx25_info = {
 	.quirks = FEC_QUIRK_USE_GASKET | FEC_QUIRK_MIB_CLEAR |
-		  FEC_QUIRK_HAS_FRREG,
+		  FEC_QUIRK_HAS_FRREG | FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx27_info = {
-	.quirks = FEC_QUIRK_MIB_CLEAR | FEC_QUIRK_HAS_FRREG,
+	.quirks = FEC_QUIRK_MIB_CLEAR | FEC_QUIRK_HAS_FRREG |
+		  FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx28_info = {
 	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME |
 		  FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC |
-		  FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII,
+		  FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII |
+		  FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx6q_info = {
 	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
 		  FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
 		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
-		  FEC_QUIRK_HAS_RACC | FEC_QUIRK_CLEAR_SETUP_MII,
+		  FEC_QUIRK_HAS_RACC | FEC_QUIRK_CLEAR_SETUP_MII |
+		  FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_mvf600_info = {
-	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC,
+	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC |
+		  FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx6x_info = {
@@ -122,7 +126,7 @@ static const struct fec_devinfo fec_imx6x_info = {
 		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
 		  FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
 		  FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
-		  FEC_QUIRK_CLEAR_SETUP_MII,
+		  FEC_QUIRK_CLEAR_SETUP_MII | FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx6ul_info = {
@@ -130,7 +134,8 @@ static const struct fec_devinfo fec_imx6ul_info = {
 		  FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
 		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR007885 |
 		  FEC_QUIRK_BUG_CAPTURE | FEC_QUIRK_HAS_RACC |
-		  FEC_QUIRK_HAS_COALESCE | FEC_QUIRK_CLEAR_SETUP_MII,
+		  FEC_QUIRK_HAS_COALESCE | FEC_QUIRK_CLEAR_SETUP_MII |
+		  FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx8mq_info = {
@@ -139,7 +144,7 @@ static const struct fec_devinfo fec_imx8mq_info = {
 		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
 		  FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
 		  FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
-		  FEC_QUIRK_CLEAR_SETUP_MII,
+		  FEC_QUIRK_CLEAR_SETUP_MII | FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static const struct fec_devinfo fec_imx8qm_info = {
@@ -148,7 +153,7 @@ static const struct fec_devinfo fec_imx8qm_info = {
 		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
 		  FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
 		  FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
-		  FEC_QUIRK_DELAYED_CLKS_SUPPORT,
+		  FEC_QUIRK_DELAYED_CLKS_SUPPORT | FEC_QUIRK_HAS_MDIO_C45,
 };
 
 static struct platform_device_id fec_devtype[] = {
@@ -1394,6 +1399,7 @@ static int fec_enet_mdio_wait(struct fec_enet_private *fep)
 	return ret;
 }
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0))
 static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 {
 	struct fec_enet_private *fep = bus->priv;
@@ -1504,6 +1510,170 @@ out:
 	return ret;
 }
 
+#else
+
+static int fec_enet_mdio_read_c22(struct mii_bus *bus, int mii_id, int regnum)
+{
+	struct fec_enet_private *fep = bus->priv;
+	struct device *dev = &fep->pdev->dev;
+	int ret = 0, frame_start, frame_addr, frame_op;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret < 0)
+		return ret;
+
+	/* C22 read */
+	frame_op = FEC_MMFR_OP_READ;
+	frame_start = FEC_MMFR_ST;
+	frame_addr = regnum;
+
+	/* start a read op */
+	writel(frame_start | frame_op |
+	       FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(frame_addr) |
+	       FEC_MMFR_TA, fep->hwp + FEC_MII_DATA);
+
+	/* wait for end of transfer */
+	ret = fec_enet_mdio_wait(fep);
+	if (ret) {
+		netdev_err(fep->netdev, "MDIO read timeout\n");
+		goto out;
+	}
+
+	ret = FEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA));
+
+out:
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return ret;
+}
+
+static int fec_enet_mdio_read_c45(struct mii_bus *bus, int mii_id,
+				  int devad, int regnum)
+{
+	struct fec_enet_private *fep = bus->priv;
+	struct device *dev = &fep->pdev->dev;
+	int ret = 0, frame_start, frame_op;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret < 0)
+		return ret;
+
+	frame_start = FEC_MMFR_ST_C45;
+
+	/* write address */
+	writel(frame_start | FEC_MMFR_OP_ADDR_WRITE |
+	       FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(devad) |
+	       FEC_MMFR_TA | (regnum & 0xFFFF),
+	       fep->hwp + FEC_MII_DATA);
+
+	/* wait for end of transfer */
+	ret = fec_enet_mdio_wait(fep);
+	if (ret) {
+		netdev_err(fep->netdev, "MDIO address write timeout\n");
+		goto out;
+	}
+
+	frame_op = FEC_MMFR_OP_READ_C45;
+
+	/* start a read op */
+	writel(frame_start | frame_op |
+	       FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(devad) |
+	       FEC_MMFR_TA, fep->hwp + FEC_MII_DATA);
+
+	/* wait for end of transfer */
+	ret = fec_enet_mdio_wait(fep);
+	if (ret) {
+		netdev_err(fep->netdev, "MDIO read timeout\n");
+		goto out;
+	}
+
+	ret = FEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA));
+
+out:
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return ret;
+}
+
+static int fec_enet_mdio_write_c22(struct mii_bus *bus, int mii_id, int regnum,
+				   u16 value)
+{
+	struct fec_enet_private *fep = bus->priv;
+	struct device *dev = &fep->pdev->dev;
+	int ret, frame_start, frame_addr;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret < 0)
+		return ret;
+
+	/* C22 write */
+	frame_start = FEC_MMFR_ST;
+	frame_addr = regnum;
+
+	/* start a write op */
+	writel(frame_start | FEC_MMFR_OP_WRITE |
+	       FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(frame_addr) |
+	       FEC_MMFR_TA | FEC_MMFR_DATA(value),
+	       fep->hwp + FEC_MII_DATA);
+
+	/* wait for end of transfer */
+	ret = fec_enet_mdio_wait(fep);
+	if (ret)
+		netdev_err(fep->netdev, "MDIO write timeout\n");
+
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return ret;
+}
+
+static int fec_enet_mdio_write_c45(struct mii_bus *bus, int mii_id,
+				   int devad, int regnum, u16 value)
+{
+	struct fec_enet_private *fep = bus->priv;
+	struct device *dev = &fep->pdev->dev;
+	int ret, frame_start;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret < 0)
+		return ret;
+
+	frame_start = FEC_MMFR_ST_C45;
+
+	/* write address */
+	writel(frame_start | FEC_MMFR_OP_ADDR_WRITE |
+	       FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(devad) |
+	       FEC_MMFR_TA | (regnum & 0xFFFF),
+	       fep->hwp + FEC_MII_DATA);
+
+	/* wait for end of transfer */
+	ret = fec_enet_mdio_wait(fep);
+	if (ret) {
+		netdev_err(fep->netdev, "MDIO address write timeout\n");
+		goto out;
+	}
+
+	/* start a write op */
+	writel(frame_start | FEC_MMFR_OP_WRITE |
+	       FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(devad) |
+	       FEC_MMFR_TA | FEC_MMFR_DATA(value),
+	       fep->hwp + FEC_MII_DATA);
+
+	/* wait for end of transfer */
+	ret = fec_enet_mdio_wait(fep);
+	if (ret)
+		netdev_err(fep->netdev, "MDIO write timeout\n");
+
+out:
+	pm_runtime_mark_last_busy(dev);
+	pm_runtime_put_autosuspend(dev);
+
+	return ret;
+}
+#endif
+
 static void fec_enet_phy_reset_after_clk_enable(struct net_device *ndev)
 {
 	struct fec_enet_private *fep = netdev_priv(ndev);
@@ -1750,8 +1920,17 @@ static int fec_enet_mii_init(struct platform_device *pdev)
 	}
 
 	fep->mii_bus->name = "fec_enet_mii_bus";
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0))
 	fep->mii_bus->read = fec_enet_mdio_read;
 	fep->mii_bus->write = fec_enet_mdio_write;
+#else
+	fep->mii_bus->read = fec_enet_mdio_read_c22;
+	fep->mii_bus->write = fec_enet_mdio_write_c22;
+	if (fep->quirks & FEC_QUIRK_HAS_MDIO_C45) {
+		fep->mii_bus->read_c45 = fec_enet_mdio_read_c45;
+		fep->mii_bus->write_c45 = fec_enet_mdio_write_c45;
+	}
+#endif
 	snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
 		pdev->name, fep->dev_id + 1);
 	fep->mii_bus->priv = fep;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/1] rtnet_fec: Get build working with linux 6.3
  2023-04-25  9:08   ` [PATCH 1/1] rtnet_fec: Get build working with linux 6.3 Gunter Grau
@ 2023-04-25 11:47     ` Jan Kiszka
  0 siblings, 0 replies; 4+ messages in thread
From: Jan Kiszka @ 2023-04-25 11:47 UTC (permalink / raw)
  To: Gunter Grau, Xenomai

On 25.04.23 11:08, Gunter Grau wrote:
> From: Gunter Grau <gunter.grau@philips.com>
> 
> Due to separation of C22 and C45 phy access in kernel 6.3 the built
> broke. This is the port from the regular freescale fec driver of
> following commits:
> 	8d03ad1ab0b0 net: fec: Separate C22 and C45 transactions
> 	abc33494ddd5 net: fec: make use of MDIO C45 quirk
> 
> In case of older kernels then 6.3 the old implementation will be
> used.
> 
> Signed-off-by: Gunter Grau <gunter.grau@philips.com>
> ---
>  kernel/drivers/net/drivers/freescale/fec.h    |   5 +
>  .../drivers/net/drivers/freescale/fec_main.c  | 197 +++++++++++++++++-
>  2 files changed, 193 insertions(+), 9 deletions(-)
> 
> diff --git a/kernel/drivers/net/drivers/freescale/fec.h b/kernel/drivers/net/drivers/freescale/fec.h
> index 0e2566296..e5c08b349 100644
> --- a/kernel/drivers/net/drivers/freescale/fec.h
> +++ b/kernel/drivers/net/drivers/freescale/fec.h
> @@ -469,6 +469,11 @@ struct bufdesc_ex {
>   */
>  #define FEC_QUIRK_DELAYED_CLKS_SUPPORT	(1 << 18)
>  
> +/* Not all FEC hardware block MDIOs support accesses in C45 mode.
> + * Older blocks in the ColdFire parts do not support it.
> + */
> +#define FEC_QUIRK_HAS_MDIO_C45		BIT(24)
> +
>  struct bufdesc_prop {
>  	int qid;
>  	/* Address of Rx and Tx buffers */
> diff --git a/kernel/drivers/net/drivers/freescale/fec_main.c b/kernel/drivers/net/drivers/freescale/fec_main.c
> index 5abf5e822..63285bf1b 100644
> --- a/kernel/drivers/net/drivers/freescale/fec_main.c
> +++ b/kernel/drivers/net/drivers/freescale/fec_main.c
> @@ -92,28 +92,32 @@ struct fec_devinfo {
>  
>  static const struct fec_devinfo fec_imx25_info = {
>  	.quirks = FEC_QUIRK_USE_GASKET | FEC_QUIRK_MIB_CLEAR |
> -		  FEC_QUIRK_HAS_FRREG,
> +		  FEC_QUIRK_HAS_FRREG | FEC_QUIRK_HAS_MDIO_C45,
>  };
>  
>  static const struct fec_devinfo fec_imx27_info = {
> -	.quirks = FEC_QUIRK_MIB_CLEAR | FEC_QUIRK_HAS_FRREG,
> +	.quirks = FEC_QUIRK_MIB_CLEAR | FEC_QUIRK_HAS_FRREG |
> +		  FEC_QUIRK_HAS_MDIO_C45,
>  };
>  
>  static const struct fec_devinfo fec_imx28_info = {
>  	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME |
>  		  FEC_QUIRK_SINGLE_MDIO | FEC_QUIRK_HAS_RACC |
> -		  FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII,
> +		  FEC_QUIRK_HAS_FRREG | FEC_QUIRK_CLEAR_SETUP_MII |
> +		  FEC_QUIRK_HAS_MDIO_C45,
>  };
>  
>  static const struct fec_devinfo fec_imx6q_info = {
>  	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
>  		  FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
>  		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
> -		  FEC_QUIRK_HAS_RACC | FEC_QUIRK_CLEAR_SETUP_MII,
> +		  FEC_QUIRK_HAS_RACC | FEC_QUIRK_CLEAR_SETUP_MII |
> +		  FEC_QUIRK_HAS_MDIO_C45,
>  };
>  
>  static const struct fec_devinfo fec_mvf600_info = {
> -	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC,
> +	.quirks = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_RACC |
> +		  FEC_QUIRK_HAS_MDIO_C45,
>  };
>  
>  static const struct fec_devinfo fec_imx6x_info = {
> @@ -122,7 +126,7 @@ static const struct fec_devinfo fec_imx6x_info = {
>  		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
>  		  FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
>  		  FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
> -		  FEC_QUIRK_CLEAR_SETUP_MII,
> +		  FEC_QUIRK_CLEAR_SETUP_MII | FEC_QUIRK_HAS_MDIO_C45,
>  };
>  
>  static const struct fec_devinfo fec_imx6ul_info = {
> @@ -130,7 +134,8 @@ static const struct fec_devinfo fec_imx6ul_info = {
>  		  FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
>  		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR007885 |
>  		  FEC_QUIRK_BUG_CAPTURE | FEC_QUIRK_HAS_RACC |
> -		  FEC_QUIRK_HAS_COALESCE | FEC_QUIRK_CLEAR_SETUP_MII,
> +		  FEC_QUIRK_HAS_COALESCE | FEC_QUIRK_CLEAR_SETUP_MII |
> +		  FEC_QUIRK_HAS_MDIO_C45,
>  };
>  
>  static const struct fec_devinfo fec_imx8mq_info = {
> @@ -139,7 +144,7 @@ static const struct fec_devinfo fec_imx8mq_info = {
>  		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
>  		  FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
>  		  FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
> -		  FEC_QUIRK_CLEAR_SETUP_MII,
> +		  FEC_QUIRK_CLEAR_SETUP_MII | FEC_QUIRK_HAS_MDIO_C45,
>  };
>  
>  static const struct fec_devinfo fec_imx8qm_info = {
> @@ -148,7 +153,7 @@ static const struct fec_devinfo fec_imx8qm_info = {
>  		  FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
>  		  FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
>  		  FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE |
> -		  FEC_QUIRK_DELAYED_CLKS_SUPPORT,
> +		  FEC_QUIRK_DELAYED_CLKS_SUPPORT | FEC_QUIRK_HAS_MDIO_C45,
>  };
>  
>  static struct platform_device_id fec_devtype[] = {
> @@ -1394,6 +1399,7 @@ static int fec_enet_mdio_wait(struct fec_enet_private *fep)
>  	return ret;
>  }
>  
> +#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0))
>  static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
>  {
>  	struct fec_enet_private *fep = bus->priv;
> @@ -1504,6 +1510,170 @@ out:
>  	return ret;
>  }
>  
> +#else
> +
> +static int fec_enet_mdio_read_c22(struct mii_bus *bus, int mii_id, int regnum)
> +{
> +	struct fec_enet_private *fep = bus->priv;
> +	struct device *dev = &fep->pdev->dev;
> +	int ret = 0, frame_start, frame_addr, frame_op;
> +
> +	ret = pm_runtime_resume_and_get(dev);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* C22 read */
> +	frame_op = FEC_MMFR_OP_READ;
> +	frame_start = FEC_MMFR_ST;
> +	frame_addr = regnum;
> +
> +	/* start a read op */
> +	writel(frame_start | frame_op |
> +	       FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(frame_addr) |
> +	       FEC_MMFR_TA, fep->hwp + FEC_MII_DATA);
> +
> +	/* wait for end of transfer */
> +	ret = fec_enet_mdio_wait(fep);
> +	if (ret) {
> +		netdev_err(fep->netdev, "MDIO read timeout\n");
> +		goto out;
> +	}
> +
> +	ret = FEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA));
> +
> +out:
> +	pm_runtime_mark_last_busy(dev);
> +	pm_runtime_put_autosuspend(dev);
> +
> +	return ret;
> +}
> +
> +static int fec_enet_mdio_read_c45(struct mii_bus *bus, int mii_id,
> +				  int devad, int regnum)
> +{
> +	struct fec_enet_private *fep = bus->priv;
> +	struct device *dev = &fep->pdev->dev;
> +	int ret = 0, frame_start, frame_op;
> +
> +	ret = pm_runtime_resume_and_get(dev);
> +	if (ret < 0)
> +		return ret;
> +
> +	frame_start = FEC_MMFR_ST_C45;
> +
> +	/* write address */
> +	writel(frame_start | FEC_MMFR_OP_ADDR_WRITE |
> +	       FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(devad) |
> +	       FEC_MMFR_TA | (regnum & 0xFFFF),
> +	       fep->hwp + FEC_MII_DATA);
> +
> +	/* wait for end of transfer */
> +	ret = fec_enet_mdio_wait(fep);
> +	if (ret) {
> +		netdev_err(fep->netdev, "MDIO address write timeout\n");
> +		goto out;
> +	}
> +
> +	frame_op = FEC_MMFR_OP_READ_C45;
> +
> +	/* start a read op */
> +	writel(frame_start | frame_op |
> +	       FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(devad) |
> +	       FEC_MMFR_TA, fep->hwp + FEC_MII_DATA);
> +
> +	/* wait for end of transfer */
> +	ret = fec_enet_mdio_wait(fep);
> +	if (ret) {
> +		netdev_err(fep->netdev, "MDIO read timeout\n");
> +		goto out;
> +	}
> +
> +	ret = FEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA));
> +
> +out:
> +	pm_runtime_mark_last_busy(dev);
> +	pm_runtime_put_autosuspend(dev);
> +
> +	return ret;
> +}
> +
> +static int fec_enet_mdio_write_c22(struct mii_bus *bus, int mii_id, int regnum,
> +				   u16 value)
> +{
> +	struct fec_enet_private *fep = bus->priv;
> +	struct device *dev = &fep->pdev->dev;
> +	int ret, frame_start, frame_addr;
> +
> +	ret = pm_runtime_resume_and_get(dev);
> +	if (ret < 0)
> +		return ret;
> +
> +	/* C22 write */
> +	frame_start = FEC_MMFR_ST;
> +	frame_addr = regnum;
> +
> +	/* start a write op */
> +	writel(frame_start | FEC_MMFR_OP_WRITE |
> +	       FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(frame_addr) |
> +	       FEC_MMFR_TA | FEC_MMFR_DATA(value),
> +	       fep->hwp + FEC_MII_DATA);
> +
> +	/* wait for end of transfer */
> +	ret = fec_enet_mdio_wait(fep);
> +	if (ret)
> +		netdev_err(fep->netdev, "MDIO write timeout\n");
> +
> +	pm_runtime_mark_last_busy(dev);
> +	pm_runtime_put_autosuspend(dev);
> +
> +	return ret;
> +}
> +
> +static int fec_enet_mdio_write_c45(struct mii_bus *bus, int mii_id,
> +				   int devad, int regnum, u16 value)
> +{
> +	struct fec_enet_private *fep = bus->priv;
> +	struct device *dev = &fep->pdev->dev;
> +	int ret, frame_start;
> +
> +	ret = pm_runtime_resume_and_get(dev);
> +	if (ret < 0)
> +		return ret;
> +
> +	frame_start = FEC_MMFR_ST_C45;
> +
> +	/* write address */
> +	writel(frame_start | FEC_MMFR_OP_ADDR_WRITE |
> +	       FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(devad) |
> +	       FEC_MMFR_TA | (regnum & 0xFFFF),
> +	       fep->hwp + FEC_MII_DATA);
> +
> +	/* wait for end of transfer */
> +	ret = fec_enet_mdio_wait(fep);
> +	if (ret) {
> +		netdev_err(fep->netdev, "MDIO address write timeout\n");
> +		goto out;
> +	}
> +
> +	/* start a write op */
> +	writel(frame_start | FEC_MMFR_OP_WRITE |
> +	       FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(devad) |
> +	       FEC_MMFR_TA | FEC_MMFR_DATA(value),
> +	       fep->hwp + FEC_MII_DATA);
> +
> +	/* wait for end of transfer */
> +	ret = fec_enet_mdio_wait(fep);
> +	if (ret)
> +		netdev_err(fep->netdev, "MDIO write timeout\n");
> +
> +out:
> +	pm_runtime_mark_last_busy(dev);
> +	pm_runtime_put_autosuspend(dev);
> +
> +	return ret;
> +}
> +#endif
> +
>  static void fec_enet_phy_reset_after_clk_enable(struct net_device *ndev)
>  {
>  	struct fec_enet_private *fep = netdev_priv(ndev);
> @@ -1750,8 +1920,17 @@ static int fec_enet_mii_init(struct platform_device *pdev)
>  	}
>  
>  	fep->mii_bus->name = "fec_enet_mii_bus";
> +#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 3, 0))
>  	fep->mii_bus->read = fec_enet_mdio_read;
>  	fep->mii_bus->write = fec_enet_mdio_write;
> +#else
> +	fep->mii_bus->read = fec_enet_mdio_read_c22;
> +	fep->mii_bus->write = fec_enet_mdio_write_c22;
> +	if (fep->quirks & FEC_QUIRK_HAS_MDIO_C45) {
> +		fep->mii_bus->read_c45 = fec_enet_mdio_read_c45;
> +		fep->mii_bus->write_c45 = fec_enet_mdio_write_c45;
> +	}
> +#endif
>  	snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
>  		pdev->name, fep->dev_id + 1);
>  	fep->mii_bus->priv = fep;

Thanks for the patch!

I was just wondering if we could do fec_enet_mdio_read via a wrapper
that either calls fec_enet_mdio_read_c22 or fec_enet_mdio_read_c45
(write likewise). Would save code and ensure that the old code would
directly benefit from changes on the new callbacks.

Jan

-- 
Siemens AG, Technology
Competence Center Embedded Linux


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-04-25 11:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-04-05  6:30 fec driver needs care Jan Kiszka
2023-04-25  9:08 ` [PATCH 0/1] " Gunter Grau
2023-04-25  9:08   ` [PATCH 1/1] rtnet_fec: Get build working with linux 6.3 Gunter Grau
2023-04-25 11:47     ` Jan Kiszka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).