linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Denis Kirjanov <kda@linux-powerpc.org>
To: Joseph CHANG <josright123@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>,
	Bill Pemberton <wfp5p@virginia.edu>,
	Matthew Leach <matthew@mattleach.net>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Joseph CHANG <joseph_chang@davicom.com.tw>,
	Jiri Pirko <jiri@resnulli.us>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial
Date: Wed, 27 Mar 2013 17:14:27 +0400	[thread overview]
Message-ID: <CAOJe8K24A6jSLsfLn6yc0cKvLPNU8+8wLs+ip0AsVUYS_HVBGg@mail.gmail.com> (raw)
In-Reply-To: <1364386168-12503-1-git-send-email-josright123@gmail.com>

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
>

  parent reply	other threads:[~2013-03-27 13:14 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 ` Denis Kirjanov [this message]
2013-03-28  2:50   ` [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial Joseph Chang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAOJe8K24A6jSLsfLn6yc0cKvLPNU8+8wLs+ip0AsVUYS_HVBGg@mail.gmail.com \
    --to=kda@linux-powerpc.org \
    --cc=davem@davemloft.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=jiri@resnulli.us \
    --cc=joseph_chang@davicom.com.tw \
    --cc=josright123@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matthew@mattleach.net \
    --cc=netdev@vger.kernel.org \
    --cc=wfp5p@virginia.edu \
    --subject='Re: [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

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