struct net_device *netdev;
struct napi_struct napi;
- struct net_device_stats stats;
-
- struct xen_netif_tx_front_ring tx;
- struct xen_netif_rx_front_ring rx;
-
- spinlock_t tx_lock;
- spinlock_t rx_lock;
unsigned int evtchn;
+ struct xenbus_device *xbdev;
- /* Receive-ring batched refills. */
-#define RX_MIN_TARGET 8
-#define RX_DFL_MIN_TARGET 64
-#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
- unsigned rx_min_target, rx_max_target, rx_target;
- struct sk_buff_head rx_batch;
-
- struct timer_list rx_refill_timer;
+ spinlock_t tx_lock;
+ struct xen_netif_tx_front_ring tx;
+ int tx_ring_ref;
/*
* {tx,rx}_skbs store outstanding skbuffs. Free tx_skb entries
grant_ref_t grant_tx_ref[NET_TX_RING_SIZE];
unsigned tx_skb_freelist;
+ spinlock_t rx_lock ____cacheline_aligned_in_smp;
+ struct xen_netif_rx_front_ring rx;
+ int rx_ring_ref;
+
+ /* Receive-ring batched refills. */
+#define RX_MIN_TARGET 8
+#define RX_DFL_MIN_TARGET 64
+#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
+ unsigned rx_min_target, rx_max_target, rx_target;
+ struct sk_buff_head rx_batch;
+
+ struct timer_list rx_refill_timer;
+
struct sk_buff *rx_skbs[NET_RX_RING_SIZE];
grant_ref_t gref_rx_head;
grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
- struct xenbus_device *xbdev;
- int tx_ring_ref;
- int rx_ring_ref;
-
unsigned long rx_pfn_array[NET_RX_RING_SIZE];
struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1];
struct mmu_update rx_mmu[NET_RX_RING_SIZE];
struct page *page;
int i, batch_target, notify;
RING_IDX req_prod = np->rx.req_prod_pvt;
- struct xen_memory_reservation reservation;
grant_ref_t ref;
unsigned long pfn;
void *vaddr;
- int nr_flips;
struct xen_netif_rx_request *req;
if (unlikely(!netif_carrier_ok(dev)))
np->rx_target = np->rx_max_target;
refill:
- for (nr_flips = i = 0; ; i++) {
+ for (i = 0; ; i++) {
skb = __skb_dequeue(&np->rx_batch);
if (skb == NULL)
break;
req->gref = ref;
}
- if (nr_flips != 0) {
- reservation.extent_start = np->rx_pfn_array;
- reservation.nr_extents = nr_flips;
- reservation.extent_order = 0;
- reservation.address_bits = 0;
- reservation.domid = DOMID_SELF;
-
- if (!xen_feature(XENFEAT_auto_translated_physmap)) {
- /* After all PTEs have been zapped, flush the TLB. */
- np->rx_mcl[i-1].args[MULTI_UVMFLAGS_INDEX] =
- UVMF_TLB_FLUSH|UVMF_ALL;
-
- /* Give away a batch of pages. */
- np->rx_mcl[i].op = __HYPERVISOR_memory_op;
- np->rx_mcl[i].args[0] = XENMEM_decrease_reservation;
- np->rx_mcl[i].args[1] = (unsigned long)&reservation;
-
- /* Zap PTEs and give away pages in one big
- * multicall. */
- (void)HYPERVISOR_multicall(np->rx_mcl, i+1);
-
- /* Check return status of HYPERVISOR_memory_op(). */
- if (unlikely(np->rx_mcl[i].result != i))
- panic("Unable to reduce memory reservation\n");
- } else {
- if (HYPERVISOR_memory_op(XENMEM_decrease_reservation,
- &reservation) != i)
- panic("Unable to reduce memory reservation\n");
- }
- } else {
- wmb(); /* barrier so backend seens requests */
- }
+ wmb(); /* barrier so backend seens requests */
/* Above is a suitable barrier to ensure backend will see requests. */
np->rx.req_prod_pvt = req_prod + i;
{
struct netfront_info *np = netdev_priv(dev);
- memset(&np->stats, 0, sizeof(np->stats));
-
napi_enable(&np->napi);
spin_lock_bh(&np->rx_lock);
if (notify)
notify_remote_via_irq(np->netdev->irq);
- np->stats.tx_bytes += skb->len;
- np->stats.tx_packets++;
+ dev->stats.tx_bytes += skb->len;
+ dev->stats.tx_packets++;
/* Note: It is not safe to access skb after xennet_tx_buf_gc()! */
xennet_tx_buf_gc(dev);
return 0;
drop:
- np->stats.tx_dropped++;
+ dev->stats.tx_dropped++;
dev_kfree_skb(skb);
return 0;
}
return 0;
}
-static struct net_device_stats *xennet_get_stats(struct net_device *dev)
-{
- struct netfront_info *np = netdev_priv(dev);
- return &np->stats;
-}
-
static void xennet_move_rx_slot(struct netfront_info *np, struct sk_buff *skb,
grant_ref_t ref)
{
}
static int handle_incoming_queue(struct net_device *dev,
- struct sk_buff_head *rxq)
+ struct sk_buff_head *rxq)
{
- struct netfront_info *np = netdev_priv(dev);
int packets_dropped = 0;
struct sk_buff *skb;
if (skb_checksum_setup(skb)) {
kfree_skb(skb);
packets_dropped++;
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
continue;
}
}
- np->stats.rx_packets++;
- np->stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
/* Pass it up. */
netif_receive_skb(skb);
spin_lock(&np->rx_lock);
- if (unlikely(!netif_carrier_ok(dev))) {
- spin_unlock(&np->rx_lock);
- return 0;
- }
-
skb_queue_head_init(&rxq);
skb_queue_head_init(&errq);
skb_queue_head_init(&tmpq);
err:
while ((skb = __skb_dequeue(&tmpq)))
__skb_queue_tail(&errq, skb);
- np->stats.rx_errors++;
+ dev->stats.rx_errors++;
i = np->rx.rsp_cons;
continue;
}
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
/* Do all the remapping work and M2P updates. */
MULTI_mmu_update(mcl, np->rx_mmu, mmu - np->rx_mmu,
- 0, DOMID_SELF);
+ NULL, DOMID_SELF);
mcl++;
HYPERVISOR_multicall(np->rx_mcl, mcl - np->rx_mcl);
}
netdev->open = xennet_open;
netdev->hard_start_xmit = xennet_start_xmit;
netdev->stop = xennet_close;
- netdev->get_stats = xennet_get_stats;
netif_napi_add(netdev, &np->napi, xennet_poll, 64);
netdev->uninit = xennet_uninit;
netdev->change_mtu = xennet_change_mtu;
netdev->features = NETIF_F_IP_CSUM;
SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops);
- SET_MODULE_OWNER(netdev);
SET_NETDEV_DEV(netdev, &dev->dev);
np->netdev = netdev;
if (!feature_rx_copy) {
dev_info(&dev->dev,
- "backend does not support copying recieve path");
+ "backend does not support copying receive path\n");
return -ENODEV;
}
static struct ethtool_ops xennet_ethtool_ops =
{
- .get_tx_csum = ethtool_op_get_tx_csum,
.set_tx_csum = ethtool_op_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
.set_sg = xennet_set_sg,
- .get_tso = ethtool_op_get_tso,
.set_tso = xennet_set_tso,
.get_link = ethtool_op_get_link,
};