diff mbox series

[net-next,1/7] net: korina: Fix MDIO functions

Message ID 20210413204818.23350-2-tsbogend@alpha.franken.de (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series net: Korina improvements | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count success Link
netdev/tree_selection success Clearly marked for net-next
netdev/subject_prefix success Link
netdev/cc_maintainers warning 5 maintainers not CCed: rppt@kernel.org vvidic@valentin-vidic.from.hr akpm@linux-foundation.org vincent.stehle@laposte.net willemb@google.com
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success Link
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 107 lines checked
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/header_inline success Link

Commit Message

Thomas Bogendoerfer April 13, 2021, 8:48 p.m. UTC
Fixed MDIO functions to work reliable and not just by accident.

Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
 drivers/net/ethernet/korina.c | 57 +++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 19 deletions(-)

Comments

Andrew Lunn April 14, 2021, 7:36 p.m. UTC | #1
> +static int korina_mdio_wait(struct korina_private *lp)
> +{
> +	int timeout = 1000;
> +
> +	while ((readl(&lp->eth_regs->miimind) & 1) && timeout-- > 0)
> +		udelay(1);
> +
> +	if (timeout <= 0)
> +		return -1;
> +
> +	return 0;

Using readl_poll_timeout_atomic() would be better.


> +}
> +
> +static int korina_mdio_read(struct net_device *dev, int phy, int reg)
>  {
>  	struct korina_private *lp = netdev_priv(dev);
>  	int ret;
>  
> -	mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
> +	if (korina_mdio_wait(lp))
> +		return -1;

This should really be -ETIMEDOUT

>  	dev->watchdog_timeo = TX_TIMEOUT;
>  	netif_napi_add(dev, &lp->napi, korina_poll, NAPI_POLL_WEIGHT);
>  
> -	lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
>  	lp->mii_if.dev = dev;
> -	lp->mii_if.mdio_read = mdio_read;
> -	lp->mii_if.mdio_write = mdio_write;
> -	lp->mii_if.phy_id = lp->phy_addr;
> +	lp->mii_if.mdio_read = korina_mdio_read;
> +	lp->mii_if.mdio_write = korina_mdio_write;
> +	lp->mii_if.phy_id = 1;
>  	lp->mii_if.phy_id_mask = 0x1f;
>  	lp->mii_if.reg_num_mask = 0x1f;

You could also replace all the mii code with phylib.

    Andrew
Thomas Bogendoerfer April 14, 2021, 8:36 p.m. UTC | #2
On Wed, Apr 14, 2021 at 09:36:04PM +0200, Andrew Lunn wrote:
> > +static int korina_mdio_wait(struct korina_private *lp)
> > +{
> > +	int timeout = 1000;
> > +
> > +	while ((readl(&lp->eth_regs->miimind) & 1) && timeout-- > 0)
> > +		udelay(1);
> > +
> > +	if (timeout <= 0)
> > +		return -1;
> > +
> > +	return 0;
> 
> Using readl_poll_timeout_atomic() would be better.

I'll have a look

> 
> 
> > +}
> > +
> > +static int korina_mdio_read(struct net_device *dev, int phy, int reg)
> >  {
> >  	struct korina_private *lp = netdev_priv(dev);
> >  	int ret;
> >  
> > -	mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
> > +	if (korina_mdio_wait(lp))
> > +		return -1;
> 
> This should really be -ETIMEDOUT

ok.

> >  	dev->watchdog_timeo = TX_TIMEOUT;
> >  	netif_napi_add(dev, &lp->napi, korina_poll, NAPI_POLL_WEIGHT);
> >  
> > -	lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
> >  	lp->mii_if.dev = dev;
> > -	lp->mii_if.mdio_read = mdio_read;
> > -	lp->mii_if.mdio_write = mdio_write;
> > -	lp->mii_if.phy_id = lp->phy_addr;
> > +	lp->mii_if.mdio_read = korina_mdio_read;
> > +	lp->mii_if.mdio_write = korina_mdio_write;
> > +	lp->mii_if.phy_id = 1;
> >  	lp->mii_if.phy_id_mask = 0x1f;
> >  	lp->mii_if.reg_num_mask = 0x1f;
> 
> You could also replace all the mii code with phylib.

that's on my todo.

Thomas.
diff mbox series

Patch

diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c
index 925161959b9b..2266b18c1377 100644
--- a/drivers/net/ethernet/korina.c
+++ b/drivers/net/ethernet/korina.c
@@ -137,7 +137,6 @@  struct korina_private {
 	struct mii_if_info mii_if;
 	struct work_struct restart_task;
 	struct net_device *dev;
-	int phy_addr;
 };
 
 extern unsigned int idt_cpu_freq;
@@ -292,32 +291,50 @@  static int korina_send_packet(struct sk_buff *skb, struct net_device *dev)
 	return NETDEV_TX_OK;
 }
 
-static int mdio_read(struct net_device *dev, int mii_id, int reg)
+static int korina_mdio_wait(struct korina_private *lp)
+{
+	int timeout = 1000;
+
+	while ((readl(&lp->eth_regs->miimind) & 1) && timeout-- > 0)
+		udelay(1);
+
+	if (timeout <= 0)
+		return -1;
+
+	return 0;
+}
+
+static int korina_mdio_read(struct net_device *dev, int phy, int reg)
 {
 	struct korina_private *lp = netdev_priv(dev);
 	int ret;
 
-	mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+	if (korina_mdio_wait(lp))
+		return -1;
 
-	writel(0, &lp->eth_regs->miimcfg);
-	writel(0, &lp->eth_regs->miimcmd);
-	writel(mii_id | reg, &lp->eth_regs->miimaddr);
-	writel(ETH_MII_CMD_SCN, &lp->eth_regs->miimcmd);
+	writel(phy << 8 | reg, &lp->eth_regs->miimaddr);
+	writel(1, &lp->eth_regs->miimcmd);
 
-	ret = (int)(readl(&lp->eth_regs->miimrdd));
+	if (korina_mdio_wait(lp))
+		return -1;
+
+	if (readl(&lp->eth_regs->miimind) & 4)
+		return -1;
+
+	ret = readl(&lp->eth_regs->miimrdd);
+	writel(0, &lp->eth_regs->miimcmd);
 	return ret;
 }
 
-static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
+static void korina_mdio_write(struct net_device *dev, int phy, int reg, int val)
 {
 	struct korina_private *lp = netdev_priv(dev);
 
-	mii_id = ((lp->rx_irq == 0x2c ? 1 : 0) << 8);
+	if (korina_mdio_wait(lp))
+		return;
 
-	writel(0, &lp->eth_regs->miimcfg);
-	writel(1, &lp->eth_regs->miimcmd);
-	writel(mii_id | reg, &lp->eth_regs->miimaddr);
-	writel(ETH_MII_CMD_SCN, &lp->eth_regs->miimcmd);
+	writel(0, &lp->eth_regs->miimcmd);
+	writel(phy << 8 | reg, &lp->eth_regs->miimaddr);
 	writel(val, &lp->eth_regs->miimwtd);
 }
 
@@ -643,7 +660,7 @@  static void korina_check_media(struct net_device *dev, unsigned int init_media)
 {
 	struct korina_private *lp = netdev_priv(dev);
 
-	mii_check_media(&lp->mii_if, 0, init_media);
+	mii_check_media(&lp->mii_if, 1, init_media);
 
 	if (lp->mii_if.full_duplex)
 		writel(readl(&lp->eth_regs->ethmac2) | ETH_MAC2_FD,
@@ -869,12 +886,15 @@  static int korina_init(struct net_device *dev)
 	 * Clock independent setting */
 	writel(((idt_cpu_freq) / MII_CLOCK + 1) & ~1,
 			&lp->eth_regs->ethmcp);
+	writel(0, &lp->eth_regs->miimcfg);
 
 	/* don't transmit until fifo contains 48b */
 	writel(48, &lp->eth_regs->ethfifott);
 
 	writel(ETH_MAC1_RE, &lp->eth_regs->ethmac1);
 
+	korina_check_media(dev, 1);
+
 	napi_enable(&lp->napi);
 	netif_start_queue(dev);
 
@@ -1089,11 +1109,10 @@  static int korina_probe(struct platform_device *pdev)
 	dev->watchdog_timeo = TX_TIMEOUT;
 	netif_napi_add(dev, &lp->napi, korina_poll, NAPI_POLL_WEIGHT);
 
-	lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
 	lp->mii_if.dev = dev;
-	lp->mii_if.mdio_read = mdio_read;
-	lp->mii_if.mdio_write = mdio_write;
-	lp->mii_if.phy_id = lp->phy_addr;
+	lp->mii_if.mdio_read = korina_mdio_read;
+	lp->mii_if.mdio_write = korina_mdio_write;
+	lp->mii_if.phy_id = 1;
 	lp->mii_if.phy_id_mask = 0x1f;
 	lp->mii_if.reg_num_mask = 0x1f;