diff --git a/Documentation/networking/netconsole.rst b/Documentation/networking/netconsole.rst
index 1f5c4a04027c..a08387fcc3f0 100644
--- a/Documentation/networking/netconsole.rst
+++ b/Documentation/networking/netconsole.rst
@@ -13,6 +13,8 @@ IPv6 support by Cong Wang <xiyou.wangcong@gmail.com>, Jan 1 2013
 
 Extended console support by Tejun Heo <tj@kernel.org>, May 1 2015
 
+VLAN support by Libing Zhou <libing.zhou@nokia-sbell.com>, Dec 8 2020
+
 Please send bug reports to Matt Mackall <mpm@selenic.com>
 Satyam Sharma <satyam.sharma@gmail.com>, and Cong Wang <xiyou.wangcong@gmail.com>
 
@@ -34,7 +36,7 @@ Sender and receiver configuration:
 It takes a string configuration parameter "netconsole" in the
 following format::
 
- netconsole=[+][src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr]
+ netconsole=[+][src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr][-V<vid:pcp>]
 
    where
 	+             if present, enable extended console support
@@ -44,11 +46,17 @@ following format::
 	tgt-port      port for logging agent (6666)
 	tgt-ip        IP address for logging agent
 	tgt-macaddr   ethernet MAC address for logging agent (broadcast)
+	-V            if present, enable VLAN support
+	vid:pcp       VLAN identifier and priority code point
 
 Examples::
 
  linux netconsole=4444@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc
 
+or using VLAN::
+
+ linux netconsole=4444@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc-V100:1
+
 or::
 
  insmod netconsole netconsole=@/,@10.0.0.2/
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 92001f7af380..f0690cd6a744 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -36,7 +36,6 @@
 #include <linux/inet.h>
 #include <linux/configfs.h>
 #include <linux/etherdevice.h>
-
 MODULE_AUTHOR("Maintainer: Matt Mackall <mpm@selenic.com>");
 MODULE_DESCRIPTION("Console driver for network interfaces");
 MODULE_LICENSE("GPL");
@@ -46,7 +45,7 @@ MODULE_LICENSE("GPL");
 
 static char config[MAX_PARAM_LENGTH];
 module_param_string(netconsole, config, MAX_PARAM_LENGTH, 0);
-MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]");
+MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr][-V<vid:pcp>]");
 
 static bool oops_only = false;
 module_param(oops_only, bool, 0600);
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h
index e6a2d72e0dc7..8ab3f25cadae 100644
--- a/include/linux/netpoll.h
+++ b/include/linux/netpoll.h
@@ -31,6 +31,9 @@ struct netpoll {
 	bool ipv6;
 	u16 local_port, remote_port;
 	u8 remote_mac[ETH_ALEN];
+	bool vlan_present;
+	u16 vlan_id;
+	u8 pcp;
 };
 
 struct netpoll_info {
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 2338753e936b..077a7aec51ae 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -478,6 +478,14 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
 
 	skb->dev = np->dev;
 
+	if (np->vlan_present) {
+		skb->vlan_proto = htons(ETH_P_8021Q);
+
+		/* htons for tci is done in __vlan_insert_inner_tag, not here */
+		skb->vlan_tci = (np->pcp << VLAN_PRIO_SHIFT) + (np->vlan_id & VLAN_VID_MASK);
+		skb->vlan_present = 1;
+	}
+
 	netpoll_send_skb(np, skb);
 }
 EXPORT_SYMBOL(netpoll_send_udp);
@@ -496,6 +504,11 @@ void netpoll_print_options(struct netpoll *np)
 	else
 		np_info(np, "remote IPv4 address %pI4\n", &np->remote_ip.ip);
 	np_info(np, "remote ethernet address %pM\n", np->remote_mac);
+
+	if (np->vlan_present) {
+		np_info(np, "vlan id %d\n", np->vlan_id);
+		np_info(np, "pcp %d\n", np->pcp);
+	}
 }
 EXPORT_SYMBOL(netpoll_print_options);
 
@@ -587,10 +600,46 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
 
 	if (*cur != 0) {
 		/* MAC address */
-		if (!mac_pton(cur, np->remote_mac))
+		delim = strchr(cur, '-');
+		if (delim)
+			*delim = 0;
+		if (*cur != 0) {
+			if (!mac_pton(cur, np->remote_mac))
+				goto parse_failed;
+		}
+		if (!delim)
+			goto parse_done;
+	}
+
+	cur = delim + 1;
+	if (*cur == 'V') {
+		/* vlan id */
+		cur++;
+		delim = strchr(cur, ':');
+		if (!delim)
+			goto parse_failed;
+		np->vlan_present = 1;
+		*delim = 0;
+		if (kstrtou16(cur, 10, &np->vlan_id))
 			goto parse_failed;
+		if (np->vlan_id > 4094) {
+			np_info(np, "error: set vlan id: %d is illegal, allowed range 0-4094\n",
+				np->vlan_id);
+			return -1;
+		}
+		cur = delim + 1;
+
+		/* vlan pcp */
+		if (kstrtou8(cur, 10, &np->pcp))
+			goto parse_failed;
+		if (np->pcp > 7) {
+			np_info(np, "error: set pcp value: %d is illegal, allowed range 0-7\n",
+				np->pcp);
+			return -1;
+		}
 	}
 
+ parse_done:
 	netpoll_print_options(np);
 
 	return 0;
@@ -671,6 +720,13 @@ int netpoll_setup(struct netpoll *np)
 		err = -ENODEV;
 		goto unlock;
 	}
+	if (is_vlan_dev(ndev) && np->vlan_present) {
+		np_err(np, "%s is vlan interface already, can't support with extra vlan parameter\n",
+		       np->dev_name);
+		err = -ENODEV;
+		goto unlock;
+	}
+
 	dev_hold(ndev);
 
 	if (netdev_master_upper_dev_get(ndev)) {
