示例#1
0
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);
}
示例#2
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);
}
示例#3
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.
	 */
}
示例#4
0
/* 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));
}
示例#5
0
/* 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;
}
示例#6
0
/* 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;
}
示例#7
0
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);
}
示例#8
0
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 */
     }
}