aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/xen-netback/common.h6
-rw-r--r--drivers/net/xen-netback/interface.c19
-rw-r--r--drivers/net/xen-netback/netback.c2
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
201enum state_bit_shift {
202 /* This bit marks that the vif is connected */
203 VIF_STATUS_CONNECTED
204};
205
201struct xenvif { 206struct 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
56int xenvif_schedulable(struct xenvif *vif) 56int 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
61static irqreturn_t xenvif_tx_interrupt(int irq, void *dev_id) 62static irqreturn_t xenvif_tx_interrupt(int irq, void *dev_id)
@@ -267,7 +268,7 @@ static void xenvif_down(struct xenvif *vif)
267static int xenvif_open(struct net_device *dev) 268static 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)
276static int xenvif_close(struct net_device *dev) 277static 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())