コード例 #1
0
ファイル: net1080.c プロジェクト: 020gzh/linux
static int net1080_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
{
	struct nc_header	*header;
	struct nc_trailer	*trailer;
	u16			hdr_len, packet_len;

	/* This check is no longer done by usbnet */
	if (skb->len < dev->net->hard_header_len)
		return 0;

	if (!(skb->len & 0x01)) {
		netdev_dbg(dev->net, "rx framesize %d range %d..%d mtu %d\n",
			   skb->len, dev->net->hard_header_len, dev->hard_mtu,
			   dev->net->mtu);
		dev->net->stats.rx_frame_errors++;
		nc_ensure_sync(dev);
		return 0;
	}

	header = (struct nc_header *) skb->data;
	hdr_len = le16_to_cpup(&header->hdr_len);
	packet_len = le16_to_cpup(&header->packet_len);
	if (FRAMED_SIZE(packet_len) > NC_MAX_PACKET) {
		dev->net->stats.rx_frame_errors++;
		netdev_dbg(dev->net, "packet too big, %d\n", packet_len);
		nc_ensure_sync(dev);
		return 0;
	} else if (hdr_len < MIN_HEADER) {
		dev->net->stats.rx_frame_errors++;
		netdev_dbg(dev->net, "header too short, %d\n", hdr_len);
		nc_ensure_sync(dev);
		return 0;
	} else if (hdr_len > MIN_HEADER) {
		// out of band data for us?
		netdev_dbg(dev->net, "header OOB, %d bytes\n", hdr_len - MIN_HEADER);
		nc_ensure_sync(dev);
		// switch (vendor/product ids) { ... }
	}
	skb_pull(skb, hdr_len);

	trailer = (struct nc_trailer *)
		(skb->data + skb->len - sizeof *trailer);
	skb_trim(skb, skb->len - sizeof *trailer);

	if ((packet_len & 0x01) == 0) {
		if (skb->data [packet_len] != PAD_BYTE) {
			dev->net->stats.rx_frame_errors++;
			netdev_dbg(dev->net, "bad pad\n");
			return 0;
		}
		skb_trim(skb, skb->len - 1);
	}
	if (skb->len != packet_len) {
		dev->net->stats.rx_frame_errors++;
		netdev_dbg(dev->net, "bad packet len %d (expected %d)\n",
			   skb->len, packet_len);
		nc_ensure_sync(dev);
		return 0;
	}
	if (header->packet_id != get_unaligned(&trailer->packet_id)) {
		dev->net->stats.rx_fifo_errors++;
		netdev_dbg(dev->net, "(2+ dropped) rx packet_id mismatch 0x%x 0x%x\n",
			   le16_to_cpu(header->packet_id),
			   le16_to_cpu(trailer->packet_id));
		return 0;
	}
#if 0
	netdev_dbg(dev->net, "frame <rx h %d p %d id %d\n", header->hdr_len,
		   header->packet_len, header->packet_id);
#endif
	dev->frame_errors = 0;
	return 1;
}
コード例 #2
0
ファイル: usb_submit_urb.c プロジェクト: 9060/spdiff
static void rx_submit (struct usbnet *dev, struct urb *urb, int flags)
{
	struct sk_buff		*skb;
	struct skb_data		*entry;
	int			retval = 0;
	unsigned long		lockflags;
	size_t			size;

#ifdef CONFIG_USB_NET1080
	if (dev->driver_info->flags & FLAG_FRAMING_NC)
		size = FRAMED_SIZE (dev->net.mtu);
	else
#endif
#ifdef CONFIG_USB_GENESYS
	if (dev->driver_info->flags & FLAG_FRAMING_GL)
		size = GL_RCV_BUF_SIZE;
	else
#endif
		size = (sizeof (struct ethhdr) + dev->net.mtu);

	if ((skb = alloc_skb (size, flags)) == 0) {
		dbg ("no rx skb");
		tasklet_schedule (&dev->bh);
		usb_free_urb (urb);
		return;
	}

	entry = (struct skb_data *) skb->cb;
	entry->urb = urb;
	entry->dev = dev;
	entry->state = rx_start;
	entry->length = 0;

	FILL_BULK_URB (urb, dev->udev,
		usb_rcvbulkpipe (dev->udev, dev->driver_info->in),
		skb->data, size, rx_complete, skb);
	urb->transfer_flags |= USB_ASYNC_UNLINK;
#ifdef	REALLY_QUEUE
	urb->transfer_flags |= USB_QUEUE_BULK;
#endif
#if 0
	// Idle-but-posted reads with UHCI really chew up
	// PCI bandwidth unless FSBR is disabled
	urb->transfer_flags |= USB_NO_FSBR;
#endif

	spin_lock_irqsave (&dev->rxq.lock, lockflags);

	if (netif_running (&dev->net)) {
		if ((retval = usb_submit_urb (urb)) != 0) {
			dbg ("%s rx submit, %d", dev->net.name, retval);
			tasklet_schedule (&dev->bh);
		} else {
			__skb_queue_tail (&dev->rxq, skb);
		}
	} else {
		dbg ("rx: stopped");
		retval = -ENOLINK;
	}
	spin_unlock_irqrestore (&dev->rxq.lock, lockflags);
	if (retval) {
		dev_kfree_skb_any (skb);
		usb_free_urb (urb);
	}
}