diff options
author | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-12-29 00:47:18 -0500 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-12-29 00:47:18 -0500 |
commit | 0a8c5395f90f06d128247844b2515c8bf3f2826b (patch) | |
tree | d95382dcdfa303b99d480c01763d6cb6767fdaca /drivers/net/virtio_net.c | |
parent | 25051158bbed127e8672b43396c71c5eb610e5f1 (diff) | |
parent | 3c92ec8ae91ecf59d88c798301833d7cf83f2179 (diff) |
[XFS] Fix merge failures
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
fs/xfs/linux-2.6/xfs_cred.h
fs/xfs/linux-2.6/xfs_globals.h
fs/xfs/linux-2.6/xfs_ioctl.c
fs/xfs/xfs_vnodeops.h
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r-- | drivers/net/virtio_net.c | 217 |
1 files changed, 183 insertions, 34 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 0196a0df9021..b7004ff36451 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -34,6 +34,7 @@ module_param(gso, bool, 0444); | |||
34 | 34 | ||
35 | /* FIXME: MTU in config. */ | 35 | /* FIXME: MTU in config. */ |
36 | #define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN) | 36 | #define MAX_PACKET_LEN (ETH_HLEN+ETH_DATA_LEN) |
37 | #define GOOD_COPY_LEN 128 | ||
37 | 38 | ||
38 | struct virtnet_info | 39 | struct virtnet_info |
39 | { | 40 | { |
@@ -58,6 +59,9 @@ struct virtnet_info | |||
58 | /* I like... big packets and I cannot lie! */ | 59 | /* I like... big packets and I cannot lie! */ |
59 | bool big_packets; | 60 | bool big_packets; |
60 | 61 | ||
62 | /* Host will merge rx buffers for big packets (shake it! shake it!) */ | ||
63 | bool mergeable_rx_bufs; | ||
64 | |||
61 | /* Receive & send queues. */ | 65 | /* Receive & send queues. */ |
62 | struct sk_buff_head recv; | 66 | struct sk_buff_head recv; |
63 | struct sk_buff_head send; | 67 | struct sk_buff_head send; |
@@ -66,22 +70,27 @@ struct virtnet_info | |||
66 | struct page *pages; | 70 | struct page *pages; |
67 | }; | 71 | }; |
68 | 72 | ||
69 | static inline struct virtio_net_hdr *skb_vnet_hdr(struct sk_buff *skb) | 73 | static inline void *skb_vnet_hdr(struct sk_buff *skb) |
70 | { | 74 | { |
71 | return (struct virtio_net_hdr *)skb->cb; | 75 | return (struct virtio_net_hdr *)skb->cb; |
72 | } | 76 | } |
73 | 77 | ||
74 | static inline void vnet_hdr_to_sg(struct scatterlist *sg, struct sk_buff *skb) | ||
75 | { | ||
76 | sg_init_one(sg, skb_vnet_hdr(skb), sizeof(struct virtio_net_hdr)); | ||
77 | } | ||
78 | |||
79 | static void give_a_page(struct virtnet_info *vi, struct page *page) | 78 | static void give_a_page(struct virtnet_info *vi, struct page *page) |
80 | { | 79 | { |
81 | page->private = (unsigned long)vi->pages; | 80 | page->private = (unsigned long)vi->pages; |
82 | vi->pages = page; | 81 | vi->pages = page; |
83 | } | 82 | } |
84 | 83 | ||
84 | static void trim_pages(struct virtnet_info *vi, struct sk_buff *skb) | ||
85 | { | ||
86 | unsigned int i; | ||
87 | |||
88 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | ||
89 | give_a_page(vi, skb_shinfo(skb)->frags[i].page); | ||
90 | skb_shinfo(skb)->nr_frags = 0; | ||
91 | skb->data_len = 0; | ||
92 | } | ||
93 | |||
85 | static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask) | 94 | static struct page *get_a_page(struct virtnet_info *vi, gfp_t gfp_mask) |
86 | { | 95 | { |
87 | struct page *p = vi->pages; | 96 | struct page *p = vi->pages; |
@@ -111,31 +120,97 @@ static void skb_xmit_done(struct virtqueue *svq) | |||
111 | static void receive_skb(struct net_device *dev, struct sk_buff *skb, | 120 | static void receive_skb(struct net_device *dev, struct sk_buff *skb, |
112 | unsigned len) | 121 | unsigned len) |
113 | { | 122 | { |
123 | struct virtnet_info *vi = netdev_priv(dev); | ||
114 | struct virtio_net_hdr *hdr = skb_vnet_hdr(skb); | 124 | struct virtio_net_hdr *hdr = skb_vnet_hdr(skb); |
115 | int err; | 125 | int err; |
126 | int i; | ||
116 | 127 | ||
117 | if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) { | 128 | if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) { |
118 | pr_debug("%s: short packet %i\n", dev->name, len); | 129 | pr_debug("%s: short packet %i\n", dev->name, len); |
119 | dev->stats.rx_length_errors++; | 130 | dev->stats.rx_length_errors++; |
120 | goto drop; | 131 | goto drop; |
121 | } | 132 | } |
122 | len -= sizeof(struct virtio_net_hdr); | ||
123 | 133 | ||
124 | if (len <= MAX_PACKET_LEN) { | 134 | if (vi->mergeable_rx_bufs) { |
125 | unsigned int i; | 135 | struct virtio_net_hdr_mrg_rxbuf *mhdr = skb_vnet_hdr(skb); |
136 | unsigned int copy; | ||
137 | char *p = page_address(skb_shinfo(skb)->frags[0].page); | ||
126 | 138 | ||
127 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | 139 | if (len > PAGE_SIZE) |
128 | give_a_page(dev->priv, skb_shinfo(skb)->frags[i].page); | 140 | len = PAGE_SIZE; |
129 | skb->data_len = 0; | 141 | len -= sizeof(struct virtio_net_hdr_mrg_rxbuf); |
130 | skb_shinfo(skb)->nr_frags = 0; | ||
131 | } | ||
132 | 142 | ||
133 | err = pskb_trim(skb, len); | 143 | memcpy(hdr, p, sizeof(*mhdr)); |
134 | if (err) { | 144 | p += sizeof(*mhdr); |
135 | pr_debug("%s: pskb_trim failed %i %d\n", dev->name, len, err); | 145 | |
136 | dev->stats.rx_dropped++; | 146 | copy = len; |
137 | goto drop; | 147 | if (copy > skb_tailroom(skb)) |
148 | copy = skb_tailroom(skb); | ||
149 | |||
150 | memcpy(skb_put(skb, copy), p, copy); | ||
151 | |||
152 | len -= copy; | ||
153 | |||
154 | if (!len) { | ||
155 | give_a_page(vi, skb_shinfo(skb)->frags[0].page); | ||
156 | skb_shinfo(skb)->nr_frags--; | ||
157 | } else { | ||
158 | skb_shinfo(skb)->frags[0].page_offset += | ||
159 | sizeof(*mhdr) + copy; | ||
160 | skb_shinfo(skb)->frags[0].size = len; | ||
161 | skb->data_len += len; | ||
162 | skb->len += len; | ||
163 | } | ||
164 | |||
165 | while (--mhdr->num_buffers) { | ||
166 | struct sk_buff *nskb; | ||
167 | |||
168 | i = skb_shinfo(skb)->nr_frags; | ||
169 | if (i >= MAX_SKB_FRAGS) { | ||
170 | pr_debug("%s: packet too long %d\n", dev->name, | ||
171 | len); | ||
172 | dev->stats.rx_length_errors++; | ||
173 | goto drop; | ||
174 | } | ||
175 | |||
176 | nskb = vi->rvq->vq_ops->get_buf(vi->rvq, &len); | ||
177 | if (!nskb) { | ||
178 | pr_debug("%s: rx error: %d buffers missing\n", | ||
179 | dev->name, mhdr->num_buffers); | ||
180 | dev->stats.rx_length_errors++; | ||
181 | goto drop; | ||
182 | } | ||
183 | |||
184 | __skb_unlink(nskb, &vi->recv); | ||
185 | vi->num--; | ||
186 | |||
187 | skb_shinfo(skb)->frags[i] = skb_shinfo(nskb)->frags[0]; | ||
188 | skb_shinfo(nskb)->nr_frags = 0; | ||
189 | kfree_skb(nskb); | ||
190 | |||
191 | if (len > PAGE_SIZE) | ||
192 | len = PAGE_SIZE; | ||
193 | |||
194 | skb_shinfo(skb)->frags[i].size = len; | ||
195 | skb_shinfo(skb)->nr_frags++; | ||
196 | skb->data_len += len; | ||
197 | skb->len += len; | ||
198 | } | ||
199 | } else { | ||
200 | len -= sizeof(struct virtio_net_hdr); | ||
201 | |||
202 | if (len <= MAX_PACKET_LEN) | ||
203 | trim_pages(vi, skb); | ||
204 | |||
205 | err = pskb_trim(skb, len); | ||
206 | if (err) { | ||
207 | pr_debug("%s: pskb_trim failed %i %d\n", dev->name, | ||
208 | len, err); | ||
209 | dev->stats.rx_dropped++; | ||
210 | goto drop; | ||
211 | } | ||
138 | } | 212 | } |
213 | |||
139 | skb->truesize += skb->data_len; | 214 | skb->truesize += skb->data_len; |
140 | dev->stats.rx_bytes += skb->len; | 215 | dev->stats.rx_bytes += skb->len; |
141 | dev->stats.rx_packets++; | 216 | dev->stats.rx_packets++; |
@@ -194,7 +269,7 @@ drop: | |||
194 | dev_kfree_skb(skb); | 269 | dev_kfree_skb(skb); |
195 | } | 270 | } |
196 | 271 | ||
197 | static void try_fill_recv(struct virtnet_info *vi) | 272 | static void try_fill_recv_maxbufs(struct virtnet_info *vi) |
198 | { | 273 | { |
199 | struct sk_buff *skb; | 274 | struct sk_buff *skb; |
200 | struct scatterlist sg[2+MAX_SKB_FRAGS]; | 275 | struct scatterlist sg[2+MAX_SKB_FRAGS]; |
@@ -202,12 +277,16 @@ static void try_fill_recv(struct virtnet_info *vi) | |||
202 | 277 | ||
203 | sg_init_table(sg, 2+MAX_SKB_FRAGS); | 278 | sg_init_table(sg, 2+MAX_SKB_FRAGS); |
204 | for (;;) { | 279 | for (;;) { |
280 | struct virtio_net_hdr *hdr; | ||
281 | |||
205 | skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN); | 282 | skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN); |
206 | if (unlikely(!skb)) | 283 | if (unlikely(!skb)) |
207 | break; | 284 | break; |
208 | 285 | ||
209 | skb_put(skb, MAX_PACKET_LEN); | 286 | skb_put(skb, MAX_PACKET_LEN); |
210 | vnet_hdr_to_sg(sg, skb); | 287 | |
288 | hdr = skb_vnet_hdr(skb); | ||
289 | sg_init_one(sg, hdr, sizeof(*hdr)); | ||
211 | 290 | ||
212 | if (vi->big_packets) { | 291 | if (vi->big_packets) { |
213 | for (i = 0; i < MAX_SKB_FRAGS; i++) { | 292 | for (i = 0; i < MAX_SKB_FRAGS; i++) { |
@@ -232,6 +311,55 @@ static void try_fill_recv(struct virtnet_info *vi) | |||
232 | err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb); | 311 | err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, num, skb); |
233 | if (err) { | 312 | if (err) { |
234 | skb_unlink(skb, &vi->recv); | 313 | skb_unlink(skb, &vi->recv); |
314 | trim_pages(vi, skb); | ||
315 | kfree_skb(skb); | ||
316 | break; | ||
317 | } | ||
318 | vi->num++; | ||
319 | } | ||
320 | if (unlikely(vi->num > vi->max)) | ||
321 | vi->max = vi->num; | ||
322 | vi->rvq->vq_ops->kick(vi->rvq); | ||
323 | } | ||
324 | |||
325 | static void try_fill_recv(struct virtnet_info *vi) | ||
326 | { | ||
327 | struct sk_buff *skb; | ||
328 | struct scatterlist sg[1]; | ||
329 | int err; | ||
330 | |||
331 | if (!vi->mergeable_rx_bufs) { | ||
332 | try_fill_recv_maxbufs(vi); | ||
333 | return; | ||
334 | } | ||
335 | |||
336 | for (;;) { | ||
337 | skb_frag_t *f; | ||
338 | |||
339 | skb = netdev_alloc_skb(vi->dev, GOOD_COPY_LEN + NET_IP_ALIGN); | ||
340 | if (unlikely(!skb)) | ||
341 | break; | ||
342 | |||
343 | skb_reserve(skb, NET_IP_ALIGN); | ||
344 | |||
345 | f = &skb_shinfo(skb)->frags[0]; | ||
346 | f->page = get_a_page(vi, GFP_ATOMIC); | ||
347 | if (!f->page) { | ||
348 | kfree_skb(skb); | ||
349 | break; | ||
350 | } | ||
351 | |||
352 | f->page_offset = 0; | ||
353 | f->size = PAGE_SIZE; | ||
354 | |||
355 | skb_shinfo(skb)->nr_frags++; | ||
356 | |||
357 | sg_init_one(sg, page_address(f->page), PAGE_SIZE); | ||
358 | skb_queue_head(&vi->recv, skb); | ||
359 | |||
360 | err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 1, skb); | ||
361 | if (err) { | ||
362 | skb_unlink(skb, &vi->recv); | ||
235 | kfree_skb(skb); | 363 | kfree_skb(skb); |
236 | break; | 364 | break; |
237 | } | 365 | } |
@@ -246,9 +374,9 @@ static void skb_recv_done(struct virtqueue *rvq) | |||
246 | { | 374 | { |
247 | struct virtnet_info *vi = rvq->vdev->priv; | 375 | struct virtnet_info *vi = rvq->vdev->priv; |
248 | /* Schedule NAPI, Suppress further interrupts if successful. */ | 376 | /* Schedule NAPI, Suppress further interrupts if successful. */ |
249 | if (netif_rx_schedule_prep(vi->dev, &vi->napi)) { | 377 | if (netif_rx_schedule_prep(&vi->napi)) { |
250 | rvq->vq_ops->disable_cb(rvq); | 378 | rvq->vq_ops->disable_cb(rvq); |
251 | __netif_rx_schedule(vi->dev, &vi->napi); | 379 | __netif_rx_schedule(&vi->napi); |
252 | } | 380 | } |
253 | } | 381 | } |
254 | 382 | ||
@@ -274,11 +402,11 @@ again: | |||
274 | 402 | ||
275 | /* Out of packets? */ | 403 | /* Out of packets? */ |
276 | if (received < budget) { | 404 | if (received < budget) { |
277 | netif_rx_complete(vi->dev, napi); | 405 | netif_rx_complete(napi); |
278 | if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq)) | 406 | if (unlikely(!vi->rvq->vq_ops->enable_cb(vi->rvq)) |
279 | && napi_schedule_prep(napi)) { | 407 | && napi_schedule_prep(napi)) { |
280 | vi->rvq->vq_ops->disable_cb(vi->rvq); | 408 | vi->rvq->vq_ops->disable_cb(vi->rvq); |
281 | __netif_rx_schedule(vi->dev, napi); | 409 | __netif_rx_schedule(napi); |
282 | goto again; | 410 | goto again; |
283 | } | 411 | } |
284 | } | 412 | } |
@@ -320,17 +448,14 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) | |||
320 | { | 448 | { |
321 | int num, err; | 449 | int num, err; |
322 | struct scatterlist sg[2+MAX_SKB_FRAGS]; | 450 | struct scatterlist sg[2+MAX_SKB_FRAGS]; |
323 | struct virtio_net_hdr *hdr; | 451 | struct virtio_net_hdr_mrg_rxbuf *mhdr = skb_vnet_hdr(skb); |
452 | struct virtio_net_hdr *hdr = skb_vnet_hdr(skb); | ||
324 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; | 453 | const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; |
325 | 454 | ||
326 | sg_init_table(sg, 2+MAX_SKB_FRAGS); | 455 | sg_init_table(sg, 2+MAX_SKB_FRAGS); |
327 | 456 | ||
328 | pr_debug("%s: xmit %p " MAC_FMT "\n", vi->dev->name, skb, | 457 | pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest); |
329 | dest[0], dest[1], dest[2], | ||
330 | dest[3], dest[4], dest[5]); | ||
331 | 458 | ||
332 | /* Encode metadata header at front. */ | ||
333 | hdr = skb_vnet_hdr(skb); | ||
334 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 459 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
335 | hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; | 460 | hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM; |
336 | hdr->csum_start = skb->csum_start - skb_headroom(skb); | 461 | hdr->csum_start = skb->csum_start - skb_headroom(skb); |
@@ -358,7 +483,14 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) | |||
358 | hdr->gso_size = hdr->hdr_len = 0; | 483 | hdr->gso_size = hdr->hdr_len = 0; |
359 | } | 484 | } |
360 | 485 | ||
361 | vnet_hdr_to_sg(sg, skb); | 486 | mhdr->num_buffers = 0; |
487 | |||
488 | /* Encode metadata header at front. */ | ||
489 | if (vi->mergeable_rx_bufs) | ||
490 | sg_init_one(sg, mhdr, sizeof(*mhdr)); | ||
491 | else | ||
492 | sg_init_one(sg, hdr, sizeof(*hdr)); | ||
493 | |||
362 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; | 494 | num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; |
363 | 495 | ||
364 | err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); | 496 | err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); |
@@ -448,9 +580,9 @@ static int virtnet_open(struct net_device *dev) | |||
448 | * won't get another interrupt, so process any outstanding packets | 580 | * won't get another interrupt, so process any outstanding packets |
449 | * now. virtnet_poll wants re-enable the queue, so we disable here. | 581 | * now. virtnet_poll wants re-enable the queue, so we disable here. |
450 | * We synchronize against interrupts via NAPI_STATE_SCHED */ | 582 | * We synchronize against interrupts via NAPI_STATE_SCHED */ |
451 | if (netif_rx_schedule_prep(dev, &vi->napi)) { | 583 | if (netif_rx_schedule_prep(&vi->napi)) { |
452 | vi->rvq->vq_ops->disable_cb(vi->rvq); | 584 | vi->rvq->vq_ops->disable_cb(vi->rvq); |
453 | __netif_rx_schedule(dev, &vi->napi); | 585 | __netif_rx_schedule(&vi->napi); |
454 | } | 586 | } |
455 | return 0; | 587 | return 0; |
456 | } | 588 | } |
@@ -478,8 +610,20 @@ static int virtnet_set_tx_csum(struct net_device *dev, u32 data) | |||
478 | static struct ethtool_ops virtnet_ethtool_ops = { | 610 | static struct ethtool_ops virtnet_ethtool_ops = { |
479 | .set_tx_csum = virtnet_set_tx_csum, | 611 | .set_tx_csum = virtnet_set_tx_csum, |
480 | .set_sg = ethtool_op_set_sg, | 612 | .set_sg = ethtool_op_set_sg, |
613 | .set_tso = ethtool_op_set_tso, | ||
481 | }; | 614 | }; |
482 | 615 | ||
616 | #define MIN_MTU 68 | ||
617 | #define MAX_MTU 65535 | ||
618 | |||
619 | static int virtnet_change_mtu(struct net_device *dev, int new_mtu) | ||
620 | { | ||
621 | if (new_mtu < MIN_MTU || new_mtu > MAX_MTU) | ||
622 | return -EINVAL; | ||
623 | dev->mtu = new_mtu; | ||
624 | return 0; | ||
625 | } | ||
626 | |||
483 | static int virtnet_probe(struct virtio_device *vdev) | 627 | static int virtnet_probe(struct virtio_device *vdev) |
484 | { | 628 | { |
485 | int err; | 629 | int err; |
@@ -495,6 +639,7 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
495 | dev->open = virtnet_open; | 639 | dev->open = virtnet_open; |
496 | dev->stop = virtnet_close; | 640 | dev->stop = virtnet_close; |
497 | dev->hard_start_xmit = start_xmit; | 641 | dev->hard_start_xmit = start_xmit; |
642 | dev->change_mtu = virtnet_change_mtu; | ||
498 | dev->features = NETIF_F_HIGHDMA; | 643 | dev->features = NETIF_F_HIGHDMA; |
499 | #ifdef CONFIG_NET_POLL_CONTROLLER | 644 | #ifdef CONFIG_NET_POLL_CONTROLLER |
500 | dev->poll_controller = virtnet_netpoll; | 645 | dev->poll_controller = virtnet_netpoll; |
@@ -547,6 +692,9 @@ static int virtnet_probe(struct virtio_device *vdev) | |||
547 | || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN)) | 692 | || virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN)) |
548 | vi->big_packets = true; | 693 | vi->big_packets = true; |
549 | 694 | ||
695 | if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) | ||
696 | vi->mergeable_rx_bufs = true; | ||
697 | |||
550 | /* We expect two virtqueues, receive then send. */ | 698 | /* We expect two virtqueues, receive then send. */ |
551 | vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); | 699 | vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); |
552 | if (IS_ERR(vi->rvq)) { | 700 | if (IS_ERR(vi->rvq)) { |
@@ -639,6 +787,7 @@ static unsigned int features[] = { | |||
639 | VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, | 787 | VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, |
640 | VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, | 788 | VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, |
641 | VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */ | 789 | VIRTIO_NET_F_GUEST_ECN, /* We don't yet handle UFO input. */ |
790 | VIRTIO_NET_F_MRG_RXBUF, | ||
642 | VIRTIO_F_NOTIFY_ON_EMPTY, | 791 | VIRTIO_F_NOTIFY_ON_EMPTY, |
643 | }; | 792 | }; |
644 | 793 | ||