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.
prev 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox