aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netback/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/xen-netback/interface.c')
-rw-r--r--drivers/net/xen-netback/interface.c47
1 files changed, 23 insertions, 24 deletions
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 625c6f49cfba..b78ee10a956a 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -214,10 +214,14 @@ static netdev_features_t xenvif_fix_features(struct net_device *dev,
214 214
215 if (!vif->can_sg) 215 if (!vif->can_sg)
216 features &= ~NETIF_F_SG; 216 features &= ~NETIF_F_SG;
217 if (!vif->gso && !vif->gso_prefix) 217 if (~(vif->gso_mask | vif->gso_prefix_mask) & GSO_BIT(TCPV4))
218 features &= ~NETIF_F_TSO; 218 features &= ~NETIF_F_TSO;
219 if (!vif->csum) 219 if (~(vif->gso_mask | vif->gso_prefix_mask) & GSO_BIT(TCPV6))
220 features &= ~NETIF_F_TSO6;
221 if (!vif->ip_csum)
220 features &= ~NETIF_F_IP_CSUM; 222 features &= ~NETIF_F_IP_CSUM;
223 if (!vif->ipv6_csum)
224 features &= ~NETIF_F_IPV6_CSUM;
221 225
222 return features; 226 return features;
223} 227}
@@ -306,18 +310,19 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
306 vif->domid = domid; 310 vif->domid = domid;
307 vif->handle = handle; 311 vif->handle = handle;
308 vif->can_sg = 1; 312 vif->can_sg = 1;
309 vif->csum = 1; 313 vif->ip_csum = 1;
310 vif->dev = dev; 314 vif->dev = dev;
311 315
312 vif->credit_bytes = vif->remaining_credit = ~0UL; 316 vif->credit_bytes = vif->remaining_credit = ~0UL;
313 vif->credit_usec = 0UL; 317 vif->credit_usec = 0UL;
314 init_timer(&vif->credit_timeout); 318 init_timer(&vif->credit_timeout);
315 /* Initialize 'expires' now: it's used to track the credit window. */ 319 vif->credit_window_start = get_jiffies_64();
316 vif->credit_timeout.expires = jiffies;
317 320
318 dev->netdev_ops = &xenvif_netdev_ops; 321 dev->netdev_ops = &xenvif_netdev_ops;
319 dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; 322 dev->hw_features = NETIF_F_SG |
320 dev->features = dev->hw_features; 323 NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
324 NETIF_F_TSO | NETIF_F_TSO6;
325 dev->features = dev->hw_features | NETIF_F_RXCSUM;
321 SET_ETHTOOL_OPS(dev, &xenvif_ethtool_ops); 326 SET_ETHTOOL_OPS(dev, &xenvif_ethtool_ops);
322 327
323 dev->tx_queue_len = XENVIF_QUEUE_LENGTH; 328 dev->tx_queue_len = XENVIF_QUEUE_LENGTH;
@@ -353,6 +358,9 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
353 } 358 }
354 359
355 netdev_dbg(dev, "Successfully created xenvif\n"); 360 netdev_dbg(dev, "Successfully created xenvif\n");
361
362 __module_get(THIS_MODULE);
363
356 return vif; 364 return vif;
357} 365}
358 366
@@ -366,8 +374,6 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
366 if (vif->tx_irq) 374 if (vif->tx_irq)
367 return 0; 375 return 0;
368 376
369 __module_get(THIS_MODULE);
370
371 err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); 377 err = xenvif_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref);
372 if (err < 0) 378 if (err < 0)
373 goto err; 379 goto err;
@@ -406,7 +412,7 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref,
406 412
407 init_waitqueue_head(&vif->wq); 413 init_waitqueue_head(&vif->wq);
408 vif->task = kthread_create(xenvif_kthread, 414 vif->task = kthread_create(xenvif_kthread,
409 (void *)vif, vif->dev->name); 415 (void *)vif, "%s", vif->dev->name);
410 if (IS_ERR(vif->task)) { 416 if (IS_ERR(vif->task)) {
411 pr_warn("Could not allocate kthread for %s\n", vif->dev->name); 417 pr_warn("Could not allocate kthread for %s\n", vif->dev->name);
412 err = PTR_ERR(vif->task); 418 err = PTR_ERR(vif->task);
@@ -452,12 +458,6 @@ void xenvif_carrier_off(struct xenvif *vif)
452 458
453void xenvif_disconnect(struct xenvif *vif) 459void xenvif_disconnect(struct xenvif *vif)
454{ 460{
455 /* Disconnect funtion might get called by generic framework
456 * even before vif connects, so we need to check if we really
457 * need to do a module_put.
458 */
459 int need_module_put = 0;
460
461 if (netif_carrier_ok(vif->dev)) 461 if (netif_carrier_ok(vif->dev))
462 xenvif_carrier_off(vif); 462 xenvif_carrier_off(vif);
463 463
@@ -468,23 +468,22 @@ void xenvif_disconnect(struct xenvif *vif)
468 unbind_from_irqhandler(vif->tx_irq, vif); 468 unbind_from_irqhandler(vif->tx_irq, vif);
469 unbind_from_irqhandler(vif->rx_irq, vif); 469 unbind_from_irqhandler(vif->rx_irq, vif);
470 } 470 }
471 /* vif->irq is valid, we had a module_get in 471 vif->tx_irq = 0;
472 * xenvif_connect.
473 */
474 need_module_put = 1;
475 } 472 }
476 473
477 if (vif->task) 474 if (vif->task)
478 kthread_stop(vif->task); 475 kthread_stop(vif->task);
479 476
477 xenvif_unmap_frontend_rings(vif);
478}
479
480void xenvif_free(struct xenvif *vif)
481{
480 netif_napi_del(&vif->napi); 482 netif_napi_del(&vif->napi);
481 483
482 unregister_netdev(vif->dev); 484 unregister_netdev(vif->dev);
483 485
484 xenvif_unmap_frontend_rings(vif);
485
486 free_netdev(vif->dev); 486 free_netdev(vif->dev);
487 487
488 if (need_module_put) 488 module_put(THIS_MODULE);
489 module_put(THIS_MODULE);
490} 489}