Commit f18ff4f7 authored by Jeff Garzik's avatar Jeff Garzik

[net drivers] update hamachi.c and starfire.c to use MII lib

parent f71c419e
......@@ -57,7 +57,7 @@ obj-$(CONFIG_TC35815) += tc35815.o
obj-$(CONFIG_SK98LIN) += sk98lin/
obj-$(CONFIG_SKFP) += skfp/
obj-$(CONFIG_VIA_RHINE) += via-rhine.o mii.o
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o mii.o
#
# end link order section
......@@ -71,7 +71,7 @@ obj-$(CONFIG_AIRONET4500_CS) += aironet4500_proc.o
obj-$(CONFIG_WINBOND_840) += mii.o
obj-$(CONFIG_SUNDANCE) += sundance.o mii.o
obj-$(CONFIG_HAMACHI) += hamachi.o
obj-$(CONFIG_HAMACHI) += hamachi.o mii.o
obj-$(CONFIG_NET) += Space.o setup.o net_init.o loopback.o
obj-$(CONFIG_SEEQ8005) += seeq8005.o
obj-$(CONFIG_ETHERTAP) += ethertap.o
......
......@@ -505,13 +505,11 @@ struct hamachi_private {
unsigned int cur_tx, dirty_tx;
unsigned int rx_buf_sz; /* Based on MTU+slack. */
unsigned int tx_full:1; /* The Tx queue is full. */
unsigned int full_duplex:1; /* Full-duplex operation requested. */
unsigned int duplex_lock:1;
unsigned int medialock:1; /* Do not sense media. */
unsigned int default_port:4; /* Last dev->if_port value. */
/* MII transceiver section. */
int mii_cnt; /* MII device addresses. */
u16 advertising; /* NWay media advertisement */
struct mii_if_info mii_if; /* MII lib hooks/info */
unsigned char phys[MII_CNT]; /* MII device addresses, only first one used. */
u32 rx_int_var, tx_int_var; /* interrupt control variables */
u32 option; /* Hold on to a copy of the options */
......@@ -554,8 +552,8 @@ MODULE_PARM_DESC(full_duplex, "GNIC-II full duplex setting(s) (1)");
MODULE_PARM_DESC(force32, "GNIC-II: Bit 0: 32 bit PCI, bit 1: disable parity, bit 2: 64 bit PCI (all boards)");
static int read_eeprom(long ioaddr, int location);
static int mdio_read(long ioaddr, int phy_id, int location);
static void mdio_write(long ioaddr, int phy_id, int location, int value);
static int mdio_read(struct net_device *dev, int phy_id, int location);
static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
static int hamachi_open(struct net_device *dev);
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static void hamachi_timer(unsigned long data);
......@@ -637,6 +635,12 @@ static int __init hamachi_init_one (struct pci_dev *pdev,
hmp = dev->priv;
spin_lock_init(&hmp->lock);
hmp->mii_if.dev = dev;
hmp->mii_if.mdio_read = mdio_read;
hmp->mii_if.mdio_write = mdio_write;
hmp->mii_if.phy_id_mask = 0x1f;
hmp->mii_if.reg_num_mask = 0x1f;
ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma);
if (!ring_space)
goto err_out_cleardev;
......@@ -685,18 +689,18 @@ static int __init hamachi_init_one (struct pci_dev *pdev,
if (option > 0) {
hmp->option = option;
if (option & 0x200)
hmp->full_duplex = 1;
hmp->mii_if.full_duplex = 1;
else if (option & 0x080)
hmp->full_duplex = 0;
hmp->mii_if.full_duplex = 0;
hmp->default_port = option & 15;
if (hmp->default_port)
hmp->medialock = 1;
hmp->mii_if.force_media = 1;
}
if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
hmp->full_duplex = 1;
hmp->mii_if.full_duplex = 1;
/* lock the duplex mode if someone specified a value */
if (hmp->full_duplex || (option & 0x080))
if (hmp->mii_if.full_duplex || (option & 0x080))
hmp->duplex_lock = 1;
/* Set interrupt tuning parameters */
......@@ -749,17 +753,21 @@ static int __init hamachi_init_one (struct pci_dev *pdev,
if (chip_tbl[hmp->chip_id].flags & CanHaveMII) {
int phy, phy_idx = 0;
for (phy = 0; phy < 32 && phy_idx < MII_CNT; phy++) {
int mii_status = mdio_read(ioaddr, phy, 1);
int mii_status = mdio_read(dev, phy, MII_BMSR);
if (mii_status != 0xffff &&
mii_status != 0x0000) {
hmp->phys[phy_idx++] = phy;
hmp->advertising = mdio_read(ioaddr, phy, 4);
hmp->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
printk(KERN_INFO "%s: MII PHY found at address %d, status "
"0x%4.4x advertising %4.4x.\n",
dev->name, phy, mii_status, hmp->advertising);
dev->name, phy, mii_status, hmp->mii_if.advertising);
}
}
hmp->mii_cnt = phy_idx;
if (hmp->mii_cnt > 0)
hmp->mii_if.phy_id = hmp->phys[0];
else
memset(&hmp->mii_if, 0, sizeof(hmp->mii_if));
}
/* Configure gigabit autonegotiation. */
writew(0x0400, ioaddr + ANXchngCtrl); /* Enable legacy links. */
......@@ -805,8 +813,9 @@ static int __init read_eeprom(long ioaddr, int location)
These routines assume the MDIO controller is idle, and do not exit until
the command is finished. */
static int mdio_read(long ioaddr, int phy_id, int location)
static int mdio_read(struct net_device *dev, int phy_id, int location)
{
long ioaddr = dev->base_addr;
int i;
/* We should check busy first - per docs -KDU */
......@@ -821,8 +830,9 @@ static int mdio_read(long ioaddr, int phy_id, int location)
return readw(ioaddr + MII_Rd_Data);
}
static void mdio_write(long ioaddr, int phy_id, int location, int value)
static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
{
long ioaddr = dev->base_addr;
int i;
/* We should check busy first - per docs -KDU */
......@@ -912,7 +922,7 @@ static int hamachi_open(struct net_device *dev)
/* Setting the Rx mode will start the Rx process. */
/* If someone didn't choose a duplex, default to full-duplex */
if (hmp->duplex_lock != 1)
hmp->full_duplex = 1;
hmp->mii_if.full_duplex = 1;
/* always 1, takes no more time to do it */
writew(0x0001, ioaddr + RxChecksum);
......@@ -1909,7 +1919,7 @@ static void set_rx_mode(struct net_device *dev)
static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
{
struct hamachi_private *hmp = dev->priv;
struct hamachi_private *np = dev->priv;
u32 ethcmd;
if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
......@@ -1920,12 +1930,53 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
strcpy(info.driver, DRV_NAME);
strcpy(info.version, DRV_VERSION);
strcpy(info.bus_info, hmp->pci_dev->slot_name);
strcpy(info.bus_info, np->pci_dev->slot_name);
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
}
/* get settings */
case ETHTOOL_GSET: {
struct ethtool_cmd ecmd = { ETHTOOL_GSET };
if (!(chip_tbl[np->chip_id].flags & CanHaveMII))
return -EINVAL;
spin_lock_irq(&np->lock);
mii_ethtool_gset(&np->mii_if, &ecmd);
spin_unlock_irq(&np->lock);
if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
return -EFAULT;
return 0;
}
/* set settings */
case ETHTOOL_SSET: {
int r;
struct ethtool_cmd ecmd;
if (!(chip_tbl[np->chip_id].flags & CanHaveMII))
return -EINVAL;
if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
return -EFAULT;
spin_lock_irq(&np->lock);
r = mii_ethtool_sset(&np->mii_if, &ecmd);
spin_unlock_irq(&np->lock);
return r;
}
/* restart autonegotiation */
case ETHTOOL_NWAY_RST: {
if (!(chip_tbl[np->chip_id].flags & CanHaveMII))
return -EINVAL;
return mii_nway_restart(&np->mii_if);
}
/* get link status */
case ETHTOOL_GLINK: {
struct ethtool_value edata = {ETHTOOL_GLINK};
if (!(chip_tbl[np->chip_id].flags & CanHaveMII))
return -EINVAL;
edata.data = mii_link_ok(&np->mii_if);
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
}
return -EOPNOTSUPP;
......@@ -1933,29 +1984,17 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
long ioaddr = dev->base_addr;
struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
struct hamachi_private *np = dev->priv;
struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
int rc;
switch(cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCGMIIPHY: /* Get address of MII PHY in use. */
data->phy_id = ((struct hamachi_private *)dev->priv)->phys[0] & 0x1f;
/* Fall Through */
if (!netif_running(dev))
return -EINVAL;
case SIOCGMIIREG: /* Read MII PHY register. */
data->val_out = mdio_read(ioaddr, data->phy_id & 0x1f, data->reg_num & 0x1f);
return 0;
if (cmd == SIOCETHTOOL)
rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
case SIOCSMIIREG: /* Write MII PHY register. */
/* TODO: Check the sequencing of this. Might need to stop and
* restart Rx and Tx engines. -KDU
*/
if (!capable(CAP_NET_ADMIN))
return -EPERM;
mdio_write(ioaddr, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
return 0;
case SIOCDEVPRIVATE+3: { /* set rx,tx intr params */
else if (cmd == (SIOCDEVPRIVATE+3)) { /* set rx,tx intr params */
u32 *d = (u32 *)&rq->ifr_data;
/* Should add this check here or an ordinary user can do nasty
* things. -KDU
......@@ -1969,11 +2008,16 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
printk(KERN_NOTICE "%s: tx %08x, rx %08x intr\n", dev->name,
(u32) readl(dev->base_addr + TxIntrCtrl),
(u32) readl(dev->base_addr + RxIntrCtrl));
return 0;
}
default:
return -EOPNOTSUPP;
rc = 0;
}
else {
spin_lock_irq(&np->lock);
rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL);
spin_unlock_irq(&np->lock);
}
return rc;
}
......
This diff is collapsed.
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