diff options
Diffstat (limited to 'drivers/net/dm9000.c')
-rw-r--r-- | drivers/net/dm9000.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 264fa0e2e075..738aa5906514 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -104,6 +104,18 @@ #define PRINTK(args...) printk(KERN_DEBUG args) #endif +#ifdef CONFIG_BLACKFIN +#define readsb insb +#define readsw insw +#define readsl insl +#define writesb outsb +#define writesw outsw +#define writesl outsl +#define DM9000_IRQ_FLAGS (IRQF_SHARED | IRQF_TRIGGER_HIGH) +#else +#define DM9000_IRQ_FLAGS IRQF_SHARED +#endif + /* * Transmit timeout, default 5 seconds. */ @@ -431,6 +443,9 @@ dm9000_probe(struct platform_device *pdev) db->io_addr = (void __iomem *)base; db->io_data = (void __iomem *)(base + 4); + /* ensure at least we have a default set of IO routines */ + dm9000_set_io(db, 2); + } else { db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); @@ -614,7 +629,7 @@ dm9000_open(struct net_device *dev) PRINTK2("entering dm9000_open\n"); - if (request_irq(dev->irq, &dm9000_interrupt, IRQF_SHARED, dev->name, dev)) + if (request_irq(dev->irq, &dm9000_interrupt, DM9000_IRQ_FLAGS, dev->name, dev)) return -EAGAIN; /* Initialize DM9000 board */ @@ -685,6 +700,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"); @@ -692,10 +708,7 @@ 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); @@ -703,12 +716,9 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) (db->outblk)(db->io_data, skb->data, skb->len); db->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); @@ -717,23 +727,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; } |