aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 00:04:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 00:04:44 -0400
commitf8965467f366fd18f01feafb5db10512d7b4422c (patch)
tree3706a9cd779859271ca61b85c63a1bc3f82d626e /drivers/net/virtio_net.c
parenta26272e5200765691e67d6780e52b32498fdb659 (diff)
parent2ec8c6bb5d8f3a62a79f463525054bae1e3d4487 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1674 commits) qlcnic: adding co maintainer ixgbe: add support for active DA cables ixgbe: dcb, do not tag tc_prio_control frames ixgbe: fix ixgbe_tx_is_paused logic ixgbe: always enable vlan strip/insert when DCB is enabled ixgbe: remove some redundant code in setting FCoE FIP filter ixgbe: fix wrong offset to fc_frame_header in ixgbe_fcoe_ddp ixgbe: fix header len when unsplit packet overflows to data buffer ipv6: Never schedule DAD timer on dead address ipv6: Use POSTDAD state ipv6: Use state_lock to protect ifa state ipv6: Replace inet6_ifaddr->dead with state cxgb4: notify upper drivers if the device is already up when they load cxgb4: keep interrupts available when the ports are brought down cxgb4: fix initial addition of MAC address cnic: Return SPQ credit to bnx2x after ring setup and shutdown. cnic: Convert cnic_local_flags to atomic ops. can: Fix SJA1000 command register writes on SMP systems bridge: fix build for CONFIG_SYSFS disabled ARCNET: Limit com20020 PCI ID matches for SOHARD cards ... Fix up various conflicts with pcmcia tree drivers/net/ {pcmcia/3c589_cs.c, wireless/orinoco/orinoco_cs.c and wireless/orinoco/spectrum_cs.c} and feature removal (Documentation/feature-removal-schedule.txt). Also fix a non-content conflict due to pm_qos_requirement getting renamed in the PM tree (now pm_qos_request) in net/mac80211/scan.c
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c57
1 files changed, 27 insertions, 30 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index b0577dd1a42d..b0a85d038796 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -40,8 +40,7 @@ module_param(gso, bool, 0444);
40 40
41#define VIRTNET_SEND_COMMAND_SG_MAX 2 41#define VIRTNET_SEND_COMMAND_SG_MAX 2
42 42
43struct virtnet_info 43struct virtnet_info {
44{
45 struct virtio_device *vdev; 44 struct virtio_device *vdev;
46 struct virtqueue *rvq, *svq, *cvq; 45 struct virtqueue *rvq, *svq, *cvq;
47 struct net_device *dev; 46 struct net_device *dev;
@@ -62,6 +61,10 @@ struct virtnet_info
62 61
63 /* Chain pages by the private ptr. */ 62 /* Chain pages by the private ptr. */
64 struct page *pages; 63 struct page *pages;
64
65 /* fragments + linear part + virtio header */
66 struct scatterlist rx_sg[MAX_SKB_FRAGS + 2];
67 struct scatterlist tx_sg[MAX_SKB_FRAGS + 2];
65}; 68};
66 69
67struct skb_vnet_hdr { 70struct skb_vnet_hdr {
@@ -324,10 +327,8 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
324{ 327{
325 struct sk_buff *skb; 328 struct sk_buff *skb;
326 struct skb_vnet_hdr *hdr; 329 struct skb_vnet_hdr *hdr;
327 struct scatterlist sg[2];
328 int err; 330 int err;
329 331
330 sg_init_table(sg, 2);
331 skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN); 332 skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN);
332 if (unlikely(!skb)) 333 if (unlikely(!skb))
333 return -ENOMEM; 334 return -ENOMEM;
@@ -335,11 +336,11 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
335 skb_put(skb, MAX_PACKET_LEN); 336 skb_put(skb, MAX_PACKET_LEN);
336 337
337 hdr = skb_vnet_hdr(skb); 338 hdr = skb_vnet_hdr(skb);
338 sg_set_buf(sg, &hdr->hdr, sizeof hdr->hdr); 339 sg_set_buf(vi->rx_sg, &hdr->hdr, sizeof hdr->hdr);
339 340
340 skb_to_sgvec(skb, sg + 1, 0, skb->len); 341 skb_to_sgvec(skb, vi->rx_sg + 1, 0, skb->len);
341 342
342 err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 2, skb); 343 err = vi->rvq->vq_ops->add_buf(vi->rvq, vi->rx_sg, 0, 2, skb);
343 if (err < 0) 344 if (err < 0)
344 dev_kfree_skb(skb); 345 dev_kfree_skb(skb);
345 346
@@ -348,13 +349,11 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
348 349
349static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp) 350static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
350{ 351{
351 struct scatterlist sg[MAX_SKB_FRAGS + 2];
352 struct page *first, *list = NULL; 352 struct page *first, *list = NULL;
353 char *p; 353 char *p;
354 int i, err, offset; 354 int i, err, offset;
355 355
356 sg_init_table(sg, MAX_SKB_FRAGS + 2); 356 /* page in vi->rx_sg[MAX_SKB_FRAGS + 1] is list tail */
357 /* page in sg[MAX_SKB_FRAGS + 1] is list tail */
358 for (i = MAX_SKB_FRAGS + 1; i > 1; --i) { 357 for (i = MAX_SKB_FRAGS + 1; i > 1; --i) {
359 first = get_a_page(vi, gfp); 358 first = get_a_page(vi, gfp);
360 if (!first) { 359 if (!first) {
@@ -362,7 +361,7 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
362 give_pages(vi, list); 361 give_pages(vi, list);
363 return -ENOMEM; 362 return -ENOMEM;
364 } 363 }
365 sg_set_buf(&sg[i], page_address(first), PAGE_SIZE); 364 sg_set_buf(&vi->rx_sg[i], page_address(first), PAGE_SIZE);
366 365
367 /* chain new page in list head to match sg */ 366 /* chain new page in list head to match sg */
368 first->private = (unsigned long)list; 367 first->private = (unsigned long)list;
@@ -376,17 +375,17 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
376 } 375 }
377 p = page_address(first); 376 p = page_address(first);
378 377
379 /* sg[0], sg[1] share the same page */ 378 /* vi->rx_sg[0], vi->rx_sg[1] share the same page */
380 /* a separated sg[0] for virtio_net_hdr only during to QEMU bug*/ 379 /* a separated vi->rx_sg[0] for virtio_net_hdr only due to QEMU bug */
381 sg_set_buf(&sg[0], p, sizeof(struct virtio_net_hdr)); 380 sg_set_buf(&vi->rx_sg[0], p, sizeof(struct virtio_net_hdr));
382 381
383 /* sg[1] for data packet, from offset */ 382 /* vi->rx_sg[1] for data packet, from offset */
384 offset = sizeof(struct padded_vnet_hdr); 383 offset = sizeof(struct padded_vnet_hdr);
385 sg_set_buf(&sg[1], p + offset, PAGE_SIZE - offset); 384 sg_set_buf(&vi->rx_sg[1], p + offset, PAGE_SIZE - offset);
386 385
387 /* chain first in list head */ 386 /* chain first in list head */
388 first->private = (unsigned long)list; 387 first->private = (unsigned long)list;
389 err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, MAX_SKB_FRAGS + 2, 388 err = vi->rvq->vq_ops->add_buf(vi->rvq, vi->rx_sg, 0, MAX_SKB_FRAGS + 2,
390 first); 389 first);
391 if (err < 0) 390 if (err < 0)
392 give_pages(vi, first); 391 give_pages(vi, first);
@@ -397,16 +396,15 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
397static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp) 396static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp)
398{ 397{
399 struct page *page; 398 struct page *page;
400 struct scatterlist sg;
401 int err; 399 int err;
402 400
403 page = get_a_page(vi, gfp); 401 page = get_a_page(vi, gfp);
404 if (!page) 402 if (!page)
405 return -ENOMEM; 403 return -ENOMEM;
406 404
407 sg_init_one(&sg, page_address(page), PAGE_SIZE); 405 sg_init_one(vi->rx_sg, page_address(page), PAGE_SIZE);
408 406
409 err = vi->rvq->vq_ops->add_buf(vi->rvq, &sg, 0, 1, page); 407 err = vi->rvq->vq_ops->add_buf(vi->rvq, vi->rx_sg, 0, 1, page);
410 if (err < 0) 408 if (err < 0)
411 give_pages(vi, page); 409 give_pages(vi, page);
412 410
@@ -515,12 +513,9 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi)
515 513
516static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) 514static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
517{ 515{
518 struct scatterlist sg[2+MAX_SKB_FRAGS];
519 struct skb_vnet_hdr *hdr = skb_vnet_hdr(skb); 516 struct skb_vnet_hdr *hdr = skb_vnet_hdr(skb);
520 const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; 517 const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
521 518
522 sg_init_table(sg, 2+MAX_SKB_FRAGS);
523
524 pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest); 519 pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest);
525 520
526 if (skb->ip_summed == CHECKSUM_PARTIAL) { 521 if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -554,12 +549,13 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
554 549
555 /* Encode metadata header at front. */ 550 /* Encode metadata header at front. */
556 if (vi->mergeable_rx_bufs) 551 if (vi->mergeable_rx_bufs)
557 sg_set_buf(sg, &hdr->mhdr, sizeof hdr->mhdr); 552 sg_set_buf(vi->tx_sg, &hdr->mhdr, sizeof hdr->mhdr);
558 else 553 else
559 sg_set_buf(sg, &hdr->hdr, sizeof hdr->hdr); 554 sg_set_buf(vi->tx_sg, &hdr->hdr, sizeof hdr->hdr);
560 555
561 hdr->num_sg = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; 556 hdr->num_sg = skb_to_sgvec(skb, vi->tx_sg + 1, 0, skb->len) + 1;
562 return vi->svq->vq_ops->add_buf(vi->svq, sg, hdr->num_sg, 0, skb); 557 return vi->svq->vq_ops->add_buf(vi->svq, vi->tx_sg, hdr->num_sg,
558 0, skb);
563} 559}
564 560
565static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) 561static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -722,7 +718,6 @@ static void virtnet_set_rx_mode(struct net_device *dev)
722 struct scatterlist sg[2]; 718 struct scatterlist sg[2];
723 u8 promisc, allmulti; 719 u8 promisc, allmulti;
724 struct virtio_net_ctrl_mac *mac_data; 720 struct virtio_net_ctrl_mac *mac_data;
725 struct dev_addr_list *addr;
726 struct netdev_hw_addr *ha; 721 struct netdev_hw_addr *ha;
727 int uc_count; 722 int uc_count;
728 int mc_count; 723 int mc_count;
@@ -779,8 +774,8 @@ static void virtnet_set_rx_mode(struct net_device *dev)
779 774
780 mac_data->entries = mc_count; 775 mac_data->entries = mc_count;
781 i = 0; 776 i = 0;
782 netdev_for_each_mc_addr(addr, dev) 777 netdev_for_each_mc_addr(ha, dev)
783 memcpy(&mac_data->macs[i++][0], addr->da_addr, ETH_ALEN); 778 memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN);
784 779
785 sg_set_buf(&sg[1], mac_data, 780 sg_set_buf(&sg[1], mac_data,
786 sizeof(mac_data->entries) + (mc_count * ETH_ALEN)); 781 sizeof(mac_data->entries) + (mc_count * ETH_ALEN));
@@ -942,6 +937,8 @@ static int virtnet_probe(struct virtio_device *vdev)
942 vdev->priv = vi; 937 vdev->priv = vi;
943 vi->pages = NULL; 938 vi->pages = NULL;
944 INIT_DELAYED_WORK(&vi->refill, refill_work); 939 INIT_DELAYED_WORK(&vi->refill, refill_work);
940 sg_init_table(vi->rx_sg, ARRAY_SIZE(vi->rx_sg));
941 sg_init_table(vi->tx_sg, ARRAY_SIZE(vi->tx_sg));
945 942
946 /* If we can receive ANY GSO packets, we must allocate large ones. */ 943 /* If we can receive ANY GSO packets, we must allocate large ones. */
947 if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || 944 if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||