mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-27 10:31:38 +08:00
🚀 Sync 2026-06-07 17:45:31
This commit is contained in:
parent
a9100725c5
commit
9c74cc341d
@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=26.6.2
|
||||
PKG_RELEASE:=155
|
||||
PKG_RELEASE:=156
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,22 +0,0 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=quectel-qmi-wwan
|
||||
PKG_VERSION:=1.2.9
|
||||
PKG_RELEASE:=1
|
||||
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define KernelPackage/usb-net-qmi-wwan-quectel
|
||||
SUBMENU:=USB Support
|
||||
TITLE:=QMI WWAN driver for Quectel modules
|
||||
DEPENDS:=+kmod-usb-net +kmod-usb-wdm
|
||||
FILES:=$(PKG_BUILD_DIR)/qmi_wwan_q.ko
|
||||
AUTOLOAD:=$(call AutoLoad,81,qmi_wwan_q)
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
+$(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules
|
||||
endef
|
||||
|
||||
$(eval $(call KernelPackage,usb-net-qmi-wwan-quectel))
|
||||
@ -1,13 +0,0 @@
|
||||
--- a/qmi_wwan_q.c
|
||||
+++ b/qmi_wwan_q.c
|
||||
@@ -62,9 +62,8 @@ struct rmnet_nss_cb {
|
||||
int (*nss_tx)(struct sk_buff *skb);
|
||||
};
|
||||
static struct rmnet_nss_cb __read_mostly *nss_cb = NULL;
|
||||
-#if defined(CONFIG_PINCTRL_IPQ807x) || defined(CONFIG_PINCTRL_IPQ5018) || defined(CONFIG_PINCTRL_IPQ8074)
|
||||
+#if defined(CONFIG_QCA_NSS_DRV)
|
||||
//#ifdef CONFIG_RMNET_DATA //spf12.x none, not effect for spf11.x
|
||||
-#define CONFIG_QCA_NSS_DRV
|
||||
/* define at qsdk/qca/src/linux-4.4/net/rmnet_data/rmnet_data_main.c */ //for spf11.x
|
||||
/* define at qsdk/qca/src/datarmnet/core/rmnet_config.c */ //for spf12.x
|
||||
/* set at qsdk/qca/src/data-kernel/drivers/rmnet-nss/rmnet_nss.c */
|
||||
@ -1,44 +0,0 @@
|
||||
--- a/qmi_wwan_q.c
|
||||
+++ b/qmi_wwan_q.c
|
||||
@@ -896,7 +896,7 @@ static void usbnet_bh(unsigned long data
|
||||
struct tasklet_struct *t = &pQmapDev->usbnet_bh;
|
||||
bool use_callback = false;
|
||||
|
||||
-#if (LINUX_VERSION_CODE > KERNEL_VERSION( 5,8,0 )) //c955e329bb9d44fab75cf2116542fcc0de0473c5
|
||||
+#if (LINUX_VERSION_CODE > KERNEL_VERSION( 5,8,0 )) && (LINUX_VERSION_CODE < KERNEL_VERSION( 6,17,0 ))
|
||||
use_callback = t->use_callback;
|
||||
if (use_callback)
|
||||
t->callback(&pQmapDev->mpNetDev->bh);
|
||||
@@ -1368,8 +1368,12 @@ static int qmap_register_device(sQmiWwan
|
||||
#endif
|
||||
priv->agg_skb = NULL;
|
||||
priv->agg_count = 0;
|
||||
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6,18,0)
|
||||
hrtimer_init(&priv->agg_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
priv->agg_hrtimer.function = rmnet_usb_tx_agg_timer_cb;
|
||||
+#else
|
||||
+ hrtimer_setup(&priv->agg_hrtimer, rmnet_usb_tx_agg_timer_cb, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
||||
+#endif
|
||||
INIT_WORK(&priv->agg_wq, rmnet_usb_tx_agg_work);
|
||||
ktime_get_ts64(&priv->agg_time);
|
||||
spin_lock_init(&priv->agg_lock);
|
||||
@@ -1472,7 +1476,7 @@ typedef struct {
|
||||
} BRMAC_SETTING;
|
||||
#endif
|
||||
|
||||
-int qma_setting_store(struct device *dev, QMAP_SETTING *qmap_settings, size_t size) {
|
||||
+static int qma_setting_store(struct device *dev, QMAP_SETTING *qmap_settings, size_t size) {
|
||||
struct net_device *netdev = to_net_dev(dev);
|
||||
struct usbnet * usbnetdev = netdev_priv( netdev );
|
||||
struct qmi_wwan_state *info = (void *)&usbnetdev->data;
|
||||
@@ -2266,8 +2270,10 @@ static int qmi_wwan_bind(struct usbnet *
|
||||
}
|
||||
|
||||
if (pQmapDev->use_rmnet_usb && !one_card_mode) {
|
||||
+#if (LINUX_VERSION_CODE < KERNEL_VERSION( 6,17,0 ))
|
||||
pQmapDev->usbnet_bh = dev->bh;
|
||||
tasklet_init(&dev->bh, usbnet_bh, (unsigned long)pQmapDev);
|
||||
+#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,28 +0,0 @@
|
||||
From 85990e155cb684ec6380bcf70f588255ec41dc69 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?=E7=80=AC=E5=90=8D=E7=94=B1=E5=B8=8C?=
|
||||
<wanglei199909210927@gmail.com>
|
||||
Date: Wed, 5 Nov 2025 14:16:56 +0800
|
||||
Subject: [PATCH] qmi_wwan: return correct tx/rx stats in kernel 6.10+ (#130)
|
||||
|
||||
---
|
||||
driver/fibocom_QMI_WWAN/src/qmi_wwan_f.c | 9 ++++++++-
|
||||
driver/quectel_QMI_WWAN/src/qmi_wwan_q.c | 7 +++++++
|
||||
2 files changed, 15 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/qmi_wwan_q.c
|
||||
+++ b/qmi_wwan_q.c
|
||||
@@ -2153,7 +2153,14 @@ static int qmi_wwan_bind(struct usbnet *
|
||||
#endif
|
||||
}
|
||||
if (!_usbnet_get_stats64)
|
||||
+#if (LINUX_VERSION_CODE < KERNEL_VERSION( 6,10,0 ))
|
||||
_usbnet_get_stats64 = dev->net->netdev_ops->ndo_get_stats64;
|
||||
+#else
|
||||
+ /* From kernel 6.10+, usbnet sets pcpu_stat_type = NETDEV_PCPU_STAT_TSTATS (352f5b3282), but removed ndo_get_stats64 (9cb3d523c1) */
|
||||
+ /* Use dev_get_tstats64 to read per-CPU stats when NETDEV_PCPU_STAT_TSTATS was set */
|
||||
+ if (dev->net->pcpu_stat_type == NETDEV_PCPU_STAT_TSTATS)
|
||||
+ _usbnet_get_stats64 = dev_get_tstats64;
|
||||
+#endif
|
||||
dev->net->netdev_ops = &qmi_wwan_netdev_ops;
|
||||
|
||||
ql_net_ethtool_ops = *dev->net->ethtool_ops;
|
||||
@ -1,16 +0,0 @@
|
||||
--- a/qmi_wwan_q.c
|
||||
+++ b/qmi_wwan_q.c
|
||||
@@ -2563,6 +2563,13 @@ static const struct usb_device_id produc
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0800, 4, sdx55) }, /* Quectel RG500 */
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0801, 4, sdx55) }, /* Quectel RG520 */
|
||||
{ QMI_FIXED_RAWIP_INTF(0x2C7C, 0x0122, 4, sdx55) }, /* Quectel RG650 */
|
||||
+ { QMI_FIXED_RAWIP_INTF(0x05c6, 0x90d5, 3, sdx55) }, /* Foxconn T99W240T00 */
|
||||
+ { QMI_FIXED_RAWIP_INTF(0x05c6, 0x90db, 2, sdx55) }, /* SIM8200 */
|
||||
+ { QMI_FIXED_RAWIP_INTF(0x02dee, 0x4d22, 5, sdx55) }, /* Meige SRM815 */
|
||||
+ { QMI_FIXED_RAWIP_INTF(0x305a, 0x1421, 3, sdx55) }, /* gm800 */
|
||||
+ { QMI_FIXED_RAWIP_INTF(0x305a, 0x1403, 3, sdx55) }, /* gm800 */
|
||||
+ { QMI_FIXED_RAWIP_INTF(0x05C6, 0x9025, 4, sdx55) },
|
||||
+ { QMI_FIXED_RAWIP_INTF(0x05C6, 0x9091, 2, sdx55) },
|
||||
{ } /* END */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, products);
|
||||
@ -1,36 +0,0 @@
|
||||
obj-m += qmi_wwan_q.o
|
||||
|
||||
DIR := $(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
|
||||
|
||||
ifneq ($(findstring &,${DIR}),)
|
||||
$(warning "${DIR}")
|
||||
$(warning "current directory contain special char '&' !")
|
||||
$(error "please remove it!")
|
||||
endif
|
||||
|
||||
default:
|
||||
$(MAKE) ARCH=${ARCH} CROSS_COMPILE=${CROSS_COMPILE} -C $(KDIR) M=$(DIR) modules
|
||||
|
||||
install: default
|
||||
cp $(DIR)/qmi_wwan_q.ko /lib/modules/$(shell uname -r)/kernel/drivers/net/usb/
|
||||
depmod
|
||||
|
||||
clean:
|
||||
rm -rf *~ .tmp_versions modules.order Module.symvers
|
||||
find . -type f -name "*~" -o -name "*.o" -o -name "*.ko" -o -name "*.cmd" -o -name "*.mod.c" | xargs rm -rf
|
||||
@ -1,177 +0,0 @@
|
||||
Release Notes
|
||||
|
||||
[V1.2.7]
|
||||
Date: 1/12/2024
|
||||
enhancement:
|
||||
1. support SDX35 platform
|
||||
fix:
|
||||
|
||||
[V1.2.6]
|
||||
Date: 5/25/2023
|
||||
enhancement:
|
||||
1. support Linux 6.1
|
||||
fix:
|
||||
|
||||
[V1.2.5]
|
||||
Date: 5/4/2023
|
||||
enhancement:
|
||||
1. support Linux 5.19
|
||||
2. NSS not effect on SPF12.x and support SFE on 9574
|
||||
fix:
|
||||
|
||||
[V1.2.4]
|
||||
Date: 4/14/2023
|
||||
enhancement:
|
||||
1. support SDX7X platform
|
||||
fix:
|
||||
|
||||
[V1.2.3]
|
||||
Date: 9/20/2022
|
||||
enhancement:
|
||||
1. support 9x07(pid 0x030E) platform
|
||||
fix:
|
||||
|
||||
[V1.2.2]
|
||||
Date: 9/7/2022
|
||||
enhancement:
|
||||
1. Optimization, the network card send queue wakeup is changed from callback to tasklet
|
||||
2. Add the function of returning LAN packets in bridge mode
|
||||
3. support ndo ioctl on kernel>5.14
|
||||
4. Allow setting MTU greater than 1500
|
||||
fix:
|
||||
|
||||
[V1.2.1]
|
||||
Date: 9/26/2021
|
||||
enhancement:
|
||||
1. support IPQ5018's NSS
|
||||
2. use 'qsdk/qca/src/data-kernel/drivers/rmnet-nss/rmnet_nss.c' instead myself rmnet_nss.c
|
||||
and qmi_wwan_q.ko must load after rmnet_nss.ko
|
||||
fix:
|
||||
|
||||
[V1.2.0.25]
|
||||
Date: 9/17/2021
|
||||
enhancement:
|
||||
fix:
|
||||
1. add sdx6x platfrom support
|
||||
|
||||
[V1.2.0.24]
|
||||
Date: 9/6/2021
|
||||
enhancement:
|
||||
fix:
|
||||
1. add BG95 support
|
||||
2. support Linux 5.14.0
|
||||
|
||||
[V1.2.0.23]
|
||||
Date: 3/23/2021
|
||||
enhancement:
|
||||
fix:
|
||||
1. add sdx12 platfrom support
|
||||
|
||||
[V1.2.0.22]
|
||||
Date: 2/5/2021
|
||||
enhancement:
|
||||
fix:
|
||||
1. fix panic (memory-access-after-free) when do modem reboot stress test
|
||||
|
||||
[V1.2.0.21]
|
||||
Date: 2/4/2021
|
||||
enhancement:
|
||||
1. Code refactoring - QMAP and rmnet
|
||||
fix:
|
||||
1. qmap_qmi_wwan_rx_fixup: change skb_dequeue to __skb_dequeue
|
||||
|
||||
[V1.2.0.20]
|
||||
Date: 11/2/2020
|
||||
enhancement:
|
||||
fix:
|
||||
1. LTE-A modems can not obtain IP by DHCP
|
||||
|
||||
[V1.2.0.19]
|
||||
Date: 10/9/2020
|
||||
enhancement:
|
||||
fix:
|
||||
1. X55 can not access internet after usb resume
|
||||
|
||||
[V1.2.0.18]
|
||||
Date: 10/9/2020
|
||||
enhancement:
|
||||
fix:
|
||||
1. X55: rename rmnet_usb0.1 to wwan0_1
|
||||
1.1 if there is '.', openwrt will think it is vlan, and auto create vlan
|
||||
1.2 if there is '.', android will think it is not vaild
|
||||
1.3 if named as rmnet_usb0, and SOC is QCOM, QCOM's netmgr will auto manager it
|
||||
|
||||
[V1.2.0.17]
|
||||
Date: 9/14/2020
|
||||
enhancement:
|
||||
1. Code refactoring - QMAP size and version
|
||||
fix:
|
||||
|
||||
[V1.2.0.16]
|
||||
Date: 9/14/2020
|
||||
enhancement:
|
||||
1. rx_fixup() check if this is enough skb_headroom() to fill ethernet header
|
||||
fix:
|
||||
1. fix "WARNING: suspicious RCU usage"
|
||||
|
||||
[V1.2.0.15]
|
||||
Date: 9/10/2020
|
||||
enhancement:
|
||||
fix:
|
||||
1. fix compile errors on kernel 3.10~3.13
|
||||
|
||||
[V1.2.0.14]
|
||||
Date: 7/24/2020
|
||||
enhancement:
|
||||
fix:
|
||||
1. fix QMAP V5 bug on Big Endian CPU
|
||||
|
||||
[V1.2.0.13]
|
||||
Date: 6/22/2020
|
||||
enhancement:
|
||||
fix:
|
||||
1. fix no data traffic when do Upload TPUT test
|
||||
|
||||
[V1.2.0.12]
|
||||
Date: 5/29/2020
|
||||
enhancement:
|
||||
fix:
|
||||
1. IPQ8074: when enable hyfi, quectel-CM will crash system crash
|
||||
|
||||
[V1.2.0.9]
|
||||
Date: 5/13/2020
|
||||
enhancement:
|
||||
fix:
|
||||
1. IPQ8074: enable CONFIG_QCA_NSS_DRV by CONFIG_PINCTRL_IPQ807x (from CONFIG_ARCH_IPQ807x)
|
||||
|
||||
[V1.2.0.8]
|
||||
Date: 5/9/2020
|
||||
enhancement:
|
||||
fix:
|
||||
1. fix compile errors on kernel V3.10
|
||||
|
||||
[V1.2.0.7]
|
||||
Date: 4/25/2020
|
||||
enhancement:
|
||||
1. X55 support bridge mode
|
||||
fix:
|
||||
|
||||
[V1.2.0.6]
|
||||
Date: 4/20/2020
|
||||
enhancement:
|
||||
1. add stat64, or the rx/tx statics will become to 0 when data > 4G
|
||||
2. do not use skb_clone, will make QCOM's NSS and SFE 's cpu loading very high
|
||||
fix:
|
||||
|
||||
[V1.2.0.5]
|
||||
Date: 4/8/2020
|
||||
enhancement:
|
||||
1. add attrite link_state, change carrier state accoring link_state
|
||||
quectel-CM will set link_state to 1 when QMI setup call success.
|
||||
fix:
|
||||
|
||||
[V1.2.0.4]
|
||||
Date: 4/8/2020
|
||||
enhancement:
|
||||
1. support X55's QMAP V5
|
||||
fix:
|
||||
@ -1,68 +0,0 @@
|
||||
1. Enable QUECTEL_BRIDGE_MODE in qmi_wwan_q.c
|
||||
|
||||
2. Guide to use ....
|
||||
Welcome to Buildroot for the Orange Pi Zero
|
||||
OrangePi_Zero login: root
|
||||
# insmod qmi_wwan_q.ko
|
||||
[ 90.591841] qmi_wwan_q 3-1:1.4: cdc-wdm0: USB WDM device
|
||||
[ 90.597185] qmi_wwan_q 3-1:1.4: Quectel EC25&EC21&EG91&EG95&EG06&EP06&EM06&EG12&EP12&EM12&EG16&EG18&BG96&AG35 work on RawIP mode
|
||||
[ 90.610176] qmi_wwan_q 3-1:1.4: rx_urb_size = 32768
|
||||
[ 90.620589] qmi_wwan_q 3-1:1.4 wwan0: register 'qmi_wwan_q' at usb-1c1b000.usb-1, WWAN/QMI device, 96:42:59:a9:f5:e4
|
||||
[ 90.631293] usbcore: registered new interface driver qmi_wwan_q
|
||||
# brctl addbr br0
|
||||
# brctl addif br0 eth0
|
||||
[ 100.413071] br0: port 1(eth0) entered blocking state
|
||||
[ 100.418081] br0: port 1(eth0) entered disabled state
|
||||
[ 100.423356] device eth0 entered promiscuous mode
|
||||
# brctl addif br0 wwan0
|
||||
[ 102.696724] br0: port 2(wwan0) entered blocking state
|
||||
[ 102.701823] br0: port 2(wwan0) entered disabled state
|
||||
[ 102.707182] device wwan0 entered promiscuous mode
|
||||
# ifconfig br0 up
|
||||
[ 110.405561] br0: port 1(eth0) entered blocking state
|
||||
[ 110.410567] br0: port 1(eth0) entered forwarding state
|
||||
# brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
br0 8000.0242b22e80d8 no eth0
|
||||
wwan0
|
||||
# ./quectel-CM &
|
||||
# [01-01_06:37:02:386] Quectel_QConnectManager_Linux_V1.4.3
|
||||
[01-01_06:37:02:388] Find /sys/bus/usb/devices/3-1 idVendor=0x2c7c idProduct=0x512
|
||||
[01-01_06:37:02:388] Auto find qmichannel = /dev/cdc-wdm0
|
||||
[01-01_06:37:02:388] Auto find usbnet_adapter = wwan0
|
||||
[01-01_06:37:02:389] qmap_mode = 1, muxid = 0x81, qmap_netcard = wwan0
|
||||
[01-01_06:37:02:389] Modem works in QMI mode
|
||||
[01-01_06:37:02:389] qmap_mode = 1, muxid = 0x81, qmap_netcard = wwan0
|
||||
[01-01_06:37:02:394] cdc_wdm_fd = 7
|
||||
[01-01_06:37:02:561] Get clientWDS = 18
|
||||
[01-01_06:37:02:633] Get clientDMS = 1
|
||||
[01-01_06:37:02:689] Get clientNAS = 2
|
||||
[01-01_06:37:02:753] Get clientUIM = 1
|
||||
[01-01_06:37:02:817] Get clientWDA = 1
|
||||
[01-01_06:37:02:881] requestBaseBandVersion EM12GBATE1127
|
||||
[01-01_06:37:02:945] qmap_settings.rx_urb_size = 16384
|
||||
[01-01_06:37:03:201] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[01-01_06:37:03:265] requestGetProfile[1] ctnet///0
|
||||
[01-01_06:37:03:329] requestRegistrationState2 MCC: 460, MNC: 11, PS: Attached, DataCap: LTE
|
||||
[01-01_06:37:03:393] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[01-01_06:37:03:457] requestSetupDataCall WdsConnectionIPv4Handle: 0x192a5ed0
|
||||
[01-01_06:37:03:717] ifconfig wwan0 up
|
||||
[01-01_06:37:03:747] echo '0x64b69855' > /sys/module/qmi_wwan_q/parameters/bridge_ipv4
|
||||
|
||||
[ 117.030116] net wwan0: link_state 0x0 -> 0x1
|
||||
[ 117.041259] br0: port 2(wwan0) entered blocking state
|
||||
[ 117.046326] br0: port 2(wwan0) entered forwarding state
|
||||
[ 117.336688] net wwan0: sip = 100.182.152.85, tip=100.182.152.86, ipv4=100.182.152.85
|
||||
[ 121.612281] random: crng init done
|
||||
[ 128.143645] net wwan0: PC Mac Address: 5e:6b:82:fa:ab:c3
|
||||
[ 128.151936] net wwan0: rx_pkts=1, rx_len=312
|
||||
[ 128.203578] net wwan0: PC Mac Address: 5e:6b:82:fa:ab:c3
|
||||
[ 131.012891] net wwan0: sip = 100.182.152.85, tip=100.182.152.86, ipv4=100.182.152.85
|
||||
[ 131.341780] net wwan0: rx_pkts=1, rx_len=316
|
||||
[ 131.434642] net wwan0: rx_pkts=1, rx_len=1404
|
||||
[ 131.439416] net wwan0: rx_pkts=3, rx_len=4212
|
||||
[ 131.512782] net wwan0: rx_pkts=4, rx_len=5616
|
||||
[ 131.535345] net wwan0: rx_pkts=7, rx_len=9828
|
||||
[ 133.778699] net wwan0: rx_pkts=8, rx_len=11232
|
||||
[ 134.143941] net wwan0: rx_pkts=9, rx_len=12636
|
||||
[ 140.053957] net wwan0: rx_pkts=11, rx_len=15444
|
||||
@ -1,234 +0,0 @@
|
||||
1. Enable QUECTEL_BRIDGE_MODE in qmi_wwan_q.c
|
||||
|
||||
2. set qmap_mode to 4
|
||||
|
||||
3. if you want add wwan0.2 to br2, wwan0.3 to br3
|
||||
set bridge_mode to BIT(1)|BIT(2)
|
||||
|
||||
4. Guide to use ....
|
||||
# insmod qmi_wwan_q.ko qmap_mode=4 bridge_mode=6
|
||||
[243467.331669] qmi_wwan_q 3-1:1.4: cdc-wdm0: USB WDM device
|
||||
[243467.337136] qmi_wwan_q 3-1:1.4: Quectel EC25&EC21&EG91&EG95&EG06&EP06&EM06&EG12&EP12&EM12&EG16&EG18&BG96&AG35 work on RawIP mode
|
||||
[243467.349471] qmi_wwan_q 3-1:1.4: rx_urb_size = 32768
|
||||
[243467.364803] qmi_wwan_q 3-1:1.4 wwan0: register 'qmi_wwan_q' at usb-1c1b000.usb-1, WWAN/QMI device, 96:42:59:a9:f5:e4
|
||||
[243467.376025] net wwan0: qmap_register_device wwan0.1
|
||||
[243467.381658] net wwan0: qmap_register_device wwan0.2
|
||||
[243467.387281] net wwan0: qmap_register_device wwan0.3
|
||||
[243467.392851] net wwan0: qmap_register_device wwan0.4
|
||||
[243467.398106] usbcore: registered new interface driver qmi_wwan_q
|
||||
|
||||
# cat /sys/class/net/wwan0.2/bridge_mode
|
||||
1
|
||||
|
||||
# cat /sys/class/net/wwan0.3/bridge_mode
|
||||
1
|
||||
|
||||
# brctl addbr br2
|
||||
# brctl addif br2 wwan0.2
|
||||
[243492.518563] br2: port 1(wwan0.2) entered blocking state
|
||||
[243492.523888] br2: port 1(wwan0.2) entered disabled state
|
||||
[243492.535948] device wwan0.2 entered promiscuous mode
|
||||
|
||||
# brctl addbr br3
|
||||
# brctl addif br3 wwan0.3
|
||||
[243507.486717] br3: port 1(wwan0.3) entered blocking state
|
||||
[243507.492248] br3: port 1(wwan0.3) entered disabled state
|
||||
[243507.497982] device wwan0.3 entered promiscuous mode
|
||||
|
||||
# brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
br2 8000.964259a9f5e4 no wwan0.2
|
||||
br3 8000.964259a9f5e4 no wwan0.3
|
||||
|
||||
# ./quectel-qmi-proxy &
|
||||
# Find /sys/bus/usb/devices/3-1 idVendor=2c7c idProduct=0512
|
||||
Find /sys/bus/usb/devices/3-1:1.4/usbmisc/cdc-wdm0
|
||||
Will use cdc-wdm /dev/cdc-wdm0
|
||||
qmi_proxy_init enter
|
||||
qmi_proxy_loop enter
|
||||
link_prot 2
|
||||
ul_data_aggregation_protocol 5
|
||||
dl_data_aggregation_protocol 5
|
||||
dl_data_aggregation_max_datagrams 32
|
||||
dl_data_aggregation_max_size 16384
|
||||
ul_data_aggregation_max_datagrams 16
|
||||
ul_data_aggregation_max_size 3072
|
||||
qmi_proxy_init finished, rx_urb_size is 16384
|
||||
local server: quectel-qmi-proxy sockfd = 4
|
||||
qmi_start_server: qmi_proxy_server_fd = 4
|
||||
|
||||
# ./quectel-CM -n 2 &
|
||||
# [01-04_02:13:53:053] Quectel_QConnectManager_Linux_V1.4.3
|
||||
[01-04_02:13:53:056] Find /sys/bus/usb/devices/3-1 idVendor=0x2c7c idProduct=0x512
|
||||
[01-04_02:13:53:056] Auto find qmichannel = /dev/cdc-wdm0
|
||||
[01-04_02:13:53:056] Auto find usbnet_adapter = wwan0
|
||||
[01-04_02:13:53:056] qmap_mode = 4, muxid = 0x82, qmap_netcard = wwan0.2
|
||||
[01-04_02:13:53:057] Modem works in QMI mode
|
||||
[01-04_02:13:53:057] qmap_mode = 4, muxid = 0x82, qmap_netcard = wwan0.2
|
||||
+++ ClientFd=5
|
||||
[01-04_02:13:53:058] connect to quectel-qmi-proxy sockfd = 7
|
||||
|
||||
[01-04_02:13:53:058] cdc_wdm_fd = 7
|
||||
+++ ClientFd=5 QMIType=1 ClientId=18
|
||||
[01-04_02:13:53:130] Get clientWDS = 18
|
||||
+++ ClientFd=5 QMIType=2 ClientId=1
|
||||
[01-04_02:13:53:194] Get clientDMS = 1
|
||||
+++ ClientFd=5 QMIType=3 ClientId=2
|
||||
[01-04_02:13:53:258] Get clientNAS = 2
|
||||
+++ ClientFd=5 QMIType=11 ClientId=2
|
||||
[01-04_02:13:53:333] Get clientUIM = 2
|
||||
[01-04_02:13:53:386] requestBaseBandVersion EM12GBATE1127
|
||||
[01-04_02:13:53:642] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[01-04_02:13:53:706] requestGetProfile[2] IMS///0
|
||||
[01-04_02:13:53:770] requestRegistrationState2 MCC: 460, MNC: 11, PS: Attached, DataCap: LTE
|
||||
[01-04_02:13:53:841] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[01-04_02:13:54:058] requestSetupDataCall WdsConnectionIPv4Handle: 0x78a3aba0
|
||||
[243527.630628] net wwan0: link_state 0x0 -> 0x2
|
||||
[01-04_02:13:54:319] ifconfig wwan0 up
|
||||
[01-04_02:13:54:325] ifconfig wwan0.2 up
|
||||
[01-04_02:13:54:330] echo '0x645026c8' > /sys/class/net/wwan0.2/bridge_ipv4
|
||||
|
||||
# udhcpc -i br2
|
||||
udhcpc: started, v1.29.3
|
||||
[243532.653027] br2: port 1(wwan0.2) entered blocking state
|
||||
[243532.658384] br2: port 1(wwan0.2) entered forwarding state
|
||||
udhcpc: sending discover
|
||||
[243532.784337] wwan0.2 PC Mac Address: 96:42:59:a9:f5:e4
|
||||
[243532.794813] net wwan0: rx_pkts=1, rx_len=312
|
||||
udhcpc: sending select for 100.80.38.200
|
||||
[243532.894325] wwan0.2 PC Mac Address: 96:42:59:a9:f5:e4
|
||||
udhcpc: lease of 100.80.38.200 obtained, lease time 7200
|
||||
deleting routers
|
||||
adding dns 202.102.213.68
|
||||
adding dns 61.132.163.68
|
||||
|
||||
|
||||
# ./quectel-CM -n 3 &
|
||||
# [01-04_02:14:03:645] Quectel_QConnectManager_Linux_V1.4.3
|
||||
[01-04_02:14:03:648] Find /sys/bus/usb/devices/3-1 idVendor=0x2c7c idProduct=0x512
|
||||
[01-04_02:14:03:648] Auto find qmichannel = /dev/cdc-wdm0
|
||||
[01-04_02:14:03:648] Auto find usbnet_adapter = wwan0
|
||||
[01-04_02:14:03:649] qmap_mode = 4, muxid = 0x83, qmap_netcard = wwan0.3
|
||||
[01-04_02:14:03:649] Modem works in QMI mode
|
||||
[01-04_02:14:03:649] qmap_mode = 4, muxid = 0x83, qmap_netcard = wwan0.3
|
||||
[01-04_02:14:03:650] connect to quectel-qmi-proxy sockfd = 7
|
||||
|
||||
+++ ClientFd=6
|
||||
[01-04_02:14:03:650] cdc_wdm_fd = 7
|
||||
+++ ClientFd=6 QMIType=1 ClientId=19
|
||||
[01-04_02:14:03:722] Get clientWDS = 19
|
||||
+++ ClientFd=6 QMIType=2 ClientId=2
|
||||
[01-04_02:14:03:786] Get clientDMS = 2
|
||||
+++ ClientFd=6 QMIType=3 ClientId=3
|
||||
[01-04_02:14:03:850] Get clientNAS = 3
|
||||
+++ ClientFd=6 QMIType=11 ClientId=3
|
||||
[01-04_02:14:03:914] Get clientUIM = 3
|
||||
[01-04_02:14:03:978] requestBaseBandVersion EM12GBATE1127
|
||||
[01-04_02:14:04:235] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[01-04_02:14:04:298] requestGetProfile[3] lte///0
|
||||
[01-04_02:14:04:362] requestRegistrationState2 MCC: 460, MNC: 11, PS: Attached, DataCap: LTE
|
||||
[01-04_02:14:04:426] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[01-04_02:14:04:555] requestSetupDataCall WdsConnectionIPv4Handle: 0x78a5c850
|
||||
[243538.126755] net wwan0: link_state 0x2 -> 0x6
|
||||
[01-04_02:14:04:815] ifconfig wwan0 up
|
||||
[01-04_02:14:04:824] ifconfig wwan0.3 up
|
||||
[01-04_02:14:04:829] echo '0x64548ae0' > /sys/class/net/wwan0.3/bridge_ipv4
|
||||
|
||||
# udhcpc -i br3
|
||||
udhcpc: started, v1.29.3
|
||||
[243541.850178] br3: port 1(wwan0.3) entered blocking state
|
||||
[243541.855509] br3: port 1(wwan0.3) entered forwarding state
|
||||
udhcpc: sending discover
|
||||
[243541.976693] wwan0.3 PC Mac Address: 96:42:59:a9:f5:e4
|
||||
udhcpc: sending select for 100.84.138.224
|
||||
[243542.056668] wwan0.3 PC Mac Address: 96:42:59:a9:f5:e4
|
||||
udhcpc: lease of 100.84.138.224 obtained, lease time 7200
|
||||
deleting routers
|
||||
adding dns 202.102.213.68
|
||||
adding dns 61.132.163.68
|
||||
|
||||
# ./quectel-CM -n 1 &
|
||||
# [01-04_02:14:12:742] Quectel_QConnectManager_Linux_V1.4.3
|
||||
[01-04_02:14:12:744] Find /sys/bus/usb/devices/3-1 idVendor=0x2c7c idProduct=0x512
|
||||
[01-04_02:14:12:745] Auto find qmichannel = /dev/cdc-wdm0
|
||||
[01-04_02:14:12:745] Auto find usbnet_adapter = wwan0
|
||||
[01-04_02:14:12:745] qmap_mode = 4, muxid = 0x81, qmap_netcard = wwan0.1
|
||||
[01-04_02:14:12:745] Modem works in QMI mode
|
||||
[01-04_02:14:12:746] qmap_mode = 4, muxid = 0x81, qmap_netcard = wwan0.1
|
||||
[01-04_02:14:12:746] connect to quectel-qmi-proxy sockfd = 7
|
||||
|
||||
+++ ClientFd=7
|
||||
[01-04_02:14:12:746] cdc_wdm_fd = 7
|
||||
+++ ClientFd=7 QMIType=1 ClientId=20
|
||||
[01-04_02:14:12:842] Get clientWDS = 20
|
||||
+++ ClientFd=7 QMIType=2 ClientId=3
|
||||
[01-04_02:14:12:906] Get clientDMS = 3
|
||||
+++ ClientFd=7 QMIType=3 ClientId=4
|
||||
[01-04_02:14:12:970] Get clientNAS = 4
|
||||
+++ ClientFd=7 QMIType=11 ClientId=4
|
||||
[01-04_02:14:13:034] Get clientUIM = 4
|
||||
[01-04_02:14:13:098] requestBaseBandVersion EM12GBATE1127
|
||||
[01-04_02:14:13:354] requestGetSIMStatus SIMStatus: SIM_READY
|
||||
[01-04_02:14:13:418] requestGetProfile[1] ctnet///0
|
||||
[01-04_02:14:13:483] requestRegistrationState2 MCC: 460, MNC: 11, PS: Attached, DataCap: LTE
|
||||
[01-04_02:14:13:546] requestQueryDataCall IPv4ConnectionStatus: DISCONNECTED
|
||||
[01-04_02:14:13:610] requestSetupDataCall WdsConnectionIPv4Handle: 0x78a92b30
|
||||
[243547.182801] net wwan0: link_state 0x6 -> 0x7
|
||||
[01-04_02:14:13:874] ifconfig wwan0 up
|
||||
[01-04_02:14:13:880] ifconfig wwan0.1 up
|
||||
[01-04_02:14:13:885] busybox udhcpc -f -n -q -t 5 -i wwan0.1
|
||||
udhcpc: started, v1.29.3
|
||||
udhcpc: sending discover
|
||||
udhcpc: sending select for 10.175.212.85
|
||||
udhcpc: lease of 10.175.212.85 obtained, lease time 7200
|
||||
[01-04_02:14:14:175] deleting routers
|
||||
[01-04_02:14:14:194] adding dns 202.102.213.68
|
||||
[01-04_02:14:14:195] adding dns 61.132.163.68
|
||||
|
||||
# ifconfig
|
||||
|
||||
br2 Link encap:Ethernet HWaddr 96:42:59:A9:F5:E4
|
||||
inet addr:100.80.38.200 Bcast:100.80.38.207 Mask:255.255.255.240
|
||||
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
|
||||
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:612 (612.0 B) TX bytes:684 (684.0 B)
|
||||
|
||||
br3 Link encap:Ethernet HWaddr 96:42:59:A9:F5:E4
|
||||
inet addr:100.84.138.224 Bcast:100.84.138.255 Mask:255.255.255.192
|
||||
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
|
||||
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:612 (612.0 B) TX bytes:684 (684.0 B)
|
||||
|
||||
|
||||
wwan0 Link encap:Ethernet HWaddr 96:42:59:A9:F5:E4
|
||||
UP BROADCAST RUNNING NOARP MULTICAST MTU:1500 Metric:1
|
||||
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
|
||||
|
||||
wwan0.1 Link encap:Ethernet HWaddr 96:42:59:A9:F5:E4
|
||||
inet addr:10.175.212.85 Bcast:10.175.212.87 Mask:255.255.255.252
|
||||
UP BROADCAST RUNNING NOARP MULTICAST MTU:1500 Metric:1
|
||||
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:612 (612.0 B) TX bytes:664 (664.0 B)
|
||||
|
||||
wwan0.2 Link encap:Ethernet HWaddr 96:42:59:A9:F5:E4
|
||||
UP BROADCAST RUNNING NOARP MULTICAST MTU:1500 Metric:1
|
||||
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:612 (612.0 B) TX bytes:664 (664.0 B)
|
||||
|
||||
wwan0.3 Link encap:Ethernet HWaddr 96:42:59:A9:F5:E4
|
||||
UP BROADCAST RUNNING NOARP MULTICAST MTU:1500 Metric:1
|
||||
RX packets:2 errors:0 dropped:0 overruns:0 frame:0
|
||||
TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
|
||||
collisions:0 txqueuelen:1000
|
||||
RX bytes:612 (612.0 B) TX bytes:664 (664.0 B)
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,428 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2023, The Linux Foundation. All rights reserved.
|
||||
|
||||
This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General
|
||||
Public licenseas published byFree Software Foundation; either version 2theof the License,(at your option)
|
||||
any later version.O1
|
||||
This program isdistributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the
|
||||
implied warranty ofOr FITNESS FOR A PARTICULAR PURPOSE.MERCHANTABILITYSee theGNU General Public License
|
||||
for more details.
|
||||
You should have received a copy of the GNU General Public licensealong withthis program; if not, write to
|
||||
the Free SoftwareFoundation, Inc.r51 Franklin Street,Fifth Floor,Boston,MA 02110-1301,USA.
|
||||
|
||||
Based on version modification, the author is Quectel <fae-support@quectel.com>
|
||||
*/
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/hashtable.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/ip.h>
|
||||
#include <qca-nss-drv/nss_api_if.h>
|
||||
|
||||
#include <linux/rmnet_nss.h>
|
||||
|
||||
#define RMNET_NSS_HASH_BITS 8
|
||||
#define hash_add_ptr(table, node, key) \
|
||||
hlist_add_head(node, &table[hash_ptr(key, HASH_BITS(table))])
|
||||
|
||||
static DEFINE_HASHTABLE(rmnet_nss_ctx_hashtable, RMNET_NSS_HASH_BITS);
|
||||
|
||||
struct rmnet_nss_ctx {
|
||||
struct hlist_node hnode;
|
||||
struct net_device *rmnet_dev;
|
||||
struct nss_rmnet_rx_handle *nss_ctx;
|
||||
};
|
||||
|
||||
enum __rmnet_nss_stat {
|
||||
RMNET_NSS_RX_ETH,
|
||||
RMNET_NSS_RX_FAIL,
|
||||
RMNET_NSS_RX_NON_ETH,
|
||||
RMNET_NSS_RX_BUSY,
|
||||
RMNET_NSS_TX_NO_CTX,
|
||||
RMNET_NSS_TX_SUCCESS,
|
||||
RMNET_NSS_TX_FAIL,
|
||||
RMNET_NSS_TX_NONLINEAR,
|
||||
RMNET_NSS_TX_BAD_IP,
|
||||
RMNET_NSS_EXCEPTIONS,
|
||||
RMNET_NSS_EX_BAD_HDR,
|
||||
RMNET_NSS_EX_BAD_IP,
|
||||
RMNET_NSS_EX_SUCCESS,
|
||||
RMNET_NSS_TX_BAD_FRAGS,
|
||||
RMNET_NSS_TX_LINEARIZE_FAILS,
|
||||
RMNET_NSS_TX_NON_ZERO_HEADLEN_FRAGS,
|
||||
RMNET_NSS_TX_BUSY_LOOP,
|
||||
RMNET_NSS_NUM_STATS,
|
||||
};
|
||||
|
||||
static unsigned long rmnet_nss_stats[RMNET_NSS_NUM_STATS];
|
||||
|
||||
#define RMNET_NSS_STAT(name, counter, desc) \
|
||||
module_param_named(name, rmnet_nss_stats[counter], ulong, 0444); \
|
||||
MODULE_PARM_DESC(name, desc)
|
||||
|
||||
RMNET_NSS_STAT(rmnet_nss_rx_ethernet, RMNET_NSS_RX_ETH,
|
||||
"Number of Ethernet headers successfully removed");
|
||||
RMNET_NSS_STAT(rmnet_nss_rx_fail, RMNET_NSS_RX_FAIL,
|
||||
"Number of Ethernet headers that could not be removed");
|
||||
RMNET_NSS_STAT(rmnet_nss_rx_non_ethernet, RMNET_NSS_RX_NON_ETH,
|
||||
"Number of non-Ethernet packets received");
|
||||
RMNET_NSS_STAT(rmnet_nss_rx_busy, RMNET_NSS_RX_BUSY,
|
||||
"Number of packets dropped decause rmnet_data device was busy");
|
||||
RMNET_NSS_STAT(rmnet_nss_tx_slow, RMNET_NSS_TX_NO_CTX,
|
||||
"Number of packets sent over non-NSS-accelerated rmnet device");
|
||||
RMNET_NSS_STAT(rmnet_nss_tx_fast, RMNET_NSS_TX_SUCCESS,
|
||||
"Number of packets sent over NSS-accelerated rmnet device");
|
||||
RMNET_NSS_STAT(rmnet_nss_tx_fail, RMNET_NSS_TX_FAIL,
|
||||
"Number of packets that NSS could not transmit");
|
||||
RMNET_NSS_STAT(rmnet_nss_tx_nonlinear, RMNET_NSS_TX_NONLINEAR,
|
||||
"Number of non linear sent over NSS-accelerated rmnet device");
|
||||
RMNET_NSS_STAT(rmnet_nss_tx_invalid_ip, RMNET_NSS_TX_BAD_IP,
|
||||
"Number of ingress packets with invalid IP headers");
|
||||
RMNET_NSS_STAT(rmnet_nss_tx_invalid_frags, RMNET_NSS_TX_BAD_FRAGS,
|
||||
"Number of ingress packets with invalid frag format");
|
||||
RMNET_NSS_STAT(rmnet_nss_tx_linearize_fail, RMNET_NSS_TX_LINEARIZE_FAILS,
|
||||
"Number of ingress packets where linearize in tx fails");
|
||||
RMNET_NSS_STAT(rmnet_nss_tx_exceptions, RMNET_NSS_EXCEPTIONS,
|
||||
"Number of times our DL exception handler was invoked");
|
||||
RMNET_NSS_STAT(rmnet_nss_exception_non_ethernet, RMNET_NSS_EX_BAD_HDR,
|
||||
"Number of non-Ethernet exception packets");
|
||||
RMNET_NSS_STAT(rmnet_nss_exception_invalid_ip, RMNET_NSS_EX_BAD_IP,
|
||||
"Number of exception packets with invalid IP headers");
|
||||
RMNET_NSS_STAT(rmnet_nss_exception_success, RMNET_NSS_EX_SUCCESS,
|
||||
"Number of exception packets handled successfully");
|
||||
RMNET_NSS_STAT(rmnet_nss_tx_non_zero_headlen_frags, RMNET_NSS_TX_NON_ZERO_HEADLEN_FRAGS,
|
||||
"Number of packets with non zero headlen");
|
||||
RMNET_NSS_STAT(rmnet_nss_tx_busy_loop, RMNET_NSS_TX_BUSY_LOOP,
|
||||
"Number of times tx packets busy looped");
|
||||
|
||||
static void rmnet_nss_inc_stat(enum __rmnet_nss_stat stat)
|
||||
{
|
||||
if (stat >= 0 && stat < RMNET_NSS_NUM_STATS)
|
||||
rmnet_nss_stats[stat]++;
|
||||
}
|
||||
|
||||
static struct rmnet_nss_ctx *rmnet_nss_find_ctx(struct net_device *dev)
|
||||
{
|
||||
struct rmnet_nss_ctx *ctx;
|
||||
struct hlist_head *bucket;
|
||||
u32 hash;
|
||||
|
||||
hash = hash_ptr(dev, HASH_BITS(rmnet_nss_ctx_hashtable));
|
||||
bucket = &rmnet_nss_ctx_hashtable[hash];
|
||||
hlist_for_each_entry(ctx, bucket, hnode) {
|
||||
if (ctx->rmnet_dev == dev)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void rmnet_nss_free_ctx(struct rmnet_nss_ctx *ctx)
|
||||
{
|
||||
if (ctx) {
|
||||
hash_del(&ctx->hnode);
|
||||
nss_rmnet_rx_xmit_callback_unregister(ctx->nss_ctx);
|
||||
nss_rmnet_rx_destroy_sync(ctx->nss_ctx);
|
||||
kfree(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
/* Pull off an ethernet header, if possible */
|
||||
static int rmnet_nss_ethhdr_pull(struct sk_buff *skb)
|
||||
{
|
||||
if (!skb->protocol || skb->protocol == htons(ETH_P_802_3)) {
|
||||
void *ret = skb_pull(skb, sizeof(struct ethhdr));
|
||||
|
||||
rmnet_nss_inc_stat((ret) ? RMNET_NSS_RX_ETH :
|
||||
RMNET_NSS_RX_FAIL);
|
||||
return !ret;
|
||||
}
|
||||
|
||||
rmnet_nss_inc_stat(RMNET_NSS_RX_NON_ETH);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy headers to linear section for non linear packets */
|
||||
static int rmnet_nss_adjust_header(struct sk_buff *skb)
|
||||
{
|
||||
struct iphdr *iph;
|
||||
skb_frag_t *frag;
|
||||
int bytes = 0;
|
||||
u8 transport;
|
||||
|
||||
if (skb_shinfo(skb)->nr_frags != 1) {
|
||||
rmnet_nss_inc_stat(RMNET_NSS_TX_BAD_FRAGS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (skb_headlen(skb)) {
|
||||
rmnet_nss_inc_stat(RMNET_NSS_TX_NON_ZERO_HEADLEN_FRAGS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
frag = &skb_shinfo(skb)->frags[0];
|
||||
|
||||
iph = (struct iphdr *)(skb_frag_address(frag));
|
||||
|
||||
if (iph->version == 4) {
|
||||
bytes = iph->ihl*4;
|
||||
transport = iph->protocol;
|
||||
} else if (iph->version == 6) {
|
||||
struct ipv6hdr *ip6h = (struct ipv6hdr *)iph;
|
||||
|
||||
bytes = sizeof(struct ipv6hdr);
|
||||
/* Dont have to account for extension headers yet */
|
||||
transport = ip6h->nexthdr;
|
||||
} else {
|
||||
rmnet_nss_inc_stat(RMNET_NSS_TX_BAD_IP);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (transport == IPPROTO_TCP) {
|
||||
struct tcphdr *th;
|
||||
|
||||
th = (struct tcphdr *)((u8 *)iph + bytes);
|
||||
bytes += th->doff * 4;
|
||||
} else if (transport == IPPROTO_UDP) {
|
||||
bytes += sizeof(struct udphdr);
|
||||
} else {
|
||||
/* cant do anything else here unfortunately so linearize */
|
||||
if (skb_linearize(skb)) {
|
||||
rmnet_nss_inc_stat(RMNET_NSS_TX_LINEARIZE_FAILS);
|
||||
return -EINVAL;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bytes > skb_frag_size(frag)) {
|
||||
rmnet_nss_inc_stat(RMNET_NSS_TX_BAD_FRAGS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
skb_push(skb, bytes);
|
||||
memcpy(skb->data, iph, bytes);
|
||||
|
||||
/* subtract to account for skb_push */
|
||||
skb->len -= bytes;
|
||||
|
||||
frag->page_offset += bytes;
|
||||
skb_frag_size_sub(frag, bytes);
|
||||
|
||||
/* subtract to account for skb_frag_size_sub */
|
||||
skb->data_len -= bytes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Main downlink handler
|
||||
* Looks up NSS contex associated with the device. If the context is found,
|
||||
* we add a dummy ethernet header with the approriate protocol field set,
|
||||
* the pass the packet off to NSS for hardware acceleration.
|
||||
*/
|
||||
int rmnet_nss_tx(struct sk_buff *skb)
|
||||
{
|
||||
struct ethhdr *eth;
|
||||
struct rmnet_nss_ctx *ctx;
|
||||
struct net_device *dev = skb->dev;
|
||||
nss_tx_status_t rc;
|
||||
unsigned int len;
|
||||
u8 version;
|
||||
|
||||
if (skb_is_nonlinear(skb)) {
|
||||
if (rmnet_nss_adjust_header(skb))
|
||||
goto fail;
|
||||
else
|
||||
rmnet_nss_inc_stat(RMNET_NSS_TX_NONLINEAR);
|
||||
}
|
||||
|
||||
version = ((struct iphdr *)skb->data)->version;
|
||||
|
||||
ctx = rmnet_nss_find_ctx(dev);
|
||||
if (!ctx) {
|
||||
rmnet_nss_inc_stat(RMNET_NSS_TX_NO_CTX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
eth = (struct ethhdr *)skb_push(skb, sizeof(*eth));
|
||||
memset(ð->h_dest, 0, ETH_ALEN * 2);
|
||||
if (version == 4) {
|
||||
eth->h_proto = htons(ETH_P_IP);
|
||||
} else if (version == 6) {
|
||||
eth->h_proto = htons(ETH_P_IPV6);
|
||||
} else {
|
||||
rmnet_nss_inc_stat(RMNET_NSS_TX_BAD_IP);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
skb->protocol = htons(ETH_P_802_3);
|
||||
/* Get length including ethhdr */
|
||||
len = skb->len;
|
||||
|
||||
transmit:
|
||||
rc = nss_rmnet_rx_tx_buf(ctx->nss_ctx, skb);
|
||||
if (rc == NSS_TX_SUCCESS) {
|
||||
/* Increment rmnet_data device stats.
|
||||
* Don't call rmnet_data_vnd_rx_fixup() to do this, as
|
||||
* there's no guarantee the skb pointer is still valid.
|
||||
*/
|
||||
dev->stats.rx_packets++;
|
||||
dev->stats.rx_bytes += len;
|
||||
rmnet_nss_inc_stat(RMNET_NSS_TX_SUCCESS);
|
||||
return 0;
|
||||
} else if (rc == NSS_TX_FAILURE_QUEUE) {
|
||||
rmnet_nss_inc_stat(RMNET_NSS_TX_BUSY_LOOP);
|
||||
goto transmit;
|
||||
}
|
||||
|
||||
fail:
|
||||
rmnet_nss_inc_stat(RMNET_NSS_TX_FAIL);
|
||||
kfree_skb(skb);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Called by NSS in the DL exception case.
|
||||
* Since the packet cannot be sent over the accelerated path, we need to
|
||||
* handle it. Remove the ethernet header and pass it onward to the stack
|
||||
* if possible.
|
||||
*/
|
||||
void rmnet_nss_receive(struct net_device *dev, struct sk_buff *skb,
|
||||
struct napi_struct *napi)
|
||||
{
|
||||
rmnet_nss_inc_stat(RMNET_NSS_EXCEPTIONS);
|
||||
|
||||
if (!skb)
|
||||
return;
|
||||
|
||||
if (rmnet_nss_ethhdr_pull(skb)) {
|
||||
rmnet_nss_inc_stat(RMNET_NSS_EX_BAD_HDR);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* reset header pointers */
|
||||
skb_reset_transport_header(skb);
|
||||
skb_reset_network_header(skb);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
/* reset packet type */
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
|
||||
skb->dev = dev;
|
||||
|
||||
/* reset protocol type */
|
||||
switch (skb->data[0] & 0xF0) {
|
||||
case 0x40:
|
||||
skb->protocol = htons(ETH_P_IP);
|
||||
break;
|
||||
case 0x60:
|
||||
skb->protocol = htons(ETH_P_IPV6);
|
||||
break;
|
||||
default:
|
||||
rmnet_nss_inc_stat(RMNET_NSS_EX_BAD_IP);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
rmnet_nss_inc_stat(RMNET_NSS_EX_SUCCESS);
|
||||
|
||||
/* Set this so that we dont loop around netif_receive_skb */
|
||||
|
||||
skb->cb[0] = 1;
|
||||
|
||||
netif_receive_skb(skb);
|
||||
return;
|
||||
|
||||
drop:
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
/* Called by NSS in the UL acceleration case.
|
||||
* We are guaranteed to have an ethernet packet here from the NSS hardware,
|
||||
* We need to pull the header off and invoke our ndo_start_xmit function
|
||||
* to handle transmitting the packet to the network stack.
|
||||
*/
|
||||
void rmnet_nss_xmit(struct net_device *dev, struct sk_buff *skb)
|
||||
{
|
||||
netdev_tx_t ret;
|
||||
|
||||
skb_pull(skb, sizeof(struct ethhdr));
|
||||
rmnet_nss_inc_stat(RMNET_NSS_RX_ETH);
|
||||
|
||||
/* NSS takes care of shaping, so bypassing Qdiscs like this is OK */
|
||||
ret = dev->netdev_ops->ndo_start_xmit(skb, dev);
|
||||
if (unlikely(ret == NETDEV_TX_BUSY)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
rmnet_nss_inc_stat(RMNET_NSS_RX_BUSY);
|
||||
}
|
||||
}
|
||||
|
||||
/* Create and register an NSS context for an rmnet_data device */
|
||||
int rmnet_nss_create_vnd(struct net_device *dev)
|
||||
{
|
||||
struct rmnet_nss_ctx *ctx;
|
||||
|
||||
ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->rmnet_dev = dev;
|
||||
ctx->nss_ctx = nss_rmnet_rx_create_sync_nexthop(dev, NSS_N2H_INTERFACE,
|
||||
NSS_C2C_TX_INTERFACE);
|
||||
if (!ctx->nss_ctx) {
|
||||
kfree(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nss_rmnet_rx_register(ctx->nss_ctx, rmnet_nss_receive, dev);
|
||||
nss_rmnet_rx_xmit_callback_register(ctx->nss_ctx, rmnet_nss_xmit);
|
||||
hash_add_ptr(rmnet_nss_ctx_hashtable, &ctx->hnode, dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unregister and destroy the NSS context for an rmnet_data device */
|
||||
int rmnet_nss_free_vnd(struct net_device *dev)
|
||||
{
|
||||
struct rmnet_nss_ctx *ctx;
|
||||
|
||||
ctx = rmnet_nss_find_ctx(dev);
|
||||
rmnet_nss_free_ctx(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct rmnet_nss_cb rmnet_nss = {
|
||||
.nss_create = rmnet_nss_create_vnd,
|
||||
.nss_free = rmnet_nss_free_vnd,
|
||||
.nss_tx = rmnet_nss_tx,
|
||||
};
|
||||
|
||||
int __init rmnet_nss_init(void)
|
||||
{
|
||||
pr_err("%s(): initializing rmnet_nss\n", __func__);
|
||||
RCU_INIT_POINTER(rmnet_nss_callbacks, &rmnet_nss);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __exit rmnet_nss_exit(void)
|
||||
{
|
||||
struct hlist_node *tmp;
|
||||
struct rmnet_nss_ctx *ctx;
|
||||
int bkt;
|
||||
|
||||
pr_err("%s(): exiting rmnet_nss\n", __func__);
|
||||
RCU_INIT_POINTER(rmnet_nss_callbacks, NULL);
|
||||
|
||||
/* Tear down all NSS contexts */
|
||||
hash_for_each_safe(rmnet_nss_ctx_hashtable, bkt, tmp, ctx, hnode)
|
||||
rmnet_nss_free_ctx(ctx);
|
||||
}
|
||||
|
||||
#if 0
|
||||
MODULE_LICENSE("GPL v2");
|
||||
module_init(rmnet_nss_init);
|
||||
module_exit(rmnet_nss_exit);
|
||||
#endif
|
||||
Loading…
Reference in New Issue
Block a user