diff options
| -rw-r--r-- | drivers/net/xen-netback/common.h | 6 | ||||
| -rw-r--r-- | drivers/net/xen-netback/interface.c | 19 | ||||
| -rw-r--r-- | drivers/net/xen-netback/netback.c | 2 |
3 files changed, 18 insertions, 9 deletions
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 28c98229e95f..4a92fc19f410 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h | |||
| @@ -198,6 +198,11 @@ struct xenvif_queue { /* Per-queue data for xenvif */ | |||
| 198 | struct xenvif_stats stats; | 198 | struct xenvif_stats stats; |
| 199 | }; | 199 | }; |
| 200 | 200 | ||
| 201 | enum state_bit_shift { | ||
| 202 | /* This bit marks that the vif is connected */ | ||
| 203 | VIF_STATUS_CONNECTED | ||
| 204 | }; | ||
| 205 | |||
| 201 | struct xenvif { | 206 | struct xenvif { |
| 202 | /* Unique identifier for this interface. */ | 207 | /* Unique identifier for this interface. */ |
| 203 | domid_t domid; | 208 | domid_t domid; |
| @@ -220,6 +225,7 @@ struct xenvif { | |||
| 220 | * frontend is rogue. | 225 | * frontend is rogue. |
| 221 | */ | 226 | */ |
| 222 | bool disabled; | 227 | bool disabled; |
| 228 | unsigned long status; | ||
| 223 | 229 | ||
| 224 | /* Queues */ | 230 | /* Queues */ |
| 225 | struct xenvif_queue *queues; | 231 | struct xenvif_queue *queues; |
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index bd59d9dbf27b..fbdadb3d8220 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
| @@ -55,7 +55,8 @@ static inline void xenvif_stop_queue(struct xenvif_queue *queue) | |||
| 55 | 55 | ||
| 56 | int xenvif_schedulable(struct xenvif *vif) | 56 | int xenvif_schedulable(struct xenvif *vif) |
| 57 | { | 57 | { |
| 58 | return netif_running(vif->dev) && netif_carrier_ok(vif->dev); | 58 | return netif_running(vif->dev) && |
| 59 | test_bit(VIF_STATUS_CONNECTED, &vif->status); | ||
| 59 | } | 60 | } |
| 60 | 61 | ||
| 61 | static irqreturn_t xenvif_tx_interrupt(int irq, void *dev_id) | 62 | static irqreturn_t xenvif_tx_interrupt(int irq, void *dev_id) |
| @@ -267,7 +268,7 @@ static void xenvif_down(struct xenvif *vif) | |||
| 267 | static int xenvif_open(struct net_device *dev) | 268 | static int xenvif_open(struct net_device *dev) |
| 268 | { | 269 | { |
| 269 | struct xenvif *vif = netdev_priv(dev); | 270 | struct xenvif *vif = netdev_priv(dev); |
| 270 | if (netif_carrier_ok(dev)) | 271 | if (test_bit(VIF_STATUS_CONNECTED, &vif->status)) |
| 271 | xenvif_up(vif); | 272 | xenvif_up(vif); |
| 272 | netif_tx_start_all_queues(dev); | 273 | netif_tx_start_all_queues(dev); |
| 273 | return 0; | 274 | return 0; |
| @@ -276,7 +277,7 @@ static int xenvif_open(struct net_device *dev) | |||
| 276 | static int xenvif_close(struct net_device *dev) | 277 | static int xenvif_close(struct net_device *dev) |
| 277 | { | 278 | { |
| 278 | struct xenvif *vif = netdev_priv(dev); | 279 | struct xenvif *vif = netdev_priv(dev); |
| 279 | if (netif_carrier_ok(dev)) | 280 | if (test_bit(VIF_STATUS_CONNECTED, &vif->status)) |
| 280 | xenvif_down(vif); | 281 | xenvif_down(vif); |
| 281 | netif_tx_stop_all_queues(dev); | 282 | netif_tx_stop_all_queues(dev); |
| 282 | return 0; | 283 | return 0; |
| @@ -528,6 +529,7 @@ void xenvif_carrier_on(struct xenvif *vif) | |||
| 528 | if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN) | 529 | if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN) |
| 529 | dev_set_mtu(vif->dev, ETH_DATA_LEN); | 530 | dev_set_mtu(vif->dev, ETH_DATA_LEN); |
| 530 | netdev_update_features(vif->dev); | 531 | netdev_update_features(vif->dev); |
| 532 | set_bit(VIF_STATUS_CONNECTED, &vif->status); | ||
| 531 | netif_carrier_on(vif->dev); | 533 | netif_carrier_on(vif->dev); |
| 532 | if (netif_running(vif->dev)) | 534 | if (netif_running(vif->dev)) |
| 533 | xenvif_up(vif); | 535 | xenvif_up(vif); |
| @@ -625,9 +627,11 @@ void xenvif_carrier_off(struct xenvif *vif) | |||
| 625 | struct net_device *dev = vif->dev; | 627 | struct net_device *dev = vif->dev; |
| 626 | 628 | ||
| 627 | rtnl_lock(); | 629 | rtnl_lock(); |
| 628 | netif_carrier_off(dev); /* discard queued packets */ | 630 | if (test_and_clear_bit(VIF_STATUS_CONNECTED, &vif->status)) { |
| 629 | if (netif_running(dev)) | 631 | netif_carrier_off(dev); /* discard queued packets */ |
| 630 | xenvif_down(vif); | 632 | if (netif_running(dev)) |
| 633 | xenvif_down(vif); | ||
| 634 | } | ||
| 631 | rtnl_unlock(); | 635 | rtnl_unlock(); |
| 632 | } | 636 | } |
| 633 | 637 | ||
| @@ -656,8 +660,7 @@ void xenvif_disconnect(struct xenvif *vif) | |||
| 656 | unsigned int num_queues = vif->num_queues; | 660 | unsigned int num_queues = vif->num_queues; |
| 657 | unsigned int queue_index; | 661 | unsigned int queue_index; |
| 658 | 662 | ||
| 659 | if (netif_carrier_ok(vif->dev)) | 663 | xenvif_carrier_off(vif); |
| 660 | xenvif_carrier_off(vif); | ||
| 661 | 664 | ||
| 662 | for (queue_index = 0; queue_index < num_queues; ++queue_index) { | 665 | for (queue_index = 0; queue_index < num_queues; ++queue_index) { |
| 663 | queue = &vif->queues[queue_index]; | 666 | queue = &vif->queues[queue_index]; |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 769e553d3f45..6c4cc0f44da5 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
| @@ -1953,7 +1953,7 @@ int xenvif_kthread_guest_rx(void *data) | |||
| 1953 | * context so we defer it here, if this thread is | 1953 | * context so we defer it here, if this thread is |
| 1954 | * associated with queue 0. | 1954 | * associated with queue 0. |
| 1955 | */ | 1955 | */ |
| 1956 | if (unlikely(queue->vif->disabled && netif_carrier_ok(queue->vif->dev) && queue->id == 0)) | 1956 | if (unlikely(queue->vif->disabled && queue->id == 0)) |
| 1957 | xenvif_carrier_off(queue->vif); | 1957 | xenvif_carrier_off(queue->vif); |
| 1958 | 1958 | ||
| 1959 | if (kthread_should_stop()) | 1959 | if (kthread_should_stop()) |
