Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
[safe/jmp/linux-2.6] / drivers / net / pcmcia / 3c574_cs.c
index 8b65e18..29d288e 100644 (file)
@@ -283,10 +283,8 @@ static int tc574_probe(struct pcmcia_device *link)
        spin_lock_init(&lp->window_lock);
        link->io.NumPorts1 = 32;
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
-       link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        link->irq.Handler = &el3_interrupt;
-       link->irq.Instance = dev;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        link->conf.IntType = INT_MEMORY_AND_IO;
        link->conf.ConfigIndex = 1;
@@ -624,8 +622,6 @@ static void mdio_write(unsigned int ioaddr, int phy_id, int location, int value)
                outw(MDIO_ENB_IN, mdio_addr);
                outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
        }
-
-       return;
 }
 
 /* Reset and restore all of the 3c574 registers. */
@@ -741,7 +737,7 @@ static void el3_tx_timeout(struct net_device *dev)
        printk(KERN_NOTICE "%s: Transmit timed out!\n", dev->name);
        dump_status(dev);
        dev->stats.tx_errors++;
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        /* Issue TX_RESET and TX_START commands. */
        tc574_wait_for_completion(dev, TxReset);
        outw(TxEnable, ioaddr + EL3_CMD);
@@ -783,12 +779,15 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
                  inw(ioaddr + EL3_STATUS));
 
        spin_lock_irqsave(&lp->window_lock, flags);
+
+       dev->stats.tx_bytes += skb->len;
+
+       /* Put out the doubleword header... */
        outw(skb->len, ioaddr + TX_FIFO);
        outw(0, ioaddr + TX_FIFO);
+       /* ... and the packet rounded to a doubleword. */
        outsl(ioaddr + TX_FIFO, skb->data, (skb->len+3)>>2);
 
-       dev->trans_start = jiffies;
-
        /* TxFree appears only in Window 1, not offset 0x1c. */
        if (inw(ioaddr + TxFree) <= 1536) {
                netif_stop_queue(dev);
@@ -914,7 +913,11 @@ static void media_check(unsigned long arg)
        if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 0xff)) {
                if (!lp->fast_poll)
                        printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
+
+               local_irq_save(flags);
                el3_interrupt(dev->irq, dev);
+               local_irq_restore(flags);
+
                lp->fast_poll = HZ;
        }
        if (lp->fast_poll) {
@@ -1019,8 +1022,6 @@ static void update_stats(struct net_device *dev)
        /* BadSSD */                               inb(ioaddr + 12);
        up                                       = inb(ioaddr + 13);
 
-       dev->stats.tx_bytes                     += tx + ((up & 0xf0) << 12);
-
        EL3WINDOW(1);
 }
 
@@ -1146,7 +1147,7 @@ static void set_rx_mode(struct net_device *dev)
        if (dev->flags & IFF_PROMISC)
                outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
                         ioaddr + EL3_CMD);
-       else if (dev->mc_count || (dev->flags & IFF_ALLMULTI))
+       else if (!netdev_mc_empty(dev) || (dev->flags & IFF_ALLMULTI))
                outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
        else
                outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);