forked from rrcarlosr/Jetpack
eg25-g: Add Quectel EG25-G Driver patches to Kernel
This commit is contained in:
parent
e7952b2f70
commit
10e21073d5
|
@ -175,6 +175,27 @@ static const u8 buggy_fw_addr[ETH_ALEN] = {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00};
|
|||
* to 00:a0:c6:00:00:00 despite the host address being different.
|
||||
* This function will also fixup such packets.
|
||||
*/
|
||||
|
||||
#if 1 /* Added by Quectel */
|
||||
#include <linux/etherdevice.h>
|
||||
struct sk_buff *qmi_wwan_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
|
||||
{
|
||||
if (dev->udev->descriptor.idVendor != cpu_to_le16(0x2C7C))
|
||||
return skb;
|
||||
|
||||
/* Skip Ethernet header from message */
|
||||
if (skb_pull(skb, ETH_HLEN)) {
|
||||
return skb;
|
||||
} else {
|
||||
dev_err(&dev->intf->dev, "Packet Dropped ");
|
||||
}
|
||||
|
||||
/* Filter the packet out, release it */
|
||||
dev_kfree_skb_any(skb);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int qmi_wwan_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
|
||||
{
|
||||
struct qmi_wwan_state *info = (void *)&dev->data;
|
||||
|
@ -445,6 +466,21 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf)
|
|||
}
|
||||
dev->net->netdev_ops = &qmi_wwan_netdev_ops;
|
||||
dev->net->sysfs_groups[0] = &qmi_wwan_sysfs_attr_group;
|
||||
#if 1 /* Added by Quectel */
|
||||
if (dev->udev->descriptor.idVendor == cpu_to_le16(0x2C7C)) {
|
||||
dev_info(&intf->dev, "Quectel EC21&EC25&EC20 R2.0 work on RawIP mode\n");
|
||||
dev->net->flags |= IFF_NOARP;
|
||||
|
||||
usb_control_msg(
|
||||
interface_to_usbdev(intf),
|
||||
usb_sndctrlpipe(interface_to_usbdev(intf), 0),
|
||||
0x22, /* USB_CDC_REQ_SET_CONTROL_LINE_STATE */
|
||||
0x21, /* USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE */
|
||||
1, /* active CDC DTR */
|
||||
intf->cur_altsetting->desc.bInterfaceNumber,
|
||||
NULL, 0, 100);
|
||||
}
|
||||
#endif
|
||||
err:
|
||||
return status;
|
||||
}
|
||||
|
@ -536,6 +572,11 @@ static const struct driver_info qmi_wwan_info = {
|
|||
.unbind = qmi_wwan_unbind,
|
||||
.manage_power = qmi_wwan_manage_power,
|
||||
.rx_fixup = qmi_wwan_rx_fixup,
|
||||
#if 1
|
||||
/* Added by Quectel */
|
||||
.tx_fixup = qmi_wwan_tx_fixup,
|
||||
/* */
|
||||
#endif
|
||||
};
|
||||
|
||||
static const struct driver_info qmi_wwan_info_quirk_dtr = {
|
||||
|
@ -1014,7 +1055,24 @@ static const struct usb_device_id products[] = {
|
|||
{QMI_GOBI_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */
|
||||
{QMI_GOBI_DEVICE(0x12d1, 0x14f1)}, /* Sony Gobi 3000 Composite */
|
||||
{QMI_GOBI_DEVICE(0x1410, 0xa021)}, /* Foxconn Gobi 3000 Modem device (Novatel E396) */
|
||||
|
||||
#if 1
|
||||
/* Added by Quectel */
|
||||
#ifndef QMI_FIXED_INTF
|
||||
/* map QMI/wwan function by a fixed interface number */
|
||||
#define QMI_FIXED_INTF(vend, prod, num) \
|
||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, \
|
||||
.idVendor = vend, \
|
||||
.idProduct = prod, \
|
||||
.bInterfaceClass = 0xff, \
|
||||
.bInterfaceSubClass = 0xff, \
|
||||
.bInterfaceProtocol = 0xff, \
|
||||
.driver_info= (unsigned long)&qmi_wwan_force_int##num,
|
||||
#endif
|
||||
{ QMI_FIXED_INTF(0x05C6, 0x9003, 4) }, /* Quectel UC20 */
|
||||
{ QMI_FIXED_INTF(0x05C6, 0x9215, 4) }, /* Quectel EC20 */
|
||||
{ QMI_FIXED_INTF(0x2C7C, 0x0125, 4) }, /* Quectel EC25/EC20 R2.0 */
|
||||
{ QMI_FIXED_INTF(0x2C7C, 0x0121, 4) }, /* Quectel EC21 */
|
||||
#endif
|
||||
{ } /* END */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, products);
|
||||
|
|
|
@ -1942,6 +1942,13 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_6802, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(WETELECOM_VENDOR_ID, WETELECOM_PRODUCT_WMD300, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x421d, 0xff, 0xff, 0xff) }, /* HP lt2523 (Novatel E371) */
|
||||
#if 1
|
||||
{ USB_DEVICE(0x05C6, 0x9090) }, /* Quectel UC15 */
|
||||
{ USB_DEVICE(0x05C6, 0x9003) }, /* Quectel UC20 */
|
||||
{ USB_DEVICE(0x05C6, 0x9215) }, /* Quectel EC20 */
|
||||
{ USB_DEVICE(0x2C7C, 0x0125) }, /* Quectel EC25/EC20 R2.0 */
|
||||
{ USB_DEVICE(0x2C7C, 0x0121) }, /* Quectel EC21 */
|
||||
#endif
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, option_ids);
|
||||
|
@ -1976,7 +1983,9 @@ static struct usb_serial_driver option_1port_device = {
|
|||
#ifdef CONFIG_PM
|
||||
.suspend = usb_wwan_suspend,
|
||||
.resume = usb_wwan_resume,
|
||||
.reset_resume = usb_wwan_resume,
|
||||
#if 1 //Added by Quectel
|
||||
.reset_resume = usb_wwan_resume,
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -2014,9 +2023,12 @@ static int option_probe(struct usb_serial *serial,
|
|||
iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
|
||||
return -ENODEV;
|
||||
|
||||
if (serial->dev->descriptor.idVendor == cpu_to_le16(QUECTEL_VENDOR_ID) && serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
|
||||
return -ENODEV;
|
||||
|
||||
#if 1 //Added by Quectel
|
||||
//Quectel EC21&EC25&EC20 R2.0's interface 4 can be used as USB Network device
|
||||
if (serial->dev->descriptor.idVendor == cpu_to_le16(0x2C7C) &&
|
||||
serial->interface->cur_altsetting->desc.bInterfaceNumber >= 4)
|
||||
return -ENODEV;
|
||||
#endif
|
||||
/* Store the device flags so we can use them during attach. */
|
||||
usb_set_serial_data(serial, (void *)device_flags);
|
||||
|
||||
|
|
|
@ -505,12 +505,19 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
|
|||
usb_fill_bulk_urb(urb, serial->dev,
|
||||
usb_sndbulkpipe(serial->dev, endpoint) | dir,
|
||||
buf, len, callback, ctx);
|
||||
|
||||
if (dir == USB_DIR_OUT) {
|
||||
struct usb_device_descriptor *desc = &serial->dev->descriptor;
|
||||
if (desc->idVendor == cpu_to_le16(QUECTEL_VENDOR_ID))
|
||||
urb->transfer_flags |= URB_ZERO_PACKET;
|
||||
}
|
||||
#if 1 //Added by Quectel for Zero Packet
|
||||
if (dir == USB_DIR_OUT) {
|
||||
struct usb_device_descriptor *desc = &serial->dev->descriptor;
|
||||
if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9090))
|
||||
urb->transfer_flags |= URB_ZERO_PACKET;
|
||||
if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9003))
|
||||
urb->transfer_flags |= URB_ZERO_PACKET;
|
||||
if (desc->idVendor == cpu_to_le16(0x05C6) && desc->idProduct == cpu_to_le16(0x9215))
|
||||
urb->transfer_flags |= URB_ZERO_PACKET;
|
||||
if (desc->idVendor == cpu_to_le16(QUECTEL_VENDOR_ID))
|
||||
urb->transfer_flags |= URB_ZERO_PACKET;
|
||||
}
|
||||
#endif
|
||||
|
||||
return urb;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue