我又回到了FreeBSD无线堆栈和802.11ac的工作中

2020-07-16 15:02:08

嗨!。是的,自从我在这里发帖以来已经有一段时间了,是的,我已经有一段时间没有积极地研究FreeBSD的无线堆栈了。生活已经..。嗯,生活。我在2015年开始了ath10k端口。我没想到要花5年时间,但我们到了。自2015年以来,我的生活发生了很大变化,我在2015年做的很多事情都有一段时间没有乐趣了。但是星辰已经排成一条直线,这又是一件有趣的事,所以我就来了。这就是现在的情况。First Up-If_Run。这是Ralink(现在的联发科)11abgn USB驱动程序,用于他们在联发科收购之前生产的产品。一位名叫Ashish Gupta的贡献者出现在efnet的#FreeBSD-wifi IRC频道上,开始致力于11n对if_run的支持,他让它达到了基础工作的程度-我拿着它跑了足够多的时间,获得了20 MHz的11n支持。原来我有几个合适的网卡可以用来测试,嗯,就这样发生了。我非常高兴阿什什来了,让11n在另一个NIC上工作。IF_RUN TODO列表(欢迎任何人参与):我们需要通过固件接口让11n TX聚合工作-看起来Linux驱动程序拥有我们需要的所有位,而且它不需要Net80211中的重传支持。如果我们正确设置描述符,固件将完成所有操作。

下一位是Net80211。所以,net80211有基本的11ac位,即使人们认为它不在那里。它还不知道MU-MIMO流,但如果驱动程序和管理域支持它,它将成为基本的11ac AP和STA。

然而,随着我实现更多的ath10k端口,我发现越来越多真正需要在net80211中的位丢失了。

硬件在硬件/固件中执行A-MPDU和A-MSDU解封,将单独解密和解封的帧推送到驱动程序。它支持原生WiFi和802.3(以太网)封装,目前我们只支持原生WiFi。(注-Net80211也支持802.3;一旦驱动程序着陆,我将尝试使用它。)。

我添加了对使用ath10k提供的A-MPDU/A-MSDU帧处理解密卸载的支持(这里根本没有PN/MIC,都是在固件/硬件中完成的!)。这样我们就可以减少交通堵塞。然而,当我最后一次尝试这一点时,接收吞吐量显然很糟糕。我还添加了A-MSDU卸载支持,其中我们不会丢弃具有相同接收802.11序列号的A-MSDU帧。然而.。

原来,我的Mac在11ac的A-MPDU中做A-MSDU,而net80211接收A-MPDU重新排序正在忠实地丢弃所有具有相同接收802.11序列号的A-MSDU帧。因此,TCP只会看到大量的数据包丢失,并以一种巨大的方式降低吞吐量。实现此功能需要在重新排序队列中缓冲A-MPDU子帧中的所有A-MSDU帧,而不是丢弃它们,然后将它们重新排序,就像它们是单个帧一样。

因此,我修改了接收重新排序逻辑,以重新排序mbuf的队列,而不是mbuf,并打补丁以允许将多个mbuf排队,只要它们被适当地标记为单个A-MPDU子帧中的A-MSDU。现在接收通信量速率是它应该在的位置(>;300mbit UDP/TCP。)。哟。

我不想在Atheros 11abgn驱动程序中实现完全的U-apsd支持,因为它需要大量的驱动工作才能正确完成,但在net80211中实际的U-apsd协商支持要容易得多。如果NIC支持U-apsd卸载(就像ath10k一样),那么我只需适当地填充WME QoS字段,并调用驱动程序来通知它们U-apsd的更改。

目前,Net80211;不支持用于请求明确QoS要求的客户端的Add-TS/Del-TS方法。

有一组net80211状态仍然是全局的,而不是按VAP的。这在旧世界是有道理的-在驱动程序或Net80211端执行操作的NIC是在软件中驱动的,而不是在固件中驱动的,所以像当前通道";、";短/长前导";等都是全局状态。然而,后来的NIC将各种事情卸载到固件中,现在可以开始做一些有趣的事情,比如扫描的后台频道切换,STA和P2P-AP/P2P-STA之间的后台频道切换。因此,应该针对每个VAP而不是全局保留许多状态,以便为给定的VAP设置正确的标志和IE。

我已经开始将此状态迁移到每个VAP字段,而不是全局字段,但它显示了第二个缺点-因为它是全局的,我们没有明确跟踪每个通道的这些内容。好的,这需要更多的解释。

假设您使用的是2 GHz信道,您需要确定是否关心11n、11g或11b客户端。如果您只查看和服务11n客户端,那么您应该使用较短的插槽时间、较短的前同步码,并且不需要RTS/CTS保护来与11n之前的客户端进行互操作。

11g客户端不需要与11b互操作,只需要11n-因此它不需要RTS/CTS。它仍然可以使用短前导码和短时隙时间。但11n客户端需要互操作,因此它需要将保护模式切换到传统模式-并且它将执行RTS/CTS保护。

在这一点上,11G保护开始生效;每个人都执行RTS/CTS保护,并且较长的前导/时隙时间开始生效。

现在-这是VAP的属性,还是通道的属性?从技术上讲,它是频道的财产。如果该通道上的任何VAP看到11b或11g客户端,则所有VAP都需要转换到更新保护模式。

我将所有这些迁移到每个VAP,但我保留了当前使用它的所有驱动程序的全局状态。ath10k驱动程序现在使用Per-VAP状态进行上述操作,极大地简化了操作(并完成了驱动程序中的TODO项!)

我收到了来自Bjorn和Geramy的一堆反馈和拉请求,指出了ath10k中的锁顺序/死锁问题。我正在慢慢地处理它们;从Linux到FreeBSD的直接转换显示了我们的锁定以及驱动程序线程运行方式/时间的不同之处。改天我会对此大喊大叫的。

加密密钥编程是使用固件调用编程的,但net80211目前希望它们同步完成。如果不将net80211的锁更改为全部为SX锁,我们就无法在net80211密钥更新中睡觉(老实说,我认为这是一个糟糕的解决方案,因为它掩盖了诚实地说应该是异步的非异步代码。)。无论如何,它和节点更新都是使用延迟调用完成的-但这需要我获取加密密钥内容的完整副本。事实证明,net80211可以非常快速地回收密钥内容-包括隐藏在ieee80211_节点中的密钥。这修复了密钥重新编程和删除-它有时会向固件发送垃圾。哎呦。

那么下一步是什么呢?嗯,我想让ath10k车手落地!在我可以这样做之前,在net80211和驱动程序中还有一大堆事情要做。

是的,我添加了-但仅限于FCC。我没有将它们添加到所有其他监管领域代码中。这是大量的工作,因为这个文件是如何实现的,我喜欢这里的帮助。

我希望确保我们至少可以支持关联到MU-MIMO AP。我认为ath10k在固件中做到了这一点,但是我们需要支持IE通知。

现在,net80211将在添加节点或发送密钥更新之后立即传输帧-它假设驱动程序在返回之前已经完成了更新。对于软件驱动的网卡,如11ac之前的Atheros芯片,这是正确的,但对于所有基于USB和更新固件的设备,这肯定不适用。

特别是对于ath10k,如果您尝试在固件中没有节点的情况下传输帧,整个传输路径就会挂起。哎呦。所以我已经修复了这个问题,所以如果固件不知道节点,但是……我们就不能将帧排队了。

..。一旦创建了节点,net80211将以主机映射模式发送关联响应。这意味着第一个关联响应不会到达关联客户端。因为net80211还不做这种流量缓冲,所以我将在密钥更新和节点添加/删除期间缓冲帧,以确保不发送或丢弃任何内容。

有一堆我们不需要或不使用的死代码,以及一些定义Linux mac80211/nl80211位的兼容位,它们应该位于net80211中。我将把这些转换成net80211方法,并从ath10k中删除linux-y位。然后,比约恩制作linuxkpi wifi垫片的工作只需将调用转换成我将添加的net80211API位,而不必在linuxkpi中使用完整的wifi方法。

。。换工作、改变关系、生孩子、拿到绿卡、买房子、还清旧房东公司的旧债,这些都会给你的生活机器带来麻烦。好的一面是,入侵FreeBSD和WiFi支持再次变得有趣起来,而且我实际上又一次能够彻夜睡眠,所以……。开始了!

如果你有兴趣帮忙,我一直在更新网上80211/司机的待办事项列表,网址是:https://wiki.freebsd.org/WiFi/TodoStuff。我想要一些帮助,即使是在小事上!