* [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 related [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 related [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).