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