一、模拟网卡简介

在 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. perl遍历哈希的所有健和值

    my %h=("001",{name,"李白",age,"18",height,"185",weight,"6 ...

  2. 搭建K8S集群前置条件

    搭建K8S集群 搭建k8s环境平台规划 单master集群 单个master节点,然后管理多个node节点 多master集群 多个master节点,管理多个node节点,同时中间多了一个负载均衡的过 ...

  3. 从 WinDbg 角度理解 .NET7 的AOT玩法

    一:背景 1.讲故事 前几天 B 站上有位朋友让我从高级调试的角度来解读下 .NET7 新出来的 AOT,毕竟这东西是新的,所以这一篇我就简单摸索一下. 二:AOT 的几个问题 1. 如何在 .NET ...

  4. java集合类 collection接口,List集合

    java集合类:collection接口,List集合 在java.util包中提供了一些集合类,集合类又被称为容器,常用的有List集合,Set集合,Map集合.下面将介绍collection接口和 ...

  5. 动态规划篇——DP问题

    动态规划篇--DP问题 本次我们介绍动态规划篇的DP问题,我们会从下面几个角度来介绍: 区间DP 计数DP 树状DP 记忆化搜索 区间DP 我们通过一个案例来讲解区间DP: /*题目展示*/ 题目名: ...

  6. 9 STL-queue

    ​ 重新系统学习c++语言,并将学习过程中的知识在这里抄录.总结.沉淀.同时希望对刷到的朋友有所帮助,一起加油哦!  生命就像一朵花,要拼尽全力绽放!死磕自个儿,身心愉悦! 写在前面,本篇章主要介绍S ...

  7. 关于sublime-build的配置详解

    前言 sublime-build 可以做很多自定义的构建命令,然后用其执行代码,十分方便! 开始 这里我就简单的用python 的配置来详细说明各个配置项目的作用 { "shell_cmd& ...

  8. 轻松玩转sed

    sed处理文本方法 1.文本或管道输入 2.读入一行到模式控件 3.sed命令处理 4.输出到屏幕 所以 sed是一个流处理编辑器 sed一次处理一行内容 sed不改变文件内容(可以通过重定向改变文件 ...

  9. uniCloud云开发入门以及对传统开发方式的思考

    事情缘由 作为选修了移动互联网应用的一员,老师讲的什么JS基础,还有ES6和uniapp,当然是没怎么听,因为是之前大二的时候都大概看过. 但是快到期末,老师讲了云开发,并且布置了与此相关的大作业,自 ...

  10. 【每日一题】【迭代器,泛型】2022年1月8日-NC93 设计LRU缓存结构

    描述设计LRU(最近最少使用)缓存结构,该结构在构造时确定大小,假设大小为 k ,并有如下两个功能1. set(key, value):将记录(key, value)插入该结构2. get(key): ...