[LEDE-DEV] generic: add support for ZTE MF667[rndis] 19d2:1403

Bjørn Mork bjorn at mork.no
Wed May 10 08:54:33 PDT 2017


Ермошкин А.Ю. <alexey.ermoshkin at gmail.com> writes:

> This patch adds support for the ZTE usb modem MF667 in rndis/network card mode.
>
> generic/099-usb-cdc_ether-zte-update.patch
> generic/774-net-usb-cdc_ether-quirks-for-zte-mf667.patch

Any reason why the first patch isn't simply a backport of mainline
commit bfe9b9d2df66 ("cdc_ether: Improve ZTE MF823/831/910 handling")?
 
 
> If debug enabled, kernel printk:
> rndis_host 1-1:1.0: ACM capabilities 02, not really RNDIS?
>
> --
> With regards,
> Alexey
>  mailto:alexey.ermoshkin at gmail.com
>
> --- a/drivers/net/usb/cdc_ether.c
> +++ b/drivers/net/usb/cdc_ether.c
> @@ -17,8 +17,8 @@
>   * along with this program; if not, see <http://www.gnu.org/licenses/>.
>   */
>  
> -// #define	DEBUG			// error path messages, extra info
> -// #define	VERBOSE			// more; success messages
> +#define	DEBUG			// error path messages, extra info
> +#define	VERBOSE			// more; success messages
>  
>  #include <linux/module.h>
>  #include <linux/netdevice.h>

Unrelated debugging.


> @@ -432,6 +432,64 @@ int usbnet_cdc_bind(struct usbnet *dev,
>  }
>  EXPORT_SYMBOL_GPL(usbnet_cdc_bind);
>  
> +static int usbnet_cdc_zte_bind(struct usbnet *dev, struct usb_interface *intf)
> +{
> +	int status = usbnet_cdc_bind(dev, intf);
> +
> +	if (!status && (dev->net->dev_addr[0] & 0x02))
> +		eth_hw_addr_random(dev->net);
> +
> +	return status;
> +}
> +
> +/* Make sure packets have correct destination MAC address
> + *
> + * A firmware bug observed on some devices (ZTE MF823/831/910) is that the
> + * device sends packets with a static, bogus, random MAC address (event if
> + * device MAC address has been updated). Always set MAC address to that of the
> + * device.
> + */
> +static int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
> +{
> +	if (skb->len < ETH_HLEN || !(skb->data[0] & 0x02))
> +		return 1;
> +
> +	skb_reset_mac_header(skb);
> +	ether_addr_copy(eth_hdr(skb)->h_dest, dev->net->dev_addr);
> +
> +	return 1;
> +}
> +
> +/* Ensure correct link state
> + *
> + * Some devices (ZTE MF823/831/910) export two carrier on notifications when
> + * connected. This causes the link state to be incorrect. Work around this by
> + * always setting the state to off, then on.
> + */
> +static void usbnet_cdc_zte_status(struct usbnet *dev, struct urb *urb)
> +{
> +	struct usb_cdc_notification *event;
> +
> +	if (urb->actual_length < sizeof(*event))
> +		return;
> +
> +	event = urb->transfer_buffer;
> +
> +	if (event->bNotificationType != USB_CDC_NOTIFY_NETWORK_CONNECTION) {
> +		usbnet_cdc_status(dev, urb);
> +		return;
> +	}
> +
> +	netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
> +		  event->wValue ? "on" : "off");
> +
> +	if (event->wValue &&
> +	    netif_carrier_ok(dev->net))
> +		netif_carrier_off(dev->net);
> +
> +	usbnet_link_change(dev, !!event->wValue, 0);
> +}
> +
>  static const struct driver_info	cdc_info = {
>  	.description =	"CDC Ethernet Device",
>  	.flags =	FLAG_ETHER | FLAG_POINTTOPOINT,
> @@ -442,6 +500,17 @@ static const struct driver_info	cdc_info
>  	.manage_power =	usbnet_manage_power,
>  };
>  
> +static const struct driver_info	zte_cdc_info = {
> +	.description =	"ZTE CDC Ethernet Device",
> +	.flags =	FLAG_ETHER | FLAG_POINTTOPOINT,
> +	.bind =		usbnet_cdc_zte_bind,
> +	.unbind =	usbnet_cdc_unbind,
> +	.status =	usbnet_cdc_zte_status,
> +	.set_rx_mode =	usbnet_cdc_update_filter,
> +	.manage_power =	usbnet_manage_power,
> +	.rx_fixup = usbnet_cdc_zte_rx_fixup,
> +};
> +
>  static const struct driver_info wwan_info = {
>  	.description =	"Mobile Broadband Network Device",
>  	.flags =	FLAG_WWAN,
> @@ -463,6 +532,7 @@ static const struct driver_info wwan_inf
>  #define LENOVO_VENDOR_ID	0x17ef
>  #define NVIDIA_VENDOR_ID	0x0955
>  #define HP_VENDOR_ID		0x03f0
> +#define MICROSOFT_VENDOR_ID	0x045e
>  
>  static const struct usb_device_id	products[] = {
>  /* BLACKLIST !!
> @@ -650,6 +720,20 @@ static const struct usb_device_id	produc
>  	.driver_info = 0,
>  },
>  
> +/* ThinkPad USB-C Dock (based on Realtek RTL8153) */
> +{
> +	USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3062, USB_CLASS_COMM,
> +			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
> +	.driver_info = 0,
> +},
> +
> +/* ThinkPad Thunderbolt 3 Dock (based on Realtek RTL8153) */
> +{
> +	USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x3069, USB_CLASS_COMM,
> +			USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
> +	.driver_info = 0,
> +},
> +
>  /* Lenovo Thinkpad USB 3.0 Ethernet Adapters (based on Realtek RTL8153) */
>  {
>  	USB_DEVICE_AND_INTERFACE_INFO(LENOVO_VENDOR_ID, 0x7205, USB_CLASS_COMM,


These and the following blacklist entries are also unrelated to the
subject.  They should go into a separate patch if they are wanted.  But
I suspect they are unwanted as they need a matching r8152 patch to be
meaningful.



> --- a/drivers/net/usb/cdc_ether.c
> +++ b/drivers/net/usb/cdc_ether.c
> @@ -218,7 +218,6 @@ skip:
>  			dev_dbg(&intf->dev,
>  				"ACM capabilities %02x, not really RNDIS?\n",
>  				header.usb_cdc_acm_descriptor->bmCapabilities);
> -			goto bad_desc;
>  	}
>  
>  	if (header.usb_cdc_ether_desc) {

This doesn't look right.  The descriptor test is either pointless and
can be removed, or it has value and need to be enabled.  I assume it was
added for a reason.  RNDIS does not have ACM capabilities.

I believe this should be implemented as a device specific quirk and go
to mainline.  It's not specific to OpenWrt/LEDE in any way



Bjørn






More information about the Lede-dev mailing list