ath10k-ct: fix build with arm/mips

This commit is contained in:
coolsnowwolf 2024-10-30 15:54:28 +08:00
parent e40fe43e49
commit 3f0ed51973
25 changed files with 15 additions and 14020 deletions

View File

@ -29,7 +29,7 @@ include $(INCLUDE_DIR)/package.mk
define KernelPackage/ath10k-ct
SUBMENU:=Wireless Drivers
TITLE:=ath10k-ct driver optimized for CT ath10k firmware
DEPENDS:=+kmod-mac80211 +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT @PCI_SUPPORT +kmod-hwmon-core
DEPENDS:=@(arm||aarch64||mips||mipsel) +kmod-mac80211 +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT @PCI_SUPPORT +kmod-hwmon-core
FILES:=\
$(PKG_BUILD_DIR)/ath10k$(CT_KVER)/ath10k_pci.ko \
$(PKG_BUILD_DIR)/ath10k$(CT_KVER)/ath10k_core.ko

View File

@ -111,3 +111,17 @@
u8 rate_idx;
u8 nss;
u8 rx_flags;
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -5750,7 +5750,11 @@
if (err)
goto out_exit_netlink;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0))
+ hwsim_class = class_create("mac80211_hwsim");
+#else
hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
+#endif
if (IS_ERR(hwsim_class)) {
err = PTR_ERR(hwsim_class);
goto out_exit_virtio;

View File

@ -1,32 +0,0 @@
#
# Copyright (C) Chen Yijun
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=xr-usb-serial
PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk
define KernelPackage/$(PKG_NAME)
SUBMENU:=USB Support
DEPENDS:=@GPIO_SUPPORT +kmod-usb-serial +kmod-usb2
TITLE:=Driver for XR21V141x (used in HUAWEI UPS)
AUTOLOAD:=$(call AutoLoad,30,xr_usb_serial_common,1)
FILES:=$(PKG_BUILD_DIR)/xr_usb_serial_common.ko
endef
define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
$(KERNEL_MAKE_FLAGS) \
M="$(PKG_BUILD_DIR)" \
EXTRA_CFLAGS="$(BUILDFLAGS)" \
modules
endef
$(eval $(call KernelPackage,$(PKG_NAME)))

View File

@ -1,10 +0,0 @@
#
# Copyright (C) Chen Yijun
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
obj-m := xr_usb_serial_common.o
EXTRA_CFLAGS := -DDEBUG=0

File diff suppressed because it is too large Load Diff

View File

@ -1,197 +0,0 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
* CMSPAR, some architectures can't have space and mark parity.
*/
#ifndef CMSPAR
#define CMSPAR 0
#endif
/*
* Major and minor numbers.
*/
#define XR_USB_SERIAL_TTY_MAJOR 266
#define XR_USB_SERIAL_TTY_MINORS 32
/*
* Requests.
*/
#define USB_RT_XR_USB_SERIAL (USB_TYPE_CLASS | USB_RECIP_INTERFACE)
/*
* Output control lines.
*/
#define XR_USB_SERIAL_CTRL_DTR 0x01
#define XR_USB_SERIAL_CTRL_RTS 0x02
/*
* Input control lines and line errors.
*/
#define XR_USB_SERIAL_CTRL_DCD 0x01
#define XR_USB_SERIAL_CTRL_DSR 0x02
#define XR_USB_SERIAL_CTRL_BRK 0x04
#define XR_USB_SERIAL_CTRL_RI 0x08
#define XR_USB_SERIAL_CTRL_FRAMING 0x10
#define XR_USB_SERIAL_CTRL_PARITY 0x20
#define XR_USB_SERIAL_CTRL_OVERRUN 0x40
/*
* Internal driver structures.
*/
/*
* The only reason to have several buffers is to accommodate assumptions
* in line disciplines. They ask for empty space amount, receive our URB size,
* and proceed to issue several 1-character writes, assuming they will fit.
* The very first write takes a complete URB. Fortunately, this only happens
* when processing onlcr, so we only need 2 buffers. These values must be
* powers of 2.
*/
#define XR_USB_SERIAL_NW 16
#define XR_USB_SERIAL_NR 16
#define RAMCTL_BUFFER_PARITY 0x1
#define RAMCTL_BUFFER_BREAK 0x2
#define RAMCTL_BUFFER_FRAME 0x4
#define RAMCTL_BUFFER_OVERRUN 0x8
struct xr_usb_serial_wb {
unsigned char *buf;
dma_addr_t dmah;
int len;
int use;
struct urb *urb;
struct xr_usb_serial *instance;
};
struct xr_usb_serial_rb {
int size;
unsigned char *base;
dma_addr_t dma;
int index;
struct xr_usb_serial *instance;
};
struct reg_addr_map {
unsigned int uart_enable_addr;
unsigned int uart_format_addr;
unsigned int uart_flow_addr;
unsigned int uart_loopback_addr;
unsigned int uart_xon_char_addr;
unsigned int uart_xoff_char_addr;
unsigned int uart_gpio_mode_addr;
unsigned int uart_gpio_dir_addr;
unsigned int uart_gpio_set_addr;
unsigned int uart_gpio_clr_addr;
unsigned int uart_gpio_status_addr;
unsigned int tx_break_addr;
unsigned int uart_custom_driver;
unsigned int uart_low_latency;
};
struct xr_usb_serial {
struct usb_device *dev; /* the corresponding usb device */
struct usb_interface *control; /* control interface */
struct usb_interface *data; /* data interface */
struct tty_port port; /* our tty port data */
struct urb *ctrlurb; /* urbs */
u8 *ctrl_buffer; /* buffers of urbs */
dma_addr_t ctrl_dma; /* dma handles of buffers */
u8 *country_codes; /* country codes from device */
unsigned int country_code_size; /* size of this buffer */
unsigned int country_rel_date; /* release date of version */
struct xr_usb_serial_wb wb[XR_USB_SERIAL_NW];
unsigned long read_urbs_free;
struct urb *read_urbs[XR_USB_SERIAL_NR];
struct xr_usb_serial_rb read_buffers[XR_USB_SERIAL_NR];
int rx_buflimit;
int rx_endpoint;
spinlock_t read_lock;
int write_used; /* number of non-empty write buffers */
int transmitting;
spinlock_t write_lock;
struct mutex mutex;
bool disconnected;
struct usb_cdc_line_coding line; /* bits, stop, parity */
struct work_struct work; /* work queue entry for line discipline waking up */
unsigned int ctrlin; /* input control lines (DCD, DSR, RI, break, overruns) */
unsigned int ctrlout; /* output control lines (DTR, RTS) */
unsigned int writesize; /* max packet size for the output bulk endpoint */
unsigned int readsize,ctrlsize; /* buffer sizes for freeing */
unsigned int minor; /* xr_usb_serial minor number */
unsigned char clocal; /* termios CLOCAL */
unsigned int ctrl_caps; /* control capabilities from the class specific header */
unsigned int susp_count; /* number of suspended interfaces */
unsigned int combined_interfaces:1; /* control and data collapsed */
unsigned int is_int_ep:1; /* interrupt endpoints contrary to spec used */
unsigned int throttled:1; /* actually throttled */
unsigned int throttle_req:1; /* throttle requested */
u8 bInterval;
struct xr_usb_serial_wb *delayed_wb; /* write queued for a device about to be woken */
unsigned int channel;
int preciseflags; /* USB: wide mode, TTY: flags per character */
int trans9; /* USB: wide mode, serial 9N1 */
int have_extra_byte;
int extra_byte;
unsigned short DeviceVendor;
unsigned short DeviceProduct;
struct reg_addr_map reg_map;
#ifdef CONFIG_GPIOLIB
struct gpio_chip xr_gpio;
int rv_gpio_created;
#endif
};
#define CDC_DATA_INTERFACE_TYPE 0x0a
/* constants describing various quirks and errors */
#define NO_UNION_NORMAL 1
#define SINGLE_RX_URB 2
#define NO_CAP_LINE 4
#define NOT_A_MODEM 8
#define NO_DATA_INTERFACE 16
#define IGNORE_DEVICE 32
#define UART_ENABLE_TX 1
#define UART_ENABLE_RX 2
#define UART_GPIO_CLR_DTR 0x8
#define UART_GPIO_SET_DTR 0x8
#define UART_GPIO_CLR_RTS 0x20
#define UART_GPIO_SET_RTS 0x20
#define LOOPBACK_ENABLE_TX_RX 1
#define LOOPBACK_ENABLE_RTS_CTS 2
#define LOOPBACK_ENABLE_DTR_DSR 4
#define UART_FLOW_MODE_NONE 0x0
#define UART_FLOW_MODE_HW 0x1
#define UART_FLOW_MODE_SW 0x2
#define UART_GPIO_MODE_SEL_GPIO 0x0
#define UART_GPIO_MODE_SEL_RTS_CTS 0x1
#define XR2280x_FUNC_MGR_OFFSET 0x40

View File

@ -1,821 +0,0 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define XR_SET_MAP_XR2280X 5
#define XR_GET_MAP_XR2280X 5
#define XR_SET_MAP_XR21B142X 0
#define XR_GET_MAP_XR21B142X 0
#define XR_SET_MAP_XR21V141X 0
#define XR_GET_MAP_XR21V141X 1
#define XR_SET_MAP_XR21B1411 0
#define XR_GET_MAP_XR21B1411 1
int xr_usb_serial_set_reg(struct xr_usb_serial *xr_usb_serial,int regnum, int value)
{
int result;
int channel = 0;
//dev_info(&xr_usb_serial->control->dev, "%s Channel:%d 0x%02x = 0x%02x\n", __func__,channel,regnum, value);
if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1400)
{
int XR2280xaddr = XR2280x_FUNC_MGR_OFFSET + regnum;
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_SET_MAP_XR2280X, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR, /* request_type */
value, /* request value */
XR2280xaddr, /* index */
NULL, /* data */
0, /* size */
5000); /* timeout */
}
else if((xr_usb_serial->DeviceProduct == 0x1410) ||
(xr_usb_serial->DeviceProduct == 0x1412) ||
(xr_usb_serial->DeviceProduct == 0x1414))
{
if(xr_usb_serial->channel)
channel = xr_usb_serial->channel - 1;
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_SET_MAP_XR21V141X, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR, /* request_type */
value, /* request value */
regnum | (channel << 8), /* index */
NULL, /* data */
0, /* size */
5000); /* timeout */
}
else if(xr_usb_serial->DeviceProduct == 0x1411)
{
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_SET_MAP_XR21B1411, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR, /* request_type */
value, /* request value */
regnum , /* index */
NULL, /* data */
0, /* size */
5000); /* timeout */
}
else if((xr_usb_serial->DeviceProduct == 0x1420)||
(xr_usb_serial->DeviceProduct == 0x1422)||
(xr_usb_serial->DeviceProduct == 0x1424))
{
channel = (xr_usb_serial->channel - 4)*2;
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_SET_MAP_XR21B142X, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR | 1, /* request_type */
value, /* request value */
regnum | (channel << 8), /* index */
NULL, /* data */
0, /* size */
5000); /* timeout */
}
else
{
result = -1;
}
if(result < 0)
dev_err(&xr_usb_serial->control->dev, "%s Error:%d\n", __func__,result);
return result;
}
int xr_usb_serial_set_reg_ext(struct xr_usb_serial *xr_usb_serial,int channel,int regnum, int value)
{
int result;
int XR2280xaddr = XR2280x_FUNC_MGR_OFFSET + regnum;
//dev_info(&xr_usb_serial->control->dev, "%s channel:%d 0x%02x = 0x%02x\n", __func__,channel,regnum, value);
if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1400)
{
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_SET_MAP_XR2280X, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR, /* request_type */
value, /* request value */
XR2280xaddr, /* index */
NULL, /* data */
0, /* size */
5000); /* timeout */
}
else if((xr_usb_serial->DeviceProduct == 0x1410) ||
(xr_usb_serial->DeviceProduct == 0x1412) ||
(xr_usb_serial->DeviceProduct == 0x1414))
{
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_SET_MAP_XR21V141X, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR, /* request_type */
value, /* request value */
regnum | (channel << 8), /* index */
NULL, /* data */
0, /* size */
5000); /* timeout */
}
else if(xr_usb_serial->DeviceProduct == 0x1411)
{
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_SET_MAP_XR21B1411, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR , /* request_type */
value, /* request value */
regnum , /* index */
NULL, /* data */
0, /* size */
5000); /* timeout */
}
else if((xr_usb_serial->DeviceProduct == 0x1420)||
(xr_usb_serial->DeviceProduct == 0x1422)||
(xr_usb_serial->DeviceProduct == 0x1424))
{
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_sndctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_SET_MAP_XR21B142X, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR | 1, /* request_type */
value, /* request value */
regnum | (channel << 8), /* index */
NULL, /* data */
0, /* size */
5000); /* timeout */
}
else
{
result = -1;
}
if(result < 0)
dev_err(&xr_usb_serial->control->dev, "%s Error:%d\n", __func__,result);
return result;
}
int xr_usb_serial_get_reg(struct xr_usb_serial *xr_usb_serial,int regnum, short *value)
{
int result;
int channel = 0;
short *dmadata;
/* Use dynamic memory instead of statically allocated buffer
This is to avoid Error -11 (EAGAIN) for Kernel no longer accept static allocated buffer after 4.9 */
dmadata = kmalloc(2, GFP_KERNEL);
if (!dmadata)
{
dev_err(&xr_usb_serial->control->dev, "[func:%s,line:%d] error no memory allocated!! \n", __func__,__LINE__);
return -ENOMEM;
}
if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1400)
{
int XR2280xaddr = XR2280x_FUNC_MGR_OFFSET + regnum;
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_GET_MAP_XR2280X, /* request */
USB_DIR_IN | USB_TYPE_VENDOR , /* request_type */
0, /* request value */
XR2280xaddr, /* index */
dmadata, /* data */
2, /* size */
5000); /* timeout */
memcpy(value, dmadata, 2);
}
else if((xr_usb_serial->DeviceProduct == 0x1410) ||
(xr_usb_serial->DeviceProduct == 0x1412) ||
(xr_usb_serial->DeviceProduct == 0x1414))
{
if(xr_usb_serial->channel)
channel = xr_usb_serial->channel -1;
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_GET_MAP_XR21V141X, /* request */
USB_DIR_IN | USB_TYPE_VENDOR, /* request_type */
0, /* request value */
regnum | (channel << 8), /* index */
dmadata, /* data */
1, /* size */
5000); /* timeout */
memcpy(value, dmadata, 1);
}
else if(xr_usb_serial->DeviceProduct == 0x1411)
{
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_GET_MAP_XR21B1411, /* request */
USB_DIR_IN | USB_TYPE_VENDOR, /* request_type */
0, /* request value */
regnum, /* index */
dmadata, /* data */
2, /* size */
5000); /* timeout */
memcpy(value, dmadata, 2);
}
else if((xr_usb_serial->DeviceProduct == 0x1420)||
(xr_usb_serial->DeviceProduct == 0x1422)||
(xr_usb_serial->DeviceProduct == 0x1424))
{
channel = (xr_usb_serial->channel -4)*2;
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_GET_MAP_XR21B142X, /* request */
USB_DIR_IN | USB_TYPE_VENDOR | 1, /* request_type */
0, /* request value */
regnum | (channel << 8), /* index */
dmadata, /* data */
2, /* size */
5000); /* timeout */
memcpy(value, dmadata, 2);
}
else
{
result = -1;
}
if(result < 0)
dev_err(&xr_usb_serial->control->dev, "%s channel:%d Reg 0x%x Error:%d\n", __func__,channel,regnum,result);
//else
//dev_info(&xr_usb_serial->control->dev, "%s channel:%d 0x%x = 0x%04x\n", __func__,channel,regnum, *value);
kfree(dmadata);
return result;
}
int xr_usb_serial_get_reg_ext(struct xr_usb_serial *xr_usb_serial,int channel,int regnum, short *value)
{
int result;
int XR2280xaddr = XR2280x_FUNC_MGR_OFFSET + regnum;
short *dmadata;
/* Use dynamic memory instead of statically allocated buffer
This is to avoid Error -11 (EAGAIN) for Kernel no longer accept static allocated buffer after 4.9 */
dmadata = kmalloc(2, GFP_KERNEL);
if (!dmadata)
{
dev_err(&xr_usb_serial->control->dev, "[func:%s,line:%d] error no memory allocated!! \n", __func__,__LINE__);
return -ENOMEM;
}
if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1400)
{
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_GET_MAP_XR2280X, /* request */
USB_DIR_IN | USB_TYPE_VENDOR , /* request_type */
0, /* request value */
XR2280xaddr, /* index */
dmadata, /* data */
2, /* size */
5000); /* timeout */
memcpy(value, dmadata, 2);
}
else if((xr_usb_serial->DeviceProduct == 0x1410) ||
(xr_usb_serial->DeviceProduct == 0x1412) ||
(xr_usb_serial->DeviceProduct == 0x1414))
{
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_GET_MAP_XR21V141X, /* request */
USB_DIR_IN | USB_TYPE_VENDOR, /* request_type */
0, /* request value */
regnum | (channel << 8), /* index */
dmadata, /* data */
1, /* size */
5000); /* timeout */
memcpy(value, dmadata, 1);
}
else if(xr_usb_serial->DeviceProduct == 0x1411)
{
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_GET_MAP_XR21B1411, /* request */
USB_DIR_IN | USB_TYPE_VENDOR , /* request_type */
0, /* request value */
regnum | (channel << 8), /* index */
dmadata, /* data */
2, /* size */
5000); /* timeout */
memcpy(value, dmadata, 2);
}
else if((xr_usb_serial->DeviceProduct == 0x1420)||
(xr_usb_serial->DeviceProduct == 0x1422)||
(xr_usb_serial->DeviceProduct == 0x1424))
{
result = usb_control_msg(xr_usb_serial->dev, /* usb device */
usb_rcvctrlpipe(xr_usb_serial->dev, 0), /* endpoint pipe */
XR_GET_MAP_XR21B142X, /* request */
USB_DIR_IN | USB_TYPE_VENDOR | 1, /* request_type */
0, /* request value */
regnum | (channel << 8), /* index */
dmadata, /* data */
2, /* size */
5000); /* timeout */
memcpy(value, dmadata, 2);
}
else
{
result = -1;
}
if(result < 0)
dev_err(&xr_usb_serial->control->dev, "%s Error:%d\n", __func__,result);
//else
//dev_info(&xr_usb_serial->control->dev, "%s channel:%d 0x%x = 0x%04x\n", __func__,channel,regnum, *value);
kfree(dmadata);
return result;
}
struct xr21v141x_baud_rate
{
unsigned int tx;
unsigned int rx0;
unsigned int rx1;
};
static struct xr21v141x_baud_rate xr21v141x_baud_rates[] = {
{ 0x000, 0x000, 0x000 },
{ 0x000, 0x000, 0x000 },
{ 0x100, 0x000, 0x100 },
{ 0x020, 0x400, 0x020 },
{ 0x010, 0x100, 0x010 },
{ 0x208, 0x040, 0x208 },
{ 0x104, 0x820, 0x108 },
{ 0x844, 0x210, 0x884 },
{ 0x444, 0x110, 0x444 },
{ 0x122, 0x888, 0x224 },
{ 0x912, 0x448, 0x924 },
{ 0x492, 0x248, 0x492 },
{ 0x252, 0x928, 0x292 },
{ 0X94A, 0X4A4, 0XA52 },
{ 0X52A, 0XAA4, 0X54A },
{ 0XAAA, 0x954, 0X4AA },
{ 0XAAA, 0x554, 0XAAA },
{ 0x555, 0XAD4, 0X5AA },
{ 0XB55, 0XAB4, 0X55A },
{ 0X6B5, 0X5AC, 0XB56 },
{ 0X5B5, 0XD6C, 0X6D6 },
{ 0XB6D, 0XB6A, 0XDB6 },
{ 0X76D, 0X6DA, 0XBB6 },
{ 0XEDD, 0XDDA, 0X76E },
{ 0XDDD, 0XBBA, 0XEEE },
{ 0X7BB, 0XF7A, 0XDDE },
{ 0XF7B, 0XEF6, 0X7DE },
{ 0XDF7, 0XBF6, 0XF7E },
{ 0X7F7, 0XFEE, 0XEFE },
{ 0XFDF, 0XFBE, 0X7FE },
{ 0XF7F, 0XEFE, 0XFFE },
{ 0XFFF, 0XFFE, 0XFFD },
};
#define UART_CLOCK_DIVISOR_0 0x004
#define UART_CLOCK_DIVISOR_1 0x005
#define UART_CLOCK_DIVISOR_2 0x006
#define UART_TX_CLOCK_MASK_0 0x007
#define UART_TX_CLOCK_MASK_1 0x008
#define UART_RX_CLOCK_MASK_0 0x009
#define UART_RX_CLOCK_MASK_1 0x00a
static int xr21v141x_set_baud_rate(struct xr_usb_serial *xr_usb_serial, unsigned int rate)
{
unsigned int divisor = 48000000 / rate;
unsigned int i = ((32 * 48000000) / rate) & 0x1f;
unsigned int tx_mask = xr21v141x_baud_rates[i].tx;
unsigned int rx_mask = (divisor & 1) ? xr21v141x_baud_rates[i].rx1 : xr21v141x_baud_rates[i].rx0;
//dev_info(&xr_usb_serial->control->dev, "Setting baud rate to %d: i=%u div=%u tx=%03x rx=%03x\n", rate, i, divisor, tx_mask, rx_mask);
xr_usb_serial_set_reg(xr_usb_serial,UART_CLOCK_DIVISOR_0, (divisor >> 0) & 0xff);
xr_usb_serial_set_reg(xr_usb_serial,UART_CLOCK_DIVISOR_1, (divisor >> 8) & 0xff);
xr_usb_serial_set_reg(xr_usb_serial,UART_CLOCK_DIVISOR_2, (divisor >> 16) & 0xff);
xr_usb_serial_set_reg(xr_usb_serial,UART_TX_CLOCK_MASK_0, (tx_mask >> 0) & 0xff);
xr_usb_serial_set_reg(xr_usb_serial,UART_TX_CLOCK_MASK_1, (tx_mask >> 8) & 0xff);
xr_usb_serial_set_reg(xr_usb_serial,UART_RX_CLOCK_MASK_0, (rx_mask >> 0) & 0xff);
xr_usb_serial_set_reg(xr_usb_serial,UART_RX_CLOCK_MASK_1, (rx_mask >> 8) & 0xff);
return 0;
}
/* devices aren't required to support these requests.
* the cdc xr_usb_serial descriptor tells whether they do...
*/
int xr_usb_serial_set_control(struct xr_usb_serial *xr_usb_serial, unsigned int control)
{
int ret = 0;
if((xr_usb_serial->DeviceProduct == 0x1410) ||
(xr_usb_serial->DeviceProduct == 0x1412) ||
(xr_usb_serial->DeviceProduct == 0x1414))
{
if (control & XR_USB_SERIAL_CTRL_DTR)
xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_gpio_clr_addr, 0x08);
else
xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_gpio_set_addr, 0x08);
if (control & XR_USB_SERIAL_CTRL_RTS)
xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_gpio_clr_addr, 0x20);
else
xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_gpio_set_addr, 0x20);
}
else
{
ret = xr_usb_serial_ctrl_msg(xr_usb_serial, USB_CDC_REQ_SET_CONTROL_LINE_STATE, control, NULL, 0);
}
return ret;
}
int xr_usb_serial_set_line(struct xr_usb_serial *xr_usb_serial, struct usb_cdc_line_coding* line)
{
int ret = 0;
unsigned int format_size;
unsigned int format_parity;
unsigned int format_stop;
if((xr_usb_serial->DeviceProduct == 0x1410) ||
(xr_usb_serial->DeviceProduct == 0x1412) ||
(xr_usb_serial->DeviceProduct == 0x1414))
{
xr21v141x_set_baud_rate(xr_usb_serial,le32_to_cpu(line->dwDTERate));
format_size = line->bDataBits;
format_parity = line->bParityType;
format_stop = line->bCharFormat;
xr_usb_serial_set_reg(xr_usb_serial,
xr_usb_serial->reg_map.uart_format_addr,
(format_size << 0) | (format_parity << 4) | (format_stop << 7) );
}
else
{
ret = xr_usb_serial_ctrl_msg(xr_usb_serial, USB_CDC_REQ_SET_LINE_CODING, 0, line, sizeof *(line));
}
return ret;
}
int xr_usb_serial_set_flow_mode(struct xr_usb_serial *xr_usb_serial, struct tty_struct *tty, unsigned int cflag)
{
unsigned int flow;
unsigned int gpio_mode;
if (cflag & CRTSCTS)
{
//dev_dbg(&xr_usb_serial->control->dev, "xr_usb_serial_set_flow_mode:hardware\n");
flow = UART_FLOW_MODE_HW;
gpio_mode = UART_GPIO_MODE_SEL_RTS_CTS;
}
else if (I_IXOFF(tty) || I_IXON(tty))
{
unsigned char start_char = START_CHAR(tty);
unsigned char stop_char = STOP_CHAR(tty);
//dev_dbg(&xr_usb_serial->control->dev, "xr_usb_serial_set_flow_mode:software\n");
flow = UART_FLOW_MODE_SW;
gpio_mode = UART_GPIO_MODE_SEL_GPIO;
xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_xon_char_addr, start_char);
xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_xoff_char_addr, stop_char);
}
else
{
//dev_dbg(&xr_usb_serial->control->dev, "xr_usb_serial_set_flow_mode:none\n");
flow = UART_FLOW_MODE_NONE;
gpio_mode = UART_GPIO_MODE_SEL_GPIO;
}
if((xr_usb_serial->DeviceProduct == 0x1420)||
(xr_usb_serial->DeviceProduct == 0x1422)||
(xr_usb_serial->DeviceProduct == 0x1424))
{
//Add support for the TXT and RXT function for 0x1420, 0x1422, 0x1424, by setting GPIO_MODE [9:8] = '11'
gpio_mode |= 0x300;
}
xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_flow_addr, flow);
xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_mode_addr, gpio_mode);
return 0;
}
int xr_usb_serial_send_break(struct xr_usb_serial *xr_usb_serial, int state)
{
int ret = 0;
if((xr_usb_serial->DeviceProduct == 0x1410)||
(xr_usb_serial->DeviceProduct == 0x1412)||
(xr_usb_serial->DeviceProduct == 0x1414))
{
if(state)
ret = xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.tx_break_addr,0xffff);
else
ret = xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.tx_break_addr,0);
}
else
{
ret = xr_usb_serial_ctrl_msg(xr_usb_serial, USB_CDC_REQ_SEND_BREAK, state, NULL, 0);
}
return ret;
}
#define URM_REG_BLOCK 4
#define URM_ENABLE_BASE 0x010
#define URM_ENABLE_0_TX 0x001
#define URM_ENABLE_0_RX 0x002
#define URM_RESET_RX_FIFO_BASE 0x018
#define URM_RESET_TX_FIFO_BASE 0x01C
int xr_usb_serial_enable(struct xr_usb_serial *xr_usb_serial)
{
int ret = 0;
int channel = xr_usb_serial->channel;
//dev_info(&xr_usb_serial->control->dev, "xr_usb_serial_enable channel=%d\n",channel);
if(channel)
channel--;
if((xr_usb_serial->DeviceProduct == 0x1410)||
(xr_usb_serial->DeviceProduct == 0x1412)||
(xr_usb_serial->DeviceProduct == 0x1414))
{
ret = xr_usb_serial_set_reg_ext(xr_usb_serial,URM_REG_BLOCK,URM_ENABLE_BASE + channel,URM_ENABLE_0_TX);
ret = xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_enable_addr,UART_ENABLE_TX | UART_ENABLE_RX);
ret = xr_usb_serial_set_reg_ext(xr_usb_serial,URM_REG_BLOCK,URM_ENABLE_BASE + channel,URM_ENABLE_0_TX | URM_ENABLE_0_RX);
}
else
{
ret = xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_enable_addr,UART_ENABLE_TX | UART_ENABLE_RX);
}
return ret;
}
int xr_usb_serial_fifo_reset(struct xr_usb_serial *xr_usb_serial)
{
int ret = 0;
int channel = xr_usb_serial->channel;
if(channel) channel--;
if((xr_usb_serial->DeviceProduct == 0x1410)||
(xr_usb_serial->DeviceProduct == 0x1412)||
(xr_usb_serial->DeviceProduct == 0x1414))
{
ret = xr_usb_serial_set_reg_ext(xr_usb_serial,URM_REG_BLOCK,URM_RESET_RX_FIFO_BASE + channel,0xff);
ret |= xr_usb_serial_set_reg_ext(xr_usb_serial,URM_REG_BLOCK,URM_RESET_TX_FIFO_BASE + channel,0xff);
}
return ret;
}
int xr_usb_serial_disable(struct xr_usb_serial *xr_usb_serial)
{
int ret = 0;
int channel = xr_usb_serial->channel;
//dev_info(&xr_usb_serial->control->dev, "xr_usb_serial_disable channel=%d\n",channel);
if(channel) channel--;
ret = xr_usb_serial_set_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_enable_addr,0);
if((xr_usb_serial->DeviceProduct == 0x1410)||
(xr_usb_serial->DeviceProduct == 0x1412)||
(xr_usb_serial->DeviceProduct == 0x1414))
{
ret = xr_usb_serial_set_reg_ext(xr_usb_serial,URM_REG_BLOCK,URM_ENABLE_BASE + channel,URM_ENABLE_0_TX);
}
return ret;
}
int xr_usb_serial_set_loopback(struct xr_usb_serial *xr_usb_serial, int channel)
{
int ret = 0;
xr_usb_serial_disable(xr_usb_serial);
if((xr_usb_serial->DeviceProduct == 0x1410) ||
(xr_usb_serial->DeviceProduct == 0x1412) ||
(xr_usb_serial->DeviceProduct == 0x1414))
{
switch (channel)
{
case 0:
ret = xr_usb_serial_set_reg_ext(xr_usb_serial,channel,
xr_usb_serial->reg_map.uart_loopback_addr,0x40);
break;
case 1:
ret = xr_usb_serial_set_reg_ext(xr_usb_serial,channel,
xr_usb_serial->reg_map.uart_loopback_addr,0x41);
break;
case 2:
ret = xr_usb_serial_set_reg_ext(xr_usb_serial,channel,
xr_usb_serial->reg_map.uart_loopback_addr,0x42);
break;
case 3:
ret = xr_usb_serial_set_reg_ext(xr_usb_serial,channel,
xr_usb_serial->reg_map.uart_loopback_addr,0x43);
break;
default:
break;
}
}
else if((xr_usb_serial->DeviceProduct == 0x1420)||
(xr_usb_serial->DeviceProduct == 0x1422)||
(xr_usb_serial->DeviceProduct == 0x1424))
{
ret = xr_usb_serial_set_reg_ext(xr_usb_serial,channel,
xr_usb_serial->reg_map.uart_loopback_addr,0x07);
}
xr_usb_serial_enable(xr_usb_serial);
return ret;
}
#define XR21V1414_WIDE_MODE_OFFSET 3
#define XR21B142X_WIDE_MODE_TX_OFFSET 0x42
#define XR21B142X_WIDE_MODE_RX_OFFSET 0x45
/* XR2280x_FUNC_MGR_OFFSET will be included in xr_usb_serial_set_reg */
#define XR21B140X_WIDE_MODE_TX_OFFSET 0x22
#define XR21B140X_WIDE_MODE_RX_OFFSET 0x25
int xr_usb_serial_set_wide_mode(struct xr_usb_serial *xr_usb_serial, int preciseflags)
{
int ret = 0;
int channel = xr_usb_serial->channel;
xr_usb_serial_disable(xr_usb_serial);
if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1400)
{
xr_usb_serial_set_reg(xr_usb_serial, XR21B140X_WIDE_MODE_TX_OFFSET, preciseflags);
xr_usb_serial_set_reg(xr_usb_serial, XR21B140X_WIDE_MODE_RX_OFFSET, preciseflags);
}
else if((xr_usb_serial->DeviceProduct == 0x1410)||
(xr_usb_serial->DeviceProduct == 0x1412)||
(xr_usb_serial->DeviceProduct == 0x1414))
{
if(channel) channel--;
xr_usb_serial_set_reg_ext(xr_usb_serial, 0x66, channel*8 + XR21V1414_WIDE_MODE_OFFSET, preciseflags);
}
else if(xr_usb_serial->DeviceProduct == 0x1411)
{
xr_usb_serial_set_reg(xr_usb_serial,0xd02, preciseflags);
}
else if((xr_usb_serial->DeviceProduct == 0x1420)||
(xr_usb_serial->DeviceProduct == 0x1422)||
(xr_usb_serial->DeviceProduct == 0x1424))
{
xr_usb_serial_set_reg(xr_usb_serial, XR21B142X_WIDE_MODE_TX_OFFSET, preciseflags);
xr_usb_serial_set_reg(xr_usb_serial, XR21B142X_WIDE_MODE_RX_OFFSET, preciseflags);
}
xr_usb_serial_enable(xr_usb_serial);
return ret;
}
static int xr_usb_serial_tiocmget(struct xr_usb_serial *xr_usb_serial)
{
short data;
int result;
result = xr_usb_serial_get_reg(xr_usb_serial,xr_usb_serial->reg_map.uart_gpio_status_addr, &data);
//dev_info(&xr_usb_serial->control->dev, "xr_usb_serial_tiocmget uart_gpio_status_addr:0x%04x\n",data);
if (result)
return ((data & 0x8) ? 0: TIOCM_DTR) | ((data & 0x20) ? 0:TIOCM_RTS ) | ((data & 0x4) ? 0:TIOCM_DSR) | ((data & 0x1) ? 0 : TIOCM_RI) | ((data & 0x2) ? 0:TIOCM_CD) | ((data & 0x10) ? 0 : TIOCM_CTS);
else
return -EFAULT;
}
static int xr_usb_serial_tiocmset(struct xr_usb_serial *xr_usb_serial,
unsigned int set, unsigned int clear)
{
unsigned int newctrl = 0;
newctrl = xr_usb_serial->ctrlout;
set = (set & TIOCM_DTR ? XR_USB_SERIAL_CTRL_DTR : 0) | (set & TIOCM_RTS ? XR_USB_SERIAL_CTRL_RTS : 0);
clear = (clear & TIOCM_DTR ? XR_USB_SERIAL_CTRL_DTR : 0) | (clear & TIOCM_RTS ? XR_USB_SERIAL_CTRL_RTS : 0);
newctrl = (newctrl & ~clear) | set;
if (xr_usb_serial->ctrlout == newctrl)
return 0;
xr_usb_serial->ctrlout = newctrl;
if (newctrl & XR_USB_SERIAL_CTRL_DTR)
xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_clr_addr, 0x08);
else
xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_set_addr, 0x08);
if (newctrl & XR_USB_SERIAL_CTRL_RTS)
xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_clr_addr, 0x20);
else
xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_set_addr, 0x20);
return 0;
}
static struct reg_addr_map xr21b140x_reg_map;
static struct reg_addr_map xr21b1411_reg_map;
static struct reg_addr_map xr21v141x_reg_map;
static struct reg_addr_map xr21b142x_reg_map;
static void init_xr21b140x_reg_map(void)
{
xr21b140x_reg_map.uart_enable_addr = 0x00;
xr21b140x_reg_map.uart_format_addr = 0x05;
xr21b140x_reg_map.uart_flow_addr = 0x06;
xr21b140x_reg_map.uart_loopback_addr = 0x16;
xr21b140x_reg_map.uart_xon_char_addr = 0x07;
xr21b140x_reg_map.uart_xoff_char_addr = 0x08;
xr21b140x_reg_map.uart_gpio_mode_addr = 0x0c;
xr21b140x_reg_map.uart_gpio_dir_addr = 0x0d;
xr21b140x_reg_map.uart_gpio_set_addr = 0x0e;
xr21b140x_reg_map.uart_gpio_clr_addr = 0x0f;
xr21b140x_reg_map.uart_gpio_status_addr = 0x10;
xr21b140x_reg_map.tx_break_addr = 0x0a;
xr21b140x_reg_map.uart_custom_driver = 0x41;
}
static void init_xr21b1411_reg_map(void)
{
xr21b1411_reg_map.uart_enable_addr = 0xc00;
xr21b1411_reg_map.uart_flow_addr = 0xc06;
xr21b1411_reg_map.uart_loopback_addr = 0xc16;
xr21b1411_reg_map.uart_xon_char_addr = 0xc07;
xr21b1411_reg_map.uart_xoff_char_addr = 0xc08;
xr21b1411_reg_map.uart_gpio_mode_addr = 0xc0c;
xr21b1411_reg_map.uart_gpio_dir_addr = 0xc0d;
xr21b1411_reg_map.uart_gpio_set_addr = 0xc0e;
xr21b1411_reg_map.uart_gpio_clr_addr = 0xc0f;
xr21b1411_reg_map.uart_gpio_status_addr = 0xc10;
xr21b1411_reg_map.tx_break_addr = 0xc0a;
xr21b1411_reg_map.uart_custom_driver = 0x20d;
}
static void init_xr21v141x_reg_map(void)
{
xr21v141x_reg_map.uart_enable_addr = 0x03;
xr21v141x_reg_map.uart_format_addr = 0x0b;
xr21v141x_reg_map.uart_flow_addr = 0x0c;
xr21v141x_reg_map.uart_loopback_addr = 0x12;
xr21v141x_reg_map.uart_xon_char_addr = 0x10;
xr21v141x_reg_map.uart_xoff_char_addr = 0x11;
xr21v141x_reg_map.uart_gpio_mode_addr = 0x1a;
xr21v141x_reg_map.uart_gpio_dir_addr = 0x1b;
xr21v141x_reg_map.uart_gpio_set_addr = 0x1d;
xr21v141x_reg_map.uart_gpio_clr_addr = 0x1e;
xr21v141x_reg_map.uart_gpio_status_addr = 0x1f;
xr21v141x_reg_map.tx_break_addr = 0x14;
}
static void init_xr21b142x_reg_map(void)
{
xr21b142x_reg_map.uart_enable_addr = 0x00;
xr21b142x_reg_map.uart_flow_addr = 0x06;
xr21b142x_reg_map.uart_loopback_addr = 0x16;
xr21b142x_reg_map.uart_xon_char_addr = 0x07;
xr21b142x_reg_map.uart_xoff_char_addr = 0x08;
xr21b142x_reg_map.uart_gpio_mode_addr = 0x0c;
xr21b142x_reg_map.uart_gpio_dir_addr = 0x0d;
xr21b142x_reg_map.uart_gpio_set_addr = 0x0e;
xr21b142x_reg_map.uart_gpio_clr_addr = 0x0f;
xr21b142x_reg_map.uart_gpio_status_addr = 0x10;
xr21b142x_reg_map.tx_break_addr = 0x0a;
xr21b142x_reg_map.uart_custom_driver = 0x60;
xr21b142x_reg_map.uart_low_latency = 0x46;
}
int xr_usb_serial_pre_setup(struct xr_usb_serial *xr_usb_serial)
{
int ret = 0;
init_xr21b140x_reg_map();
init_xr21b1411_reg_map();
init_xr21v141x_reg_map();
init_xr21b142x_reg_map();
if((xr_usb_serial->DeviceProduct&0xfff0) == 0x1400)
{
memcpy(&(xr_usb_serial->reg_map),&xr21b140x_reg_map,sizeof(struct reg_addr_map));
}
else if(xr_usb_serial->DeviceProduct == 0x1411)
{
memcpy(&(xr_usb_serial->reg_map),&xr21b1411_reg_map,sizeof(struct reg_addr_map));
}
else if((xr_usb_serial->DeviceProduct == 0x1410)||
(xr_usb_serial->DeviceProduct == 0x1412)||
(xr_usb_serial->DeviceProduct == 0x1414))
{
memcpy(&(xr_usb_serial->reg_map),&xr21v141x_reg_map,sizeof(struct reg_addr_map));
}
else if((xr_usb_serial->DeviceProduct == 0x1420)||
(xr_usb_serial->DeviceProduct == 0x1422)||
(xr_usb_serial->DeviceProduct == 0x1424))
{
memcpy(&(xr_usb_serial->reg_map),&xr21b142x_reg_map,sizeof(struct reg_addr_map));
}
else
{
ret = -1;
}
if(xr_usb_serial->reg_map.uart_custom_driver)
xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_custom_driver, 1);
xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_mode_addr, 0);
xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_dir_addr, 0x28);
xr_usb_serial_set_reg(xr_usb_serial, xr_usb_serial->reg_map.uart_gpio_set_addr, UART_GPIO_SET_DTR | UART_GPIO_SET_RTS);
return ret;
}

View File

@ -1,35 +0,0 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/ioctl.h>
#define XR_USB_SERIAL_IOC_MAGIC 'v'
#define XR_USB_SERIAL_GET_REG _IOWR(XR_USB_SERIAL_IOC_MAGIC, 1, int)
#define XR_USB_SERIAL_SET_REG _IOWR(XR_USB_SERIAL_IOC_MAGIC, 2, int)
#define XR_USB_SERIAL_SET_ADDRESS_MATCH _IO(XR_USB_SERIAL_IOC_MAGIC, 3)
#define XR_USB_SERIAL_SET_PRECISE_FLAGS _IO(XR_USB_SERIAL_IOC_MAGIC, 4)
#define XR_USB_SERIAL_TEST_MODE _IO(XR_USB_SERIAL_IOC_MAGIC, 5)
#define XR_USB_SERIAL_LOOPBACK _IO(XR_USB_SERIAL_IOC_MAGIC, 6)
#define XR_USB_SERIAL_SET_GPIO_MODE_REG _IO(XR_USB_SERIAL_IOC_MAGIC, 9)
#define XR_USB_SERIAL_GET_GPIO_MODE_REG _IO(XR_USB_SERIAL_IOC_MAGIC, 10)
#define XRIOC_SET_ANY_BAUD_RATE _IO(XR_USB_SERIAL_IOC_MAGIC, 11)
#define XRIOC_SET_PRECISE_FLAGS _IO(XR_USB_SERIAL_IOC_MAGIC, 12)
#define VZ_ADDRESS_UNICAST_S 0
#define VZ_ADDRESS_BROADCAST_S 8
#define VZ_ADDRESS_MATCH(U, B) (0x8000000 | ((B) << VZ_ADDRESS_BROADCAST_S) | ((U) << VZ_ADDRESS_UNICAST_S))
#define VZ_ADDRESS_MATCH_DISABLE 0

View File

@ -1,17 +0,0 @@
#
# Copyright (C) 2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=Modem Server
LUCI_DEPENDS:=+luci-compat +quectel-CM-5G +kmod-gobinet \
+kmod-usb-net-cdc-ether +kmod-usb-net-qmi-wwan \
+kmod-usb-net-rndis +kmod-usb-serial-option
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -1,9 +0,0 @@
module("luci.controller.gobinetmodem", package.seeall)
function index()
if not nixio.fs.access("/etc/config/gobinetmodem") then
return
end
entry({"admin", "network", "gobinetmodem"}, cbi("gobinetmodem"), _("Gobinet Modem Server"), 80).dependent = false
end

View File

@ -1,39 +0,0 @@
-- Copyright 2016 David Thornley <david.thornley@touchstargroup.com>
-- Licensed to the public under the Apache License 2.0.
mp = Map("gobinetmodem")
mp.title = translate("gobinet Modem Server")
mp.description = translate("Modem Server For OpenWrt")
s = mp:section(TypedSection, "service", "Base Setting")
s.anonymous = true
enabled = s:option(Flag, "enabled", translate("Enable"))
enabled.default = 0
enabled.rmempty = false
apn = s:option(Value, "apn", translate("APN"))
apn.rmempty = true
pincode = s:option(Value, "pincode", translate("PIN"))
pincode.rmempty = true
username = s:option(Value, "username", translate("PAP/CHAP username"))
username.rmempty = true
password = s:option(Value, "password", translate("PAP/CHAP password"))
password.rmempty = true
auth = s:option(Value, "auth", translate("Authentication Type"))
auth.rmempty = true
auth:value("", translate("-- Please choose --"))
auth:value("both", "PAP/CHAP (both)")
auth:value("pap", "PAP")
auth:value("chap", "CHAP")
auth:value("none", "NONE")
tool = s:option(Value, "tool", translate("Tools"))
tool:value("quectel-CM", "quectel-CM")
tool.rmempty = true
return mp

View File

@ -1,24 +0,0 @@
msgid ""
msgstr ""
"Project-Id-Version: \n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: dingpengyu <dingpengyu06@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: zh_CN\n"
"X-Generator: Poedit 2.3.1\n"
msgid "Base Setting"
msgstr "基本设置"
msgid "gobinet Modem Server"
msgstr "gobinet移动网络拨号服务"
msgid "Modem Server For OpenWrt"
msgstr "OpenWrt移动网络拨号服务"
msgid "Tools"
msgstr "拨号工具"

View File

@ -1,4 +0,0 @@
config service
option tool 'quectel-CM'
option enabled '0'

View File

@ -1,80 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2014 OpenWrt.org
START=99
STOP=16
USE_PROCD=1
#使用procd启动
run_4g()
{
local enabled
config_get_bool enabled $1 enabled
echo "run 4G" >> /tmp/log4g
if [ "$enabled" = "1" ]; then
local user
local password
local apn
local auth
local pincode
local device
local tool
# echo "enable 4G" >> /tmp/log4g
config_get user $1 user
config_get password $1 password
config_get apn $1 apn
config_get auth $1 auth
config_get pincode $1 pincode
config_get device $1 device
config_get tool $1 tool
config_get tty $1 tty
config_get atcmd $1 atcmd
devname="$(basename "$device")"
devpath="$(readlink -f /sys/class/usbmisc/$devname/device/)"
ifname="$( ls "$devpath"/net )"
if [ "$tool" = "at" ];then
at_tool "$atcmd" -d $tty
else
procd_open_instance
#创建一个实例, 在procd看来一个应用程序可以多个实\E4\BE?
#ubus call service list 可以查看实例
procd_set_param command $tool -i $ifname -s $apn
if [ "$password" != "" ];then
procd_append_param command $user $password $auth
fi
if [ "$pincode" != "" ]; then
procd_append_param command -p $pincode
fi
# procd_append_param command -f /tmp/4g.log
procd_set_param respawn
echo "quectel-CM has started."
procd_close_instance
#关闭实例
fi
fi
}
service_triggers()
{
procd_add_reload_trigger "gobinetmodem"
}
start_service() {
config_load gobinetmodem
config_foreach run_4g service
}
stop_service()
{
echo "4G stop" >> /tmp/log4g
killall quectel-CM
echo "quectel-CM has stoped."
}

View File

@ -1,11 +0,0 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete ucitrack.@gobinetmodem[-1]
add ucitrack gobinetmodem
set ucitrack.@gobinetmodem[-1].init=gobinetmodem
commit ucitrack
EOF
rm -f /tmp/luci-indexcache
exit 0

View File

@ -1,47 +0,0 @@
#
# Copyright (C) 2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=gobinet
PKG_VERSION:=1.6.3
PKG_RELEASE:=1
include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk
define KernelPackage/gobinet
SUBMENU:=WWAN Support
TITLE:=Quectel Linux USB Gobinet Driver
DEPENDS:=+kmod-usb-net
FILES:=$(PKG_BUILD_DIR)/GobiNet.ko
AUTOLOAD:=$(call AutoLoad,81,GobiNet)
endef
define KernelPackage/gobinet/description
Quectel Linux USB gobinet Driver
endef
MAKE_OPTS:= \
ARCH="$(LINUX_KARCH)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
CXXFLAGS="$(TARGET_CXXFLAGS)" \
M="$(PKG_BUILD_DIR)" \
$(EXTRA_KCONFIG)
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
$(MAKE_OPTS) \
modules
endef
$(eval $(call KernelPackage,gobinet))

File diff suppressed because it is too large Load Diff

View File

@ -1,43 +0,0 @@
obj-m := GobiNet.o
GobiNet-objs := GobiUSBNet.o QMIDevice.o QMI.o
PWD := $(shell pwd)
OUTPUTDIR=/lib/modules/`uname -r`/kernel/drivers/net/usb/
ifeq ($(ARCH),)
ARCH := $(shell uname -m)
endif
ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE :=
endif
ifeq ($(KDIR),)
KDIR := /lib/modules/$(shell uname -r)/build
ifeq ($(ARCH),i686)
ifeq ($(wildcard $KDIR/arch/$ARCH),)
ARCH=i386
endif
endif
endif
$(shell rm -rf usbnet.h)
ifneq ($(wildcard $(KDIR)/drivers/usb/net/usbnet.h),)
$(shell ln -s $(KDIR)/drivers/usb/net/usbnet.h usbnet.h)
endif
ifneq ($(wildcard $(KDIR)/drivers/net/usb/usbnet.h),)
$(shell ln -s $(KDIR)/drivers/net/usb/usbnet.h usbnet.h)
endif
default:
ln -sf makefile Makefile
$(MAKE) ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} -C $(KDIR) M=$(PWD) modules
install: default
mkdir -p $(OUTPUTDIR)
cp -f GobiNet.ko $(OUTPUTDIR)
depmod
modprobe -r GobiNet
modprobe GobiNet
clean:
rm -rf Makefile usbnet.h
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions Module.* modules.order

File diff suppressed because it is too large Load Diff

View File

@ -1,337 +0,0 @@
/*===========================================================================
FILE:
QMI.h
DESCRIPTION:
Qualcomm QMI driver header
FUNCTIONS:
Generic QMUX functions
ParseQMUX
FillQMUX
Generic QMI functions
GetTLV
ValidQMIMessage
GetQMIMessageID
Get sizes of buffers needed by QMI requests
QMUXHeaderSize
QMICTLGetClientIDReqSize
QMICTLReleaseClientIDReqSize
QMICTLReadyReqSize
QMIWDSSetEventReportReqSize
QMIWDSGetPKGSRVCStatusReqSize
QMIDMSGetMEIDReqSize
QMICTLSyncReqSize
Fill Buffers with QMI requests
QMICTLGetClientIDReq
QMICTLReleaseClientIDReq
QMICTLReadyReq
QMIWDSSetEventReportReq
QMIWDSGetPKGSRVCStatusReq
QMIDMSGetMEIDReq
QMICTLSetDataFormatReq
QMICTLSyncReq
Parse data from QMI responses
QMICTLGetClientIDResp
QMICTLReleaseClientIDResp
QMIWDSEventResp
QMIDMSGetMEIDResp
Copyright (c) 2011, Code Aurora Forum. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Code Aurora Forum nor
the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
===========================================================================*/
#pragma once
/*=========================================================================*/
// Definitions
/*=========================================================================*/
extern int quec_debug;
// DBG macro
#define DBG( format, arg... ) do { \
if (quec_debug == 1)\
{ \
printk( KERN_INFO "GobiNet::%s " format, __FUNCTION__, ## arg ); \
} }while(0)
#if 0
#define VDBG( format, arg... ) do { \
if (debug == 1)\
{ \
printk( KERN_INFO "GobiNet::%s " format, __FUNCTION__, ## arg ); \
} } while(0)
#else
#define VDBG( format, arg... ) do { } while(0)
#endif
#define INFO( format, arg... ) do { \
printk( KERN_INFO "GobiNet::%s " format, __FUNCTION__, ## arg ); \
}while(0)
// QMI Service Types
#define QMICTL 0
#define QMIWDS 1
#define QMIDMS 2
#define QMINAS 3
#define QMIUIM 11
#define QMIWDA 0x1A
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned int
#define u64 unsigned long long
#define bool u8
#define true 1
#define false 0
#define ENOMEM 12
#define EFAULT 14
#define EINVAL 22
#ifndef ENOMSG
#define ENOMSG 42
#endif
#define ENODATA 61
#define TLV_TYPE_LINK_PROTO 0x10
/*=========================================================================*/
// Struct sQMUX
//
// Structure that defines a QMUX header
/*=========================================================================*/
typedef struct sQMUX
{
/* T\F, always 1 */
u8 mTF;
/* Size of message */
u16 mLength;
/* Control flag */
u8 mCtrlFlag;
/* Service Type */
u8 mQMIService;
/* Client ID */
u8 mQMIClientID;
}__attribute__((__packed__)) sQMUX;
#if 0
/*=========================================================================*/
// Generic QMUX functions
/*=========================================================================*/
// Remove QMUX headers from a buffer
int ParseQMUX(
u16 * pClientID,
void * pBuffer,
u16 buffSize );
// Fill buffer with QMUX headers
int FillQMUX(
u16 clientID,
void * pBuffer,
u16 buffSize );
/*=========================================================================*/
// Generic QMI functions
/*=========================================================================*/
// Get data buffer of a specified TLV from a QMI message
int GetTLV(
void * pQMIMessage,
u16 messageLen,
u8 type,
void * pOutDataBuf,
u16 bufferLen );
// Check mandatory TLV in a QMI message
int ValidQMIMessage(
void * pQMIMessage,
u16 messageLen );
// Get the message ID of a QMI message
int GetQMIMessageID(
void * pQMIMessage,
u16 messageLen );
/*=========================================================================*/
// Get sizes of buffers needed by QMI requests
/*=========================================================================*/
// Get size of buffer needed for QMUX
u16 QMUXHeaderSize( void );
// Get size of buffer needed for QMUX + QMICTLGetClientIDReq
u16 QMICTLGetClientIDReqSize( void );
// Get size of buffer needed for QMUX + QMICTLReleaseClientIDReq
u16 QMICTLReleaseClientIDReqSize( void );
// Get size of buffer needed for QMUX + QMICTLReadyReq
u16 QMICTLReadyReqSize( void );
// Get size of buffer needed for QMUX + QMIWDSSetEventReportReq
u16 QMIWDSSetEventReportReqSize( void );
// Get size of buffer needed for QMUX + QMIWDSGetPKGSRVCStatusReq
u16 QMIWDSGetPKGSRVCStatusReqSize( void );
u16 QMIWDSSetQMUXBindMuxDataPortSize( void );
// Get size of buffer needed for QMUX + QMIDMSGetMEIDReq
u16 QMIDMSGetMEIDReqSize( void );
// Get size of buffer needed for QMUX + QMIWDASetDataFormatReq
u16 QMIWDASetDataFormatReqSize( int qmap_mode );
// Get size of buffer needed for QMUX + QMICTLSyncReq
u16 QMICTLSyncReqSize( void );
/*=========================================================================*/
// Fill Buffers with QMI requests
/*=========================================================================*/
// Fill buffer with QMI CTL Get Client ID Request
int QMICTLGetClientIDReq(
void * pBuffer,
u16 buffSize,
u8 transactionID,
u8 serviceType );
// Fill buffer with QMI CTL Release Client ID Request
int QMICTLReleaseClientIDReq(
void * pBuffer,
u16 buffSize,
u8 transactionID,
u16 clientID );
// Fill buffer with QMI CTL Get Version Info Request
int QMICTLReadyReq(
void * pBuffer,
u16 buffSize,
u8 transactionID );
// Fill buffer with QMI WDS Set Event Report Request
int QMIWDSSetEventReportReq(
void * pBuffer,
u16 buffSize,
u16 transactionID );
// Fill buffer with QMI WDS Get PKG SRVC Status Request
int QMIWDSGetPKGSRVCStatusReq(
void * pBuffer,
u16 buffSize,
u16 transactionID );
u16 QMIWDSSetQMUXBindMuxDataPortReq(
void * pBuffer,
u16 buffSize,
u8 MuxId,
u16 transactionID );
// Fill buffer with QMI DMS Get Serial Numbers Request
int QMIDMSGetMEIDReq(
void * pBuffer,
u16 buffSize,
u16 transactionID );
// Fill buffer with QMI WDA Set Data Format Request
int QMIWDASetDataFormatReq(
void * pBuffer,
u16 buffSize,
bool bRawIPMode, int qmap_mode, u32 rx_size,
u16 transactionID );
#if 0
int QMIWDASetDataQmapReq(
void * pBuffer,
u16 buffSize,
u16 transactionID );
#endif
int QMICTLSyncReq(
void * pBuffer,
u16 buffSize,
u16 transactionID );
/*=========================================================================*/
// Parse data from QMI responses
/*=========================================================================*/
// Parse the QMI CTL Get Client ID Resp
int QMICTLGetClientIDResp(
void * pBuffer,
u16 buffSize,
u16 * pClientID );
// Verify the QMI CTL Release Client ID Resp is valid
int QMICTLReleaseClientIDResp(
void * pBuffer,
u16 buffSize );
// Parse the QMI WDS Set Event Report Resp/Indication or
// QMI WDS Get PKG SRVC Status Resp/Indication
int QMIWDSEventResp(
void * pBuffer,
u16 buffSize,
u32 * pTXOk,
u32 * pRXOk,
u32 * pTXErr,
u32 * pRXErr,
u32 * pTXOfl,
u32 * pRXOfl,
u64 * pTXBytesOk,
u64 * pRXBytesOk,
bool * pbLinkState,
bool * pbReconfigure );
// Parse the QMI DMS Get Serial Numbers Resp
int QMIDMSGetMEIDResp(
void * pBuffer,
u16 buffSize,
char * pMEID,
int meidSize );
// Parse the QMI DMS Get Serial Numbers Resp
int QMIWDASetDataFormatResp(
void * pBuffer,
u16 buffSize, bool bRawIPMode, int *qmap_enabled, int *rx_size, int *tx_size);
// Pasre the QMI CTL Sync Response
int QMICTLSyncResp(
void *pBuffer,
u16 buffSize );
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,368 +0,0 @@
/*===========================================================================
FILE:
QMIDevice.h
DESCRIPTION:
Functions related to the QMI interface device
FUNCTIONS:
Generic functions
IsDeviceValid
PrintHex
GobiSetDownReason
GobiClearDownReason
GobiTestDownReason
Driver level asynchronous read functions
ResubmitIntURB
ReadCallback
IntCallback
StartRead
KillRead
Internal read/write functions
ReadAsync
UpSem
ReadSync
WriteSyncCallback
WriteSync
Internal memory management functions
GetClientID
ReleaseClientID
FindClientMem
AddToReadMemList
PopFromReadMemList
AddToNotifyList
NotifyAndPopNotifyList
AddToURBList
PopFromURBList
Internal userspace wrapper functions
UserspaceunlockedIOCTL
Userspace wrappers
UserspaceOpen
UserspaceIOCTL
UserspaceClose
UserspaceRead
UserspaceWrite
UserspacePoll
Initializer and destructor
RegisterQMIDevice
DeregisterQMIDevice
Driver level client management
QMIReady
QMIWDSCallback
SetupQMIWDSCallback
QMIDMSGetMEID
Copyright (c) 2011, Code Aurora Forum. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Code Aurora Forum nor
the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
===========================================================================*/
//---------------------------------------------------------------------------
// Pragmas
//---------------------------------------------------------------------------
#pragma once
//---------------------------------------------------------------------------
// Include Files
//---------------------------------------------------------------------------
#include "Structs.h"
#include "QMI.h"
/*=========================================================================*/
// Generic functions
/*=========================================================================*/
#ifdef __QUECTEL_INTER__
// Basic test to see if device memory is valid
static bool IsDeviceValid( sGobiUSBNet * pDev );
/*=========================================================================*/
// Driver level asynchronous read functions
/*=========================================================================*/
// Resubmit interrupt URB, re-using same values
static int ResubmitIntURB( struct urb * pIntURB );
// Read callback
// Put the data in storage and notify anyone waiting for data
#if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,18 ))
static void ReadCallback( struct urb * pReadURB );
#else
static void ReadCallback(struct urb *pReadURB, struct pt_regs *regs);
#endif
// Inturrupt callback
// Data is available, start a read URB
#if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,18 ))
static void IntCallback( struct urb * pIntURB );
#else
static void IntCallback(struct urb *pIntURB, struct pt_regs *regs);
#endif
/*=========================================================================*/
// Internal read/write functions
/*=========================================================================*/
// Start asynchronous read
// Reading client's data store, not device
static int ReadAsync(
sGobiUSBNet * pDev,
u16 clientID,
u16 transactionID,
void (*pCallback)(sGobiUSBNet *, u16, void *),
void * pData );
// Notification function for synchronous read
static void UpSem(
sGobiUSBNet * pDev,
u16 clientID,
void * pData );
// Start synchronous read
// Reading client's data store, not device
static int ReadSync(
sGobiUSBNet * pDev,
void ** ppOutBuffer,
u16 clientID,
u16 transactionID );
// Write callback
#if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,18 ))
static void WriteSyncCallback( struct urb * pWriteURB );
#else
static void WriteSyncCallback(struct urb *pWriteURB, struct pt_regs *regs);
#endif
// Start synchronous write
static int WriteSync(
sGobiUSBNet * pDev,
char * pInWriteBuffer,
int size,
u16 clientID );
/*=========================================================================*/
// Internal memory management functions
/*=========================================================================*/
// Create client and allocate memory
static int GetClientID(
sGobiUSBNet * pDev,
u8 serviceType );
// Release client and free memory
static void ReleaseClientID(
sGobiUSBNet * pDev,
u16 clientID );
// Find this client's memory
static sClientMemList * FindClientMem(
sGobiUSBNet * pDev,
u16 clientID );
// Add Data to this client's ReadMem list
static bool AddToReadMemList(
sGobiUSBNet * pDev,
u16 clientID,
u16 transactionID,
void * pData,
u16 dataSize );
// Remove data from this client's ReadMem list if it matches
// the specified transaction ID.
static bool PopFromReadMemList(
sGobiUSBNet * pDev,
u16 clientID,
u16 transactionID,
void ** ppData,
u16 * pDataSize );
// Add Notify entry to this client's notify List
static bool AddToNotifyList(
sGobiUSBNet * pDev,
u16 clientID,
u16 transactionID,
void (* pNotifyFunct)(sGobiUSBNet *, u16, void *),
void * pData );
// Remove first Notify entry from this client's notify list
// and Run function
static bool NotifyAndPopNotifyList(
sGobiUSBNet * pDev,
u16 clientID,
u16 transactionID );
// Add URB to this client's URB list
static bool AddToURBList(
sGobiUSBNet * pDev,
u16 clientID,
struct urb * pURB );
// Remove URB from this client's URB list
static struct urb * PopFromURBList(
sGobiUSBNet * pDev,
u16 clientID );
/*=========================================================================*/
// Internal userspace wrappers
/*=========================================================================*/
// Userspace unlocked ioctl
static long UserspaceunlockedIOCTL(
struct file * pFilp,
unsigned int cmd,
unsigned long arg );
/*=========================================================================*/
// Userspace wrappers
/*=========================================================================*/
// Userspace open
static int UserspaceOpen(
struct inode * pInode,
struct file * pFilp );
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,36 ))
// Userspace ioctl
static int UserspaceIOCTL(
struct inode * pUnusedInode,
struct file * pFilp,
unsigned int cmd,
unsigned long arg );
#endif
// Userspace close
#define quectel_no_for_each_process
#ifdef quectel_no_for_each_process
static int UserspaceClose(
struct inode * pInode,
struct file * pFilp );
#else
#if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,14 ))
static int UserspaceClose(
struct file * pFilp,
fl_owner_t unusedFileTable );
#else
static int UserspaceClose( struct file * pFilp );
#endif
#endif
// Userspace read (synchronous)
static ssize_t UserspaceRead(
struct file * pFilp,
char __user * pBuf,
size_t size,
loff_t * pUnusedFpos );
// Userspace write (synchronous)
static ssize_t UserspaceWrite(
struct file * pFilp,
const char __user * pBuf,
size_t size,
loff_t * pUnusedFpos );
static unsigned int UserspacePoll(
struct file * pFilp,
struct poll_table_struct * pPollTable );
/*=========================================================================*/
// Driver level client management
/*=========================================================================*/
// Check if QMI is ready for use
static bool QMIReady(
sGobiUSBNet * pDev,
u16 timeout );
// QMI WDS callback function
static void QMIWDSCallback(
sGobiUSBNet * pDev,
u16 clientID,
void * pData );
// Fire off reqests and start async read for QMI WDS callback
static int SetupQMIWDSCallback( sGobiUSBNet * pDev );
// Register client, send req and parse MEID response, release client
static int QMIDMSGetMEID( sGobiUSBNet * pDev );
// Register client, send req and parse Data format response, release client
static int QMIWDASetDataFormat( sGobiUSBNet * pDev, int qmap_mode, int *rx_urb_size );
#endif
// Print Hex data, for debug purposes
void QuecPrintHex(
void * pBuffer,
u16 bufSize );
// Sets mDownReason and turns carrier off
void QuecGobiSetDownReason(
sGobiUSBNet * pDev,
u8 reason );
// Clear mDownReason and may turn carrier on
void QuecGobiClearDownReason(
sGobiUSBNet * pDev,
u8 reason );
// Tests mDownReason and returns whether reason is set
bool QuecGobiTestDownReason(
sGobiUSBNet * pDev,
u8 reason );
// Start continuous read "thread"
int QuecStartRead( sGobiUSBNet * pDev );
// Kill continuous read "thread"
void QuecKillRead( sGobiUSBNet * pDev );
/*=========================================================================*/
// Initializer and destructor
/*=========================================================================*/
// QMI Device initialization function
int QuecRegisterQMIDevice( sGobiUSBNet * pDev );
// QMI Device cleanup function
void QuecDeregisterQMIDevice( sGobiUSBNet * pDev );
int QuecQMIWDASetDataFormat( sGobiUSBNet * pDev, int qmap_mode, int *rx_urb_size );
#define PrintHex QuecPrintHex
#define GobiSetDownReason QuecGobiSetDownReason
#define GobiClearDownReason QuecGobiClearDownReason
#define GobiTestDownReason QuecGobiTestDownReason
#define StartRead QuecStartRead
#define KillRead QuecKillRead
#define RegisterQMIDevice QuecRegisterQMIDevice
#define DeregisterQMIDevice QuecDeregisterQMIDevice

View File

@ -1,78 +0,0 @@
Gobi3000 network driver 2011-07-29-1026
This readme covers important information concerning
the Gobi Net driver.
Table of Contents
1. What's new in this release
2. Known issues
3. Known platform issues
-------------------------------------------------------------------------------
1. WHAT'S NEW
This Release (Gobi3000 network driver 2011-07-29-1026)
a. Signal the device to leave low power mode on enumeration
b. Add "txQueueLength" parameter, which will set the Tx Queue Length
c. Send SetControlLineState message during driver/device removal
d. Change to new date-based versioning scheme
Prior Release (Gobi3000 network driver 1.0.60) 06/29/2011
a. Add UserspacePoll() function, to support select()
b. Fix possible deadlock on GobiUSBNetTXTimeout()
c. Fix memory leak on data transmission
Prior Release (Gobi3000 network driver 1.0.50) 05/18/2011
a. Add support for kernels up to 2.6.38
b. Add support for dynamic interface binding
Prior Release (Gobi3000 network driver 1.0.40) 02/28/2011
a. In cases of QMI read errors, discard the error and continue reading.
b. Add "interruptible" parameter, which may be disabled for debugging purposes.
Prior Release (Gobi3000 network driver 1.0.30) 01/05/2011
a. Fix rare kernel PANIC if a process terminates while file handle close
or device removal is in progress.
Prior Release (Gobi3000 network driver 1.0.20) 11/01/2010
a. Fix possible kernel WARNING if device removed before QCWWANDisconnect().
b. Fix multiple memory leaks in error cases.
Prior Release (Gobi3000 network driver 1.0.10) 09/17/2010
a. Initial release
-------------------------------------------------------------------------------
2. KNOWN ISSUES
No known issues.
-------------------------------------------------------------------------------
3. KNOWN PLATFORM ISSUES
a. Enabling autosuspend:
Autosuspend is supported by the Gobi3000 module and its drivers,
but by default it is not enabled by the open source kernel. As such,
the Gobi3000 module will not enter autosuspend unless the
user specifically turns on autosuspend with the command:
echo auto > /sys/bus/usb/devices/.../power/level
b. Ksoftirq using 100% CPU:
There is a known issue with the open source usbnet driver that can
result in infinite software interrupts. The fix for this is to test
(in the usbnet_bh() function) if the usb_device can submit URBs before
attempting to submit the response URB buffers.
c. NetworkManager does not recognize connection after resume:
After resuming from sleep/hibernate, NetworkManager may not recognize new
network connections by the Gobi device. This is a system issue not specific
to the Gobi device, which may result in dhcp not being run and the default
route not being updated. One way to fix this is to simply restart the
NetworkManager service.
-------------------------------------------------------------------------------

View File

@ -1,166 +0,0 @@
Release Notes
[V1.6.3]
Date: 9/26/2021
enhancement:
1. change version to 1.6.3
fix:
[V1.6.2.16]
Date: 9/17/2021
enhancement:
fix:
1. add sdx6x platform support
[V1.6.2.15]
Date: 3/23/2021
enhancement:
fix:
1. add sdx12 platform support
[V1.6.2.14]
Date: 3/18/2021
enhancement:
fix:
1. fix kasam: use-after-free when do modem reboot stress test
2. wait qmi_sync_thread() finish in DeregisterQMIDevice(), usb will disconnect when driver is still in qmi_sync_thread()
[V1.6.2.13]
Date: 12/31/2020
enhancement:
fix:
1. fix quectel-CM open error when driver is still in qmi_sync_thread() but SOC enter sleep.
[V1.6.2.12]
Date: 12/31/2020
enhancement:
fix:
1. for multi-pdn-call, can not ping when usb resume for usb suspend state.
[V1.6.2.11]
Date: 11/7/2020
enhancement:
1. support QUECTEL_QMI_MERGE, for some SOC, control endpoint only support read max 64 bytes QMI.
for QMI that size > 64, we need read serval times, and merge.
fix:
[V1.6.2.10]
Date: 9/15/2020
enhancement:
fix:
1. for X55, fix panic on kernel V2.6 ~ V3.2
[V1.6.2.9]
Date: 7/24/2020
enhancement:
fix:
1. for X55, fix errors on Big Endian SOC.
[V1.6.2.8]
Date: 7/2/2020
enhancement:
1. support QMAPV5, UL AGG (porting from qmi_wwan_q)
fix:
1. fix errors kernel V2.6 .
[V1.6.2.7]
Date: 6/9/2020
enhancement:
fix:
1. when send qmi ctl request, clear qmi ctl response which's TID is same
[V1.6.2.6]
Date: 5/19/2020
enhancement:
1. support bridge mode for multi-pdn-call
fix:
[V1.6.2.5]
Date: 4/26/2020
enhancement:
1. fix netcard name as usbX (from ethX)
fix:
......
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.5.0]
Date: 2018/04/17
enhancement::
1. support EG20&RG500
2. fix set rx_urb_size as 1520. do not change accroding to MTU
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.4.3]
Date: 2018/04/16
enhancement::
1. increase QMAP's rx_urb_size to 32KB
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.4.2]
Date: 2018/04/03
bug fix:
1. fix qmi client can not be released when quectel-CM killed by ¡®kill -9¡¯
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.4.1]
Date: 2018/02/20
bug fix:
1. fix a compiler error on Kernel lager than 4.11
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.4.0]
Date: 2018/12/17
bug fix:
1. fix a USB DMA error when built as GobiNet.ko on Kernel lager than 4.15
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.8]
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.7]
Date: 2018/09/25
enhancement:
1. check skb length in tx_fixup functions.
2. when QMAP enabled, set FLAG_RX_ASSEMBLE to advoid 'RX errors' of ifconfig
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.6]
Date: 2018/09/11
enhancement:
1. support EG12 EM12
2. optimization QMAP source code
3. fix compile errors and warnnings on kernel version 4.15
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.5]
Date: 2018/05/12
enhancement:
1. provide two method to enable QMAP function.
1.1 set module parameters 'qmap_mode' to X(1~4) to enable QMAP.
1.2 ifconfig usb0 down, then 'echo X > /sys/class/usbX/qmap_mode' to enable QMAP
for above two method, X(1) used to enable 'IP Aggregation' and X(2~4) to enable 'IP Mux'
2. support bridge mode, also provide two method to enable bridge mode.
2.1 set module parameters 'bridge_mode' to 1 to enable bridge mode.
2.2 'echo 1 > /sys/class/usbX/bridge_mode' to enable bridge mode.
bridge mode setups:
brctl addbr br0; brctl addif br0 eth0; brctl addif usb0; ./quectel-CM; ifconfig br0 up; ifconfig eth0 up
then connect eth0 to PC by ethernet cable. and PC run DHCP tool to obtain network public IP address.
'WCDMA&LTE_QConnectManager_Linux&Android_V1.1.40' and later version is required to use QMAP and bridge mode.
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.4]
Date: 2018/05/07
enhancement:
1. support use 'AT$QCRMCALL=1,1' to setup data call.
when use 'AT$QCRMCALL=1,1', must set module parameters 'qcrmcall_mode' to 1,
and GobiNet Driver will do not tx&rx QMI.
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.3]
Date: 2018/04/04
optimization:
1. optimization QMAP source code
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.2]
Date: 2018/03/23
enhancement:
1. support Qualcomm Mux and Aggregation Protocol (QMAP)
1.1 IP Mux: GobiNet Driver register multiple netcards, one netcards corresponding to one PDP.
and GobiNet Driver will tx/rx multiple IP packets maybe belong to different PDPs in one URB.
1.2 IP Aggregation: GobiNet Driver will rx multiple IP packets in one URB, used to increase throughput theoretically by reducing the number of usb interrupts.
the max rx URB size of MDM9x07 is 4KB, the max rx URB size of MDM9x40&SDX20 is 16KB
[Quectel_WCDMA&LTE_Linux&Android_GobiNet_Driver_V1.3.1]
Date: 2017/11/20
enhancement:
1. support BG96

View File

@ -1,529 +0,0 @@
/*===========================================================================
FILE:
Structs.h
DESCRIPTION:
Declaration of structures used by the Qualcomm Linux USB Network driver
FUNCTIONS:
none
Copyright (c) 2011, Code Aurora Forum. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Code Aurora Forum nor
the names of its contributors may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
===========================================================================*/
//---------------------------------------------------------------------------
// Pragmas
//---------------------------------------------------------------------------
#pragma once
//---------------------------------------------------------------------------
// Include Files
//---------------------------------------------------------------------------
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
#include <linux/usb.h>
#include <linux/version.h>
#include <linux/cdev.h>
#include <linux/kthread.h>
#include <linux/poll.h>
#include <linux/completion.h>
#include <linux/hrtimer.h>
#include <linux/interrupt.h>
#define QUECTEL_WWAN_QMAP 4 //MAX is 7
#ifdef QUECTEL_WWAN_QMAP
#define QUECTEL_QMAP_MUX_ID 0x81
#endif
//#define QUECTEL_QMI_MERGE
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
#define QUECTEL_BRIDGE_MODE
#endif
#if (LINUX_VERSION_CODE <= KERNEL_VERSION( 2,6,21 ))
static inline void skb_reset_mac_header(struct sk_buff *skb)
{
skb->mac.raw = skb->data;
}
#endif
#if (LINUX_VERSION_CODE <= KERNEL_VERSION( 2,6,22 ))
#define bool u8
#ifndef URB_FREE_BUFFER
#define URB_FREE_BUFFER_BY_SELF //usb_free_urb will not free, should free by self
#define URB_FREE_BUFFER 0x0100 /* Free transfer buffer with the URB */
#endif
/**
* usb_endpoint_type - get the endpoint's transfer type
* @epd: endpoint to be checked
*
* Returns one of USB_ENDPOINT_XFER_{CONTROL, ISOC, BULK, INT} according
* to @epd's transfer type.
*/
static inline int usb_endpoint_type(const struct usb_endpoint_descriptor *epd)
{
return epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
}
#endif
#if (LINUX_VERSION_CODE <= KERNEL_VERSION( 2,6,18 ))
/**
* usb_endpoint_dir_in - check if the endpoint has IN direction
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type IN, otherwise it returns false.
*/
static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
{
return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
}
/**
* usb_endpoint_dir_out - check if the endpoint has OUT direction
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type OUT, otherwise it returns false.
*/
static inline int usb_endpoint_dir_out(
const struct usb_endpoint_descriptor *epd)
{
return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
}
/**
* usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type
* @epd: endpoint to be checked
*
* Returns true if the endpoint is of type interrupt, otherwise it returns
* false.
*/
static inline int usb_endpoint_xfer_int(
const struct usb_endpoint_descriptor *epd)
{
return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
USB_ENDPOINT_XFER_INT);
}
static inline int usb_autopm_set_interface(struct usb_interface *intf)
{ return 0; }
static inline int usb_autopm_get_interface(struct usb_interface *intf)
{ return 0; }
static inline int usb_autopm_get_interface_async(struct usb_interface *intf)
{ return 0; }
static inline void usb_autopm_put_interface(struct usb_interface *intf)
{ }
static inline void usb_autopm_put_interface_async(struct usb_interface *intf)
{ }
static inline void usb_autopm_enable(struct usb_interface *intf)
{ }
static inline void usb_autopm_disable(struct usb_interface *intf)
{ }
static inline void usb_mark_last_busy(struct usb_device *udev)
{ }
#endif
#if (LINUX_VERSION_CODE <= KERNEL_VERSION( 2,6,24 ))
#include "usbnet.h"
#else
#include <linux/usb/usbnet.h>
#endif
#if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,25 ))
#include <linux/fdtable.h>
#else
#include <linux/file.h>
#endif
// Used in recursion, defined later below
struct sGobiUSBNet;
#if defined(QUECTEL_WWAN_QMAP)
#define QUECTEL_UL_DATA_AGG 1
#if defined(QUECTEL_UL_DATA_AGG)
struct ul_agg_ctx {
/* QMIWDS_ADMIN_SET_DATA_FORMAT_RESP TLV_0x17 and TLV_0x18 */
uint ul_data_aggregation_max_datagrams; //UplinkDataAggregationMaxDatagramsTlv
uint ul_data_aggregation_max_size; //UplinkDataAggregationMaxSizeTlv
uint dl_minimum_padding;
};
#endif
#endif
/*=========================================================================*/
// Struct sReadMemList
//
// Structure that defines an entry in a Read Memory linked list
/*=========================================================================*/
typedef struct sReadMemList
{
/* Data buffer */
void * mpData;
/* Transaction ID */
u16 mTransactionID;
/* Size of data buffer */
u16 mDataSize;
/* Next entry in linked list */
struct sReadMemList * mpNext;
} sReadMemList;
/*=========================================================================*/
// Struct sNotifyList
//
// Structure that defines an entry in a Notification linked list
/*=========================================================================*/
typedef struct sNotifyList
{
/* Function to be run when data becomes available */
void (* mpNotifyFunct)(struct sGobiUSBNet *, u16, void *);
/* Transaction ID */
u16 mTransactionID;
/* Data to provide as parameter to mpNotifyFunct */
void * mpData;
/* Next entry in linked list */
struct sNotifyList * mpNext;
} sNotifyList;
/*=========================================================================*/
// Struct sURBList
//
// Structure that defines an entry in a URB linked list
/*=========================================================================*/
typedef struct sURBList
{
/* The current URB */
struct urb * mpURB;
/* Next entry in linked list */
struct sURBList * mpNext;
} sURBList;
/*=========================================================================*/
// Struct sClientMemList
//
// Structure that defines an entry in a Client Memory linked list
// Stores data specific to a Service Type and Client ID
/*=========================================================================*/
typedef struct sClientMemList
{
/* Client ID for this Client */
u16 mClientID;
/* Linked list of Read entries */
/* Stores data read from device before sending to client */
sReadMemList * mpList;
/* Linked list of Notification entries */
/* Stores notification functions to be run as data becomes
available or the device is removed */
sNotifyList * mpReadNotifyList;
/* Linked list of URB entries */
/* Stores pointers to outstanding URBs which need canceled
when the client is deregistered or the device is removed */
sURBList * mpURBList;
/* Next entry in linked list */
struct sClientMemList * mpNext;
/* Wait queue object for poll() */
wait_queue_head_t mWaitQueue;
} sClientMemList;
/*=========================================================================*/
// Struct sURBSetupPacket
//
// Structure that defines a USB Setup packet for Control URBs
// Taken from USB CDC specifications
/*=========================================================================*/
typedef struct sURBSetupPacket
{
/* Request type */
u8 mRequestType;
/* Request code */
u8 mRequestCode;
/* Value */
u16 mValue;
/* Index */
u16 mIndex;
/* Length of Control URB */
u16 mLength;
} sURBSetupPacket;
// Common value for sURBSetupPacket.mLength
#define DEFAULT_READ_URB_LENGTH 0x1000
#ifdef QUECTEL_QMI_MERGE
#define MERGE_PACKET_IDENTITY 0x2c7c
#define MERGE_PACKET_VERSION 0x0001
#define MERGE_PACKET_MAX_PAYLOAD_SIZE 56
typedef struct sQMIMsgHeader {
u16 idenity;
u16 version;
u16 cur_len;
u16 total_len;
} sQMIMsgHeader;
typedef struct sQMIMsgPacket {
sQMIMsgHeader header;
u16 len;
char buf[DEFAULT_READ_URB_LENGTH];
} sQMIMsgPacket;
#endif
#ifdef CONFIG_PM
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,29 ))
/*=========================================================================*/
// Struct sAutoPM
//
// Structure used to manage AutoPM thread which determines whether the
// device is in use or may enter autosuspend. Also submits net
// transmissions asynchronously.
/*=========================================================================*/
typedef struct sAutoPM
{
/* Thread for atomic autopm function */
struct task_struct * mpThread;
/* Signal for completion when it's time for the thread to work */
struct completion mThreadDoWork;
/* Time to exit? */
bool mbExit;
/* List of URB's queued to be sent to the device */
sURBList * mpURBList;
/* URB list lock (for adding and removing elements) */
spinlock_t mURBListLock;
/* Length of the URB list */
atomic_t mURBListLen;
/* Active URB */
struct urb * mpActiveURB;
/* Active URB lock (for adding and removing elements) */
spinlock_t mActiveURBLock;
/* Duplicate pointer to USB device interface */
struct usb_interface * mpIntf;
} sAutoPM;
#endif
#endif /* CONFIG_PM */
/*=========================================================================*/
// Struct sQMIDev
//
// Structure that defines the data for the QMI device
/*=========================================================================*/
typedef struct sQMIDev
{
/* Device number */
dev_t mDevNum;
/* Device class */
struct class * mpDevClass;
/* cdev struct */
struct cdev mCdev;
/* is mCdev initialized? */
bool mbCdevIsInitialized;
/* Pointer to read URB */
struct urb * mpReadURB;
//#define READ_QMI_URB_ERROR
#ifdef READ_QMI_URB_ERROR
struct timer_list mReadUrbTimer;
#endif
#ifdef QUECTEL_QMI_MERGE
sQMIMsgPacket * mpQmiMsgPacket;
#endif
/* Read setup packet */
sURBSetupPacket * mpReadSetupPacket;
/* Read buffer attached to current read URB */
void * mpReadBuffer;
/* Inturrupt URB */
/* Used to asynchronously notify when read data is available */
struct urb * mpIntURB;
/* Buffer used by Inturrupt URB */
void * mpIntBuffer;
/* Pointer to memory linked list for all clients */
sClientMemList * mpClientMemList;
/* Spinlock for client Memory entries */
spinlock_t mClientMemLock;
/* Transaction ID associated with QMICTL "client" */
atomic_t mQMICTLTransactionID;
} sQMIDev;
typedef struct {
u32 qmap_enabled;
u32 dl_data_aggregation_max_datagrams;
u32 dl_data_aggregation_max_size ;
u32 ul_data_aggregation_max_datagrams;
u32 ul_data_aggregation_max_size;
u32 dl_minimum_padding;
} QMAP_SETTING;
/*=========================================================================*/
// Struct sGobiUSBNet
//
// Structure that defines the data associated with the Qualcomm USB device
/*=========================================================================*/
typedef struct sGobiUSBNet
{
atomic_t refcount;
/* Net device structure */
struct usbnet * mpNetDev;
#ifdef QUECTEL_WWAN_QMAP
unsigned link_state;
int qmap_mode;
int qmap_size;
int qmap_version;
struct net_device *mpQmapNetDev[QUECTEL_WWAN_QMAP];
struct tasklet_struct txq;
QMAP_SETTING qmap_settings;
#if defined(QUECTEL_UL_DATA_AGG)
struct ul_agg_ctx agg_ctx;
#endif
#ifdef QUECTEL_BRIDGE_MODE
int m_qmap_bridge_mode[QUECTEL_WWAN_QMAP];
#endif
#endif
#if 1 //def DATA_MODE_RP
bool mbMdm9x07;
bool mbMdm9x06; //for BG96
/* QMI "device" work in IP Mode or ETH Mode */
bool mbRawIPMode;
#ifdef QUECTEL_BRIDGE_MODE
int m_bridge_mode;
uint m_bridge_ipv4;
unsigned char mHostMAC[6];
#endif
int m_qcrmcall_mode;
#endif
struct completion mQMIReadyCompletion;
bool mbQMIReady;
bool mbProbeDone;
bool mbQMISyncIng;
/* Usb device interface */
struct usb_interface * mpIntf;
/* Pointers to usbnet_open and usbnet_stop functions */
int (* mpUSBNetOpen)(struct net_device *);
int (* mpUSBNetStop)(struct net_device *);
/* Reason(s) why interface is down */
/* Used by Gobi*DownReason */
unsigned long mDownReason;
#define NO_NDIS_CONNECTION 0
#define CDC_CONNECTION_SPEED 1
#define DRIVER_SUSPENDED 2
#define NET_IFACE_STOPPED 3
/* QMI "device" status */
bool mbQMIValid;
bool mbDeregisterQMIDevice;
/* QMI "device" memory */
sQMIDev mQMIDev;
/* Device MEID */
char mMEID[14];
struct hrtimer timer;
struct tasklet_struct bh;
unsigned long
pending_num : 8,
pending_size : 16;
struct sk_buff *pending_pool[16];
#ifdef CONFIG_PM
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,29 ))
/* AutoPM thread */
sAutoPM mAutoPM;
#endif
#endif /* CONFIG_PM */
} sGobiUSBNet;
/*=========================================================================*/
// Struct sQMIFilpStorage
//
// Structure that defines the storage each file handle contains
// Relates the file handle to a client
/*=========================================================================*/
typedef struct sQMIFilpStorage
{
/* Client ID */
u16 mClientID;
/* Device pointer */
sGobiUSBNet * mpDev;
} sQMIFilpStorage;