static void el16_tx_timeout (struct net_device *dev) { struct net_local *lp = (struct net_local *) dev->priv; int ioaddr = dev->base_addr; unsigned long shmem = dev->mem_start; if (net_debug > 1) printk ("%s: transmit timed out, %s? ", dev->name, isa_readw (shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" : "network cable problem"); /* Try to restart the adaptor. */ if (lp->last_restart == lp->stats.tx_packets) { if (net_debug > 1) printk ("Resetting board.\n"); /* Completely reset the adaptor. */ init_82586_mem (dev); lp->tx_pkts_in_ring = 0; } else { /* Issue the channel attention signal and hope it "gets better". */ if (net_debug > 1) printk ("Kicking board.\n"); isa_writew (0xf000 | CUC_START | RX_START, shmem + iSCB_CMD); outb (0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */ lp->last_restart = lp->stats.tx_packets; } dev->trans_start = jiffies; netif_wake_queue (dev); }
static int eexp_open(struct device *dev) { int ioaddr = dev->base_addr; if (dev->irq == 0 || irqrmap[dev->irq] == 0) return -ENXIO; if (irq2dev_map[dev->irq] != 0 /* This is always true, but avoid the false IRQ. */ || (irq2dev_map[dev->irq] = dev) == 0 || request_irq(dev->irq, &eexp_interrupt, 0, "EExpress")) { return -EAGAIN; } /* Initialize the 82586 memory and start it. */ init_82586_mem(dev); /* Enable the interrupt line. */ outb(irqrmap[dev->irq] | 0x08, ioaddr + SET_IRQ); dev->tbusy = 0; dev->interrupt = 0; dev->start = 1; return 0; }
static int el16_open(struct net_device *dev) { /* Initialize the 82586 memory and start it. */ init_82586_mem(dev); netif_start_queue(dev); return 0; }
static int eexp_send_packet(struct sk_buff *skb, struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; if (dev->tbusy) { /* If we get here, some higher level has decided we are broken. There should really be a "kick me" function call instead. */ int tickssofar = jiffies - dev->trans_start; if (tickssofar < 5) return 1; if (net_debug > 1) printk("%s: transmit timed out, %s? ", dev->name, inw(ioaddr+SCB_STATUS) & 0x8000 ? "IRQ conflict" : "network cable problem"); lp->stats.tx_errors++; /* Try to restart the adaptor. */ if (lp->last_restart == lp->stats.tx_packets) { if (net_debug > 1) printk("Resetting board.\n"); /* Completely reset the adaptor. */ init_82586_mem(dev); } else { /* Issue the channel attention signal and hope it "gets better". */ if (net_debug > 1) printk("Kicking board.\n"); outw(0xf000|CUC_START|RX_START, ioaddr + SCB_CMD); outb(0, ioaddr + SIGNAL_CA); lp->last_restart = lp->stats.tx_packets; } dev->tbusy=0; dev->trans_start = jiffies; } /* If some higher layer thinks we've missed an tx-done interrupt we are passed NULL. Caution: dev_tint() handles the cli()/sti() itself. */ if (skb == NULL) { dev_tint(dev); return 0; } /* Block a timer-based transmit from overlapping. */ if (set_bit(0, (void*)&dev->tbusy) != 0) printk("%s: Transmitter access conflict.\n", dev->name); else { short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; /* Disable the 82586's input to the interrupt line. */ outb(irqrmap[dev->irq], ioaddr + SET_IRQ); hardware_send_packet(dev, buf, length); dev->trans_start = jiffies; /* Enable the 82586 interrupt input. */ outb(0x08 | irqrmap[dev->irq], ioaddr + SET_IRQ); } dev_kfree_skb (skb, FREE_WRITE); /* You might need to clean up and record Tx statistics here. */ lp->stats.tx_aborted_errors++; return 0; }