X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fhamachi.c;h=3d96714ed3cf8dbddbd4a8fc1a920604d18c98df;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=6b0cb2cabdc6967d5a5f8a8d97e041c470e3bcca;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 6b0cb2cab..3d96714ed 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -170,10 +170,10 @@ static int tx_params[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; #include #include #include +#include #include #include /* Processor type for cache alignment. */ -#include #include #include #include @@ -512,27 +512,28 @@ struct hamachi_private { u32 rx_int_var, tx_int_var; /* interrupt control variables */ u32 option; /* Hold on to a copy of the options */ struct pci_dev *pci_dev; + void __iomem *base; }; MODULE_AUTHOR("Donald Becker , Eric Kasten , Keith Underwood "); MODULE_DESCRIPTION("Packet Engines 'Hamachi' GNIC-II Gigabit Ethernet driver"); MODULE_LICENSE("GPL"); -MODULE_PARM(max_interrupt_work, "i"); -MODULE_PARM(mtu, "i"); -MODULE_PARM(debug, "i"); -MODULE_PARM(min_rx_pkt, "i"); -MODULE_PARM(max_rx_gap, "i"); -MODULE_PARM(max_rx_latency, "i"); -MODULE_PARM(min_tx_pkt, "i"); -MODULE_PARM(max_tx_gap, "i"); -MODULE_PARM(max_tx_latency, "i"); -MODULE_PARM(rx_copybreak, "i"); -MODULE_PARM(rx_params, "1-" __MODULE_STRING(MAX_UNITS) "i"); -MODULE_PARM(tx_params, "1-" __MODULE_STRING(MAX_UNITS) "i"); -MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i"); -MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i"); -MODULE_PARM(force32, "i"); +module_param(max_interrupt_work, int, 0); +module_param(mtu, int, 0); +module_param(debug, int, 0); +module_param(min_rx_pkt, int, 0); +module_param(max_rx_gap, int, 0); +module_param(max_rx_latency, int, 0); +module_param(min_tx_pkt, int, 0); +module_param(max_tx_gap, int, 0); +module_param(max_tx_latency, int, 0); +module_param(rx_copybreak, int, 0); +module_param_array(rx_params, int, NULL, 0); +module_param_array(tx_params, int, NULL, 0); +module_param_array(options, int, NULL, 0); +module_param_array(full_duplex, int, NULL, 0); +module_param(force32, int, 0); MODULE_PARM_DESC(max_interrupt_work, "GNIC-II maximum events handled per interrupt"); MODULE_PARM_DESC(mtu, "GNIC-II MTU (all boards)"); MODULE_PARM_DESC(debug, "GNIC-II debug level (0-7)"); @@ -549,7 +550,7 @@ MODULE_PARM_DESC(options, "GNIC-II Bits 0-3: media type, bits 4-6: as force32, b 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 read_eeprom(void __iomem *ioaddr, int location); 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); @@ -565,7 +566,8 @@ static void hamachi_error(struct net_device *dev, int intr_status); static int hamachi_close(struct net_device *dev); static struct net_device_stats *hamachi_get_stats(struct net_device *dev); static void set_rx_mode(struct net_device *dev); - +static struct ethtool_ops ethtool_ops; +static struct ethtool_ops ethtool_ops_no_mii; static int __devinit hamachi_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) @@ -574,7 +576,8 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev, int option, i, rx_int_var, tx_int_var, boguscnt; int chip_id = ent->driver_data; int irq; - long ioaddr; + void __iomem *ioaddr; + unsigned long base; static int card_idx; struct net_device *dev; void *ring_space; @@ -593,9 +596,9 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev, goto err_out; } - ioaddr = pci_resource_start(pdev, 0); + base = pci_resource_start(pdev, 0); #ifdef __alpha__ /* Really "64 bit addrs" */ - ioaddr |= (pci_resource_start(pdev, 1) << 32); + base |= (pci_resource_start(pdev, 1) << 32); #endif pci_set_master(pdev); @@ -604,7 +607,7 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev, if (i) return i; irq = pdev->irq; - ioaddr = (long) ioremap(ioaddr, 0x400); + ioaddr = ioremap(base, 0x400); if (!ioaddr) goto err_out_release; @@ -631,7 +634,7 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev, read_eeprom(ioaddr, i), i % 16 != 15 ? " " : "\n"); #endif - hmp = dev->priv; + hmp = netdev_priv(dev); spin_lock_init(&hmp->lock); hmp->mii_if.dev = dev; @@ -677,7 +680,8 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev, i = readb(ioaddr + PCIClkMeas); } - dev->base_addr = ioaddr; + hmp->base = ioaddr; + dev->base_addr = (unsigned long)ioaddr; dev->irq = irq; pci_set_drvdata(pdev, dev); @@ -725,6 +729,10 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev, dev->get_stats = &hamachi_get_stats; dev->set_multicast_list = &set_rx_mode; dev->do_ioctl = &netdev_ioctl; + if (chip_tbl[hmp->chip_id].flags & CanHaveMII) + SET_ETHTOOL_OPS(dev, ðtool_ops); + else + SET_ETHTOOL_OPS(dev, ðtool_ops_no_mii); dev->tx_timeout = &hamachi_tx_timeout; dev->watchdog_timeo = TX_TIMEOUT; if (mtu) @@ -736,7 +744,7 @@ static int __devinit hamachi_init_one (struct pci_dev *pdev, goto err_out_unmap_rx; } - printk(KERN_INFO "%s: %s type %x at 0x%lx, ", + printk(KERN_INFO "%s: %s type %x at %p, ", dev->name, chip_tbl[chip_id].name, readl(ioaddr + ChipRev), ioaddr); for (i = 0; i < 5; i++) @@ -785,14 +793,14 @@ err_out_unmap_tx: err_out_cleardev: free_netdev (dev); err_out_iounmap: - iounmap((char *)ioaddr); + iounmap(ioaddr); err_out_release: pci_release_regions(pdev); err_out: return ret; } -static int __devinit read_eeprom(long ioaddr, int location) +static int __devinit read_eeprom(void __iomem *ioaddr, int location) { int bogus_cnt = 1000; @@ -814,7 +822,8 @@ static int __devinit read_eeprom(long ioaddr, int location) static int mdio_read(struct net_device *dev, int phy_id, int location) { - long ioaddr = dev->base_addr; + struct hamachi_private *hmp = netdev_priv(dev); + void __iomem *ioaddr = hmp->base; int i; /* We should check busy first - per docs -KDU */ @@ -831,7 +840,8 @@ 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) { - long ioaddr = dev->base_addr; + struct hamachi_private *hmp = netdev_priv(dev); + void __iomem *ioaddr = hmp->base; int i; /* We should check busy first - per docs -KDU */ @@ -851,8 +861,8 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val static int hamachi_open(struct net_device *dev) { - struct hamachi_private *hmp = dev->priv; - long ioaddr = dev->base_addr; + struct hamachi_private *hmp = netdev_priv(dev); + void __iomem *ioaddr = hmp->base; int i; u32 rx_int_var, tx_int_var; u16 fifo_info; @@ -982,7 +992,7 @@ static int hamachi_open(struct net_device *dev) writew(0x001D, ioaddr + RxDMACtrl); writew(0x001D, ioaddr + TxDMACtrl); #endif - writew(0x0001, dev->base_addr + RxCmd); + writew(0x0001, ioaddr + RxCmd); if (hamachi_debug > 2) { printk(KERN_DEBUG "%s: Done hamachi_open(), status: Rx %x Tx %x.\n", @@ -1000,7 +1010,7 @@ static int hamachi_open(struct net_device *dev) static inline int hamachi_tx(struct net_device *dev) { - struct hamachi_private *hmp = dev->priv; + struct hamachi_private *hmp = netdev_priv(dev); /* Update the dirty pointer until we find an entry that is still owned by the card */ @@ -1032,8 +1042,8 @@ static inline int hamachi_tx(struct net_device *dev) static void hamachi_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; - struct hamachi_private *hmp = dev->priv; - long ioaddr = dev->base_addr; + struct hamachi_private *hmp = netdev_priv(dev); + void __iomem *ioaddr = hmp->base; int next_tick = 10*HZ; if (hamachi_debug > 2) { @@ -1057,8 +1067,8 @@ static void hamachi_timer(unsigned long data) static void hamachi_tx_timeout(struct net_device *dev) { int i; - struct hamachi_private *hmp = dev->priv; - long ioaddr = dev->base_addr; + struct hamachi_private *hmp = netdev_priv(dev); + void __iomem *ioaddr = hmp->base; printk(KERN_WARNING "%s: Hamachi transmit timed out, status %8.8x," " resetting...\n", dev->name, (int)readw(ioaddr + TxStatus)); @@ -1110,7 +1120,7 @@ static void hamachi_tx_timeout(struct net_device *dev) } udelay(60); /* Sleep 60 us just for safety sake */ - writew(0x0002, dev->base_addr + RxCmd); /* STOP Rx */ + writew(0x0002, ioaddr + RxCmd); /* STOP Rx */ writeb(0x01, ioaddr + ChipReset); /* Reinit the hardware */ @@ -1152,9 +1162,9 @@ static void hamachi_tx_timeout(struct net_device *dev) hmp->stats.tx_errors++; /* Restart the chip's Tx/Rx processes . */ - writew(0x0002, dev->base_addr + TxCmd); /* STOP Tx */ - writew(0x0001, dev->base_addr + TxCmd); /* START Tx */ - writew(0x0001, dev->base_addr + RxCmd); /* START Rx */ + writew(0x0002, ioaddr + TxCmd); /* STOP Tx */ + writew(0x0001, ioaddr + TxCmd); /* START Tx */ + writew(0x0001, ioaddr + RxCmd); /* START Rx */ netif_wake_queue(dev); } @@ -1163,7 +1173,7 @@ static void hamachi_tx_timeout(struct net_device *dev) /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ static void hamachi_init_ring(struct net_device *dev) { - struct hamachi_private *hmp = dev->priv; + struct hamachi_private *hmp = netdev_priv(dev); int i; hmp->tx_full = 0; @@ -1255,7 +1265,7 @@ do { \ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev) { - struct hamachi_private *hmp = dev->priv; + struct hamachi_private *hmp = netdev_priv(dev); unsigned entry; u16 status; @@ -1270,9 +1280,9 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Wake the potentially-idle transmit channel. */ /* If we don't need to read status, DON'T -KDU */ - status=readw(dev->base_addr + TxStatus); + status=readw(hmp->base + TxStatus); if( !(status & 0x0001) || (status & 0x0002)) - writew(0x0001, dev->base_addr + TxCmd); + writew(0x0001, hmp->base + TxCmd); return 1; } @@ -1338,9 +1348,9 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev) /* Wake the potentially-idle transmit channel. */ /* If we don't need to read status, DON'T -KDU */ - status=readw(dev->base_addr + TxStatus); + status=readw(hmp->base + TxStatus); if( !(status & 0x0001) || (status & 0x0002)) - writew(0x0001, dev->base_addr + TxCmd); + writew(0x0001, hmp->base + TxCmd); /* Immediately before returning, let's clear as many entries as we can. */ hamachi_tx(dev); @@ -1371,8 +1381,9 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev) static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs *rgs) { struct net_device *dev = dev_instance; - struct hamachi_private *hmp; - long ioaddr, boguscnt = max_interrupt_work; + struct hamachi_private *hmp = netdev_priv(dev); + void __iomem *ioaddr = hmp->base; + long boguscnt = max_interrupt_work; int handled = 0; #ifndef final_version /* Can never occur. */ @@ -1382,8 +1393,6 @@ static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs } #endif - ioaddr = dev->base_addr; - hmp = dev->priv; spin_lock(&hmp->lock); do { @@ -1477,7 +1486,7 @@ static irqreturn_t hamachi_interrupt(int irq, void *dev_instance, struct pt_regs for clarity and better register allocation. */ static int hamachi_rx(struct net_device *dev) { - struct hamachi_private *hmp = dev->priv; + struct hamachi_private *hmp = netdev_priv(dev); int entry = hmp->cur_rx % RX_RING_SIZE; int boguscnt = (hmp->dirty_rx + RX_RING_SIZE) - hmp->cur_rx; @@ -1682,8 +1691,8 @@ static int hamachi_rx(struct net_device *dev) /* Restart Rx engine if stopped. */ /* If we don't need to check status, don't. -KDU */ - if (readw(dev->base_addr + RxStatus) & 0x0002) - writew(0x0001, dev->base_addr + RxCmd); + if (readw(hmp->base + RxStatus) & 0x0002) + writew(0x0001, hmp->base + RxCmd); return 0; } @@ -1692,8 +1701,8 @@ static int hamachi_rx(struct net_device *dev) than just errors. */ static void hamachi_error(struct net_device *dev, int intr_status) { - long ioaddr = dev->base_addr; - struct hamachi_private *hmp = dev->priv; + struct hamachi_private *hmp = netdev_priv(dev); + void __iomem *ioaddr = hmp->base; if (intr_status & (LinkChange|NegotiationChange)) { if (hamachi_debug > 1) @@ -1726,8 +1735,8 @@ static void hamachi_error(struct net_device *dev, int intr_status) static int hamachi_close(struct net_device *dev) { - long ioaddr = dev->base_addr; - struct hamachi_private *hmp = dev->priv; + struct hamachi_private *hmp = netdev_priv(dev); + void __iomem *ioaddr = hmp->base; struct sk_buff *skb; int i; @@ -1812,8 +1821,8 @@ static int hamachi_close(struct net_device *dev) static struct net_device_stats *hamachi_get_stats(struct net_device *dev) { - long ioaddr = dev->base_addr; - struct hamachi_private *hmp = dev->priv; + struct hamachi_private *hmp = netdev_priv(dev); + void __iomem *ioaddr = hmp->base; /* We should lock this segment of code for SMP eventually, although the vulnerability window is very small and statistics are @@ -1840,7 +1849,8 @@ static struct net_device_stats *hamachi_get_stats(struct net_device *dev) static void set_rx_mode(struct net_device *dev) { - long ioaddr = dev->base_addr; + struct hamachi_private *hmp = netdev_priv(dev); + void __iomem *ioaddr = hmp->base; if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ /* Unconditionally log net taps. */ @@ -1867,84 +1877,76 @@ static void set_rx_mode(struct net_device *dev) } } -static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr) +static int check_if_running(struct net_device *dev) { - struct hamachi_private *np = dev->priv; - u32 ethcmd; - - if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) - return -EFAULT; - - switch (ethcmd) { - case ETHTOOL_GDRVINFO: { - struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO}; - strcpy(info.driver, DRV_NAME); - strcpy(info.version, DRV_VERSION); - strcpy(info.bus_info, pci_name(np->pci_dev)); - if (copy_to_user(useraddr, &info, sizeof(info))) - return -EFAULT; - return 0; - } + if (!netif_running(dev)) + return -EINVAL; + 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; +static void hamachi_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + struct hamachi_private *np = netdev_priv(dev); + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, pci_name(np->pci_dev)); } +static int hamachi_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +{ + struct hamachi_private *np = netdev_priv(dev); + spin_lock_irq(&np->lock); + mii_ethtool_gset(&np->mii_if, ecmd); + spin_unlock_irq(&np->lock); + return 0; +} + +static int hamachi_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) +{ + struct hamachi_private *np = netdev_priv(dev); + int res; + spin_lock_irq(&np->lock); + res = mii_ethtool_sset(&np->mii_if, ecmd); + spin_unlock_irq(&np->lock); + return res; +} + +static int hamachi_nway_reset(struct net_device *dev) +{ + struct hamachi_private *np = netdev_priv(dev); + return mii_nway_restart(&np->mii_if); +} + +static u32 hamachi_get_link(struct net_device *dev) +{ + struct hamachi_private *np = netdev_priv(dev); + return mii_link_ok(&np->mii_if); +} + +static struct ethtool_ops ethtool_ops = { + .begin = check_if_running, + .get_drvinfo = hamachi_get_drvinfo, + .get_settings = hamachi_get_settings, + .set_settings = hamachi_set_settings, + .nway_reset = hamachi_nway_reset, + .get_link = hamachi_get_link, +}; + +static struct ethtool_ops ethtool_ops_no_mii = { + .begin = check_if_running, + .get_drvinfo = hamachi_get_drvinfo, +}; + static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct hamachi_private *np = dev->priv; + struct hamachi_private *np = netdev_priv(dev); struct mii_ioctl_data *data = if_mii(rq); int rc; if (!netif_running(dev)) return -EINVAL; - if (cmd == SIOCETHTOOL) - rc = netdev_ethtool_ioctl(dev, rq->ifr_data); - - else if (cmd == (SIOCDEVPRIVATE+3)) { /* set rx,tx intr params */ + if (cmd == (SIOCDEVPRIVATE+3)) { /* set rx,tx intr params */ u32 *d = (u32 *)&rq->ifr_ifru; /* Should add this check here or an ordinary user can do nasty * things. -KDU @@ -1953,11 +1955,11 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) */ if (!capable(CAP_NET_ADMIN)) return -EPERM; - writel(d[0], dev->base_addr + TxIntrCtrl); - writel(d[1], dev->base_addr + RxIntrCtrl); + writel(d[0], np->base + TxIntrCtrl); + writel(d[1], np->base + RxIntrCtrl); printk(KERN_NOTICE "%s: tx %08x, rx %08x intr\n", dev->name, - (u32) readl(dev->base_addr + TxIntrCtrl), - (u32) readl(dev->base_addr + RxIntrCtrl)); + (u32) readl(np->base + TxIntrCtrl), + (u32) readl(np->base + RxIntrCtrl)); rc = 0; } @@ -1976,14 +1978,14 @@ static void __devexit hamachi_remove_one (struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); if (dev) { - struct hamachi_private *hmp = dev->priv; + struct hamachi_private *hmp = netdev_priv(dev); pci_free_consistent(pdev, RX_TOTAL_SIZE, hmp->rx_ring, hmp->rx_ring_dma); pci_free_consistent(pdev, TX_TOTAL_SIZE, hmp->tx_ring, hmp->tx_ring_dma); unregister_netdev(dev); - iounmap((char *)dev->base_addr); + iounmap(hmp->base); free_netdev(dev); pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); @@ -2009,10 +2011,7 @@ static int __init hamachi_init (void) #ifdef MODULE printk(version); #endif - if (pci_register_driver(&hamachi_driver) > 0) - return 0; - pci_unregister_driver(&hamachi_driver); - return -ENODEV; + return pci_register_driver(&hamachi_driver); } static void __exit hamachi_exit (void)