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); }
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); }