]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/dm9000.c
Merge branch 'slub-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/christoph/vm
[linux-2.6-omap-h63xx.git] / drivers / net / dm9000.c
index c3de81bf090a3f92062c236f560cee7f63fd1d69..6a20a5491a9666fad9edb9fabf830e3bccf0bc6d 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/dm9000.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
+#include <linux/irq.h>
 
 #include <asm/delay.h>
 #include <asm/irq.h>
 #define writesl        outsl
 #define DM9000_IRQ_FLAGS       (IRQF_SHARED | IRQF_TRIGGER_HIGH)
 #else
-#define DM9000_IRQ_FLAGS       IRQF_SHARED
+#define DM9000_IRQ_FLAGS       (IRQF_SHARED | IRQT_RISING)
 #endif
 
 /*
@@ -148,7 +149,6 @@ typedef struct board_info {
        struct resource *irq_res;
 
        struct timer_list timer;
-       struct net_device_stats stats;
        unsigned char srom[128];
        spinlock_t lock;
 
@@ -166,8 +166,6 @@ static int dm9000_stop(struct net_device *);
 static void dm9000_timer(unsigned long);
 static void dm9000_init_dm9000(struct net_device *);
 
-static struct net_device_stats *dm9000_get_stats(struct net_device *);
-
 static irqreturn_t dm9000_interrupt(int, void *);
 
 static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg);
@@ -416,7 +414,6 @@ dm9000_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
-       SET_MODULE_OWNER(ndev);
        SET_NETDEV_DEV(ndev, &pdev->dev);
 
        PRINTK2("dm9000_probe()");
@@ -546,7 +543,8 @@ dm9000_probe(struct platform_device *pdev)
 
        if (id_val != DM9000_ID) {
                printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val);
-               goto release;
+               ret = -ENODEV;
+               goto out;
        }
 
        /* from this point we assume that we have found a DM9000 */
@@ -559,7 +557,6 @@ dm9000_probe(struct platform_device *pdev)
        ndev->tx_timeout         = &dm9000_timeout;
        ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
        ndev->stop               = &dm9000_stop;
-       ndev->get_stats          = &dm9000_get_stats;
        ndev->set_multicast_list = &dm9000_hash_table;
 #ifdef CONFIG_NET_POLL_CONTROLLER
        ndev->poll_controller    = &dm9000_poll_controller;
@@ -600,16 +597,14 @@ dm9000_probe(struct platform_device *pdev)
        ret = register_netdev(ndev);
 
        if (ret == 0) {
-               printk("%s: dm9000 at %p,%p IRQ %d MAC: ",
-                      ndev->name,  db->io_addr, db->io_data, ndev->irq);
-               for (i = 0; i < 5; i++)
-                       printk("%02x:", ndev->dev_addr[i]);
-               printk("%02x\n", ndev->dev_addr[5]);
+               DECLARE_MAC_BUF(mac);
+               printk("%s: dm9000 at %p,%p IRQ %d MAC: %s\n",
+                      ndev->name,  db->io_addr, db->io_data, ndev->irq,
+                      print_mac(mac, ndev->dev_addr));
        }
        return 0;
 
- release:
- out:
+out:
        printk("%s: not found (%d).\n", CARDNAME, ret);
 
        dm9000_release_board(pdev, db);
@@ -700,6 +695,7 @@ dm9000_init_dm9000(struct net_device *dev)
 static int
 dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
+       unsigned long flags;
        board_info_t *db = (board_info_t *) dev->priv;
 
        PRINTK3("dm9000_start_xmit\n");
@@ -707,23 +703,17 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (db->tx_pkt_cnt > 1)
                return 1;
 
-       netif_stop_queue(dev);
-
-       /* Disable all interrupts */
-       iow(db, DM9000_IMR, IMR_PAR);
+       spin_lock_irqsave(&db->lock, flags);
 
        /* Move data to DM9000 TX RAM */
        writeb(DM9000_MWCMD, db->io_addr);
 
        (db->outblk)(db->io_data, skb->data, skb->len);
-       db->stats.tx_bytes += skb->len;
+       dev->stats.tx_bytes += skb->len;
 
+       db->tx_pkt_cnt++;
        /* TX control: First packet immediately send, second packet queue */
-       if (db->tx_pkt_cnt == 0) {
-
-               /* First Packet */
-               db->tx_pkt_cnt++;
-
+       if (db->tx_pkt_cnt == 1) {
                /* Set TX length to DM9000 */
                iow(db, DM9000_TXPLL, skb->len & 0xff);
                iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff);
@@ -732,23 +722,17 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
                iow(db, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */
 
                dev->trans_start = jiffies;     /* save the time stamp */
-
        } else {
                /* Second packet */
-               db->tx_pkt_cnt++;
                db->queue_pkt_len = skb->len;
+               netif_stop_queue(dev);
        }
 
+       spin_unlock_irqrestore(&db->lock, flags);
+
        /* free this SKB */
        dev_kfree_skb(skb);
 
-       /* Re-enable resource check */
-       if (db->tx_pkt_cnt == 1)
-               netif_wake_queue(dev);
-
-       /* Re-enable interrupt */
-       iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
-
        return 0;
 }
 
@@ -802,7 +786,7 @@ dm9000_tx_done(struct net_device *dev, board_info_t * db)
        if (tx_status & (NSR_TX2END | NSR_TX1END)) {
                /* One packet sent complete */
                db->tx_pkt_cnt--;
-               db->stats.tx_packets++;
+               dev->stats.tx_packets++;
 
                /* Queue packet check & send */
                if (db->tx_pkt_cnt > 0) {
@@ -863,17 +847,6 @@ dm9000_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-/*
- *  Get statistics from driver.
- */
-static struct net_device_stats *
-dm9000_get_stats(struct net_device *dev)
-{
-       board_info_t *db = (board_info_t *) dev->priv;
-       return &db->stats;
-}
-
-
 /*
  *  A periodic timer routine
  *  Dynamic media sense, allocated Rx buffer...
@@ -951,15 +924,15 @@ dm9000_rx(struct net_device *dev)
                        GoodPacket = false;
                        if (rxhdr.RxStatus & 0x100) {
                                PRINTK1("fifo error\n");
-                               db->stats.rx_fifo_errors++;
+                               dev->stats.rx_fifo_errors++;
                        }
                        if (rxhdr.RxStatus & 0x200) {
                                PRINTK1("crc error\n");
-                               db->stats.rx_crc_errors++;
+                               dev->stats.rx_crc_errors++;
                        }
                        if (rxhdr.RxStatus & 0x8000) {
                                PRINTK1("length error\n");
-                               db->stats.rx_length_errors++;
+                               dev->stats.rx_length_errors++;
                        }
                }
 
@@ -972,12 +945,12 @@ dm9000_rx(struct net_device *dev)
                        /* Read received packet from RX SRAM */
 
                        (db->inblk)(db->io_data, rdptr, RxLen);
-                       db->stats.rx_bytes += RxLen;
+                       dev->stats.rx_bytes += RxLen;
 
                        /* Pass to upper layer */
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_rx(skb);
-                       db->stats.rx_packets++;
+                       dev->stats.rx_packets++;
 
                } else {
                        /* need to dump the packet's data */