Linux-ACPI Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 1/3] net: cdc_ncm: add get/set ethernet address functions
@ 2019-09-05 21:01 Charles.Hyde
  2019-09-06  9:02 ` Bjørn Mork
  0 siblings, 1 reply; 12+ messages in thread
From: Charles.Hyde @ 2019-09-05 21:01 UTC (permalink / raw)
  To: oliver, rjw, lenb
  Cc: Mario.Limonciello, chip.programmer, nic_swsd, linux-usb, linux-acpi

This patch adds support for pushing a MAC address out to USB based
ethernet controllers driven by cdc_ncm.  With this change, ifconfig can
now set the device's MAC address.  For example, the Dell Universal Dock
D6000 is driven by cdc_ncm.  The D6000 can now have its MAC address set
by ifconfig, as it can be done in Windows.  This was tested with a D6000
using ifconfig on an x86 based chromebook, where iproute2 is not
available.

Signed-off-by: Charles Hyde <charles.hyde@dellteam.com>
Cc: Mario Limonciello <mario.limonciello@dell.com>
Cc: chip.programmer@gmail.com
Cc: Oliver Neukum <oliver@neukum.org>
Cc: linux-usb@vger.kernel.org
---
 drivers/net/usb/cdc_ncm.c | 74 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 50c05d0f44cb..85093579612f 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -750,6 +750,78 @@ int cdc_ncm_change_mtu(struct net_device *net, int new_mtu)
 }
 EXPORT_SYMBOL_GPL(cdc_ncm_change_mtu);
 
+/* Provide method to get MAC address from the USB device's ethernet controller.
+ * If the device supports CDC_GET_ADDRESS, we should receive just six bytes.
+ * Otherwise, use the prior method by asking for the descriptor.
+ */
+static int cdc_ncm_get_ethernet_address(struct usbnet *dev,
+					struct cdc_ncm_ctx *ctx)
+{
+	int ret;
+	char *buf;
+
+	buf = kmalloc(ETH_ALEN, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = usbnet_read_cmd(dev, USB_CDC_GET_NET_ADDRESS,
+			      USB_DIR_IN | USB_TYPE_CLASS
+			      | USB_RECIP_INTERFACE, 0,
+			      USB_REQ_SET_ADDRESS, buf, ETH_ALEN);
+	if (ret == ETH_ALEN) {
+		memcpy(dev->net->dev_addr, buf, ETH_ALEN);
+		ret = 0;	/* success */
+	} else {
+		ret = usbnet_get_ethernet_addr(dev,
+					       ctx->ether_desc->iMACAddress);
+	}
+	kfree(buf);
+	return ret;
+}
+
+/* Provide method to push MAC address to the USB device's ethernet controller.
+ * If the device does not support CDC_SET_ADDRESS, there is no harm and we
+ * proceed as before.
+ */
+static int cdc_ncm_set_ethernet_address(struct usbnet *dev,
+					struct sockaddr *addr)
+{
+	int ret;
+	char *buf;
+
+	buf = kmalloc(ETH_ALEN, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	memcpy(buf, addr->sa_data, ETH_ALEN);
+	ret = usbnet_write_cmd(dev, USB_CDC_SET_NET_ADDRESS,
+			       USB_DIR_OUT | USB_TYPE_CLASS
+			       | USB_RECIP_INTERFACE, 0,
+			       USB_REQ_SET_ADDRESS, buf, ETH_ALEN);
+	if (ret == ETH_ALEN)
+		ret = 0;	/* success */
+	else if (ret < 0)
+		dev_dbg(&dev->udev->dev, "bad MAC address put, %d\n", ret);
+
+	kfree(buf);
+	return ret;
+}
+
+/* Provide method to push MAC address to the USB device's ethernet controller.
+ */
+int cdc_ncm_set_mac_addr(struct net_device *net, void *p)
+{
+	struct usbnet *dev = netdev_priv(net);
+
+	/* Try to push the MAC address out to the device.  Ignore any errors,
+	 * to be compatible with prior versions of this source.
+	 */
+	cdc_ncm_set_ethernet_address(dev, (struct sockaddr *)p);
+
+	return eth_mac_addr(net, p);
+}
+EXPORT_SYMBOL_GPL(cdc_ncm_set_mac_addr);
+
 static const struct net_device_ops cdc_ncm_netdev_ops = {
 	.ndo_open	     = usbnet_open,
 	.ndo_stop	     = usbnet_stop,
@@ -757,7 +829,7 @@ static const struct net_device_ops cdc_ncm_netdev_ops = {
 	.ndo_tx_timeout	     = usbnet_tx_timeout,
 	.ndo_get_stats64     = usbnet_get_stats64,
 	.ndo_change_mtu	     = cdc_ncm_change_mtu,
-	.ndo_set_mac_address = eth_mac_addr,
+	.ndo_set_mac_address = cdc_ncm_set_mac_addr,
 	.ndo_validate_addr   = eth_validate_addr,
 };
 
-- 
2.20.1

^ permalink raw reply	[flat|nested] 12+ messages in thread
* [PATCH 1/3] net: cdc_ncm: add get/set ethernet address functions
@ 2019-08-30 19:37 Charles.Hyde
  2019-09-02  9:43 ` Oliver Neukum
  0 siblings, 1 reply; 12+ messages in thread
From: Charles.Hyde @ 2019-08-30 19:37 UTC (permalink / raw)
  To: oliver, rjw, lenb; +Cc: linux-usb, linux-acpi, nic_swsd, Mario.Limonciello

This patch adds support for pushing a MAC address out to USB based
ethernet controllers driven by cdc_ncm.  With this change, ifconfig can
now set the device's MAC address.  For example, the Dell Universal Dock
D6000 is driven by cdc_ncm.  The D6000 can now have its MAC address set
by ifconfig, as it can be done in Windows.  This was tested with a D6000
using ifconfig on an x86 based chromebook, where iproute2 is not
available.

Signed-off-by: Charles Hyde <charles.hyde@dellteam.com>
Cc: Mario Limonciello <mario.limonciello@dell.com>
Cc: Oliver Neukum <oliver@neukum.org>
Cc: linux-usb@vger.kernel.org
---
 drivers/net/usb/cdc_ncm.c | 74 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 73 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 50c05d0f44cb..85093579612f 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -750,6 +750,78 @@ int cdc_ncm_change_mtu(struct net_device *net, int new_mtu)
 }
 EXPORT_SYMBOL_GPL(cdc_ncm_change_mtu);
 
+/* Provide method to get MAC address from the USB device's ethernet controller.
+ * If the device supports CDC_GET_ADDRESS, we should receive just six bytes.
+ * Otherwise, use the prior method by asking for the descriptor.
+ */
+static int cdc_ncm_get_ethernet_address(struct usbnet *dev,
+					struct cdc_ncm_ctx *ctx)
+{
+	int ret;
+	char *buf;
+
+	buf = kmalloc(ETH_ALEN, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	ret = usbnet_read_cmd(dev, USB_CDC_GET_NET_ADDRESS,
+			      USB_DIR_IN | USB_TYPE_CLASS
+			      | USB_RECIP_INTERFACE, 0,
+			      USB_REQ_SET_ADDRESS, buf, ETH_ALEN);
+	if (ret == ETH_ALEN) {
+		memcpy(dev->net->dev_addr, buf, ETH_ALEN);
+		ret = 0;	/* success */
+	} else {
+		ret = usbnet_get_ethernet_addr(dev,
+					       ctx->ether_desc->iMACAddress);
+	}
+	kfree(buf);
+	return ret;
+}
+
+/* Provide method to push MAC address to the USB device's ethernet controller.
+ * If the device does not support CDC_SET_ADDRESS, there is no harm and we
+ * proceed as before.
+ */
+static int cdc_ncm_set_ethernet_address(struct usbnet *dev,
+					struct sockaddr *addr)
+{
+	int ret;
+	char *buf;
+
+	buf = kmalloc(ETH_ALEN, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
+	memcpy(buf, addr->sa_data, ETH_ALEN);
+	ret = usbnet_write_cmd(dev, USB_CDC_SET_NET_ADDRESS,
+			       USB_DIR_OUT | USB_TYPE_CLASS
+			       | USB_RECIP_INTERFACE, 0,
+			       USB_REQ_SET_ADDRESS, buf, ETH_ALEN);
+	if (ret == ETH_ALEN)
+		ret = 0;	/* success */
+	else if (ret < 0)
+		dev_dbg(&dev->udev->dev, "bad MAC address put, %d\n", ret);
+
+	kfree(buf);
+	return ret;
+}
+
+/* Provide method to push MAC address to the USB device's ethernet controller.
+ */
+int cdc_ncm_set_mac_addr(struct net_device *net, void *p)
+{
+	struct usbnet *dev = netdev_priv(net);
+
+	/* Try to push the MAC address out to the device.  Ignore any errors,
+	 * to be compatible with prior versions of this source.
+	 */
+	cdc_ncm_set_ethernet_address(dev, (struct sockaddr *)p);
+
+	return eth_mac_addr(net, p);
+}
+EXPORT_SYMBOL_GPL(cdc_ncm_set_mac_addr);
+
 static const struct net_device_ops cdc_ncm_netdev_ops = {
 	.ndo_open	     = usbnet_open,
 	.ndo_stop	     = usbnet_stop,
@@ -757,7 +829,7 @@ static const struct net_device_ops cdc_ncm_netdev_ops = {
 	.ndo_tx_timeout	     = usbnet_tx_timeout,
 	.ndo_get_stats64     = usbnet_get_stats64,
 	.ndo_change_mtu	     = cdc_ncm_change_mtu,
-	.ndo_set_mac_address = eth_mac_addr,
+	.ndo_set_mac_address = cdc_ncm_set_mac_addr,
 	.ndo_validate_addr   = eth_validate_addr,
 };
 
-- 
2.20.1

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

end of thread, back to index

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-05 21:01 [PATCH 1/3] net: cdc_ncm: add get/set ethernet address functions Charles.Hyde
2019-09-06  9:02 ` Bjørn Mork
2019-09-06 18:00   ` Charles.Hyde
2019-09-06 18:15     ` Alan Stern
2019-09-06 18:19       ` Charles.Hyde
2019-09-06 20:07         ` Bjørn Mork
2019-09-06 20:20           ` Charles.Hyde
2019-09-06 20:39             ` Bjørn Mork
2019-09-06 21:00               ` Charles.Hyde
  -- strict thread matches above, loose matches on Subject: below --
2019-08-30 19:37 Charles.Hyde
2019-09-02  9:43 ` Oliver Neukum
2019-09-03 16:45   ` Charles.Hyde

Linux-ACPI Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-acpi/0 linux-acpi/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-acpi linux-acpi/ https://lore.kernel.org/linux-acpi \
		linux-acpi@vger.kernel.org linux-acpi@archiver.kernel.org
	public-inbox-index linux-acpi

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-acpi


AGPL code for this site: git clone https://public-inbox.org/ public-inbox