mirror of
https://github.com/coolsnowwolf/lede
synced 2025-01-07 07:46:47 +08: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
|
||||
SUBMENU:=Wireless Drivers
|
||||
TITLE:=ath10k-ct driver optimized for CT ath10k firmware
|
||||
DEPENDS:=+kmod-mac80211 +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT @PCI_SUPPORT +kmod-hwmon-core
|
||||
DEPENDS:=@(arm||aarch64||mips||mipsel) +kmod-mac80211 +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT @PCI_SUPPORT +kmod-hwmon-core
|
||||
FILES:=\
|
||||
$(PKG_BUILD_DIR)/ath10k$(CT_KVER)/ath10k_pci.ko \
|
||||
$(PKG_BUILD_DIR)/ath10k$(CT_KVER)/ath10k_core.ko
|
||||
|
@ -111,3 +111,17 @@
|
||||
u8 rate_idx;
|
||||
u8 nss;
|
||||
u8 rx_flags;
|
||||
--- a/drivers/net/wireless/mac80211_hwsim.c
|
||||
+++ b/drivers/net/wireless/mac80211_hwsim.c
|
||||
@@ -5750,7 +5750,11 @@
|
||||
if (err)
|
||||
goto out_exit_netlink;
|
||||
|
||||
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 4, 0))
|
||||
+ hwsim_class = class_create("mac80211_hwsim");
|
||||
+#else
|
||||
hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
|
||||
+#endif
|
||||
if (IS_ERR(hwsim_class)) {
|
||||
err = PTR_ERR(hwsim_class);
|
||||
goto out_exit_virtio;
|
||||
|
@ -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