From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755599Ab3C1CvA (ORCPT ); Wed, 27 Mar 2013 22:51:00 -0400 Received: from 60-250-193-73.HINET-IP.hinet.net ([60.250.193.73]:61189 "EHLO mail.davicom.com.tw" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755140Ab3C1Cu6 (ORCPT ); Wed, 27 Mar 2013 22:50:58 -0400 X-Greylist: delayed 1465 seconds by postgrey-1.27 at vger.kernel.org; Wed, 27 Mar 2013 22:50:58 EDT Message-Id: <201303280250.r2S2oR0l010911@mail.davicom.com.tw> From: "Joseph Chang" To: "'Denis Kirjanov'" , "'Joseph CHANG'" Cc: "'David S. Miller'" , "'Bill Pemberton'" , "'Matthew Leach'" , "'Greg Kroah-Hartman'" , "'Joseph CHANG'" , "'Jiri Pirko'" , , Subject: RE: [PATCH 1/2] ethernet: dm9000 driver: davicom: upgrade driver: 3rd trial Date: Thu, 28 Mar 2013 10:50:29 +0800 MIME-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Office Outlook, Build 11.0.5510 Thread-Index: Ac4q7QzCM3m5db4/Ri2N91RK/1kgLAAawAqw X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3350 In-Reply-To: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 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 > --- > 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.