[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