diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index e8d9e4a9c9..c5eb552129 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -25,11 +25,22 @@
 #include "rndis.h"
 
 #include <dm.h>
+#include <dm/lists.h>
 #include <dm/uclass-internal.h>
 #include <dm/device-internal.h>
 
 #define USB_NET_NAME "usb_ether"
 
+/*
+ * This driver support only the following combinations.
+ * DM_ETH + DM_USB
+ * !DM_ETH + DM_USB
+ * !DM_ETH + !DM_USB
+ */
+#if defined(CONFIG_DM_ETH) && !defined(CONFIG_DM_USB)
+#error "This driver doesn't support the combination of DM_ETH and !DM_USB"
+#endif
+
 #define atomic_read
 extern struct platform_data brd;
 
@@ -116,7 +127,11 @@ struct eth_dev {
 
 	struct usb_request	*tx_req, *rx_req;
 
+#ifdef CONFIG_DM_ETH
+	struct udevice		*net;
+#else
 	struct eth_device	*net;
+#endif
 	struct net_device_stats	stats;
 	unsigned int		tx_qlen;
 
@@ -143,7 +158,11 @@ struct eth_dev {
 /*-------------------------------------------------------------------------*/
 struct ether_priv {
 	struct eth_dev ethdev;
+#ifdef CONFIG_DM_ETH
+	struct udevice *netdev;
+#else
 	struct eth_device netdev;
+#endif
 	struct usb_gadget_driver eth_driver;
 };
 
@@ -1851,7 +1870,11 @@ static void rndis_control_ack_complete(struct usb_ep *ep,
 
 static char rndis_resp_buf[8] __attribute__((aligned(sizeof(__le32))));
 
+#ifdef CONFIG_DM_ETH
+static int rndis_control_ack(struct udevice *net)
+#else
 static int rndis_control_ack(struct eth_device *net)
+#endif
 {
 	struct ether_priv	*priv = (struct ether_priv *)net->priv;
 	struct eth_dev		*dev = &priv->ethdev;
@@ -2000,6 +2023,9 @@ static int eth_bind(struct usb_gadget *gadget)
 	struct usb_ep		*in_ep, *out_ep, *status_ep = NULL;
 	int			status = -ENOMEM;
 	int			gcnum;
+#ifdef CONFIG_DM_ETH
+	struct eth_pdata	*pdata = dev_get_platdata(l_priv->netdev);
+#endif
 
 	/* these flags are only ever cleared; compiler take note */
 #ifndef	CONFIG_USB_ETH_CDC
@@ -2187,7 +2213,11 @@ autoconf_fail:
 
 
 	/* network device setup */
+#ifdef CONFIG_DM_ETH
+	dev->net = l_priv->netdev;
+#else
 	dev->net = &l_priv->netdev;
+#endif
 
 	dev->cdc = cdc;
 	dev->zlp = zlp;
@@ -2203,7 +2233,13 @@ autoconf_fail:
 	 * host side code for the SAFE thing cares -- its original BLAN
 	 * thing didn't, Sharp never assigned those addresses on Zaurii.
 	 */
-	get_ether_addr(dev_addr, dev->net->enetaddr);
+#ifdef CONFIG_DM_ETH
+	if (is_eth_addr_valid(dev_addr))
+		get_ether_addr(dev_addr, pdata->enetaddr);
+#else
+	if (is_eth_addr_valid(dev_addr))
+		get_ether_addr(dev_addr, dev->net->enetaddr);
+#endif
 
 	get_ether_addr(host_addr, dev->host_mac);
 
@@ -2264,10 +2300,11 @@ autoconf_fail:
 		status_ep ? " STATUS " : "",
 		status_ep ? status_ep->name : ""
 		);
-	printf("MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
-		dev->net->enetaddr[0], dev->net->enetaddr[1],
-		dev->net->enetaddr[2], dev->net->enetaddr[3],
-		dev->net->enetaddr[4], dev->net->enetaddr[5]);
+#ifdef CONFIG_DM_ETH
+	printf("MAC %pM\n", pdata->enetaddr);
+#else
+	printf("MAC %pM\n", dev->net->enetaddr);
+#endif
 
 	if (cdc || rndis)
 		printf("HOST MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -2364,10 +2401,6 @@ static int _usb_eth_init(struct ether_priv *priv)
 		strlcpy(host_addr, getenv("usbnet_hostaddr"),
 			sizeof(host_addr));
 
-	if (!is_eth_addr_valid(dev_addr)) {
-		error("Need valid 'usbnet_devaddr' to be set");
-		goto fail;
-	}
 	if (!is_eth_addr_valid(host_addr)) {
 		error("Need valid 'usbnet_hostaddr' to be set");
 		goto fail;
@@ -2527,6 +2560,7 @@ void _usb_eth_halt(struct ether_priv *priv)
 #endif
 }
 
+#ifndef CONFIG_DM_ETH
 static int usb_eth_init(struct eth_device *netdev, bd_t *bd)
 {
 	struct ether_priv *priv = (struct ether_priv *)netdev->priv;
@@ -2593,3 +2627,103 @@ int usb_eth_initialize(bd_t *bi)
 	eth_register(netdev);
 	return 0;
 }
+#else
+static int usb_eth_start(struct udevice *dev)
+{
+	struct ether_priv *priv = dev_get_priv(dev);
+
+	return _usb_eth_init(priv);
+}
+
+static int usb_eth_send(struct udevice *dev, void *packet, int length)
+{
+	struct ether_priv *priv = dev_get_priv(dev);
+
+	return _usb_eth_send(priv, packet, length);
+}
+
+static int usb_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+	struct ether_priv *priv = dev_get_priv(dev);
+	struct eth_dev *ethdev = &priv->ethdev;
+	int ret;
+
+	ret = _usb_eth_recv(priv);
+	if (ret) {
+		error("error packet receive\n");
+		return ret;
+	}
+
+	if (packet_received) {
+		if (ethdev->rx_req) {
+			*packetp = (uchar *)net_rx_packets[0];
+			return ethdev->rx_req->length;
+		} else {
+			error("dev->rx_req invalid");
+			return -EFAULT;
+		}
+	}
+
+	return -EAGAIN;
+}
+
+static int usb_eth_free_pkt(struct udevice *dev, uchar *packet,
+				   int length)
+{
+	struct ether_priv *priv = dev_get_priv(dev);
+	struct eth_dev *ethdev = &priv->ethdev;
+
+	packet_received = 0;
+
+	return rx_submit(ethdev, ethdev->rx_req, 0);
+}
+
+static void usb_eth_stop(struct udevice *dev)
+{
+	struct ether_priv *priv = dev_get_priv(dev);
+
+	_usb_eth_halt(priv);
+}
+
+static int usb_eth_probe(struct udevice *dev)
+{
+	struct ether_priv *priv = dev_get_priv(dev);
+
+	priv->netdev = dev;
+	l_priv = priv;
+
+	return 0;
+}
+
+static const struct eth_ops usb_eth_ops = {
+	.start		= usb_eth_start,
+	.send		= usb_eth_send,
+	.recv		= usb_eth_recv,
+	.free_pkt	= usb_eth_free_pkt,
+	.stop		= usb_eth_stop,
+};
+
+int usb_ether_init(struct udevice *usb_dev)
+{
+	struct udevice *dev;
+	int ret;
+
+	ret = device_bind_driver(usb_dev, "usb_ether", "usb_ether", &dev);
+	if (!dev || ret) {
+		error("usb - not able to bind usb_ether device\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+U_BOOT_DRIVER(eth_usb) = {
+	.name	= "usb_ether",
+	.id	= UCLASS_ETH,
+	.probe	= usb_eth_probe,
+	.ops	= &usb_eth_ops,
+	.priv_auto_alloc_size = sizeof(struct ether_priv),
+	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
+	.flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif /* CONFIG_DM_ETH */
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 844a0c7236..669eb3e59d 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -1121,7 +1121,11 @@ int rndis_msg_parser(u8 configNr, u8 *buf)
 	return -ENOTSUPP;
 }
 
+#ifdef CONFIG_DM_ETH
+int rndis_register(int (*rndis_control_ack)(struct udevice *))
+#else
 int rndis_register(int (*rndis_control_ack)(struct eth_device *))
+#endif
 {
 	u8 i;
 
@@ -1149,8 +1153,13 @@ void rndis_deregister(int configNr)
 	return;
 }
 
-int rndis_set_param_dev(u8 configNr, struct eth_device *dev, int mtu,
-			struct net_device_stats *stats,	u16 *cdc_filter)
+#ifdef CONFIG_DM_ETH
+int  rndis_set_param_dev(u8 configNr, struct udevice *dev, int mtu,
+			 struct net_device_stats *stats, u16 *cdc_filter)
+#else
+int  rndis_set_param_dev(u8 configNr, struct eth_device *dev, int mtu,
+			 struct net_device_stats *stats, u16 *cdc_filter)
+#endif
 {
 	debug("%s: configNr = %d\n", __func__, configNr);
 	if (!dev || !stats)
diff --git a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h
index 7a389a580a..ac225e9846 100644
--- a/drivers/usb/gadget/rndis.h
+++ b/drivers/usb/gadget/rndis.h
@@ -222,23 +222,34 @@ typedef struct rndis_params {
 
 	const u8		*host_mac;
 	u16			*filter;
-	struct eth_device	*dev;
 	struct net_device_stats *stats;
 	int			mtu;
 
 	u32			vendorID;
 	const char		*vendorDescr;
-	int			(*ack)(struct eth_device *);
+#ifdef CONFIG_DM_ETH
+	struct udevice		*dev;
+	int (*ack)(struct udevice *);
+#else
+	struct eth_device	*dev;
+	int (*ack)(struct eth_device *);
+#endif
 	struct list_head	resp_queue;
 } rndis_params;
 
 /* RNDIS Message parser and other useless functions */
 int  rndis_msg_parser(u8 configNr, u8 *buf);
 enum rndis_state rndis_get_state(int configNr);
-int  rndis_register(int (*rndis_control_ack)(struct eth_device *));
 void rndis_deregister(int configNr);
+#ifdef CONFIG_DM_ETH
+int  rndis_register(int (*rndis_control_ack)(struct udevice *));
+int  rndis_set_param_dev(u8 configNr, struct udevice *dev, int mtu,
+			 struct net_device_stats *stats, u16 *cdc_filter);
+#else
+int  rndis_register(int (*rndis_control_ack)(struct eth_device *));
 int  rndis_set_param_dev(u8 configNr, struct eth_device *dev, int mtu,
-			struct net_device_stats *stats, u16 *cdc_filter);
+			 struct net_device_stats *stats, u16 *cdc_filter);
+#endif
 int  rndis_set_param_vendor(u8 configNr, u32 vendorID,
 			    const char *vendorDescr);
 int  rndis_set_param_medium(u8 configNr, u32 medium, u32 speed);
diff --git a/include/net.h b/include/net.h
index 06320c6514..72a2961eed 100644
--- a/include/net.h
+++ b/include/net.h
@@ -156,6 +156,14 @@ unsigned char *eth_get_ethaddr(void); /* get the current device MAC */
 int eth_is_active(struct udevice *dev); /* Test device for active state */
 int eth_init_state_only(void); /* Set active state */
 void eth_halt_state_only(void); /* Set passive state */
+
+/*
+ * Initialize USB ethernet device with CONFIG_DM_ETH
+ * @usb_dev: usb device pointer to which the ethernet device to be atached to
+ * Returns:
+ *	0 is success, non-zero is error status.
+ */
+int usb_ether_init(struct udevice *usb_dev);
 #endif
 
 #ifndef CONFIG_DM_ETH
