linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next] hyperv: Add handler for RNDIS_STATUS_NETWORK_CHANGE event
@ 2014-06-20  1:34 Haiyang Zhang
  2014-06-20  4:21 ` David Miller
                   ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Haiyang Zhang @ 2014-06-20  1:34 UTC (permalink / raw)
  To: davem, netdev
  Cc: haiyangz, kys, olaf, jasowang, linux-kernel, driverdev-devel

The RNDIS_STATUS_NETWORK_CHANGE event is received after the Hyper-V host
sleep or hibernation. We refresh network at this time.
MS-TFS: 135162

Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Reviewed-by: K. Y. Srinivasan <kys@microsoft.com>

---
 drivers/net/hyperv/hyperv_net.h   |    3 ++-
 drivers/net/hyperv/netvsc_drv.c   |   30 ++++++++++++++++++++++++++----
 drivers/net/hyperv/rndis_filter.c |   21 +--------------------
 include/linux/rndis.h             |    1 +
 4 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 6cc37c1..24441ae 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -170,6 +170,7 @@ struct rndis_device {
 
 	enum rndis_device_state state;
 	bool link_state;
+	bool link_change;
 	atomic_t new_req_id;
 
 	spinlock_t request_lock;
@@ -185,7 +186,7 @@ int netvsc_device_remove(struct hv_device *device);
 int netvsc_send(struct hv_device *device,
 		struct hv_netvsc_packet *packet);
 void netvsc_linkstatus_callback(struct hv_device *device_obj,
-				unsigned int status);
+				struct rndis_message *resp);
 int netvsc_recv_callback(struct hv_device *device_obj,
 			struct hv_netvsc_packet *packet,
 			struct ndis_tcp_ip_checksum_info *csum_info);
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 4fd71b7..9b27ca8 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -579,8 +579,9 @@ drop:
  * netvsc_linkstatus_callback - Link up/down notification
  */
 void netvsc_linkstatus_callback(struct hv_device *device_obj,
-				       unsigned int status)
+				struct rndis_message *resp)
 {
+	struct rndis_indicate_status *indicate = &resp->msg.indicate_status;
 	struct net_device *net;
 	struct net_device_context *ndev_ctx;
 	struct netvsc_device *net_device;
@@ -589,7 +590,19 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
 	net_device = hv_get_drvdata(device_obj);
 	rdev = net_device->extension;
 
-	rdev->link_state = status != 1;
+	switch (indicate->status) {
+	case RNDIS_STATUS_MEDIA_CONNECT:
+		rdev->link_state = false;
+		break;
+	case RNDIS_STATUS_MEDIA_DISCONNECT:
+		rdev->link_state = true;
+		break;
+	case RNDIS_STATUS_NETWORK_CHANGE:
+		rdev->link_change = true;
+		break;
+	default:
+		return;
+	}
 
 	net = net_device->ndev;
 
@@ -597,7 +610,7 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
 		return;
 
 	ndev_ctx = netdev_priv(net);
-	if (status == 1) {
+	if (!rdev->link_state) {
 		schedule_delayed_work(&ndev_ctx->dwork, 0);
 		schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20));
 	} else {
@@ -767,7 +780,9 @@ static void netvsc_link_change(struct work_struct *w)
 	struct net_device *net;
 	struct netvsc_device *net_device;
 	struct rndis_device *rdev;
-	bool notify;
+	bool notify, refresh = false;
+	char *argv[] = { "/etc/init.d/network", "restart", NULL };
+	char *envp[] = { "HOME=/", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
 
 	rtnl_lock();
 
@@ -782,10 +797,17 @@ static void netvsc_link_change(struct work_struct *w)
 	} else {
 		netif_carrier_on(net);
 		notify = true;
+		if (rdev->link_change) {
+			rdev->link_change = false;
+			refresh = true;
+		}
 	}
 
 	rtnl_unlock();
 
+	if (refresh)
+		call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
+
 	if (notify)
 		netdev_notify_peers(net);
 }
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 99c527a..2b86f0b 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -320,25 +320,6 @@ static void rndis_filter_receive_response(struct rndis_device *dev,
 	}
 }
 
-static void rndis_filter_receive_indicate_status(struct rndis_device *dev,
-					     struct rndis_message *resp)
-{
-	struct rndis_indicate_status *indicate =
-			&resp->msg.indicate_status;
-
-	if (indicate->status == RNDIS_STATUS_MEDIA_CONNECT) {
-		netvsc_linkstatus_callback(
-			dev->net_dev->dev, 1);
-	} else if (indicate->status == RNDIS_STATUS_MEDIA_DISCONNECT) {
-		netvsc_linkstatus_callback(
-			dev->net_dev->dev, 0);
-	} else {
-		/*
-		 * TODO:
-		 */
-	}
-}
-
 /*
  * Get the Per-Packet-Info with the specified type
  * return NULL if not found.
@@ -464,7 +445,7 @@ int rndis_filter_receive(struct hv_device *dev,
 
 	case RNDIS_MSG_INDICATE:
 		/* notification msgs */
-		rndis_filter_receive_indicate_status(rndis_dev, rndis_msg);
+		netvsc_linkstatus_callback(dev, rndis_msg);
 		break;
 	default:
 		netdev_err(ndev,
diff --git a/include/linux/rndis.h b/include/linux/rndis.h
index 0c8dc71..93c0a64 100644
--- a/include/linux/rndis.h
+++ b/include/linux/rndis.h
@@ -65,6 +65,7 @@
 #define	RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION	0x40010012
 #define RNDIS_STATUS_WW_INDICATION		RDIA_SPECIFIC_INDICATION
 #define RNDIS_STATUS_LINK_SPEED_CHANGE		0x40010013L
+#define RNDIS_STATUS_NETWORK_CHANGE		0x40010018
 
 #define RNDIS_STATUS_NOT_RESETTABLE		0x80010001
 #define RNDIS_STATUS_SOFT_ERRORS		0x80010003
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2015-10-30 22:36 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-20  1:34 [PATCH net-next] hyperv: Add handler for RNDIS_STATUS_NETWORK_CHANGE event Haiyang Zhang
2014-06-20  4:21 ` David Miller
2014-06-20  4:57 ` Olaf Hering
2014-06-20  5:12   ` Greg KH
2014-06-20 16:09     ` Haiyang Zhang
2014-06-23  8:02       ` Olaf Hering
2014-06-23 12:47         ` Haiyang Zhang
2014-06-23 13:17           ` Olaf Hering
2014-06-23 16:09             ` Haiyang Zhang
2014-06-23 16:27               ` Olaf Hering
2014-06-23 18:21                 ` Haiyang Zhang
2014-06-26  8:45                   ` Olaf Hering
2014-06-26 14:55                     ` Haiyang Zhang
2014-06-23 16:29               ` Greg KH
2014-06-23 18:23                 ` Haiyang Zhang
2014-06-23 20:11                 ` David Miller
2014-06-23 20:10               ` David Miller
2014-06-23 20:17                 ` Haiyang Zhang
2015-10-27 22:36                 ` Richard Weinberger
2015-10-28 17:59                   ` Haiyang Zhang
2015-10-29 19:09                   ` Haiyang Zhang
2015-10-30 10:56                     ` Vitaly Kuznetsov
2015-10-30 22:03                       ` Haiyang Zhang
2015-10-30 22:10                         ` Richard Weinberger
2014-06-23 20:06             ` David Miller
2014-06-20  8:41 ` Dan Carpenter
2014-06-20 15:48   ` Haiyang Zhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).