sky2: Factor out code to calculate packet sizes
[safe/jmp/linux-2.6] / drivers / net / amd8111e.c
index 85f7276..bdffdfb 100644 (file)
@@ -101,9 +101,9 @@ Revision History:
 
 #include "amd8111e.h"
 #define MODULE_NAME    "amd8111e"
-#define MODULE_VERS    "3.0.6"
+#define MODULE_VERS    "3.0.7"
 MODULE_AUTHOR("Advanced Micro Devices, Inc.");
-MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version 3.0.6");
+MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version "MODULE_VERS);
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, amd8111e_pci_tbl);
 module_param_array(speed_duplex, int, NULL, 0);
@@ -113,7 +113,7 @@ MODULE_PARM_DESC(coalesce, "Enable or Disable interrupt coalescing, 1: Enable, 0
 module_param_array(dynamic_ipg, bool, NULL, 0);
 MODULE_PARM_DESC(dynamic_ipg, "Enable or Disable dynamic IPG, 1: Enable, 0: Disable");
 
-static struct pci_device_id amd8111e_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(amd8111e_pci_tbl) = {
 
        { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD8111E_7462,
         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
@@ -644,10 +644,6 @@ This function frees the  transmiter and receiver descriptor rings.
 */
 static void amd8111e_free_ring(struct amd8111e_priv* lp)
 {
-
-       /* Free transmit and receive skbs */
-       amd8111e_free_skbs(lp->amd8111e_net_dev);
-
        /* Free transmit and receive descriptor rings */
        if(lp->rx_ring){
                pci_free_consistent(lp->pci_dev,
@@ -671,11 +667,7 @@ This is the receive indication function for packets with vlan tag.
 */
 static int amd8111e_vlan_rx(struct amd8111e_priv *lp, struct sk_buff *skb, u16 vlan_tag)
 {
-#ifdef CONFIG_AMD8111E_NAPI
        return vlan_hwaccel_receive_skb(skb, lp->vlgrp,vlan_tag);
-#else
-       return vlan_hwaccel_rx(skb, lp->vlgrp, vlan_tag);
-#endif /* CONFIG_AMD8111E_NAPI */
 }
 #endif
 
@@ -722,7 +714,6 @@ static int amd8111e_tx(struct net_device *dev)
        return 0;
 }
 
-#ifdef CONFIG_AMD8111E_NAPI
 /* This function handles the driver receive operation in polling mode */
 static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
 {
@@ -734,7 +725,6 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
        int min_pkt_len, status;
        unsigned int intr0;
        int num_rx_pkt = 0;
-       /*int max_rx_pkt = NUM_RX_BUFFERS;*/
        short pkt_len;
 #if AMD8111E_VLAN_TAG_USED
        short vtag;
@@ -819,7 +809,6 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
                        lp->coal_conf.rx_packets++;
                        lp->coal_conf.rx_bytes += pkt_len;
                        num_rx_pkt++;
-                       dev->last_rx = jiffies;
 
                err_next_pkt:
                        lp->rx_ring[rx_index].buff_phy_addr
@@ -839,119 +828,19 @@ static int amd8111e_rx_poll(struct napi_struct *napi, int budget)
 
        } while(intr0 & RINT0);
 
-       /* Receive descriptor is empty now */
-       spin_lock_irqsave(&lp->lock, flags);
-       __netif_rx_complete(dev, napi);
-       writel(VAL0|RINTEN0, mmio + INTEN0);
-       writel(VAL2 | RDMD0, mmio + CMD0);
-       spin_unlock_irqrestore(&lp->lock, flags);
+       if (rx_pkt_limit > 0) {
+               /* Receive descriptor is empty now */
+               spin_lock_irqsave(&lp->lock, flags);
+               __napi_complete(napi);
+               writel(VAL0|RINTEN0, mmio + INTEN0);
+               writel(VAL2 | RDMD0, mmio + CMD0);
+               spin_unlock_irqrestore(&lp->lock, flags);
+       }
 
 rx_not_empty:
        return num_rx_pkt;
 }
 
-#else
-/*
-This function will check the ownership of receive buffers and descriptors. It will indicate to kernel up to half the number of maximum receive buffers in the descriptor ring, in a single receive interrupt. It will also replenish the descriptors with new skbs.
-*/
-static int amd8111e_rx(struct net_device *dev)
-{
-       struct amd8111e_priv *lp = netdev_priv(dev);
-       struct sk_buff *skb,*new_skb;
-       int rx_index = lp->rx_idx & RX_RING_DR_MOD_MASK;
-       int min_pkt_len, status;
-       int num_rx_pkt = 0;
-       int max_rx_pkt = NUM_RX_BUFFERS;
-       short pkt_len;
-#if AMD8111E_VLAN_TAG_USED
-       short vtag;
-#endif
-
-       /* If we own the next entry, it's a new packet. Send it up. */
-       while(++num_rx_pkt <= max_rx_pkt){
-               status = le16_to_cpu(lp->rx_ring[rx_index].rx_flags);
-               if(status & OWN_BIT)
-                       return 0;
-
-               /* check if err summary bit is set */
-               if(status & ERR_BIT){
-                       /*
-                        * There is a tricky error noted by John Murphy,
-                        * <murf@perftech.com> to Russ Nelson: Even with full-sized
-                        * buffers it's possible for a jabber packet to use two
-                        * buffers, with only the last correctly noting the error.                       */
-                       /* reseting flags */
-                       lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
-                       goto err_next_pkt;
-               }
-               /* check for STP and ENP */
-               if(!((status & STP_BIT) && (status & ENP_BIT))){
-                       /* reseting flags */
-                       lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
-                       goto err_next_pkt;
-               }
-               pkt_len = le16_to_cpu(lp->rx_ring[rx_index].msg_count) - 4;
-
-#if AMD8111E_VLAN_TAG_USED
-               vtag = status & TT_MASK;
-               /*MAC will strip vlan tag*/
-               if(lp->vlgrp != NULL && vtag !=0)
-                       min_pkt_len =MIN_PKT_LEN - 4;
-               else
-#endif
-                       min_pkt_len =MIN_PKT_LEN;
-
-               if (pkt_len < min_pkt_len) {
-                       lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
-                       lp->drv_rx_errors++;
-                       goto err_next_pkt;
-               }
-               if(!(new_skb = dev_alloc_skb(lp->rx_buff_len))){
-                       /* if allocation fail,
-                               ignore that pkt and go to next one */
-                       lp->rx_ring[rx_index].rx_flags &= RESET_RX_FLAGS;
-                       lp->drv_rx_errors++;
-                       goto err_next_pkt;
-               }
-
-               skb_reserve(new_skb, 2);
-               skb = lp->rx_skbuff[rx_index];
-               pci_unmap_single(lp->pci_dev,lp->rx_dma_addr[rx_index],
-                       lp->rx_buff_len-2, PCI_DMA_FROMDEVICE);
-               skb_put(skb, pkt_len);
-               lp->rx_skbuff[rx_index] = new_skb;
-               lp->rx_dma_addr[rx_index] = pci_map_single(lp->pci_dev,
-                       new_skb->data, lp->rx_buff_len-2,PCI_DMA_FROMDEVICE);
-
-               skb->protocol = eth_type_trans(skb, dev);
-
-#if AMD8111E_VLAN_TAG_USED
-               if(lp->vlgrp != NULL && (vtag == TT_VLAN_TAGGED)){
-                       amd8111e_vlan_rx(lp, skb,
-                                le16_to_cpu(lp->rx_ring[rx_index].tag_ctrl_info));
-               } else
-#endif
-
-                       netif_rx (skb);
-                       /*COAL update rx coalescing parameters*/
-                       lp->coal_conf.rx_packets++;
-                       lp->coal_conf.rx_bytes += pkt_len;
-
-                       dev->last_rx = jiffies;
-
-err_next_pkt:
-               lp->rx_ring[rx_index].buff_phy_addr
-                        = cpu_to_le32(lp->rx_dma_addr[rx_index]);
-               lp->rx_ring[rx_index].buff_count =
-                               cpu_to_le16(lp->rx_buff_len-2);
-               wmb();
-               lp->rx_ring[rx_index].rx_flags |= cpu_to_le16(OWN_BIT);
-               rx_index = (++lp->rx_idx) & RX_RING_DR_MOD_MASK;
-       }
-
-       return 0;
-}
-#endif /* CONFIG_AMD8111E_NAPI */
 /*
 This function will indicate the link status to the kernel.
 */
@@ -1280,29 +1169,21 @@ static irqreturn_t amd8111e_interrupt(int irq, void *dev_id)
        writel(intr0, mmio + INT0);
 
        /* Check if Receive Interrupt has occurred. */
-#ifdef CONFIG_AMD8111E_NAPI
-       if(intr0 & RINT0){
-               if(netif_rx_schedule_prep(dev, &lp->napi)){
+       if (intr0 & RINT0) {
+               if (napi_schedule_prep(&lp->napi)) {
                        /* Disable receive interupts */
                        writel(RINTEN0, mmio + INTEN0);
                        /* Schedule a polling routine */
-                       __netif_rx_schedule(dev, &lp->napi);
-               }
-               else if (intren0 & RINTEN0) {
-                       printk("************Driver bug! \
-                               interrupt while in poll\n");
+                       __napi_schedule(&lp->napi);
+               } else if (intren0 & RINTEN0) {
+                       printk("************Driver bug! interrupt while in poll\n");
                        /* Fix by disable receive interrupts */
                        writel(RINTEN0, mmio + INTEN0);
                }
        }
-#else
-       if(intr0 & RINT0){
-               amd8111e_rx(dev);
-               writel(VAL2 | RDMD0, mmio + CMD0);
-       }
-#endif /* CONFIG_AMD8111E_NAPI */
+
        /* Check if  Transmit Interrupt has occurred. */
-       if(intr0 & TINT0)
+       if (intr0 & TINT0)
                amd8111e_tx(dev);
 
        /* Check if  Link Change Interrupt has occurred. */
@@ -1340,15 +1221,15 @@ static int amd8111e_close(struct net_device * dev)
        struct amd8111e_priv *lp = netdev_priv(dev);
        netif_stop_queue(dev);
 
-#ifdef CONFIG_AMD8111E_NAPI
        napi_disable(&lp->napi);
-#endif
 
        spin_lock_irq(&lp->lock);
 
        amd8111e_disable_interrupt(lp);
        amd8111e_stop_chip(lp);
-       amd8111e_free_ring(lp);
+
+       /* Free transmit and receive skbs */
+       amd8111e_free_skbs(lp->amd8111e_net_dev);
 
        netif_carrier_off(lp->amd8111e_net_dev);
 
@@ -1358,6 +1239,7 @@ static int amd8111e_close(struct net_device * dev)
 
        spin_unlock_irq(&lp->lock);
        free_irq(dev->irq, dev);
+       amd8111e_free_ring(lp);
 
        /* Update the statistics before closing */
        amd8111e_get_stats(dev);
@@ -1374,9 +1256,7 @@ static int amd8111e_open(struct net_device * dev )
                                         dev->name, dev))
                return -EAGAIN;
 
-#ifdef CONFIG_AMD8111E_NAPI
        napi_enable(&lp->napi);
-#endif
 
        spin_lock_irq(&lp->lock);
 
@@ -1384,9 +1264,7 @@ static int amd8111e_open(struct net_device * dev )
 
        if(amd8111e_restart(dev)){
                spin_unlock_irq(&lp->lock);
-#ifdef CONFIG_AMD8111E_NAPI
                napi_disable(&lp->napi);
-#endif
                if (dev->irq)
                        free_irq(dev->irq, dev);
                return -ENOMEM;
@@ -1421,7 +1299,8 @@ static int amd8111e_tx_queue_avail(struct amd8111e_priv* lp )
 This function will queue the transmit packets to the descriptors and will trigger the send operation. It also initializes the transmit descriptors with buffer physical address, byte count, ownership to hardware etc.
 */
 
-static int amd8111e_start_xmit(struct sk_buff *skb, struct net_device * dev)
+static netdev_tx_t amd8111e_start_xmit(struct sk_buff *skb,
+                                      struct net_device * dev)
 {
        struct amd8111e_priv *lp = netdev_priv(dev);
        int tx_index;
@@ -1467,7 +1346,7 @@ static int amd8111e_start_xmit(struct sk_buff *skb, struct net_device * dev)
                netif_stop_queue(dev);
        }
        spin_unlock_irqrestore(&lp->lock, flags);
-       return 0;
+       return NETDEV_TX_OK;
 }
 /*
 This function returns all the memory mapped registers of the device.
@@ -1508,7 +1387,8 @@ static void amd8111e_set_multicast_list(struct net_device *dev)
        }
        else
                writel( PROM, lp->mmio + CMD2);
-       if(dev->flags & IFF_ALLMULTI || dev->mc_count > MAX_FILTER_SIZE){
+       if (dev->flags & IFF_ALLMULTI ||
+           netdev_mc_count(dev) > MAX_FILTER_SIZE) {
                /* get all multicast packet */
                mc_filter[1] = mc_filter[0] = 0xffffffff;
                lp->mc_list = dev->mc_list;
@@ -1516,7 +1396,7 @@ static void amd8111e_set_multicast_list(struct net_device *dev)
                amd8111e_writeq(*(u64*)mc_filter,lp->mmio + LADRF);
                return;
        }
-       if( dev->mc_count == 0 ){
+       if (netdev_mc_empty(dev)) {
                /* get only own packets */
                mc_filter[1] = mc_filter[0] = 0;
                lp->mc_list = NULL;
@@ -1530,7 +1410,7 @@ static void amd8111e_set_multicast_list(struct net_device *dev)
        lp->options |= OPTION_MULTICAST_ENABLE;
        lp->mc_list = dev->mc_list;
        mc_filter[1] = mc_filter[0] = 0;
-       for (i = 0, mc_ptr = dev->mc_list; mc_ptr && i < dev->mc_count;
+       for (i = 0, mc_ptr = dev->mc_list; mc_ptr && i < netdev_mc_count(dev);
                     i++, mc_ptr = mc_ptr->next) {
                bit_num = (ether_crc_le(ETH_ALEN, mc_ptr->dmi_addr) >> 26) & 0x3f;
                mc_filter[bit_num >> 5] |= 1 << (bit_num & 31);
@@ -1644,9 +1524,6 @@ static int amd8111e_ioctl(struct net_device * dev , struct ifreq *ifr, int cmd)
        int err;
        u32 mii_regval;
 
-       if (!capable(CAP_NET_ADMIN))
-               return -EPERM;
-
        switch(cmd) {
        case SIOCGMIIPHY:
                data->phy_id = lp->ext_phy_addr;
@@ -1756,8 +1633,13 @@ static int amd8111e_enable_link_change(struct amd8111e_priv* lp)
        readl(lp->mmio + CMD7);
        return 0;
 }
-/* This function is called when a packet transmission fails to complete within a  resonable period, on the assumption that an interrupts have been failed or the  interface is locked up. This function will reinitialize the hardware */
 
+/*
+ * This function is called when a packet transmission fails to complete
+ * within a reasonable period, on the assumption that an interrupt have
+ * failed or the interface is locked up. This function will reinitialize
+ * the hardware.
+ */
 static void amd8111e_tx_timeout(struct net_device *dev)
 {
        struct amd8111e_priv* lp = netdev_priv(dev);
@@ -1934,6 +1816,25 @@ static void __devinit amd8111e_probe_ext_phy(struct net_device* dev)
        lp->ext_phy_addr = 1;
 }
 
+static const struct net_device_ops amd8111e_netdev_ops = {
+       .ndo_open               = amd8111e_open,
+       .ndo_stop               = amd8111e_close,
+       .ndo_start_xmit         = amd8111e_start_xmit,
+       .ndo_tx_timeout         = amd8111e_tx_timeout,
+       .ndo_get_stats          = amd8111e_get_stats,
+       .ndo_set_multicast_list = amd8111e_set_multicast_list,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = amd8111e_set_mac_address,
+       .ndo_do_ioctl           = amd8111e_ioctl,
+       .ndo_change_mtu         = amd8111e_change_mtu,
+#if AMD8111E_VLAN_TAG_USED
+       .ndo_vlan_rx_register   = amd8111e_vlan_rx_register,
+#endif
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller     = amd8111e_poll,
+#endif
+};
+
 static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
                                  const struct pci_device_id *ent)
 {
@@ -1941,7 +1842,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
        unsigned long reg_addr,reg_len;
        struct amd8111e_priv* lp;
        struct net_device* dev;
-       DECLARE_MAC_BUF(mac);
 
        err = pci_enable_device(pdev);
        if(err){
@@ -1974,7 +1874,7 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
        }
 
        /* Initialize DMA */
-       if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) < 0) {
+       if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) < 0) {
                printk(KERN_ERR "amd8111e: DMA not supported,"
                        "exiting.\n");
                goto err_free_reg;
@@ -1994,7 +1894,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
 
 #if AMD8111E_VLAN_TAG_USED
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX ;
-       dev->vlan_rx_register =amd8111e_vlan_rx_register;
 #endif
 
        lp = netdev_priv(dev);
@@ -2023,29 +1922,16 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
        if(dynamic_ipg[card_idx++])
                lp->options |= OPTION_DYN_IPG_ENABLE;
 
+
        /* Initialize driver entry points */
-       dev->open = amd8111e_open;
-       dev->hard_start_xmit = amd8111e_start_xmit;
-       dev->stop = amd8111e_close;
-       dev->get_stats = amd8111e_get_stats;
-       dev->set_multicast_list = amd8111e_set_multicast_list;
-       dev->set_mac_address = amd8111e_set_mac_address;
-       dev->do_ioctl = amd8111e_ioctl;
-       dev->change_mtu = amd8111e_change_mtu;
+       dev->netdev_ops = &amd8111e_netdev_ops;
        SET_ETHTOOL_OPS(dev, &ops);
        dev->irq =pdev->irq;
-       dev->tx_timeout = amd8111e_tx_timeout;
        dev->watchdog_timeo = AMD8111E_TX_TIMEOUT;
-#ifdef CONFIG_AMD8111E_NAPI
        netif_napi_add(dev, &lp->napi, amd8111e_rx_poll, 32);
-#endif
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = amd8111e_poll;
-#endif
 
 #if AMD8111E_VLAN_TAG_USED
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-       dev->vlan_rx_register =amd8111e_vlan_rx_register;
 #endif
        /* Probe the external PHY */
        amd8111e_probe_ext_phy(dev);
@@ -2085,8 +1971,8 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev,
        chip_version = (readl(lp->mmio + CHIPID) & 0xf0000000)>>28;
        printk(KERN_INFO "%s: AMD-8111e Driver Version: %s\n",
               dev->name,MODULE_VERS);
-       printk(KERN_INFO "%s: [ Rev %x ] PCI 10/100BaseT Ethernet %s\n",
-              dev->name, chip_version, print_mac(mac, dev->dev_addr));
+       printk(KERN_INFO "%s: [ Rev %x ] PCI 10/100BaseT Ethernet %pM\n",
+              dev->name, chip_version, dev->dev_addr);
        if (lp->ext_phy_id)
                printk(KERN_INFO "%s: Found MII PHY ID 0x%08x at address 0x%02x\n",
                       dev->name, lp->ext_phy_id, lp->ext_phy_addr);