static int net_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; printk("%s: transmit timed out, %s?\n", dev->name, tx_done(dev) ? "IRQ conflict" : "network cable problem"); /* Try to restart the adaptor. */ chipset_init(dev, 1); 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; } /* For ethernet, fill in the header. This should really be done by a higher level, rather than duplicated for each ethernet adaptor. */ if (!skb->arp && dev->rebuild_header(skb->data, dev)) { skb->dev = dev; arp_queue (skb); return 0; } skb->arp=1; /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ 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; hardware_send_packet(ioaddr, buf, length); dev->trans_start = jiffies; } if (skb->free) kfree_skb (skb, FREE_WRITE); /* You might need to clean up and record Tx statistics here. */ if (inw(ioaddr) == /*RU*/81) lp->stats.tx_aborted_errors++; return 0; }
static netdev_tx_t eepro_send_packet(struct sk_buff *skb, struct net_device *dev) { struct eepro_local *lp = netdev_priv(dev); unsigned long flags; int ioaddr = dev->base_addr; short length = skb->len; if (net_debug > 5) printk(KERN_DEBUG "%s: entering eepro_send_packet routine.\n", dev->name); if (length < ETH_ZLEN) { if (skb_padto(skb, ETH_ZLEN)) return NETDEV_TX_OK; length = ETH_ZLEN; } netif_stop_queue (dev); eepro_dis_int(ioaddr); spin_lock_irqsave(&lp->lock, flags); { unsigned char *buf = skb->data; if (hardware_send_packet(dev, buf, length)) /* we won't wake queue here because we're out of space */ dev->stats.tx_dropped++; else { dev->stats.tx_bytes+=skb->len; netif_wake_queue(dev); } } dev_kfree_skb (skb); /* You might need to clean up and record Tx statistics here. */ /* dev->stats.tx_aborted_errors++; */ if (net_debug > 5) printk(KERN_DEBUG "%s: exiting eepro_send_packet routine.\n", dev->name); eepro_en_int(ioaddr); spin_unlock_irqrestore(&lp->lock, flags); return NETDEV_TX_OK; }
static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = skb->data; /* Block a timer-based transmit from overlapping */ netif_stop_queue(dev); hardware_send_packet(dev, buf, length); dev->trans_start = jiffies; lp->stats.tx_bytes += length; dev_kfree_skb (skb); /* You might need to clean up and record Tx statistics here. */ return 0; }
static int seeq8005_send_packet(struct sk_buff *skb, struct device *dev) { int ioaddr = dev->base_addr; struct net_local *lp = (struct net_local *)dev->priv; 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; printk("%s: transmit timed out, %s?\n", dev->name, tx_done(dev) ? "IRQ conflict" : "network cable problem"); /* Try to restart the adaptor. */ seeq8005_init(dev, 1); dev->tbusy=0; dev->trans_start = jiffies; } /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ if (test_and_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; hardware_send_packet(dev, buf, length); dev->trans_start = jiffies; lp->stats.tx_bytes += length; } dev_kfree_skb (skb); /* You might need to clean up and record Tx statistics here. */ return 0; }
static netdev_tx_t seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) { short length = skb->len; unsigned char *buf; if (length < ETH_ZLEN) { if (skb_padto(skb, ETH_ZLEN)) return NETDEV_TX_OK; length = ETH_ZLEN; } buf = skb->data; netif_stop_queue(dev); hardware_send_packet(dev, buf, length); dev->stats.tx_bytes += length; dev_kfree_skb (skb); return NETDEV_TX_OK; }
static netdev_tx_t seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev) { short length = skb->len; unsigned char *buf; if (length < ETH_ZLEN) { if (skb_padto(skb, ETH_ZLEN)) return NETDEV_TX_OK; length = ETH_ZLEN; } buf = skb->data; /* Block a timer-based transmit from overlapping */ netif_stop_queue(dev); hardware_send_packet(dev, buf, length); dev->stats.tx_bytes += length; dev_kfree_skb (skb); /* You might need to clean up and record Tx statistics here. */ return NETDEV_TX_OK; }
static int bionet_send_packet(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = netdev_priv(dev); unsigned long flags; /* Block a timer-based transmit from overlapping. This could better be * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ local_irq_save(flags); if (stdma_islocked()) { local_irq_restore(flags); lp->stats.tx_errors++; } else { int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned long buf = virt_to_phys(skb->data); int stat; stdma_lock(bionet_intr, NULL); local_irq_restore(flags); if( !STRAM_ADDR(buf+length-1) ) { memcpy(nic_packet->buffer, skb->data, length); buf = (unsigned long)&((struct nic_pkt_s *)phys_nic_packet)->buffer; } if (bionet_debug >1) { u_char *data = nic_packet->buffer, *p; int i; printk( "%s: TX pkt type 0x%4x from ", dev->name, ((u_short *)data)[6]); for( p = &data[6], i = 0; i < 6; i++ ) printk("%02x%s", *p++,i != 5 ? ":" : "" ); printk(" to "); for( p = data, i = 0; i < 6; i++ ) printk("%02x%s", *p++,i != 5 ? ":" : "" "\n" ); printk( "%s: ", dev->name ); printk(" data %02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x" " %02x%02x%02x%02x len %d\n", data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], data[32], data[33], length ); } dma_cache_maintenance(buf, length, 1); stat = hardware_send_packet(buf, length); ENABLE_IRQ(); stdma_release(); dev->trans_start = jiffies; dev->tbusy = 0; lp->stats.tx_packets++; lp->stats.tx_bytes+=length; } dev_kfree_skb(skb); 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; }