static int loopback_xmit(struct sk_buff *skb, struct device *dev) { int done; if (!skb || !dev) return 0; PRINTK (("loopback_xmit (dev = %X)\n", dev)); cli(); if (dev->tbusy != 0) { sti(); return (1); } dev->tbusy = 1; sti(); done = dev_rint ((unsigned char *)(skb+1), skb->len, 0, dev); if (skb->free) kfree_skb (skb, FREE_WRITE); while (done != 1) { done = dev_rint (NULL, 0, 0, dev); } dev->tbusy = 0; return (0); }
static int loopback_xmit(struct sk_buff *skb, struct device *dev) { struct enet_statistics *stats = (struct enet_statistics *)dev->priv; int done; DPRINTF((DBG_LOOPB, "loopback_xmit(dev=%X, skb=%X)\n", dev, skb)); if (skb == NULL || dev == NULL) return(0); cli(); if (dev->tbusy != 0) { sti(); stats->tx_errors++; return(1); } dev->tbusy = 1; sti(); done = dev_rint(skb->data, skb->len, 0, dev); if (skb->free) kfree_skb(skb, FREE_WRITE); while (done != 1) { done = dev_rint(NULL, 0, 0, dev); } stats->tx_packets++; dev->tbusy = 0; #if 1 __asm__("cmpl $0,_intr_count\n\t" "jne 1f\n\t" "movl _bh_active,%%eax\n\t" "testl _bh_mask,%%eax\n\t" "je 1f\n\t" "incl _intr_count\n\t" "call _do_bottom_half\n\t" "decl _intr_count\n" "1:" : : : "ax", "dx", "cx"); #endif return(0); }
/* * We have a good packet, get it out of the adapter. */ static void de600_rx_intr(struct device *dev) { struct sk_buff *skb; int i; int read_from; int size; register unsigned char *buffer; cli(); /* Get size of received packet */ size = de600_read_byte(RX_LEN, dev); /* low byte */ size += (de600_read_byte(RX_LEN, dev) << 8); /* high byte */ size -= 4; /* Ignore trailing 4 CRC-bytes */ /* Tell adapter where to store next incoming packet, enable receiver */ read_from = rx_page_adr(); next_rx_page(); de600_put_command(RX_ENABLE); sti(); if ((size < 32) || (size > 1535)) { printk("%s: Bogus packet size %d.\n", dev->name, size); if (size > 10000) adapter_init(dev); return; } skb = alloc_skb(size, GFP_ATOMIC); sti(); if (skb == NULL) { printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size); return; } /* else */ skb->lock = 0; /* 'skb->data' points to the start of sk_buff data area. */ buffer = skb->data; /* copy the packet into the buffer */ de600_setup_address(read_from, RW_ADDR); for (i = size; i > 0; --i, ++buffer) *buffer = de600_read_byte(READ_DATA, dev); ((struct netstats *)(dev->priv))->rx_packets++; /* count all receives */ if (dev_rint((unsigned char *)skb, size, IN_SKBUFF, dev)) printk("%s: receive buffers full.\n", dev->name); /* * If any worth-while packets have been received, dev_rint() * has done a mark_bh(INET_BH) for us and will work on them * when we get to the bottom-half routine. */ }
/* This routine just calls the ether rcv_int. */ static int wdget(volatile struct wd_ring *ring, struct device *dev) { unsigned char *fptr; long len; fptr = (unsigned char *)(ring +1); /* some people have bugs in their hardware which let ring->count be 0. It shouldn't happen, but we should check for it. */ len = ring->count-4; if (len < 56) printk ("we.c: Hardware problem, runt packet. ring->count = %d\n", ring->count); return (dev_rint(fptr, len, 0, dev)); }
/* We have a good packet. Well, not really "good", just mostly not broken. We must check everything to see if it is good. */ static void el_receive(struct device *dev) { int sksize, pkt_len; struct sk_buff *skb; pkt_len = inw(RX_LOW); if (el_debug > 4) printk(" el_receive %d.\n", pkt_len); if ((pkt_len < 60) || (pkt_len > 1536)) { if (el_debug) printk("%s: bogus packet, length=%d\n", dev->name, pkt_len); el_status.stats.rx_over_errors++; return; } outb(AX_SYS, AX_CMD); sksize = sizeof(struct sk_buff) + pkt_len; skb = alloc_skb(sksize, GFP_ATOMIC); outw(0x00, GP_LOW); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); el_status.stats.rx_dropped++; return; } else { skb->mem_len = sksize; skb->mem_addr = skb; skb->len = pkt_len; skb->dev = dev; insb(DATAPORT, skb->data, pkt_len); #ifdef HAVE_NETIF_RX netif_rx(skb); #else skb->lock = 0; if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) { kfree_skbmem(skb, sksize); lp->stats.rx_dropped++; break; } #endif el_status.stats.rx_packets++; } return; }
/* We have a good packet(s), get it/them out of the buffers. */ static void net_rx(struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; int boguscount = 10; do { int status = inw(ioaddr); int pkt_len = inw(ioaddr); if (pkt_len == 0) /* Read all the frames? */ break; /* Done for now */ if (status & 0x40) { /* There was an error. */ lp->stats.rx_errors++; if (status & 0x20) lp->stats.rx_frame_errors++; if (status & 0x10) lp->stats.rx_over_errors++; if (status & 0x08) lp->stats.rx_crc_errors++; if (status & 0x04) lp->stats.rx_fifo_errors++; } else { /* Malloc up new buffer. */ int sksize = sizeof(struct sk_buff) + pkt_len; struct sk_buff *skb; skb = alloc_skb(sksize, GFP_ATOMIC); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); lp->stats.rx_dropped++; break; } skb->mem_len = sksize; skb->mem_addr = skb; skb->len = pkt_len; skb->dev = dev; /* 'skb->data' points to the start of sk_buff data area. */ memcpy(skb->data, (void*)dev->rmem_start, pkt_len); /* or */ insw(ioaddr, skb->data, (pkt_len + 1) >> 1); #ifdef HAVE_NETIF_RX netif_rx(skb); #else skb->lock = 0; if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) { kfree_s(skb, sksize); lp->stats.rx_dropped++; break; } #endif lp->stats.rx_packets++; } } while (--boguscount); /* If any worth-while packets have been received, dev_rint() has done a mark_bh(INET_BH) for us and will work on them when we get to the bottom-half routine. */ return; }
static void receive_packet(struct device * dev, elp_device * adapter, int len) { register int i; unsigned short * ptr; short d; int timeout; int rlen; struct sk_buff *skb; /* * allocate a buffer to put the packet into. * (for kernels prior to 1.1.4 only) */ #if (ELP_KERNEL_TYPE < 2) int sksize = sizeof(struct sk_buff) + len + 4; #endif CHECK_NULL(dev); CHECK_NULL(adapter); if (len <= 0 || ((len & ~1) != len)) if (elp_debug >= 3) printk("*** bad packet len %d at %s(%d)\n",len,filename,__LINE__); rlen = (len+1) & ~1; #if (ELP_KERNEL_TYPE < 2) skb = alloc_skb(sksize, GFP_ATOMIC); #else skb = alloc_skb(rlen, GFP_ATOMIC); #endif /* * make sure the data register is going the right way */ OUTB(INB(adapter->io_addr+PORT_CONTROL)|CONTROL_DIR, adapter->io_addr+PORT_CONTROL); /* * if buffer could not be allocated, swallow it */ if (skb == NULL) { for (i = 0; i < (rlen/2); i++) { timeout = jiffies + TIMEOUT; while ((INB(adapter->io_addr+PORT_STATUS)&STATUS_HRDY) == 0 && jiffies < timeout) ; if (jiffies >= timeout) TIMEOUT_MSG(); d = inw(adapter->io_addr+PORT_DATA); } adapter->stats.rx_dropped++; } else { skb->lock = 0; skb->len = rlen; skb->dev = dev; /* * for kernels before 1.1.4, the driver allocated the buffer */ #if (ELP_KERNEL_TYPE < 2) skb->mem_len = sksize; skb->mem_addr = skb; #endif /* * now read the data from the adapter */ ptr = (unsigned short *)SKB_DATA; for (i = 0; i < (rlen/2); i++) { timeout = jiffies + TIMEOUT; while ((INB(adapter->io_addr+PORT_STATUS)&STATUS_HRDY) == 0 && jiffies < timeout) ; if (jiffies >= timeout) { printk("*** timeout at %s(%d) reading word %d of %d ***\n", filename,__LINE__, i, rlen/2); #if (ELP_KERNEL_TYPE < 2) kfree_s(skb, sksize); #else kfree_s(skb, rlen); #endif return; } *ptr = inw(adapter->io_addr+PORT_DATA); ptr++; } /* * the magic routine "dev_rint" passes the packet up the * protocol chain. If it returns 0, we can assume the packet was * swallowed up. If not, then we are responsible for freeing memory */ IS_SKB(skb); /* * for kernels before 1.1.4, the driver allocated the buffer, so it had * to free it */ #if (ELP_KERNEL_TYPE < 2) if (dev_rint((unsigned char *)skb, rlen, IN_SKBUFF, dev) != 0) { printk("%s: receive buffers full.\n", dev->name); kfree_s(skb, sksize); } #else netif_rx(skb); #endif } OUTB(INB(adapter->io_addr+PORT_CONTROL)&(~CONTROL_DIR), adapter->io_addr+PORT_CONTROL); }
static void wd_rcv( struct device *dev ) { unsigned char pkt; /* Next packet page start */ unsigned char bnd; /* Last packet page end */ unsigned char cur; /* Future packet page start */ unsigned char cmd; /* Command register save */ volatile struct wd_ring *ring; int done=0; /* Calculate next packet location */ cur = wd_get_cur( dev ); bnd = wd_get_bnd( dev ); if( (pkt = bnd + 1) == max_pages ) pkt = WD_TXBS; while( done != 1) { if (pkt != cur) { /* Position pointer to packet in card ring buffer */ ring = (volatile struct wd_ring *) (dev->mem_start + (pkt << 8)); /* Ensure a valid packet */ if( ring->status & 1 ) { /* Too small and too big packets are filtered by the board */ if( wd_debug ) printk("\nwd8013 - wdget: bnd = %d, pkt = %d, " "cur = %d, status = %d, len = %d, next = %d", bnd, pkt, cur, ring->status, ring->count, ring->next); stats.rx_packets++; /* count all receives */ done = wdget( ring, dev ); /* get the packet */ /* Calculate next packet location */ pkt = ring->next; /* Compute new boundry - tell the chip */ if( (bnd = pkt - 1) < WD_TXBS ) bnd = max_pages - 1; wd_put_bnd(bnd, dev); /* update our copy of cur. */ cur = wd_get_cur(dev); } else { /* Bad packet in ring buffer - should not happen due to hardware filtering */ printk("wd8013 - bad packet: len = %d, status = x%x, " "bnd = %d, pkt = %d, cur = %d\n" "trashing receive buffer!", ring->count, ring->status, bnd, pkt, cur); /* Reset bnd = cur-1 */ if( ( bnd = wd_get_cur( dev ) - 1 ) < WD_TXBS ) bnd = max_pages - 1; wd_put_bnd( bnd, dev ); break; /* return */ } } else { done = dev_rint(NULL, 0,0, dev); } } /* reset to page 0 */ cmd = inb_p(WD_COMM); if (cmd & 0x40) { outb_p(cmd & ~(CPAGE1), WD_COMM); /* select page 0 */ } }