一、模拟网卡简介

在 Linux 通过 usb 模拟网卡时,有四种方式:

1. 使用 usb gadget rndis
2. 使用 usb gadget ecm
3. 使用 usb gadget ncm
4. 使用 usb gadget eem

rndis:是微软公司制定的协议规范, 不过似乎规范不完整, 引起 rndis host 驱动作者的强烈反对。lichee\linux-4.9\drivers\net\usb\rndis_host.c

ecm:传输的是纯粹的以太网包,一次USB传输只包含一个以太网帧,因此吞吐量较低,实测在 6MB/s 左右,Windows 的驱动不太好找,Ubuntu 可以直接支持。

ncm:ecm 的改进版本,每个NCM报文可以包含多个以太网帧,这种特性称为报文聚合,即调用一次URB可以发送或者接收多个IP报文,实测在 17MB/s 左右,Windows 自带有驱动(本文在 Win10 平台实测通过),Ubuntu 可以直接支持。

eem:了解不多。

二、问题现象

接入 Windows 之后,启用该网卡,会不停的输出 "Wrong NDP SIGN",并且无法相互 ping 通。

检查发现因为 ncm->ndp_sign 的值等于 0,未被正确赋值。(f_ncm.c)

分析发现 ncm->ndp_sign 只有在设置 CRC 模式的时候才会拷贝 ncm->parser_opts,由此可见 Win10 的 ncm 驱动并未主动配置 CRC 模式引起。

经调试发现 USB_CDC_SET_NTB_FORMAT 会被触发,会设置 ncm->parser_opts,那么如果也顺道一同拷贝 ncm->ndp_sign 应该就能解决问题。

实测确实解决了问题,既然 f_ncm.c 驱动有缺陷,那么很有可能最新的内核已经解决了此问题,查看了最新内核的驱动(v5.18),发现已经调整了 ncm->ndp_sign 顺序,在 switch 语句后面进行赋值,同样也能解决问题。

f_ncm.c « function « gadget « usb « drivers - kernel/git/torvalds/linux.git - Linux kernel source tree

三、修复补丁

由于 5.9.y 相对于 4.9 版本改动较大,这里发出一个针对 4.9 版本修复此问题的最小改动补丁。

diff --git a/lichee/linux-4.9/drivers/usb/gadget/function/f_ncm.c b/lichee/linux-4.9/drivers/usb/gadget/function/f_ncm.c
old mode 100644
new mode 100755
index 639603722..278580b5a
--- a/lichee/linux-4.9/drivers/usb/gadget/function/f_ncm.c
+++ b/lichee/linux-4.9/drivers/usb/gadget/function/f_ncm.c
@@ -828,7 +828,7 @@ static int ncm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
default:
goto invalid;
}
- ncm->ndp_sign = ncm->parser_opts->ndp_sign | ndp_hdr_crc;
+ // ncm->ndp_sign = ncm->parser_opts->ndp_sign | ndp_hdr_crc;
value = 0;
break;
}
@@ -846,6 +846,9 @@ static int ncm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
w_value, w_index, w_length);
} + // lmx: fix ncm_unwrap_ntb() --> ncm->ndp_sign to==0, generate "Wrong NDP SIGN" Bug
+ ncm->ndp_sign = ncm->parser_opts->ndp_sign | (ncm->is_crc ? NCM_NDP_HDR_CRC : 0);
+
/* respond with data transfer or status phase? */
if (value >= 0) {
DBG(cdev, "ncm req%02x.%02x v%04x i%04x l%d\n",

实测吞吐量:

【随笔记】linux usb gadget ncm wrong ndp sign 问题修复的更多相关文章

  1. Linux usb gadget框架概述

    很幸运,在公司开发了gadget相关驱动,总结下来,大大小小开发了四个与gadget相关的驱动,字符驱动.g_multi.g_ether.g_zero,在这里把自己对gadget的开发中自己的感悟记录 ...

  2. Android USB gadget configfs学习笔记总结

    1.一个config_item 是通过显式用户空间mkdir操作创建的,通过rmdir销毁.属性(文件)在mkdir之后出现,可以通过read和write读取或修改属性文件.与sysfs一样,read ...

  3. Linux USB ECM Gadget 驱动介绍

    ​1 USB ECM介绍 USB ECM,属于USB-IF定义的CDC(Communication Device Class)下的一个子类:Ethernet Networking Control Mo ...

  4. Android USB gadget框架学习笔记

    一 Gadget框架结构 kernel/drivers/usb/gadget,这个目录是android下usbgadget的主要目录. Gadget功能组织单元:主要文件android.c,usb g ...

  5. linux USB 编程

    Linux USB架构 可以看出一个USB体系需要4个驱动:USB设备驱动(主要编写这部分),USB主控制器驱动,Gadget驱动,UDC驱动. USB主要有4个功能: MassStorage:大容量 ...

  6. Linux USB Project

    转自:http://www.linux-usb.org/ Welcome to the home of the Linux USB Project This web site was created ...

  7. Linux USB驱动

    linux usb 驱动详解 一 http://blog.163.com/cl2006ky@126/blog/static/87195173201131245557340/ USB设备驱动开发-USB ...

  8. Linux usb子系统(二):USB设备驱动usb-skeleton.c

    usb驱动分为通过usbfs操作设备的用户空间驱动,内核空间的内核驱动.两者不能同时进行,否则容易引发对共享资源访问的问题,死锁!使用了内核驱动,就不能在usbfs里驱动该设备. 下面转载的一篇分析u ...

  9. Linux usb子系统(一) _写一个usb鼠标驱动

    USB总线是一种典型的热插拔的总线标准,由于其优异的性能几乎成为了当下大小设备中的标配. USB的驱动可以分为3类:SoC的USB控制器的驱动,主机端USB设备的驱动,设备上的USB Gadget驱动 ...

  10. USB gadget 驱动 printer.c 分析

    1. modprobe g_printer idVendor=0x0525 idProduct=0xa4a8 modprobe后面也可以加模块参数 2. prn_example从stdout获取数据然 ...

随机推荐

  1. Java多线程(7):JUC(上)

    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 前面把线程相关的生命周期.关键字.线程池(ThreadPool).ThreadLocal.CAS.锁和AQS都讲完了,现在就剩下怎么来用多线程了 ...

  2. Java Stream流的使用

    流相关的方法可以分为三种类型,分别是:获取Stream流.中间方法.终结方法.中间方法会返回当前流,可以方便的进行链式调用. 流不可重复使用,否则会报错: java.lang.IllegalState ...

  3. 抠网页标题栏logo(图标)

    1.打开自己需要抠的网页,例如百度页面 2.在这个网页链接后面+" /favicon.ico " 就可以提取ico图片 3.回车进去,右键鼠标,选择另存为图片就可以成功保存网页中的 ...

  4. Centos 7.6 安装部署 openGauss 3.1.0 企业版一主两备集群

    一.安装环境设置 1.1 硬件环境 名称 最低配置 建议配置 测试配置 服务器数量 3 略 略 硬盘 * 至少1GB用于安装openGauss的应用程序.* 每个主机需大约300MB用于元数据存储.* ...

  5. HSSFSheet XSSFWorkbook SXSSF Java读取Excel数据

    HSSF是POI工程对Excel 97(-2007)文件操作的纯Java实现 XSSF是POI工程对Excel 2007 OOXML (.xlsx)文件操作的纯Java实现 SXSSF通过一个滑动窗口 ...

  6. 【Java EE】Day05 JDBC概念、对象、控制事务

    一.基本概念 1.概念 Java Database Connectivity:Java数据库连接 2.本质 SUN公司提供的操作所有关系型数据库的规则,是一套接口 各厂商实现此接口,提供相应的驱动ja ...

  7. 锂电池升压芯片,IC电路图资料

    锂电池常规的供电电压范围是3V-4.2V之间,标称电压是3.7V.锂电池具有宽供电电压范围,需要进行降压或者升压到固定电压值,进行恒压输出,同时根据输出功率的不同,(输出功率=输出电压乘以输出电流). ...

  8. 带你了解基于Ploto构建自动驾驶平台

    摘要:华为云Solution as Code推出基于Ploto构建自动驾驶平台解决方案. 本文分享自华为云社区<基于Ploto构建自动驾驶平台>,作者:阿米托福 . 2022年6月15日, ...

  9. day34-JSON&Ajax02

    JSON&Ajax02 1.Ajax基本介绍 1.1Ajax是什么 AJAX 即"Asynchronous JavaScript And XML"(异步JavaScript ...

  10. 【Redis场景1】用户登录注册

    细节回顾: 关于cookie和session不熟悉的朋友: 建议阅读该博客:https://www.cnblogs.com/ityouknow/p/10856177.html 执行流程: 在单体模式下 ...