Example #1
0
void netfront_rx(struct netfront_dev *dev)
{
	RING_IDX rp, cons;
	struct netif_rx_response *rsp = &(dev->rsp);
	int more, flags;

	local_irq_save(flags);
	netfront_tx_buf_gc(dev);
	local_irq_restore(flags);
#ifdef CONFIG_NETMAP
	if (dev->netmap) {
		netmap_netfront_rx(dev);
		return;
	}
#endif
moretodo:
	rp = dev->rx.sring->rsp_prod;
	rmb(); /* Ensure we see queued responses up to 'rp'. */
	cons = dev->rx.rsp_cons;

	while (cons != rp) {
		NETIF_MEMCPY(rsp, RING_GET_RESPONSE(&dev->rx, cons), sizeof(*rsp));
		netfront_get_responses(dev, cons);
		cons = dev->rx.rsp_cons;
	}

	dev->rx.rsp_cons = cons;
	RING_FINAL_CHECK_FOR_RESPONSES(&dev->rx, more);
	if(more)
		goto moretodo;

	netfront_fillup_rx_buffers(dev);
}
Example #2
0
void network_rx(struct netfront_dev *dev)
{
    RING_IDX rp,cons,req_prod;
    struct netif_rx_response *rx;
    int nr_consumed, some, more, i, notify;

#ifdef CONFIG_NETMAP
    if (dev->netmap) {
        netmap_netfront_rx(dev);
        return;
    }
#endif
moretodo:
    rp = dev->rx.sring->rsp_prod;
    rmb(); /* Ensure we see queued responses up to 'rp'. */
    cons = dev->rx.rsp_cons;

    for (nr_consumed = 0, some = 0;
	 (cons != rp);
         nr_consumed++, cons++)
    {
        struct net_buffer* buf;
        unsigned char* page;
        int id;

        rx = RING_GET_RESPONSE(&dev->rx, cons);

        if (rx->flags & NETRXF_extra_info)
        {
            printk("+++++++++++++++++++++ we have extras!\n");
            continue;
        }


        if (rx->status == NETIF_RSP_NULL) continue;

        id = rx->id;
        BUG_ON(id >= NET_TX_RING_SIZE);

        buf = &dev->rx_buffers[id];
        page = (unsigned char*)buf->page;

        if(rx->status>0)
        {
#ifdef HAVE_LIBC
	    if (dev->netif_rx == NETIF_SELECT_RX) {
		int len = rx->status;
		ASSERT(current == main_thread);
		if (len > dev->len)
		    len = dev->len;
		memcpy(dev->data, page+rx->offset, len);
		dev->rlen = len;
	    } else
#endif
		dev->netif_rx(page+rx->offset,rx->status, dev->netif_rx_arg);
		some = 1;
        }
    }
    dev->rx.rsp_cons=cons;

    RING_FINAL_CHECK_FOR_RESPONSES(&dev->rx,more);
    if(more && !some) goto moretodo;
    req_prod = dev->rx.req_prod_pvt;

    for(i=0; i<nr_consumed; i++)
    {
        int id = xennet_rxidx(req_prod + i);
        netif_rx_request_t *req = RING_GET_REQUEST(&dev->rx, req_prod + i);
        struct net_buffer* buf = &dev->rx_buffers[id];

	req->gref = buf->gref;
        req->id = id;
    }

    wmb();

    dev->rx.req_prod_pvt = req_prod + i;
    
    RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->rx, notify);
    if (notify)
        notify_remote_via_evtchn(dev->evtchn);

}