All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ulrich Eckhardt <eckhardt@satorlaser.com>
To: linux-mips@linux-mips.org
Subject: Re: bitrot in drivers/net/au1000_eth.c
Date: Sun, 30 Jan 2005 12:50:53 +0100	[thread overview]
Message-ID: <200501301250.54188.eckhardt@satorlaser.com> (raw)
In-Reply-To: <200501281501.19162.eckhardt@satorlaser.com>

I received a private reply from Herbert Valerio Riedel with a patch that falls 
into category

> 3. Split off the MII handling code or, better, reuse the facility already
> provided by drivers/net/mii.c. 

with the permission to forward the patch here. Here comes the code and some 
comments by him...

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>code>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

there's a nasty bug in the code, which triggers a kernel freeze when
performing MII ioctl's w/ mii-tool on a device which is down;

the following code fixes that, and uses the generic mii ioctl helper in
order to use proven code...

hope it's welcomed or useful :-)


Index: drivers/net/au1000_eth.c
===================================================================
--- drivers/net/au1000_eth.c (revision 25)
+++ drivers/net/au1000_eth.c (working copy)
@@ -91,7 +91,7 @@
 static void au1000_timer(unsigned long);
 static int au1000_ioctl(struct net_device *, struct ifreq *, int);
 static int mdio_read(struct net_device *, int, int);
-static void mdio_write(struct net_device *, int, int, u16);
+static void mdio_write(struct net_device *, int, int, int);
 static void dump_mii(struct net_device *dev, int phy_id);
 
 // externs
@@ -846,7 +846,7 @@
  return (int)*mii_data_reg;
 }
 
-static void mdio_write(struct net_device *dev, int phy_id, int reg, u16 
value)
+static void mdio_write(struct net_device *dev, int phy_id, int reg, int 
value)
 {
  struct au1000_private *aup = (struct au1000_private *) dev->priv;
  volatile u32 *mii_control_reg;
@@ -951,6 +951,10 @@
     aup->phy_ops = mii_chip_table[i].phy_ops;
     aup->phy_ops->phy_init(dev,phy_addr);
 
+    aup->mii_if.phy_id = phy_addr;
+    aup->mii_if.phy_id_mask = 0x1f;    
+    aup->mii_if.reg_num_mask = 0x1f;
+
     // Check for dual-phy and then store required 
     // values and set indicators. We need to do 
     // this now since mdio_{read,write} need the 
@@ -1544,6 +1548,10 @@
  aup->mii->mii_control_reg = 0;
  aup->mii->mii_data_reg = 0;
 
+        aup->mii_if.dev = dev;
+        aup->mii_if.mdio_read = mdio_read;
+        aup->mii_if.mdio_write = mdio_write;
+
  if (mii_probe(dev) != 0) {
   goto err_out;
  }
@@ -1592,6 +1600,7 @@
  dev->tx_timeout = au1000_tx_timeout;
  dev->watchdog_timeo = ETH_TX_TIMEOUT;
 
+
  /* 
   * The boot code uses the ethernet controller, so reset it to start 
   * fresh.  au1000_init() expects that the device is in reset state.
@@ -2127,24 +2136,17 @@
 
 static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
- struct au1000_private *aup = (struct au1000_private *)dev->priv;
- u16 *data = (u16 *)&rq->ifr_ifru;
+ struct au1000_private *const aup = netdev_priv(dev);
+ int rc;
+ unsigned long flags;
 
- switch(cmd) { 
- case SIOCGMIIPHY:
-  data[0] = aup->phy_addr;
-  /* Fall through */
- case SIOCGMIIREG:
-  data[3] = mdio_read(dev, aup->phy_addr, data[1]);
-  return 0;
- case SIOCSMIIREG:
-  if (!capable(CAP_NET_ADMIN))
-   return -EPERM;
-  mdio_write(dev, aup->phy_addr, data[1], data[2]);
-  return 0;
- default:
-  return -EOPNOTSUPP;
- }
+ if (!netif_running(dev))
+  return -EINVAL;
+
+ spin_lock_irqsave(&aup->lock, flags);
+        rc = generic_mii_ioctl(&aup->mii_if, if_mii(rq), cmd, NULL);
+        spin_unlock_irqrestore(&aup->lock, flags);
+        return rc;
 }
 
 
Index: drivers/net/au1000_eth.h
===================================================================
--- drivers/net/au1000_eth.h (revision 25)
+++ drivers/net/au1000_eth.h (working copy)
@@ -214,6 +214,7 @@
  int mac_id;
  mii_phy_t *mii;
  struct phy_ops *phy_ops;
+ struct mii_if_info mii_if;
  
  /* These variables are just for quick access to certain regs addresses. */
  volatile mac_reg_t *mac;  /* mac registers                      */   
Index: drivers/net/Kconfig
===================================================================
--- drivers/net/Kconfig (revision 25)
+++ drivers/net/Kconfig (working copy)
@@ -467,6 +467,7 @@
  bool "MIPS AU1000 Ethernet support"
  depends on NET_ETHERNET && SOC_AU1X00
  select CRC32
+ select MII
  help
    If you have an Alchemy Semi AU1X00 based system
    say Y.  Otherwise, say N.

      parent reply	other threads:[~2005-01-30 11:50 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-01-28 14:01 bitrot in drivers/net/au1000_eth.c Ulrich Eckhardt
2005-01-28 17:01 ` Pete Popov
2005-01-28 17:20   ` Matt Porter
2005-01-28 18:15     ` Pete Popov
2005-01-29 10:04     ` Ulrich Eckhardt
2005-01-30 11:50 ` Ulrich Eckhardt [this message]

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=200501301250.54188.eckhardt@satorlaser.com \
    --to=eckhardt@satorlaser.com \
    --cc=linux-mips@linux-mips.org \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.