mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-15 18:03:30 +00:00
ath10k-ct: fix build with arm/mips
This commit is contained in:
parent
e40fe43e49
commit
3f0ed51973
@ -29,7 +29,7 @@ include $(INCLUDE_DIR)/package.mk
|
|||||||
define KernelPackage/ath10k-ct
|
define KernelPackage/ath10k-ct
|
||||||
SUBMENU:=Wireless Drivers
|
SUBMENU:=Wireless Drivers
|
||||||
TITLE:=ath10k-ct driver optimized for CT ath10k firmware
|
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:=\
|
FILES:=\
|
||||||
$(PKG_BUILD_DIR)/ath10k$(CT_KVER)/ath10k_pci.ko \
|
$(PKG_BUILD_DIR)/ath10k$(CT_KVER)/ath10k_pci.ko \
|
||||||
$(PKG_BUILD_DIR)/ath10k$(CT_KVER)/ath10k_core.ko
|
$(PKG_BUILD_DIR)/ath10k$(CT_KVER)/ath10k_core.ko
|
||||||
|
@ -111,3 +111,17 @@
|
|||||||
u8 rate_idx;
|
u8 rate_idx;
|
||||||
u8 nss;
|
u8 nss;
|
||||||
u8 rx_flags;
|
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;
|
||||||
|
@ -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)))
|
|
@ -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
@ -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
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 "拨号工具"
|
|
@ -1,4 +0,0 @@
|
|||||||
config service
|
|
||||||
option tool 'quectel-CM'
|
|
||||||
option enabled '0'
|
|
||||||
|
|
@ -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."
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
@ -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
@ -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
@ -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
@ -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
|
|
@ -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.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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<E_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<E_Linux&Android_GobiNet_Driver_V1.4.3]
|
|
||||||
Date: 2018/04/16
|
|
||||||
enhancement::
|
|
||||||
1. increase QMAP's rx_urb_size to 32KB
|
|
||||||
|
|
||||||
[Quectel_WCDMA<E_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<E_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<E_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<E_Linux&Android_GobiNet_Driver_V1.3.8]
|
|
||||||
[Quectel_WCDMA<E_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<E_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<E_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<E_QConnectManager_Linux&Android_V1.1.40' and later version is required to use QMAP and bridge mode.
|
|
||||||
|
|
||||||
[Quectel_WCDMA<E_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<E_Linux&Android_GobiNet_Driver_V1.3.3]
|
|
||||||
Date: 2018/04/04
|
|
||||||
optimization:
|
|
||||||
1. optimization QMAP source code
|
|
||||||
|
|
||||||
[Quectel_WCDMA<E_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<E_Linux&Android_GobiNet_Driver_V1.3.1]
|
|
||||||
Date: 2017/11/20
|
|
||||||
enhancement:
|
|
||||||
1. support BG96
|
|
@ -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;
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user