diff options
Diffstat (limited to 'drivers/net/via-velocity.c')
| -rw-r--r-- | drivers/net/via-velocity.c | 122 |
1 files changed, 64 insertions, 58 deletions
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index ed1f837c8fda..f5b0078eb4ad 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -47,7 +47,6 @@ #include <linux/module.h> #include <linux/types.h> -#include <linux/config.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/errno.h> @@ -65,7 +64,6 @@ #include <linux/wait.h> #include <asm/io.h> #include <linux/if.h> -#include <linux/config.h> #include <asm/uaccess.h> #include <linux/proc_fs.h> #include <linux/inetdevice.h> @@ -231,7 +229,8 @@ static int rx_copybreak = 200; module_param(rx_copybreak, int, 0644); MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames"); -static void velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr, struct velocity_info_tbl *info); +static void velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr, + const struct velocity_info_tbl *info); static int velocity_get_pci_info(struct velocity_info *, struct pci_dev *pdev); static void velocity_print_info(struct velocity_info *vptr); static int velocity_open(struct net_device *dev); @@ -248,6 +247,7 @@ static void velocity_free_rd_ring(struct velocity_info *vptr); static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_info *); static int velocity_soft_reset(struct velocity_info *vptr); static void mii_init(struct velocity_info *vptr, u32 mii_status); +static u32 velocity_get_link(struct net_device *dev); static u32 velocity_get_opt_media_mode(struct velocity_info *vptr); static void velocity_print_link_status(struct velocity_info *vptr); static void safe_disable_mii_autopoll(struct mac_regs __iomem * regs); @@ -295,9 +295,9 @@ static void velocity_unregister_notifier(void) * Internal board variants. At the moment we have only one */ -static struct velocity_info_tbl chip_info_table[] = { - {CHIP_TYPE_VT6110, "VIA Networking Velocity Family Gigabit Ethernet Adapter", 256, 1, 0x00FFFFFFUL}, - {0, NULL} +static const struct velocity_info_tbl chip_info_table[] __devinitdata = { + {CHIP_TYPE_VT6110, "VIA Networking Velocity Family Gigabit Ethernet Adapter", 1, 0x00FFFFFFUL}, + { } }; /* @@ -305,10 +305,9 @@ static struct velocity_info_tbl chip_info_table[] = { * device driver. Used for hotplug autoloading. */ -static struct pci_device_id velocity_id_table[] __devinitdata = { - {PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_612X, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) chip_info_table}, - {0, } +static const struct pci_device_id velocity_id_table[] __devinitdata = { + { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_612X) }, + { } }; MODULE_DEVICE_TABLE(pci, velocity_id_table); @@ -342,7 +341,7 @@ static char __devinit *get_chip_name(enum chip_type chip_id) static void __devexit velocity_remove1(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev); - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); #ifdef CONFIG_PM unsigned long flags; @@ -687,21 +686,23 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi static int first = 1; struct net_device *dev; int i; - struct velocity_info_tbl *info = (struct velocity_info_tbl *) ent->driver_data; + const struct velocity_info_tbl *info = &chip_info_table[ent->driver_data]; struct velocity_info *vptr; struct mac_regs __iomem * regs; int ret = -ENOMEM; + /* FIXME: this driver, like almost all other ethernet drivers, + * can support more than MAX_UNITS. + */ if (velocity_nics >= MAX_UNITS) { - printk(KERN_NOTICE VELOCITY_NAME ": already found %d NICs.\n", - velocity_nics); + dev_notice(&pdev->dev, "already found %d NICs.\n", + velocity_nics); return -ENODEV; } dev = alloc_etherdev(sizeof(struct velocity_info)); - - if (dev == NULL) { - printk(KERN_ERR VELOCITY_NAME ": allocate net device failed.\n"); + if (!dev) { + dev_err(&pdev->dev, "allocate net device failed.\n"); goto out; } @@ -709,7 +710,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); - vptr = dev->priv; + vptr = netdev_priv(dev); if (first) { @@ -732,17 +733,17 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi ret = velocity_get_pci_info(vptr, pdev); if (ret < 0) { - printk(KERN_ERR VELOCITY_NAME ": Failed to find PCI device.\n"); + /* error message already printed */ goto err_disable; } ret = pci_request_regions(pdev, VELOCITY_NAME); if (ret < 0) { - printk(KERN_ERR VELOCITY_NAME ": Failed to find PCI device.\n"); + dev_err(&pdev->dev, "No PCI resources.\n"); goto err_disable; } - regs = ioremap(vptr->memaddr, vptr->io_size); + regs = ioremap(vptr->memaddr, VELOCITY_IO_SIZE); if (regs == NULL) { ret = -EIO; goto err_release_res; @@ -798,6 +799,9 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi if (ret < 0) goto err_iounmap; + if (velocity_get_link(dev)) + netif_carrier_off(dev); + velocity_print_info(vptr); pci_set_drvdata(pdev, dev); @@ -857,13 +861,14 @@ static void __devinit velocity_print_info(struct velocity_info *vptr) * discovered. */ -static void __devinit velocity_init_info(struct pci_dev *pdev, struct velocity_info *vptr, struct velocity_info_tbl *info) +static void __devinit velocity_init_info(struct pci_dev *pdev, + struct velocity_info *vptr, + const struct velocity_info_tbl *info) { memset(vptr, 0, sizeof(struct velocity_info)); vptr->pdev = pdev; vptr->chip_id = info->chip_id; - vptr->io_size = info->io_size; vptr->num_txq = info->txqueue; vptr->multicast_limit = MCAM_SIZE; spin_lock_init(&vptr->lock); @@ -881,8 +886,7 @@ static void __devinit velocity_init_info(struct pci_dev *pdev, struct velocity_i static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pci_dev *pdev) { - - if(pci_read_config_byte(pdev, PCI_REVISION_ID, &vptr->rev_id) < 0) + if (pci_read_config_byte(pdev, PCI_REVISION_ID, &vptr->rev_id) < 0) return -EIO; pci_set_master(pdev); @@ -890,24 +894,20 @@ static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pc vptr->ioaddr = pci_resource_start(pdev, 0); vptr->memaddr = pci_resource_start(pdev, 1); - if(!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) - { - printk(KERN_ERR "%s: region #0 is not an I/O resource, aborting.\n", - pci_name(pdev)); + if (!(pci_resource_flags(pdev, 0) & IORESOURCE_IO)) { + dev_err(&pdev->dev, + "region #0 is not an I/O resource, aborting.\n"); return -EINVAL; } - if((pci_resource_flags(pdev, 1) & IORESOURCE_IO)) - { - printk(KERN_ERR "%s: region #1 is an I/O resource, aborting.\n", - pci_name(pdev)); + if ((pci_resource_flags(pdev, 1) & IORESOURCE_IO)) { + dev_err(&pdev->dev, + "region #1 is an I/O resource, aborting.\n"); return -EINVAL; } - if(pci_resource_len(pdev, 1) < 256) - { - printk(KERN_ERR "%s: region #1 is too small.\n", - pci_name(pdev)); + if (pci_resource_len(pdev, 1) < VELOCITY_IO_SIZE) { + dev_err(&pdev->dev, "region #1 is too small.\n"); return -EINVAL; } vptr->pdev = pdev; @@ -1653,8 +1653,10 @@ static void velocity_error(struct velocity_info *vptr, int status) if (linked) { vptr->mii_status &= ~VELOCITY_LINK_FAIL; + netif_carrier_on(vptr->dev); } else { vptr->mii_status |= VELOCITY_LINK_FAIL; + netif_carrier_off(vptr->dev); } velocity_print_link_status(vptr); @@ -1724,7 +1726,7 @@ static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_ static int velocity_open(struct net_device *dev) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); int ret; vptr->rx_buf_sz = (dev->mtu <= 1504 ? PKT_BUF_SZ : dev->mtu + 32); @@ -1746,7 +1748,7 @@ static int velocity_open(struct net_device *dev) velocity_init_registers(vptr, VELOCITY_INIT_COLD); - ret = request_irq(vptr->pdev->irq, &velocity_intr, SA_SHIRQ, + ret = request_irq(vptr->pdev->irq, &velocity_intr, IRQF_SHARED, dev->name, dev); if (ret < 0) { /* Power down the chip */ @@ -1781,7 +1783,7 @@ err_free_desc_rings: static int velocity_change_mtu(struct net_device *dev, int new_mtu) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); unsigned long flags; int oldmtu = dev->mtu; int ret = 0; @@ -1857,7 +1859,7 @@ static void velocity_shutdown(struct velocity_info *vptr) static int velocity_close(struct net_device *dev) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); netif_stop_queue(dev); velocity_shutdown(vptr); @@ -1890,7 +1892,7 @@ static int velocity_close(struct net_device *dev) static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); int qnum = 0; struct tx_desc *td_ptr; struct velocity_td_info *tdinfo; @@ -1899,6 +1901,13 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) int pktlen = skb->len; +#ifdef VELOCITY_ZERO_COPY_SUPPORT + if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) { + kfree_skb(skb); + return 0; + } +#endif + spin_lock_irqsave(&vptr->lock, flags); index = vptr->td_curr[qnum]; @@ -1914,8 +1923,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) */ if (pktlen < ETH_ZLEN) { /* Cannot occur until ZC support */ - if(skb_linearize(skb, GFP_ATOMIC)) - return 0; pktlen = ETH_ZLEN; memcpy(tdinfo->buf, skb->data, skb->len); memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len); @@ -1933,7 +1940,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) int nfrags = skb_shinfo(skb)->nr_frags; tdinfo->skb = skb; if (nfrags > 6) { - skb_linearize(skb, GFP_ATOMIC); memcpy(tdinfo->buf, skb->data, skb->len); tdinfo->skb_dma[0] = tdinfo->buf_dma; td_ptr->tdesc0.pktsize = @@ -2041,7 +2047,7 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev) static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs) { struct net_device *dev = dev_instance; - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); u32 isr_status; int max_count = 0; @@ -2096,7 +2102,7 @@ static int velocity_intr(int irq, void *dev_instance, struct pt_regs *regs) static void velocity_set_multi(struct net_device *dev) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); struct mac_regs __iomem * regs = vptr->mac_regs; u8 rx_mode; int i; @@ -2145,7 +2151,7 @@ static void velocity_set_multi(struct net_device *dev) static struct net_device_stats *velocity_get_stats(struct net_device *dev) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); /* If the hardware is down, don't touch MII */ if(!netif_running(dev)) @@ -2188,7 +2194,7 @@ static struct net_device_stats *velocity_get_stats(struct net_device *dev) static int velocity_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); int ret; /* If we are asked for information and the device is power @@ -2817,7 +2823,7 @@ static void enable_flow_control_ability(struct velocity_info *vptr) static int velocity_ethtool_up(struct net_device *dev) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); if (!netif_running(dev)) pci_set_power_state(vptr->pdev, PCI_D0); return 0; @@ -2833,14 +2839,14 @@ static int velocity_ethtool_up(struct net_device *dev) static void velocity_ethtool_down(struct net_device *dev) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); if (!netif_running(dev)) pci_set_power_state(vptr->pdev, PCI_D3hot); } static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); struct mac_regs __iomem * regs = vptr->mac_regs; u32 status; status = check_connection_type(vptr->mac_regs); @@ -2865,7 +2871,7 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); u32 curr_status; u32 new_status = 0; int ret = 0; @@ -2888,14 +2894,14 @@ static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd static u32 velocity_get_link(struct net_device *dev) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); struct mac_regs __iomem * regs = vptr->mac_regs; return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 0 : 1; } static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); strcpy(info->driver, VELOCITY_NAME); strcpy(info->version, VELOCITY_VERSION); strcpy(info->bus_info, pci_name(vptr->pdev)); @@ -2903,7 +2909,7 @@ static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo static void velocity_ethtool_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); wol->supported = WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_ARP; wol->wolopts |= WAKE_MAGIC; /* @@ -2919,7 +2925,7 @@ static void velocity_ethtool_get_wol(struct net_device *dev, struct ethtool_woli static int velocity_ethtool_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); if (!(wol->wolopts & (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_ARP))) return -EFAULT; @@ -2984,7 +2990,7 @@ static struct ethtool_ops velocity_ethtool_ops = { static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - struct velocity_info *vptr = dev->priv; + struct velocity_info *vptr = netdev_priv(dev); struct mac_regs __iomem * regs = vptr->mac_regs; unsigned long flags; struct mii_ioctl_data *miidata = if_mii(ifr); |
