Merge branch 'docs-next' of git://git.lwn.net/linux-2.6
[safe/jmp/linux-2.6] / drivers / net / via-velocity.c
index a8009c2..bc278d4 100644 (file)
@@ -297,14 +297,6 @@ VELOCITY_PARAM(DMA_length, "DMA length");
 */
 VELOCITY_PARAM(IP_byte_align, "Enable IP header dword aligned");
 
-#define TX_CSUM_DEF     1
-/* txcsum_offload[] is used for setting the checksum offload ability of NIC.
-   (We only support RX checksum offload now)
-   0: disable csum_offload[checksum offload
-   1: enable checksum offload. (Default)
-*/
-VELOCITY_PARAM(txcsum_offload, "Enable transmit packet checksum offload");
-
 #define FLOW_CNTL_DEF   1
 #define FLOW_CNTL_MIN   1
 #define FLOW_CNTL_MAX   5
@@ -369,7 +361,7 @@ static struct velocity_info_tbl chip_info_table[] = {
  *     Describe the PCI device identifiers that we support in this
  *     device driver. Used for hotplug autoloading.
  */
-static const struct pci_device_id velocity_id_table[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(velocity_id_table) = {
        { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_612X) },
        { }
 };
@@ -490,7 +482,6 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index,
        velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname);
        velocity_set_int_opt(&opts->numtx, TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors", devname);
 
-       velocity_set_bool_opt(&opts->flags, txcsum_offload[index], TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM, "txcsum_offload", devname);
        velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname);
        velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname);
        velocity_set_bool_opt(&opts->flags, ValPktLen[index], VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN, "ValPktLen", devname);
@@ -821,7 +812,7 @@ static void set_mii_flow_control(struct velocity_info *vptr)
 
        case FLOW_CNTL_TX_RX:
                MII_REG_BITS_ON(ANAR_PAUSE, MII_REG_ANAR, vptr->mac_regs);
-               MII_REG_BITS_ON(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
+               MII_REG_BITS_OFF(ANAR_ASMDIR, MII_REG_ANAR, vptr->mac_regs);
                break;
 
        case FLOW_CNTL_DISABLE:
@@ -904,8 +895,8 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status)
 
        /*
           Check if new status is consisent with current status
-          if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE)
-          || (mii_status==curr_status)) {
+          if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE) ||
+              (mii_status==curr_status)) {
           vptr->mii_status=mii_check_media_mode(vptr->mac_regs);
           vptr->mii_status=check_connection_type(vptr->mac_regs);
           VELOCITY_PRT(MSG_LEVEL_INFO, "Velocity link no change\n");
@@ -1141,8 +1132,8 @@ static void velocity_set_multi(struct net_device *dev)
                writel(0xffffffff, &regs->MARCAM[0]);
                writel(0xffffffff, &regs->MARCAM[4]);
                rx_mode = (RCR_AM | RCR_AB | RCR_PROM);
-       } else if ((dev->mc_count > vptr->multicast_limit)
-                  || (dev->flags & IFF_ALLMULTI)) {
+       } else if ((netdev_mc_count(dev) > vptr->multicast_limit) ||
+                  (dev->flags & IFF_ALLMULTI)) {
                writel(0xffffffff, &regs->MARCAM[0]);
                writel(0xffffffff, &regs->MARCAM[4]);
                rx_mode = (RCR_AM | RCR_AB);
@@ -1150,9 +1141,11 @@ static void velocity_set_multi(struct net_device *dev)
                int offset = MCAM_SIZE - vptr->multicast_limit;
                mac_get_cam_mask(regs, vptr->mCAMmask);
 
-               for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) {
+               i = 0;
+               netdev_for_each_mc_addr(mclist, dev) {
                        mac_set_cam(regs, i + offset, mclist->dmi_addr);
                        vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7);
+                       i++;
                }
 
                mac_set_cam_mask(regs, vptr->mCAMmask);
@@ -1886,13 +1879,12 @@ static void velocity_error(struct velocity_info *vptr, int status)
 /**
  *     tx_srv          -       transmit interrupt service
  *     @vptr; Velocity
- *     @status:
  *
  *     Scan the queues looking for transmitted packets that
  *     we can complete and clean up. Update any statistics as
  *     necessary/
  */
-static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
+static int velocity_tx_srv(struct velocity_info *vptr)
 {
        struct tx_desc *td;
        int qnum;
@@ -1945,8 +1937,8 @@ static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
         *      Look to see if we should kick the transmit network
         *      layer for more work.
         */
-       if (netif_queue_stopped(vptr->dev) && (full == 0)
-           && (!(vptr->mii_status & VELOCITY_LINK_FAIL))) {
+       if (netif_queue_stopped(vptr->dev) && (full == 0) &&
+           (!(vptr->mii_status & VELOCITY_LINK_FAIL))) {
                netif_wake_queue(vptr->dev);
        }
        return works;
@@ -2099,14 +2091,12 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 /**
  *     velocity_rx_srv         -       service RX interrupt
  *     @vptr: velocity
- *     @status: adapter status (unused)
  *
  *     Walk the receive ring of the velocity adapter and remove
  *     any received packets from the receive queue. Hand the ring
  *     slots back to the adapter for reuse.
  */
-static int velocity_rx_srv(struct velocity_info *vptr, int status,
-               int budget_left)
+static int velocity_rx_srv(struct velocity_info *vptr, int budget_left)
 {
        struct net_device_stats *stats = &vptr->dev->stats;
        int rd_curr = vptr->rx.curr;
@@ -2160,32 +2150,24 @@ static int velocity_poll(struct napi_struct *napi, int budget)
        struct velocity_info *vptr = container_of(napi,
                        struct velocity_info, napi);
        unsigned int rx_done;
-       u32 isr_status;
-
-       spin_lock(&vptr->lock);
-       isr_status = mac_read_isr(vptr->mac_regs);
-
-       /* Ack the interrupt */
-       mac_write_isr(vptr->mac_regs, isr_status);
-       if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
-               velocity_error(vptr, isr_status);
+       unsigned long flags;
 
+       spin_lock_irqsave(&vptr->lock, flags);
        /*
         * Do rx and tx twice for performance (taken from the VIA
         * out-of-tree driver).
         */
-       rx_done = velocity_rx_srv(vptr, isr_status, budget / 2);
-       velocity_tx_srv(vptr, isr_status);
-       rx_done += velocity_rx_srv(vptr, isr_status, budget - rx_done);
-       velocity_tx_srv(vptr, isr_status);
-
-       spin_unlock(&vptr->lock);
+       rx_done = velocity_rx_srv(vptr, budget / 2);
+       velocity_tx_srv(vptr);
+       rx_done += velocity_rx_srv(vptr, budget - rx_done);
+       velocity_tx_srv(vptr);
 
        /* If budget not fully consumed, exit the polling mode */
        if (rx_done < budget) {
                napi_complete(napi);
                mac_enable_int(vptr->mac_regs);
        }
+       spin_unlock_irqrestore(&vptr->lock, flags);
 
        return rx_done;
 }
@@ -2215,10 +2197,17 @@ static irqreturn_t velocity_intr(int irq, void *dev_instance)
                return IRQ_NONE;
        }
 
+       /* Ack the interrupt */
+       mac_write_isr(vptr->mac_regs, isr_status);
+
        if (likely(napi_schedule_prep(&vptr->napi))) {
                mac_disable_int(vptr->mac_regs);
                __napi_schedule(&vptr->napi);
        }
+
+       if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
+               velocity_error(vptr, isr_status);
+
        spin_unlock(&vptr->lock);
 
        return IRQ_HANDLED;
@@ -2246,8 +2235,6 @@ static int velocity_open(struct net_device *dev)
        /* Ensure chip is running */
        pci_set_power_state(vptr->pdev, PCI_D0);
 
-       velocity_give_many_rx_descs(vptr);
-
        velocity_init_registers(vptr, VELOCITY_INIT_COLD);
 
        ret = request_irq(vptr->pdev->irq, velocity_intr, IRQF_SHARED,
@@ -2259,6 +2246,8 @@ static int velocity_open(struct net_device *dev)
                goto out;
        }
 
+       velocity_give_many_rx_descs(vptr);
+
        mac_enable_int(vptr->mac_regs);
        netif_start_queue(dev);
        napi_enable(&vptr->napi);
@@ -2348,10 +2337,10 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu)
 
                dev->mtu = new_mtu;
 
-               velocity_give_many_rx_descs(vptr);
-
                velocity_init_registers(vptr, VELOCITY_INIT_COLD);
 
+               velocity_give_many_rx_descs(vptr);
+
                mac_enable_int(vptr->mac_regs);
                netif_start_queue(dev);
 
@@ -2593,8 +2582,8 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
        /*
         *      Handle hardware checksum
         */
-       if ((vptr->flags & VELOCITY_FLAGS_TX_CSUM)
-                                && (skb->ip_summed == CHECKSUM_PARTIAL)) {
+       if ((dev->features & NETIF_F_IP_CSUM) &&
+           (skb->ip_summed == CHECKSUM_PARTIAL)) {
                const struct iphdr *ip = ip_hdr(skb);
                if (ip->protocol == IPPROTO_TCP)
                        td_ptr->tdesc1.TCR |= TCR0_TCPCK;
@@ -2711,10 +2700,8 @@ static void __devinit velocity_print_info(struct velocity_info *vptr)
        struct net_device *dev = vptr->dev;
 
        printk(KERN_INFO "%s: %s\n", dev->name, get_chip_name(vptr->chip_id));
-       printk(KERN_INFO "%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
-               dev->name,
-               dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-               dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+       printk(KERN_INFO "%s: Ethernet Address: %pM\n",
+               dev->name, dev->dev_addr);
 }
 
 static u32 velocity_get_link(struct net_device *dev)
@@ -2838,10 +2825,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
        netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
 
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
-               NETIF_F_HW_VLAN_RX;
-
-       if (vptr->flags & VELOCITY_FLAGS_TX_CSUM)
-               dev->features |= NETIF_F_IP_CSUM;
+               NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM | NETIF_F_SG;
 
        ret = register_netdev(dev);
        if (ret < 0)
@@ -3112,7 +3096,7 @@ static int velocity_resume(struct pci_dev *pdev)
        velocity_init_registers(vptr, VELOCITY_INIT_WOL);
        mac_disable_int(vptr->mac_regs);
 
-       velocity_tx_srv(vptr, 0);
+       velocity_tx_srv(vptr);
 
        for (i = 0; i < vptr->tx.numq; i++) {
                if (vptr->tx.used[i])
@@ -3356,6 +3340,7 @@ static int velocity_set_coalesce(struct net_device *dev,
 {
        struct velocity_info *vptr = netdev_priv(dev);
        int max_us = 0x3f * 64;
+       unsigned long flags;
 
        /* 6 bits of  */
        if (ecmd->tx_coalesce_usecs > max_us)
@@ -3377,6 +3362,7 @@ static int velocity_set_coalesce(struct net_device *dev,
                        ecmd->tx_coalesce_usecs);
 
        /* Setup the interrupt suppression and queue timers */
+       spin_lock_irqsave(&vptr->lock, flags);
        mac_disable_int(vptr->mac_regs);
        setup_adaptive_interrupts(vptr);
        setup_queue_timers(vptr);
@@ -3384,6 +3370,7 @@ static int velocity_set_coalesce(struct net_device *dev,
        mac_write_int_mask(vptr->int_mask, vptr->mac_regs);
        mac_clear_isr(vptr->mac_regs);
        mac_enable_int(vptr->mac_regs);
+       spin_unlock_irqrestore(&vptr->lock, flags);
 
        return 0;
 }
@@ -3392,6 +3379,8 @@ static const struct ethtool_ops velocity_ethtool_ops = {
        .get_settings   =       velocity_get_settings,
        .set_settings   =       velocity_set_settings,
        .get_drvinfo    =       velocity_get_drvinfo,
+       .set_tx_csum    =       ethtool_op_set_tx_csum,
+       .get_tx_csum    =       ethtool_op_get_tx_csum,
        .get_wol        =       velocity_ethtool_get_wol,
        .set_wol        =       velocity_ethtool_set_wol,
        .get_msglevel   =       velocity_get_msglevel,