Commit 949682fe authored by Jeff Garzik's avatar Jeff Garzik

Add helper function generic_mii_ioctl to MII lib, use it in 8139cp net drvr

parent 439f01a0
...@@ -27,8 +27,6 @@ ...@@ -27,8 +27,6 @@
TODO, in rough priority order: TODO, in rough priority order:
* Test Tx checksumming thoroughly * Test Tx checksumming thoroughly
* dev->tx_timeout * dev->tx_timeout
* Support forcing media type with a module parameter,
like dl2k.c/sundance.c
* Constants (module parms?) for Rx work limit * Constants (module parms?) for Rx work limit
* Complete reset on PciErr * Complete reset on PciErr
* Consider Rx interrupt mitigation using TimerIntr * Consider Rx interrupt mitigation using TimerIntr
...@@ -49,8 +47,8 @@ ...@@ -49,8 +47,8 @@
*/ */
#define DRV_NAME "8139cp" #define DRV_NAME "8139cp"
#define DRV_VERSION "0.2.1" #define DRV_VERSION "0.3.0"
#define DRV_RELDATE "Aug 9, 2002" #define DRV_RELDATE "Sep 29, 2002"
#include <linux/config.h> #include <linux/config.h>
...@@ -1657,33 +1655,18 @@ static int cp_ethtool_ioctl (struct cp_private *cp, void *useraddr) ...@@ -1657,33 +1655,18 @@ static int cp_ethtool_ioctl (struct cp_private *cp, void *useraddr)
static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd) static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
{ {
struct cp_private *cp = dev->priv; struct cp_private *cp = dev->priv;
struct mii_ioctl_data *mii; struct mii_ioctl_data *mii = (struct mii_ioctl_data *) &rq->ifr_data;
int rc = 0; int rc;
mii = (struct mii_ioctl_data *) &rq->ifr_data;
if (!netif_running(dev)) if (!netif_running(dev))
return -EINVAL; return -EINVAL;
if (cmd != SIOCETHTOOL) if (cmd == SIOCETHTOOL)
mii->reg_num &= 0x1f;
switch (cmd) {
case SIOCETHTOOL:
return cp_ethtool_ioctl(cp, (void *) rq->ifr_data); return cp_ethtool_ioctl(cp, (void *) rq->ifr_data);
case SIOCGMIIPHY: /* Get the address of the PHY in use. */ rc = generic_mii_ioctl(dev, &cp->mii_if, mii, cmd);
mii->phy_id = CP_INTERNAL_PHY; if (rc == 1) /* we don't care about duplex change, fixup rc */
/* Fall Through */ rc = 0;
case SIOCGMIIREG: /* Read the specified MII register. */
mii->val_out = mdio_read (dev, CP_INTERNAL_PHY, mii->reg_num);
break;
default:
rc = -EOPNOTSUPP;
break;
}
return rc; return rc;
} }
...@@ -1821,6 +1804,8 @@ static int __devinit cp_init_one (struct pci_dev *pdev, ...@@ -1821,6 +1804,8 @@ static int __devinit cp_init_one (struct pci_dev *pdev,
cp->mii_if.mdio_read = mdio_read; cp->mii_if.mdio_read = mdio_read;
cp->mii_if.mdio_write = mdio_write; cp->mii_if.mdio_write = mdio_write;
cp->mii_if.phy_id = CP_INTERNAL_PHY; cp->mii_if.phy_id = CP_INTERNAL_PHY;
cp->mii_if.phy_id_mask = 0x1f;
cp->mii_if.reg_num_mask = 0x1f;
cp_set_rxbufsize(cp); cp_set_rxbufsize(cp);
rc = pci_enable_device(pdev); rc = pci_enable_device(pdev);
......
...@@ -5,6 +5,26 @@ ...@@ -5,6 +5,26 @@
Maintained by Jeff Garzik <jgarzik@mandrakesoft.com> Maintained by Jeff Garzik <jgarzik@mandrakesoft.com>
Copyright 2001,2002 Jeff Garzik Copyright 2001,2002 Jeff Garzik
Various code came from myson803.c and other files by
Donald Becker. Copyright:
Written 1998-2002 by Donald Becker.
This software may be used and distributed according
to the terms of the GNU General Public License (GPL),
incorporated herein by reference. Drivers based on
or derived from this code fall under the GPL and must
retain the authorship, copyright and license notice.
This file is not a complete program and may only be
used when the entire operating system is licensed
under the GPL.
The author may be reached as becker@scyld.com, or C/O
Scyld Computing Corporation
410 Severn Ave., Suite 210
Annapolis MD 21403
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -241,6 +261,73 @@ unsigned int mii_check_media (struct mii_if_info *mii, ...@@ -241,6 +261,73 @@ unsigned int mii_check_media (struct mii_if_info *mii,
return 0; /* duplex did not change */ return 0; /* duplex did not change */
} }
int generic_mii_ioctl(struct net_device *dev, struct mii_if_info *mii_if,
struct mii_ioctl_data *mii_data, int cmd)
{
int rc = 0;
unsigned int duplex_changed = 0;
mii_data->phy_id &= mii_if->phy_id_mask;
mii_data->reg_num &= mii_if->reg_num_mask;
switch(cmd) {
case SIOCGMIIPHY:
mii_data->phy_id = mii_if->phy_id;
/* fall through */
case SIOCGMIIREG:
mii_data->val_out =
mii_if->mdio_read(dev, mii_data->phy_id,
mii_data->reg_num);
break;
case SIOCSMIIREG: {
u16 val = mii_data->val_in;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
if (mii_data->phy_id == mii_if->phy_id) {
switch(mii_data->reg_num) {
case MII_BMCR: {
unsigned int new_duplex = 0;
if (val & (BMCR_RESET|BMCR_ANENABLE))
mii_if->force_media = 1;
else
mii_if->force_media = 0;
if (mii_if->force_media &&
(val & BMCR_FULLDPLX))
new_duplex = 1;
if (mii_if->full_duplex != new_duplex) {
duplex_changed = 1;
mii_if->full_duplex = new_duplex;
}
break;
}
case MII_ADVERTISE:
mii_if->advertising = val;
break;
default:
/* do nothing */
break;
}
}
mii_if->mdio_write(dev, mii_data->phy_id,
mii_data->reg_num, val);
break;
}
default:
rc = -EOPNOTSUPP;
break;
}
if ((rc == 0) && (duplex_changed))
rc = 1;
return rc;
}
MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>"); MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>");
MODULE_DESCRIPTION ("MII hardware support library"); MODULE_DESCRIPTION ("MII hardware support library");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -251,4 +338,5 @@ EXPORT_SYMBOL(mii_ethtool_gset); ...@@ -251,4 +338,5 @@ EXPORT_SYMBOL(mii_ethtool_gset);
EXPORT_SYMBOL(mii_ethtool_sset); EXPORT_SYMBOL(mii_ethtool_sset);
EXPORT_SYMBOL(mii_check_link); EXPORT_SYMBOL(mii_check_link);
EXPORT_SYMBOL(mii_check_media); EXPORT_SYMBOL(mii_check_media);
EXPORT_SYMBOL(generic_mii_ioctl);
...@@ -107,6 +107,8 @@ ...@@ -107,6 +107,8 @@
struct mii_if_info { struct mii_if_info {
int phy_id; int phy_id;
int advertising; int advertising;
int phy_id_mask;
int reg_num_mask;
unsigned int full_duplex : 1; /* is full duplex? */ unsigned int full_duplex : 1; /* is full duplex? */
unsigned int force_media : 1; /* is autoneg. disabled? */ unsigned int force_media : 1; /* is autoneg. disabled? */
...@@ -117,6 +119,7 @@ struct mii_if_info { ...@@ -117,6 +119,7 @@ struct mii_if_info {
}; };
struct ethtool_cmd; struct ethtool_cmd;
struct mii_ioctl_data;
extern int mii_link_ok (struct mii_if_info *mii); extern int mii_link_ok (struct mii_if_info *mii);
extern int mii_nway_restart (struct mii_if_info *mii); extern int mii_nway_restart (struct mii_if_info *mii);
...@@ -126,6 +129,9 @@ extern void mii_check_link (struct mii_if_info *mii); ...@@ -126,6 +129,9 @@ extern void mii_check_link (struct mii_if_info *mii);
extern unsigned int mii_check_media (struct mii_if_info *mii, extern unsigned int mii_check_media (struct mii_if_info *mii,
unsigned int ok_to_print, unsigned int ok_to_print,
unsigned int init_media); unsigned int init_media);
extern int generic_mii_ioctl(struct net_device *dev, struct mii_if_info *mii_if,
struct mii_ioctl_data *mii_data, int cmd);
/* This structure is used in all SIOCxMIIxxx ioctl calls */ /* This structure is used in all SIOCxMIIxxx ioctl calls */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment