Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9399d4e authored by Konrad Gräfe's avatar Konrad Gräfe Committed by Greg Kroah-Hartman
Browse files

usb: gadget: u_ether: Fix host MAC address case

[ Upstream commit 3c0f4f09c063e143822393d99cb2b19a85451c07 ]

The CDC-ECM specification [1] requires to send the host MAC address as
an uppercase hexadecimal string in chapter "5.4 Ethernet Networking
Functional Descriptor":
    The Unicode character is chosen from the set of values 30h through
    39h and 41h through 46h (0-9 and A-F).

However, snprintf(.., "%pm", ..) generates a lowercase MAC address
string. While most host drivers are tolerant to this, UsbNcm.sys on
Windows 10 is not. Instead it uses a different MAC address with all
bytes set to zero including and after the first byte containing a
lowercase letter. On Windows 11 Microsoft fixed it, but apparently they
did not backport the fix.

This change fixes the issue by upper-casing the MAC to comply with the
specification.

[1]: https://www.usb.org/document-library/class-definitions-communication-devices-12

, file ECM120.pdf

Fixes: bcd4a1c4 ("usb: gadget: u_ether: construct with default values and add setters/getters")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarKonrad Gräfe <k.graefe@gateware.de>
Link: https://lore.kernel.org/r/20230505143640.443014-1-k.graefe@gateware.de


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 939cafcd
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/etherdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/if_vlan.h>
#include <linux/string_helpers.h>
#include <linux/usb/composite.h>
#include <linux/usb/composite.h>


#include "u_ether.h"
#include "u_ether.h"
@@ -940,6 +941,8 @@ int gether_get_host_addr_cdc(struct net_device *net, char *host_addr, int len)
	dev = netdev_priv(net);
	dev = netdev_priv(net);
	snprintf(host_addr, len, "%pm", dev->host_mac);
	snprintf(host_addr, len, "%pm", dev->host_mac);


	string_upper(host_addr, host_addr);

	return strlen(host_addr);
	return strlen(host_addr);
}
}
EXPORT_SYMBOL_GPL(gether_get_host_addr_cdc);
EXPORT_SYMBOL_GPL(gether_get_host_addr_cdc);