netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: <Charles.Hyde@dellteam.com>
To: <linux-usb@vger.kernel.org>, <linux-acpi@vger.kernel.org>
Cc: <gregkh@linuxfoundation.org>, <Mario.Limonciello@dell.com>,
	<oliver@neukum.org>, <netdev@vger.kernel.org>,
	<nic_swsd@realtek.com>
Subject: [RFC 1/4] Add usb_get_address and usb_set_address support
Date: Tue, 20 Aug 2019 22:18:42 +0000	[thread overview]
Message-ID: <1566339522507.45056@Dellteam.com> (raw)

The core USB driver message.c is missing get/set address functionality
that stops ifconfig from being able to push MAC addresses out to USB
based ethernet devices.  Without this functionality, some USB devices
stop responding to ethernet packets when using ifconfig to change MAC
addresses.  This has been tested with a Dell Universal Dock D6000.

Signed-off-by: Charles Hyde <charles.hyde@dellteam.com>
Cc: Mario Limonciello <mario.limonciello@dell.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-usb@vger.kernel.org
---
 drivers/usb/core/message.c | 59 ++++++++++++++++++++++++++++++++++++++
 include/linux/usb.h        |  3 ++
 2 files changed, 62 insertions(+)

diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 5adf489428aa..eea775234b09 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1085,6 +1085,65 @@ int usb_clear_halt(struct usb_device *dev, int pipe)
 }
 EXPORT_SYMBOL_GPL(usb_clear_halt);
 
+/**
+ * usb_get_address - 
+ * @dev: device whose endpoint is halted
+ * @mac: buffer for containing 
+ * Context: !in_interrupt ()
+ *
+ * This will attempt to get the six byte MAC address from a USB device's
+ * ethernet controller using GET_NET_ADDRESS command.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Return: Zero on success, or else the status code returned by the
+ * underlying usb_control_msg() call.
+ */
+int usb_get_address(struct usb_device *dev, unsigned char * mac)
+{
+	int ret = -ENOMEM;
+	unsigned char *tbuf = kmalloc(256, GFP_NOIO);
+
+	if (!tbuf)
+		return -ENOMEM;
+
+	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+			USB_CDC_GET_NET_ADDRESS,
+			USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+			0, USB_REQ_SET_ADDRESS, tbuf, 256,
+			USB_CTRL_GET_TIMEOUT);
+	if (ret == 6)
+		memcpy(mac, tbuf, 6);
+
+	kfree(tbuf);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(usb_get_address);
+
+/**
+ * usb_set_address - 
+ * @dev: device whose endpoint is halted
+ * @mac: desired MAC address in network address order
+ * Context: !in_interrupt ()
+ *
+ * This will attempt to set a six byte MAC address to the USB device's ethernet
+ * controller using SET_NET_ADDRESS command.
+ *
+ * This call is synchronous, and may not be used in an interrupt context.
+ *
+ * Return: Zero on success, or else the status code returned by the
+ * underlying usb_control_msg() call.
+ */
+int usb_set_address(struct usb_device *dev, unsigned char *mac)
+{
+	return usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+			USB_CDC_SET_NET_ADDRESS,
+			USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+			0, USB_REQ_SET_ADDRESS, mac, 6,
+			USB_CTRL_SET_TIMEOUT);
+}
+EXPORT_SYMBOL_GPL(usb_set_address);
+
 static int create_intf_ep_devs(struct usb_interface *intf)
 {
 	struct usb_device *udev = interface_to_usbdev(intf);
diff --git a/include/linux/usb.h b/include/linux/usb.h
index e87826e23d59..862c979d9821 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -1806,6 +1806,9 @@ static inline int usb_get_ptm_status(struct usb_device *dev, void *data)
 extern int usb_string(struct usb_device *dev, int index,
 	char *buf, size_t size);
 
+extern int usb_get_address(struct usb_device *dev, unsigned char * mac);
+extern int usb_set_address(struct usb_device *dev, unsigned char * mac);
+
 /* wrappers that also update important state inside usbcore */
 extern int usb_clear_halt(struct usb_device *dev, int pipe);
 extern int usb_reset_configuration(struct usb_device *dev);
-- 
2.20.1

             reply	other threads:[~2019-08-20 22:18 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-20 22:18 Charles.Hyde [this message]
2019-08-20 22:26 ` [RFC 1/4] Add usb_get_address and usb_set_address support Greg KH
2019-08-21 23:35   ` Charles.Hyde
2019-08-22  8:08     ` Oliver Neukum
2019-08-22 17:14       ` Charles.Hyde
2019-08-20 22:28 ` Greg KH
2019-08-21  1:22 ` Andrew Lunn
2019-08-21 23:45   ` Charles.Hyde
2019-08-21  9:08 ` Oliver Neukum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1566339522507.45056@Dellteam.com \
    --to=charles.hyde@dellteam.com \
    --cc=Mario.Limonciello@dell.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=nic_swsd@realtek.com \
    --cc=oliver@neukum.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).