linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial
@ 2013-03-27 12:09 Joseph CHANG
  2013-03-27 12:09 ` [PATCH 2/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial patch2 Joseph CHANG
  2013-03-27 13:14 ` [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial Denis Kirjanov
  0 siblings, 2 replies; 4+ messages in thread
From: Joseph CHANG @ 2013-03-27 12:09 UTC (permalink / raw)
  To: David S. Miller, Bill Pemberton, Matthew Leach,
	Greg Kroah-Hartman, Joseph CHANG, Jiri Pirko, netdev
  Cc: linux-kernel, Joseph CHANG

Fixing bug for DM9000B(DSP) which is a DSP revision! 3rd trial.

Tested to Davicom DM9000 series include DM9000E(analog),
DM9000A(analog), DM9000B(DSP), and DM9000C(DSP) in X86 and
ARM Embedded Linux these years.

Signed-off-by: Joseph CHANG <josright123@gmail.com>
---
 drivers/net/ethernet/davicom/dm9000.c |  219 +++++++++++++++++----------------
 drivers/net/ethernet/davicom/dm9000.h |   11 ++-
 2 files changed, 124 insertions(+), 106 deletions(-)

diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c
index 8cdf025..9dd4bd6 100644
--- a/drivers/net/ethernet/davicom/dm9000.c
+++ b/drivers/net/ethernet/davicom/dm9000.c
@@ -47,7 +47,7 @@
 #define DM9000_PHY		0x40	/* PHY address 0x01 */
 
 #define CARDNAME	"dm9000"
-#define DRV_VERSION	"1.31"
+#define DRV_VERSION	"1.39"
 
 /*
  * Transmit timeout, default 5 seconds.
@@ -257,6 +257,109 @@ static void dm9000_dumpblk_32bit(void __iomem *reg, int count)
 		tmp = readl(reg);
 }
 
+/*
+ * Sleep, either by using msleep() or if we are suspending, then
+ * use mdelay() to sleep.
+ */
+static void dm9000_msleep(board_info_t *db, unsigned int ms)
+{
+	if (db->in_suspend)
+		mdelay(ms);
+	else
+		msleep(ms);
+}
+
+/*
+ *   Read a word from phyxcer
+ */
+static int
+dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
+{
+	board_info_t *db = netdev_priv(dev);
+	unsigned long flags;
+	unsigned int reg_save;
+	int ret;
+
+	mutex_lock(&db->addr_lock);
+
+	spin_lock_irqsave(&db->lock,flags);
+
+	/* Save previous register address */
+	reg_save = readb(db->io_addr);
+
+	/* Fill the phyxcer register into REG_0C */
+	iow(db, DM9000_EPAR, DM9000_PHY | reg);
+
+	iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);	/* Issue phyxcer read command */
+
+	writeb(reg_save, db->io_addr);
+	spin_unlock_irqrestore(&db->lock,flags);
+
+	dm9000_msleep(db, 1);		/* Wait read complete */
+
+	spin_lock_irqsave(&db->lock,flags);
+	reg_save = readb(db->io_addr);
+
+	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer read command */
+
+	/* The read data keeps on REG_0D & REG_0E */
+	ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
+
+	/* restore the previous address */
+	writeb(reg_save, db->io_addr);
+	spin_unlock_irqrestore(&db->lock,flags);
+
+	mutex_unlock(&db->addr_lock);
+
+	dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
+	return ret;
+}
+
+/*
+ *   Write a word to phyxcer
+ */
+static void
+dm9000_phy_write(struct net_device *dev,
+		 int phyaddr_unused, int reg, int value)
+{
+	board_info_t *db = netdev_priv(dev);
+	unsigned long flags;
+	unsigned long reg_save;
+
+	dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
+	mutex_lock(&db->addr_lock);
+
+	spin_lock_irqsave(&db->lock,flags);
+
+	/* Save previous register address */
+	reg_save = readb(db->io_addr);
+
+	/* Fill the phyxcer register into REG_0C */
+	iow(db, DM9000_EPAR, DM9000_PHY | reg);
+
+	/* Fill the written data into REG_0D & REG_0E */
+	iow(db, DM9000_EPDRL, value);
+	iow(db, DM9000_EPDRH, value >> 8);
+
+	iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);	/* Issue phyxcer write command */
+
+	writeb(reg_save, db->io_addr);
+	spin_unlock_irqrestore(&db->lock, flags);
+
+	dm9000_msleep(db, 1);		/* Wait write complete */
+
+	spin_lock_irqsave(&db->lock,flags);
+	reg_save = readb(db->io_addr);
+
+	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer write command */
+
+	/* restore the previous address */
+	writeb(reg_save, db->io_addr);
+
+	spin_unlock_irqrestore(&db->lock, flags);
+	mutex_unlock(&db->addr_lock);
+}
+
 /* dm9000_set_io
  *
  * select the specified set of io routines to use with the
@@ -795,6 +898,8 @@ dm9000_init_dm9000(struct net_device *dev)
 
 	iow(db, DM9000_GPCR, GPCR_GEP_CNTL);	/* Let GPIO0 output */
 
+	dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
+
 	ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0;
 
 	/* if wol is needed, then always set NCR_WAKEEN otherwise we end
@@ -830,6 +935,8 @@ dm9000_init_dm9000(struct net_device *dev)
 	db->tx_pkt_cnt = 0;
 	db->queue_pkt_len = 0;
 	dev->trans_start = jiffies;
+
+	dm9000_phy_write(dev, 0, MII_DM_DSPCR, DSPCR_INIT_PARAM); /* Init */
 }
 
 /* Our watchdog timed out. Called by the networking layer */
@@ -1201,109 +1308,6 @@ dm9000_open(struct net_device *dev)
 	return 0;
 }
 
-/*
- * Sleep, either by using msleep() or if we are suspending, then
- * use mdelay() to sleep.
- */
-static void dm9000_msleep(board_info_t *db, unsigned int ms)
-{
-	if (db->in_suspend)
-		mdelay(ms);
-	else
-		msleep(ms);
-}
-
-/*
- *   Read a word from phyxcer
- */
-static int
-dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
-{
-	board_info_t *db = netdev_priv(dev);
-	unsigned long flags;
-	unsigned int reg_save;
-	int ret;
-
-	mutex_lock(&db->addr_lock);
-
-	spin_lock_irqsave(&db->lock,flags);
-
-	/* Save previous register address */
-	reg_save = readb(db->io_addr);
-
-	/* Fill the phyxcer register into REG_0C */
-	iow(db, DM9000_EPAR, DM9000_PHY | reg);
-
-	iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);	/* Issue phyxcer read command */
-
-	writeb(reg_save, db->io_addr);
-	spin_unlock_irqrestore(&db->lock,flags);
-
-	dm9000_msleep(db, 1);		/* Wait read complete */
-
-	spin_lock_irqsave(&db->lock,flags);
-	reg_save = readb(db->io_addr);
-
-	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer read command */
-
-	/* The read data keeps on REG_0D & REG_0E */
-	ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
-
-	/* restore the previous address */
-	writeb(reg_save, db->io_addr);
-	spin_unlock_irqrestore(&db->lock,flags);
-
-	mutex_unlock(&db->addr_lock);
-
-	dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
-	return ret;
-}
-
-/*
- *   Write a word to phyxcer
- */
-static void
-dm9000_phy_write(struct net_device *dev,
-		 int phyaddr_unused, int reg, int value)
-{
-	board_info_t *db = netdev_priv(dev);
-	unsigned long flags;
-	unsigned long reg_save;
-
-	dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
-	mutex_lock(&db->addr_lock);
-
-	spin_lock_irqsave(&db->lock,flags);
-
-	/* Save previous register address */
-	reg_save = readb(db->io_addr);
-
-	/* Fill the phyxcer register into REG_0C */
-	iow(db, DM9000_EPAR, DM9000_PHY | reg);
-
-	/* Fill the written data into REG_0D & REG_0E */
-	iow(db, DM9000_EPDRL, value);
-	iow(db, DM9000_EPDRH, value >> 8);
-
-	iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);	/* Issue phyxcer write command */
-
-	writeb(reg_save, db->io_addr);
-	spin_unlock_irqrestore(&db->lock, flags);
-
-	dm9000_msleep(db, 1);		/* Wait write complete */
-
-	spin_lock_irqsave(&db->lock,flags);
-	reg_save = readb(db->io_addr);
-
-	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer write command */
-
-	/* restore the previous address */
-	writeb(reg_save, db->io_addr);
-
-	spin_unlock_irqrestore(&db->lock, flags);
-	mutex_unlock(&db->addr_lock);
-}
-
 static void
 dm9000_shutdown(struct net_device *dev)
 {
@@ -1502,7 +1506,12 @@ dm9000_probe(struct platform_device *pdev)
 	db->flags |= DM9000_PLATF_SIMPLE_PHY;
 #endif
 
-	dm9000_reset(db);
+	/* Fixing bug on dm9000_probe, takeover dm9000_reset(db),
+	 * Need 'NCR_MAC_LBK' bit to indeed stable our DM9000 fifo
+	 * while probe stage.
+	 */
+
+	iow(db, DM9000_NCR, NCR_MAC_LBK | NCR_RST);
 
 	/* try multiple times, DM9000 sometimes gets the read wrong */
 	for (i = 0; i < 8; i++) {
diff --git a/drivers/net/ethernet/davicom/dm9000.h b/drivers/net/ethernet/davicom/dm9000.h
index 55688bd..9ce058a 100644
--- a/drivers/net/ethernet/davicom/dm9000.h
+++ b/drivers/net/ethernet/davicom/dm9000.h
@@ -69,7 +69,9 @@
 #define NCR_WAKEEN          (1<<6)
 #define NCR_FCOL            (1<<4)
 #define NCR_FDX             (1<<3)
-#define NCR_LBK             (3<<1)
+
+#define NCR_RESERVED        (3<<1)
+#define NCR_MAC_LBK         (1<<1)
 #define NCR_RST	            (1<<0)
 
 #define NSR_SPEED           (1<<7)
@@ -167,5 +169,12 @@
 #define ISR_LNKCHNG		(1<<5)
 #define ISR_UNDERRUN		(1<<4)
 
+/* Davicom MII registers.
+ */
+
+#define MII_DM_DSPCR		0x1b    /* DSP Control Register */
+
+#define DSPCR_INIT_PARAM	0xE100	/* DSP init parameter */
+
 #endif /* _DM9000X_H_ */
 
-- 
1.7.1


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

* [PATCH 2/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial patch2
  2013-03-27 12:09 [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial Joseph CHANG
@ 2013-03-27 12:09 ` Joseph CHANG
  2013-03-27 13:14 ` [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial Denis Kirjanov
  1 sibling, 0 replies; 4+ messages in thread
From: Joseph CHANG @ 2013-03-27 12:09 UTC (permalink / raw)
  To: David S. Miller, Bill Pemberton, Matthew Leach,
	Greg Kroah-Hartman, Joseph CHANG, Jiri Pirko, netdev
  Cc: linux-kernel, Joseph CHANG

Fixing bug for DM9000B(DSP) patch2

Tested to Davicom DM9000E, DM9000A, DM9000B(DSP),
and DM9000C(DSP) patch2

Signed-off-by: Joseph CHANG <josright123@gmail.com>
---
 drivers/net/ethernet/davicom/dm9000.c |   26 ++++++++++++--------------
 1 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c
index 9dd4bd6..a5cd4ad 100644
--- a/drivers/net/ethernet/davicom/dm9000.c
+++ b/drivers/net/ethernet/davicom/dm9000.c
@@ -269,9 +269,7 @@ static void dm9000_msleep(board_info_t *db, unsigned int ms)
 		msleep(ms);
 }
 
-/*
- *   Read a word from phyxcer
- */
+/* Read a word from phyxcer */
 static int
 dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
 {
@@ -282,7 +280,7 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
 
 	mutex_lock(&db->addr_lock);
 
-	spin_lock_irqsave(&db->lock,flags);
+	spin_lock_irqsave(&db->lock, flags);
 
 	/* Save previous register address */
 	reg_save = readb(db->io_addr);
@@ -290,14 +288,15 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
 	/* Fill the phyxcer register into REG_0C */
 	iow(db, DM9000_EPAR, DM9000_PHY | reg);
 
-	iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);	/* Issue phyxcer read command */
+	/* Issue phyxcer read command */
+	iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);
 
 	writeb(reg_save, db->io_addr);
-	spin_unlock_irqrestore(&db->lock,flags);
+	spin_unlock_irqrestore(&db->lock, flags);
 
 	dm9000_msleep(db, 1);		/* Wait read complete */
 
-	spin_lock_irqsave(&db->lock,flags);
+	spin_lock_irqsave(&db->lock, flags);
 	reg_save = readb(db->io_addr);
 
 	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer read command */
@@ -307,7 +306,7 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
 
 	/* restore the previous address */
 	writeb(reg_save, db->io_addr);
-	spin_unlock_irqrestore(&db->lock,flags);
+	spin_unlock_irqrestore(&db->lock, flags);
 
 	mutex_unlock(&db->addr_lock);
 
@@ -315,9 +314,7 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
 	return ret;
 }
 
-/*
- *   Write a word to phyxcer
- */
+/* Write a word to phyxcer */
 static void
 dm9000_phy_write(struct net_device *dev,
 		 int phyaddr_unused, int reg, int value)
@@ -329,7 +326,7 @@ dm9000_phy_write(struct net_device *dev,
 	dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
 	mutex_lock(&db->addr_lock);
 
-	spin_lock_irqsave(&db->lock,flags);
+	spin_lock_irqsave(&db->lock, flags);
 
 	/* Save previous register address */
 	reg_save = readb(db->io_addr);
@@ -341,14 +338,15 @@ dm9000_phy_write(struct net_device *dev,
 	iow(db, DM9000_EPDRL, value);
 	iow(db, DM9000_EPDRH, value >> 8);
 
-	iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);	/* Issue phyxcer write command */
+	/* Issue phyxcer write command */
+	iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);
 
 	writeb(reg_save, db->io_addr);
 	spin_unlock_irqrestore(&db->lock, flags);
 
 	dm9000_msleep(db, 1);		/* Wait write complete */
 
-	spin_lock_irqsave(&db->lock,flags);
+	spin_lock_irqsave(&db->lock, flags);
 	reg_save = readb(db->io_addr);
 
 	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer write command */
-- 
1.7.1


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

* Re: [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial
  2013-03-27 12:09 [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial Joseph CHANG
  2013-03-27 12:09 ` [PATCH 2/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial patch2 Joseph CHANG
@ 2013-03-27 13:14 ` Denis Kirjanov
  2013-03-28  2:50   ` Joseph Chang
  1 sibling, 1 reply; 4+ messages in thread
From: Denis Kirjanov @ 2013-03-27 13:14 UTC (permalink / raw)
  To: Joseph CHANG
  Cc: David S. Miller, Bill Pemberton, Matthew Leach,
	Greg Kroah-Hartman, Joseph CHANG, Jiri Pirko, netdev,
	linux-kernel

It's not clear from your log what was wrong with the driver. Could you
please update the log message.

On 3/27/13, Joseph CHANG <josright123@gmail.com> wrote:
> Fixing bug for DM9000B(DSP) which is a DSP revision! 3rd trial.
>
> Tested to Davicom DM9000 series include DM9000E(analog),
> DM9000A(analog), DM9000B(DSP), and DM9000C(DSP) in X86 and
> ARM Embedded Linux these years.
>
> Signed-off-by: Joseph CHANG <josright123@gmail.com>
> ---
>  drivers/net/ethernet/davicom/dm9000.c |  219
> +++++++++++++++++----------------
>  drivers/net/ethernet/davicom/dm9000.h |   11 ++-
>  2 files changed, 124 insertions(+), 106 deletions(-)
>
> diff --git a/drivers/net/ethernet/davicom/dm9000.c
> b/drivers/net/ethernet/davicom/dm9000.c
> index 8cdf025..9dd4bd6 100644
> --- a/drivers/net/ethernet/davicom/dm9000.c
> +++ b/drivers/net/ethernet/davicom/dm9000.c
> @@ -47,7 +47,7 @@
>  #define DM9000_PHY		0x40	/* PHY address 0x01 */
>
>  #define CARDNAME	"dm9000"
> -#define DRV_VERSION	"1.31"
> +#define DRV_VERSION	"1.39"
>
>  /*
>   * Transmit timeout, default 5 seconds.
> @@ -257,6 +257,109 @@ static void dm9000_dumpblk_32bit(void __iomem *reg,
> int count)
>  		tmp = readl(reg);
>  }
>
> +/*
> + * Sleep, either by using msleep() or if we are suspending, then
> + * use mdelay() to sleep.
> + */
> +static void dm9000_msleep(board_info_t *db, unsigned int ms)
> +{
> +	if (db->in_suspend)
> +		mdelay(ms);
> +	else
> +		msleep(ms);
> +}
> +
> +/*
> + *   Read a word from phyxcer
> + */
> +static int
> +dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
> +{
> +	board_info_t *db = netdev_priv(dev);
> +	unsigned long flags;
> +	unsigned int reg_save;
> +	int ret;
> +
> +	mutex_lock(&db->addr_lock);
> +
> +	spin_lock_irqsave(&db->lock,flags);
> +
> +	/* Save previous register address */
> +	reg_save = readb(db->io_addr);
> +
> +	/* Fill the phyxcer register into REG_0C */
> +	iow(db, DM9000_EPAR, DM9000_PHY | reg);
> +
> +	iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);	/* Issue phyxcer read
> command */
> +
> +	writeb(reg_save, db->io_addr);
> +	spin_unlock_irqrestore(&db->lock,flags);
> +
> +	dm9000_msleep(db, 1);		/* Wait read complete */
> +
> +	spin_lock_irqsave(&db->lock,flags);
> +	reg_save = readb(db->io_addr);
> +
> +	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer read command */
> +
> +	/* The read data keeps on REG_0D & REG_0E */
> +	ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
> +
> +	/* restore the previous address */
> +	writeb(reg_save, db->io_addr);
> +	spin_unlock_irqrestore(&db->lock,flags);
> +
> +	mutex_unlock(&db->addr_lock);
> +
> +	dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
> +	return ret;
> +}
> +
> +/*
> + *   Write a word to phyxcer
> + */
> +static void
> +dm9000_phy_write(struct net_device *dev,
> +		 int phyaddr_unused, int reg, int value)
> +{
> +	board_info_t *db = netdev_priv(dev);
> +	unsigned long flags;
> +	unsigned long reg_save;
> +
> +	dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
> +	mutex_lock(&db->addr_lock);
> +
> +	spin_lock_irqsave(&db->lock,flags);
> +
> +	/* Save previous register address */
> +	reg_save = readb(db->io_addr);
> +
> +	/* Fill the phyxcer register into REG_0C */
> +	iow(db, DM9000_EPAR, DM9000_PHY | reg);
> +
> +	/* Fill the written data into REG_0D & REG_0E */
> +	iow(db, DM9000_EPDRL, value);
> +	iow(db, DM9000_EPDRH, value >> 8);
> +
> +	iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);	/* Issue phyxcer write
> command */
> +
> +	writeb(reg_save, db->io_addr);
> +	spin_unlock_irqrestore(&db->lock, flags);
> +
> +	dm9000_msleep(db, 1);		/* Wait write complete */
> +
> +	spin_lock_irqsave(&db->lock,flags);
> +	reg_save = readb(db->io_addr);
> +
> +	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer write command */
> +
> +	/* restore the previous address */
> +	writeb(reg_save, db->io_addr);
> +
> +	spin_unlock_irqrestore(&db->lock, flags);
> +	mutex_unlock(&db->addr_lock);
> +}
> +
>  /* dm9000_set_io
>   *
>   * select the specified set of io routines to use with the
> @@ -795,6 +898,8 @@ dm9000_init_dm9000(struct net_device *dev)
>
>  	iow(db, DM9000_GPCR, GPCR_GEP_CNTL);	/* Let GPIO0 output */
>
> +	dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
> +
>  	ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0;
>
>  	/* if wol is needed, then always set NCR_WAKEEN otherwise we end
> @@ -830,6 +935,8 @@ dm9000_init_dm9000(struct net_device *dev)
>  	db->tx_pkt_cnt = 0;
>  	db->queue_pkt_len = 0;
>  	dev->trans_start = jiffies;
> +
> +	dm9000_phy_write(dev, 0, MII_DM_DSPCR, DSPCR_INIT_PARAM); /* Init */
>  }
>
>  /* Our watchdog timed out. Called by the networking layer */
> @@ -1201,109 +1308,6 @@ dm9000_open(struct net_device *dev)
>  	return 0;
>  }
>
> -/*
> - * Sleep, either by using msleep() or if we are suspending, then
> - * use mdelay() to sleep.
> - */
> -static void dm9000_msleep(board_info_t *db, unsigned int ms)
> -{
> -	if (db->in_suspend)
> -		mdelay(ms);
> -	else
> -		msleep(ms);
> -}
> -
> -/*
> - *   Read a word from phyxcer
> - */
> -static int
> -dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
> -{
> -	board_info_t *db = netdev_priv(dev);
> -	unsigned long flags;
> -	unsigned int reg_save;
> -	int ret;
> -
> -	mutex_lock(&db->addr_lock);
> -
> -	spin_lock_irqsave(&db->lock,flags);
> -
> -	/* Save previous register address */
> -	reg_save = readb(db->io_addr);
> -
> -	/* Fill the phyxcer register into REG_0C */
> -	iow(db, DM9000_EPAR, DM9000_PHY | reg);
> -
> -	iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);	/* Issue phyxcer read
> command */
> -
> -	writeb(reg_save, db->io_addr);
> -	spin_unlock_irqrestore(&db->lock,flags);
> -
> -	dm9000_msleep(db, 1);		/* Wait read complete */
> -
> -	spin_lock_irqsave(&db->lock,flags);
> -	reg_save = readb(db->io_addr);
> -
> -	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer read command */
> -
> -	/* The read data keeps on REG_0D & REG_0E */
> -	ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
> -
> -	/* restore the previous address */
> -	writeb(reg_save, db->io_addr);
> -	spin_unlock_irqrestore(&db->lock,flags);
> -
> -	mutex_unlock(&db->addr_lock);
> -
> -	dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
> -	return ret;
> -}
> -
> -/*
> - *   Write a word to phyxcer
> - */
> -static void
> -dm9000_phy_write(struct net_device *dev,
> -		 int phyaddr_unused, int reg, int value)
> -{
> -	board_info_t *db = netdev_priv(dev);
> -	unsigned long flags;
> -	unsigned long reg_save;
> -
> -	dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
> -	mutex_lock(&db->addr_lock);
> -
> -	spin_lock_irqsave(&db->lock,flags);
> -
> -	/* Save previous register address */
> -	reg_save = readb(db->io_addr);
> -
> -	/* Fill the phyxcer register into REG_0C */
> -	iow(db, DM9000_EPAR, DM9000_PHY | reg);
> -
> -	/* Fill the written data into REG_0D & REG_0E */
> -	iow(db, DM9000_EPDRL, value);
> -	iow(db, DM9000_EPDRH, value >> 8);
> -
> -	iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);	/* Issue phyxcer write
> command */
> -
> -	writeb(reg_save, db->io_addr);
> -	spin_unlock_irqrestore(&db->lock, flags);
> -
> -	dm9000_msleep(db, 1);		/* Wait write complete */
> -
> -	spin_lock_irqsave(&db->lock,flags);
> -	reg_save = readb(db->io_addr);
> -
> -	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer write command */
> -
> -	/* restore the previous address */
> -	writeb(reg_save, db->io_addr);
> -
> -	spin_unlock_irqrestore(&db->lock, flags);
> -	mutex_unlock(&db->addr_lock);
> -}
> -
>  static void
>  dm9000_shutdown(struct net_device *dev)
>  {
> @@ -1502,7 +1506,12 @@ dm9000_probe(struct platform_device *pdev)
>  	db->flags |= DM9000_PLATF_SIMPLE_PHY;
>  #endif
>
> -	dm9000_reset(db);
> +	/* Fixing bug on dm9000_probe, takeover dm9000_reset(db),
> +	 * Need 'NCR_MAC_LBK' bit to indeed stable our DM9000 fifo
> +	 * while probe stage.
> +	 */
> +
> +	iow(db, DM9000_NCR, NCR_MAC_LBK | NCR_RST);
>
>  	/* try multiple times, DM9000 sometimes gets the read wrong */
>  	for (i = 0; i < 8; i++) {
> diff --git a/drivers/net/ethernet/davicom/dm9000.h
> b/drivers/net/ethernet/davicom/dm9000.h
> index 55688bd..9ce058a 100644
> --- a/drivers/net/ethernet/davicom/dm9000.h
> +++ b/drivers/net/ethernet/davicom/dm9000.h
> @@ -69,7 +69,9 @@
>  #define NCR_WAKEEN          (1<<6)
>  #define NCR_FCOL            (1<<4)
>  #define NCR_FDX             (1<<3)
> -#define NCR_LBK             (3<<1)
> +
> +#define NCR_RESERVED        (3<<1)
> +#define NCR_MAC_LBK         (1<<1)
>  #define NCR_RST	            (1<<0)
>
>  #define NSR_SPEED           (1<<7)
> @@ -167,5 +169,12 @@
>  #define ISR_LNKCHNG		(1<<5)
>  #define ISR_UNDERRUN		(1<<4)
>
> +/* Davicom MII registers.
> + */
> +
> +#define MII_DM_DSPCR		0x1b    /* DSP Control Register */
> +
> +#define DSPCR_INIT_PARAM	0xE100	/* DSP init parameter */
> +
>  #endif /* _DM9000X_H_ */
>
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

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

* RE: [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial
  2013-03-27 13:14 ` [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial Denis Kirjanov
@ 2013-03-28  2:50   ` Joseph Chang
  0 siblings, 0 replies; 4+ messages in thread
From: Joseph Chang @ 2013-03-28  2:50 UTC (permalink / raw)
  To: 'Denis Kirjanov', 'Joseph CHANG'
  Cc: 'David S. Miller', 'Bill Pemberton',
	'Matthew Leach', 'Greg Kroah-Hartman',
	'Joseph CHANG', 'Jiri Pirko',
	netdev, linux-kernel

Dear Denis,

  Yes, I can tell more detail, Should I re-do the patch and submit again? 

  I will revise the log as below: (Please help comment again, thanks.)

- Fixing bug for DM9000B(DSP) which is a DSP revision! 3rd trial.
-
- The chip of DM9000B(DSP) is different in internal PHY compare to
DM9000A(analog) and 
- DM9000E(analog).
- This patch add a PHY RESET and a PHY INIT PARAMETER settings in 
- "dm9000_init_dm9000()", and
- This patch change set DM9000_NCR by reset-bit to be set DM9000_NCR by
reset-bit 
- conjunction with mac_loopback-bit in "dm9000_probe()".
- The driver could get wrong DM9000B FIFO(internal) state during driver
initialize, But not each 
- target board case, error rate is around 2%. 
- We patch the driver this way to solve this initial fatal issue.

Best Regards,
Joseph CHANG 
System Application Engineering Division 
Davicom Semiconductor, Inc. 
No. 6 Li-Hsin Rd. VI, Science-Based Park, 
Hsin-Chu, Taiwan. 
Tel: 886-3-5798797 Ex 8534
Fax: 886-3-5646929 
Web: http://www.davicom.com.tw 


-----Original Message-----
From: Denis Kirjanov [mailto:kda@linux-powerpc.org] 
Sent: Wednesday, March 27, 2013 9:14 PM
To: Joseph CHANG
Cc: David S. Miller; Bill Pemberton; Matthew Leach; Greg Kroah-Hartman; Joseph
CHANG; Jiri Pirko; netdev@vger.kernel.org; linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd
trial

It's not clear from your log what was wrong with the driver. Could you
please update the log message.

On 3/27/13, Joseph CHANG <josright123@gmail.com> wrote:
> Fixing bug for DM9000B(DSP) which is a DSP revision! 3rd trial.
>
> Tested to Davicom DM9000 series include DM9000E(analog),
> DM9000A(analog), DM9000B(DSP), and DM9000C(DSP) in X86 and
> ARM Embedded Linux these years.
>
> Signed-off-by: Joseph CHANG <josright123@gmail.com>
> ---
>  drivers/net/ethernet/davicom/dm9000.c |  219
> +++++++++++++++++----------------
>  drivers/net/ethernet/davicom/dm9000.h |   11 ++-
>  2 files changed, 124 insertions(+), 106 deletions(-)
>
> diff --git a/drivers/net/ethernet/davicom/dm9000.c
> b/drivers/net/ethernet/davicom/dm9000.c
> index 8cdf025..9dd4bd6 100644
> --- a/drivers/net/ethernet/davicom/dm9000.c
> +++ b/drivers/net/ethernet/davicom/dm9000.c
> @@ -47,7 +47,7 @@
>  #define DM9000_PHY		0x40	/* PHY address 0x01 */
>
>  #define CARDNAME	"dm9000"
> -#define DRV_VERSION	"1.31"
> +#define DRV_VERSION	"1.39"
>
>  /*
>   * Transmit timeout, default 5 seconds.
> @@ -257,6 +257,109 @@ static void dm9000_dumpblk_32bit(void __iomem *reg,
> int count)
>  		tmp = readl(reg);
>  }
>
> +/*
> + * Sleep, either by using msleep() or if we are suspending, then
> + * use mdelay() to sleep.
> + */
> +static void dm9000_msleep(board_info_t *db, unsigned int ms)
> +{
> +	if (db->in_suspend)
> +		mdelay(ms);
> +	else
> +		msleep(ms);
> +}
> +
> +/*
> + *   Read a word from phyxcer
> + */
> +static int
> +dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
> +{
> +	board_info_t *db = netdev_priv(dev);
> +	unsigned long flags;
> +	unsigned int reg_save;
> +	int ret;
> +
> +	mutex_lock(&db->addr_lock);
> +
> +	spin_lock_irqsave(&db->lock,flags);
> +
> +	/* Save previous register address */
> +	reg_save = readb(db->io_addr);
> +
> +	/* Fill the phyxcer register into REG_0C */
> +	iow(db, DM9000_EPAR, DM9000_PHY | reg);
> +
> +	iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);	/* Issue phyxcer read
> command */
> +
> +	writeb(reg_save, db->io_addr);
> +	spin_unlock_irqrestore(&db->lock,flags);
> +
> +	dm9000_msleep(db, 1);		/* Wait read complete */
> +
> +	spin_lock_irqsave(&db->lock,flags);
> +	reg_save = readb(db->io_addr);
> +
> +	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer read command */
> +
> +	/* The read data keeps on REG_0D & REG_0E */
> +	ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
> +
> +	/* restore the previous address */
> +	writeb(reg_save, db->io_addr);
> +	spin_unlock_irqrestore(&db->lock,flags);
> +
> +	mutex_unlock(&db->addr_lock);
> +
> +	dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
> +	return ret;
> +}
> +
> +/*
> + *   Write a word to phyxcer
> + */
> +static void
> +dm9000_phy_write(struct net_device *dev,
> +		 int phyaddr_unused, int reg, int value)
> +{
> +	board_info_t *db = netdev_priv(dev);
> +	unsigned long flags;
> +	unsigned long reg_save;
> +
> +	dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
> +	mutex_lock(&db->addr_lock);
> +
> +	spin_lock_irqsave(&db->lock,flags);
> +
> +	/* Save previous register address */
> +	reg_save = readb(db->io_addr);
> +
> +	/* Fill the phyxcer register into REG_0C */
> +	iow(db, DM9000_EPAR, DM9000_PHY | reg);
> +
> +	/* Fill the written data into REG_0D & REG_0E */
> +	iow(db, DM9000_EPDRL, value);
> +	iow(db, DM9000_EPDRH, value >> 8);
> +
> +	iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);	/* Issue phyxcer write
> command */
> +
> +	writeb(reg_save, db->io_addr);
> +	spin_unlock_irqrestore(&db->lock, flags);
> +
> +	dm9000_msleep(db, 1);		/* Wait write complete */
> +
> +	spin_lock_irqsave(&db->lock,flags);
> +	reg_save = readb(db->io_addr);
> +
> +	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer write command */
> +
> +	/* restore the previous address */
> +	writeb(reg_save, db->io_addr);
> +
> +	spin_unlock_irqrestore(&db->lock, flags);
> +	mutex_unlock(&db->addr_lock);
> +}
> +
>  /* dm9000_set_io
>   *
>   * select the specified set of io routines to use with the
> @@ -795,6 +898,8 @@ dm9000_init_dm9000(struct net_device *dev)
>
>  	iow(db, DM9000_GPCR, GPCR_GEP_CNTL);	/* Let GPIO0 output */
>
> +	dm9000_phy_write(dev, 0, MII_BMCR, BMCR_RESET); /* PHY RESET */
> +
>  	ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0;
>
>  	/* if wol is needed, then always set NCR_WAKEEN otherwise we end
> @@ -830,6 +935,8 @@ dm9000_init_dm9000(struct net_device *dev)
>  	db->tx_pkt_cnt = 0;
>  	db->queue_pkt_len = 0;
>  	dev->trans_start = jiffies;
> +
> +	dm9000_phy_write(dev, 0, MII_DM_DSPCR, DSPCR_INIT_PARAM); /* Init */
>  }
>
>  /* Our watchdog timed out. Called by the networking layer */
> @@ -1201,109 +1308,6 @@ dm9000_open(struct net_device *dev)
>  	return 0;
>  }
>
> -/*
> - * Sleep, either by using msleep() or if we are suspending, then
> - * use mdelay() to sleep.
> - */
> -static void dm9000_msleep(board_info_t *db, unsigned int ms)
> -{
> -	if (db->in_suspend)
> -		mdelay(ms);
> -	else
> -		msleep(ms);
> -}
> -
> -/*
> - *   Read a word from phyxcer
> - */
> -static int
> -dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
> -{
> -	board_info_t *db = netdev_priv(dev);
> -	unsigned long flags;
> -	unsigned int reg_save;
> -	int ret;
> -
> -	mutex_lock(&db->addr_lock);
> -
> -	spin_lock_irqsave(&db->lock,flags);
> -
> -	/* Save previous register address */
> -	reg_save = readb(db->io_addr);
> -
> -	/* Fill the phyxcer register into REG_0C */
> -	iow(db, DM9000_EPAR, DM9000_PHY | reg);
> -
> -	iow(db, DM9000_EPCR, EPCR_ERPRR | EPCR_EPOS);	/* Issue phyxcer read
> command */
> -
> -	writeb(reg_save, db->io_addr);
> -	spin_unlock_irqrestore(&db->lock,flags);
> -
> -	dm9000_msleep(db, 1);		/* Wait read complete */
> -
> -	spin_lock_irqsave(&db->lock,flags);
> -	reg_save = readb(db->io_addr);
> -
> -	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer read command */
> -
> -	/* The read data keeps on REG_0D & REG_0E */
> -	ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
> -
> -	/* restore the previous address */
> -	writeb(reg_save, db->io_addr);
> -	spin_unlock_irqrestore(&db->lock,flags);
> -
> -	mutex_unlock(&db->addr_lock);
> -
> -	dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
> -	return ret;
> -}
> -
> -/*
> - *   Write a word to phyxcer
> - */
> -static void
> -dm9000_phy_write(struct net_device *dev,
> -		 int phyaddr_unused, int reg, int value)
> -{
> -	board_info_t *db = netdev_priv(dev);
> -	unsigned long flags;
> -	unsigned long reg_save;
> -
> -	dm9000_dbg(db, 5, "phy_write[%02x] = %04x\n", reg, value);
> -	mutex_lock(&db->addr_lock);
> -
> -	spin_lock_irqsave(&db->lock,flags);
> -
> -	/* Save previous register address */
> -	reg_save = readb(db->io_addr);
> -
> -	/* Fill the phyxcer register into REG_0C */
> -	iow(db, DM9000_EPAR, DM9000_PHY | reg);
> -
> -	/* Fill the written data into REG_0D & REG_0E */
> -	iow(db, DM9000_EPDRL, value);
> -	iow(db, DM9000_EPDRH, value >> 8);
> -
> -	iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW);	/* Issue phyxcer write
> command */
> -
> -	writeb(reg_save, db->io_addr);
> -	spin_unlock_irqrestore(&db->lock, flags);
> -
> -	dm9000_msleep(db, 1);		/* Wait write complete */
> -
> -	spin_lock_irqsave(&db->lock,flags);
> -	reg_save = readb(db->io_addr);
> -
> -	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer write command */
> -
> -	/* restore the previous address */
> -	writeb(reg_save, db->io_addr);
> -
> -	spin_unlock_irqrestore(&db->lock, flags);
> -	mutex_unlock(&db->addr_lock);
> -}
> -
>  static void
>  dm9000_shutdown(struct net_device *dev)
>  {
> @@ -1502,7 +1506,12 @@ dm9000_probe(struct platform_device *pdev)
>  	db->flags |= DM9000_PLATF_SIMPLE_PHY;
>  #endif
>
> -	dm9000_reset(db);
> +	/* Fixing bug on dm9000_probe, takeover dm9000_reset(db),
> +	 * Need 'NCR_MAC_LBK' bit to indeed stable our DM9000 fifo
> +	 * while probe stage.
> +	 */
> +
> +	iow(db, DM9000_NCR, NCR_MAC_LBK | NCR_RST);
>
>  	/* try multiple times, DM9000 sometimes gets the read wrong */
>  	for (i = 0; i < 8; i++) {
> diff --git a/drivers/net/ethernet/davicom/dm9000.h
> b/drivers/net/ethernet/davicom/dm9000.h
> index 55688bd..9ce058a 100644
> --- a/drivers/net/ethernet/davicom/dm9000.h
> +++ b/drivers/net/ethernet/davicom/dm9000.h
> @@ -69,7 +69,9 @@
>  #define NCR_WAKEEN          (1<<6)
>  #define NCR_FCOL            (1<<4)
>  #define NCR_FDX             (1<<3)
> -#define NCR_LBK             (3<<1)
> +
> +#define NCR_RESERVED        (3<<1)
> +#define NCR_MAC_LBK         (1<<1)
>  #define NCR_RST	            (1<<0)
>
>  #define NSR_SPEED           (1<<7)
> @@ -167,5 +169,12 @@
>  #define ISR_LNKCHNG		(1<<5)
>  #define ISR_UNDERRUN		(1<<4)
>
> +/* Davicom MII registers.
> + */
> +
> +#define MII_DM_DSPCR		0x1b    /* DSP Control Register */
> +
> +#define DSPCR_INIT_PARAM	0xE100	/* DSP init parameter */
> +
>  #endif /* _DM9000X_H_ */
>
> --
> 1.7.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.


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

end of thread, other threads:[~2013-03-28  2:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-27 12:09 [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial Joseph CHANG
2013-03-27 12:09 ` [PATCH 2/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial patch2 Joseph CHANG
2013-03-27 13:14 ` [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial Denis Kirjanov
2013-03-28  2:50   ` Joseph Chang

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).