Hi Thomas,

Thomas Chou wrote:
Contributed by Fred,

- use of MR0 instead of MR1 to determine speed & duplex (reg 1 gives the
_capability_, not the current state)
- addition of do_ioctl management for mii-tool
- warnings suppression (warning due to extra "volatile" use, the real
usefull one being missing in the structure definition)

Signed-off-by: Thomas Chou <[EMAIL PROTECTED]>

The use of volatile is probably overdone here.
But since NIOS is the only user of this driver currently,
I don't see any reason not to put it in uClinux-dist.

Regards
Greg



 linux-2.6.x/drivers/net/open_eth.c |   73 ++++++++++++++++++++++++++++-------
 1 files changed, 58 insertions(+), 15 deletions(-)

diff --git a/linux-2.6.x/drivers/net/open_eth.c 
b/linux-2.6.x/drivers/net/open_eth.c
index f9672c0..dce6c52 100644
--- a/linux-2.6.x/drivers/net/open_eth.c
+++ b/linux-2.6.x/drivers/net/open_eth.c
@@ -80,6 +80,7 @@
       #define PHY_ADDRESS                           0x00
     #else /* generic PHY, eg NS,Micrel */
       #define PHY_ADDRESS                           0x01
+      #undef PHYIRQ_NUM       // No PHY irq with generic MII
     #endif /* defined(TDK78Q2120PHY) */
 #endif  /* CONFIG_EXCALIBUR */
@@ -178,13 +179,16 @@ struct oeth_private {
     ushort           tx_full;   /* Buffer ring fuul indicator */
     ushort           rx_cur;    /* Next buffer to be checked if packet 
received */
- oeth_regs *regs; /* Address of controller registers. */
-    oeth_bd         *rx_bd_base;/* Address of Rx BDs. */
-    oeth_bd         *tx_bd_base;/* Address of Tx BDs. */
+    volatile oeth_regs       *regs;      /* Address of controller registers. */
+    volatile oeth_bd         *rx_bd_base;/* Address of Rx BDs. */
+    volatile oeth_bd         *tx_bd_base;/* Address of Tx BDs. */
struct net_device_stats stats;
     struct tasklet_struct      oeth_rx_tasklet;
     struct tasklet_struct      oeth_tx_tasklet;
+
+    struct mii_if_info mii;
+    spinlock_t       lock;
 };
#ifdef SANCHKEPKT
@@ -648,6 +652,20 @@ oeth_print_packet(unsigned long add, int len)
 }
 #endif
+static int mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       struct oeth_private *np = netdev_priv(dev);
+       int rc;
+       if (!netif_running(dev))
+               return -EINVAL;
+
+       spin_lock_irq(&np->lock);
+       rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
+       spin_unlock_irq(&np->lock);
+
+       return rc;
+}
+
 // Read a phy register
 int eth_mdread(struct net_device *dev,
                int                fiad_phy_addr,
@@ -715,7 +733,11 @@ void oeth_phymac_synch (struct net_device *dev, int 
callerflg)
     volatile oeth_regs  *regs = (oeth_regs *)dev->base_addr;
     unsigned long        ulmoderval;
     unsigned long        ulmr1sts;
+    #if defined(TDK78Q2120PHY)
     unsigned long        ulphydiagval;
+    #else
+    unsigned long        bmcrval;
+    #endif
ulmr1sts = eth_mdread(dev, PHY_ADDRESS, MII_BMSR);
     /* Read twice to get CURRENT status                                 */
@@ -725,6 +747,8 @@ void oeth_phymac_synch (struct net_device *dev, int 
callerflg)
#if defined(TDK78Q2120PHY)
       ulphydiagval = eth_mdread(dev, PHY_ADDRESS, 18);
+    #else
+      bmcrval = eth_mdread(dev, PHY_ADDRESS, MII_BMCR);
     #endif
if(callerflg == 0)
@@ -905,11 +929,12 @@ void oeth_phymac_synch (struct net_device *dev, int 
callerflg)
                    (ulphydiagval & 0x0400) ? "100BASE-TX" : "10BASE-T");
           #endif
- #else /* generic PHY, use MR1 */
+        #else /* generic PHY, use MR0 */
+
- if((ulmr1sts & (BMSR_100FULL | BMSR_10FULL)) != 0)
+           if((bmcrval & (BMCR_FULLDPLX)) != 0)
             {
-              /* Phy MR1 indicates              */
+              /* Phy MR0 indicates              */
               /*  link is (now) running full duplex.                    */
if((ulmoderval & (OETH_MODER_FULLD)) == 0)
@@ -932,7 +957,7 @@ void oeth_phymac_synch (struct net_device *dev, int 
callerflg)
             }
             else
             {
-              /* Phy MR1 indicates              */
+              /* Phy MR0 indicates              */
               /*  link is (now) running half duplex.                    */
if((ulmoderval & (OETH_MODER_FULLD)) != 0)
@@ -956,7 +981,7 @@ void oeth_phymac_synch (struct net_device *dev, int 
callerflg)
#if defined(ANNOUNCEPHYINT)
             printk("             %s\n",
-                   (ulmr1sts & (BMSR_100FULL | BMSR_100HALF)) ? "100BASE-TX" : 
"10BASE-T");
+                   (bmcrval & BMCR_SPEED100) ? "100BASE-TX" : "10BASE-T");
           #endif
#endif /* defined(TDK78Q2120PHY) */
@@ -1193,7 +1218,7 @@ oeth_rx(unsigned long devn)
/* Check status for errors.
          */
-       if (bdp->len_status & 0x1ff) printk("oeth: 
rx%02d,%08x\n",cep->rx_cur,bdp->len_status);
+       //if (bdp->len_status & 0x1ff) printk("oeth: 
rx%02d,%08x\n",cep->rx_cur,bdp->len_status);
if (bdp->len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) {
             cep->stats.rx_length_errors++;
@@ -1484,7 +1509,7 @@ static irqreturn_t oeth_interrupt(int             irq,
                                   void           *dev_id)
 {
     struct  net_device *dev = dev_id;
-    volatile struct oeth_private *cep;
+    struct oeth_private *cep;
     uint    int_events;
cep = (struct oeth_private *)dev->priv;
@@ -1519,7 +1544,7 @@ static int
 oeth_open(struct net_device *dev)
 {
     volatile oeth_regs *regs = (oeth_regs *)dev->base_addr;
-    volatile struct oeth_private *cep = (struct oeth_private *)dev->priv;
+    struct oeth_private *cep = (struct oeth_private *)dev->priv;
#ifndef RXBUFF_PREALLOC
     struct  sk_buff *skb;
@@ -1612,7 +1637,7 @@ oeth_open(struct net_device *dev)
 static int
 oeth_close(struct net_device *dev)
 {
-    volatile struct oeth_private *cep = (struct oeth_private *)dev->priv;
+    struct oeth_private *cep = (struct oeth_private *)dev->priv;
     volatile oeth_regs *regs = (oeth_regs *)dev->base_addr;
     volatile oeth_bd *bdp;
     int i;
@@ -1895,7 +1920,7 @@ static int calc_crc(char *mac_addr)
static struct net_device_stats *oeth_get_stats(struct net_device *dev)
 {
-    volatile struct oeth_private *cep = (struct oeth_private *)dev->priv;
+    struct oeth_private *cep = (struct oeth_private *)dev->priv;
return &cep->stats;
 }
@@ -1968,7 +1993,7 @@ static void oeth_set_multicast_list(struct net_device 
*dev)
     }
 }
-static void oeth_set_mac_add(struct net_device *dev, void *p)
+static int oeth_set_mac_add(struct net_device *dev, void *p)
 {
     struct sockaddr *addr=p;
     volatile oeth_regs *regs;
@@ -1983,6 +2008,7 @@ static void oeth_set_mac_add(struct net_device *dev, void 
*p)
                       (dev->dev_addr[3]) << 16 |
                       (dev->dev_addr[4]) <<  8 |
                       (dev->dev_addr[5]);
+    return 0;
 }
#ifdef OETH_SYSFS_MDIO_ACCESS
@@ -2139,7 +2165,7 @@ static void init_mdio(struct net_device *dev) {
 */
 static int __init oeth_probe(struct net_device *dev)
 {
-    volatile struct oeth_private  *cep;
+    struct          oeth_private  *cep;
     volatile        oeth_regs     *regs;
     volatile        oeth_bd       *tx_bd, *rx_bd;
     int                            i, j, k;
@@ -2148,6 +2174,7 @@ static int __init oeth_probe(struct net_device *dev)
   #else
     unsigned long mem_addr;
   #endif    // SRAM_BUFF
+    unsigned bmcr_val;
PRINTK2("%s:oeth_probe\n", dev->name); @@ -2250,6 +2277,9 @@ static int __init oeth_probe(struct net_device *dev)
       regs->miiaddress = 20<<8;
       regs->miitx_data = 0x1422;
       regs->miicommand = OETH_MIICOMMAND_WCTRLDATA;
+    #else
+//      printk("\n*** WARNING : forcing link 10Mbps - autoneg... ***\n");
+//      eth_mdwrite(dev, PHY_ADDRESS, 0, 0x0100);
     #endif  // TDK78Q2120PHY
#ifdef TXBUFF_PREALLOC
@@ -2387,6 +2417,18 @@ static int __init oeth_probe(struct net_device *dev)
     dev->set_multicast_list = oeth_set_multicast_list;
     dev->set_mac_address = oeth_set_mac_add;
+ bmcr_val = eth_mdread(dev, PHY_ADDRESS, MII_BMCR);
+    dev->do_ioctl = mii_ioctl;
+    cep->mii.dev = dev;
+    cep->mii.mdio_read = eth_mdread;
+    cep->mii.mdio_write = eth_mdwrite;
+    cep->mii.phy_id_mask = 0x1f;
+    cep->mii.reg_num_mask = 0x1f;
+    cep->mii.phy_id = PHY_ADDRESS;
+    cep->mii.full_duplex = (bmcr_val & BMCR_FULLDPLX) ? 1 : 0;  /* is full 
duplex? */
+    cep->mii.force_media = (bmcr_val & BMCR_ANENABLE) ? 1 : 0;  /* is autoneg. 
disabled? */
+    cep->mii.supports_gmii = 0; /* are GMII registers supported? */
+
 #ifdef CONFIG_EXCALIBUR
   #ifdef SRAM_BUFF
     printk(" SRAM @0x%08X",SRAM_BUFF_BASE);
@@ -2413,6 +2455,7 @@ static int __init oeth_probe(struct net_device *dev)
              "NOT "
            #endif
           );
+    printk("              BMCR = %04xh.\n", bmcr_val);
 #endif
 #ifdef SANCHKEPKT
     printk("              SANCHKEPKT defined.\n");

--
------------------------------------------------------------------------
Greg Ungerer  --  Chief Software Dude       EMAIL:     [EMAIL PROTECTED]
Secure Computing Corporation                PHONE:       +61 7 3435 2888
825 Stanley St,                             FAX:         +61 7 3891 3630
Woolloongabba, QLD, 4102, Australia         WEB: http://www.SnapGear.com
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev

Reply via email to