一个高通 ath10k 路由 Openwrt 适配记(QCA9563+QCA9886)

您所在的位置:网站首页 openwrt无线驱动移植编译 一个高通 ath10k 路由 Openwrt 适配记(QCA9563+QCA9886)

一个高通 ath10k 路由 Openwrt 适配记(QCA9563+QCA9886)

2023-10-22 09:52| 来源: 网络整理| 查看: 265

宿舍设备密度太太太大,2.4G 的无线几乎没法用,不管是学校的 AP 还是自己的路由都卡成屎,所以没法必须搞个 5G+802.11AC 的路由。

总方向自然是越便宜越好,但是以后还是有机会用到的,还是不能太差了,加之本人对高通方案的路由比较偏爱,锁定视线到了斐讯的 K2T 上。不过一百多的售价还是贵了,最终偶然发现恩山有人卖相同方案的矿渣,79 包邮:https://www.right.com.cn/forum/thread-1023506-1-1.html

硬件篇

收到货,应该是矿渣倒闭之后滞留在工厂的货,是全新的。

配置:CPU: QCA9563+128M DDR2+16M SPI Flash2.4G: CPU 自带 2.4G 功能+SKY85310-21 独立功放5G: QCA9886+MSC589H 功放全千兆网口

虽然功放是外置的但是似乎参数一般。不过这个价钱这个配置不算亏。

12V1.5A DC 5.5*2.1mm 电源,有点分量,比三无电源要靠谱很多。

巨大的外壳,底面贴纸标明着他的身份:CSAC 路由器。这是层铁板(增重装高端吗?)脚垫和标签下面有一共 5 颗螺丝,拧下之后铁板就可以很轻松的取下来。

拆出来主板其实跟硕大的铁壳相比小多了,买家秀里有大佬给做了个亚克力外壳。

用料还可以,该有的都有,主要芯片还给上了散热片。2.4G 本来是 3T3R 的,被阉割了一路。5G 是 2T2R,值得一提的是 5G 的天线是 IPEX 插头的(白胶下面),可以自己更换天线,但是 2.4G 是焊接头的。难道这矿渣还准备出好几个挡位的配置吗,哈哈。

板子上还有 1 个 Mini PCIE 接口留了焊盘,不过貌似没看到主板有走线,不懂什么意思。但是 USB 脚是有走线的,可以引出额外的 1 组 USB2.0 接口。(没什么卵用)

左上角可以看到两颗芯片,丝印着 CSAC5K,应该是挖矿芯片了。据说没通电,但是还是用自己的固件比较放心。

原厂固件篇

自带的固件是 qsdk 的,功能简陋,确实没什么好说的。不过好奇心使我还是解包去研究了下。这是伏笔。

nmap 扫一下,发现有两个端口开了 HTTP 服务,还有个好像是 HTTPS 的,响应的结果有些奇怪的名字

先上 TTL,拿到 dmesg,之后发现要密码才能进系统,随便试了试,无果。

先刷 Breed:breed-qca956x-uart_rx18_tx22-reset2(Auto).bin

用 Breed 导出完整固件备份,解包得到 rootfs。

逛了逛,发现如下信息,为 openwrt 适配作准备:

Caldata:2.4G: /tmp/wifi0.caldata 来自 ART 分区 skip=4096 count=10885G: /tmp/wifi1.caldata 来自 ART 分区 skip=20480 count=12064Board Data File:boardData_2_0_QCA9888_5G_Y9690.bin/lib/firmware/QCA9888/hw.2/boarddata_0.bin 来自 /usr/share/base-config/9886_calData_20171012_edit.binCode swap structure:bin_filename=QCA9888/hw.2/athwlan.bin swap_filename=/lib/firmware/QCA9888/hw.2/athwlan.codeswap.bin

此外虽然我们没有在原厂固件发现挖矿相关的信息,但是在固件内是可以看到他们业务的相关代码的。

代码位置在 rootfs/usr/share 中,都是 lua 写的。

至于有些啥,感兴趣的自己研究吧

番外篇

其实也不算秘密,这个圈子就这么大,做矿机的自己不懂技术,那找谁做呢?其实做矿机的,和那些捡 “垃圾” 的大神,研究矿渣的大神其实就是一拨人。

前脚给矿机做系统赚一波钱,矿机崩了就 “民间大神” 出来适配固件迅速低价抛货清盘走人。你说民间大神多厉害,做出来的固件又好用,那你说民间大神他能不厉害吗,本身这玩意就是他做的,他能不懂么。

不过对于垃圾佬来说,只要价钱合适,我们倒是不亏的。

这个机子就是这样的,一个老板,一个 “圈内玩家”,一个 “民间大神”,一起唱出戏,机子就清掉了~

这个民间大神倒是确实是也应该对路由器感兴趣,github 上可以看到给 Openwrt 也有不少的 Contribution。

那他跟这路由还有啥关系呢?

随手搜一下,发现固件中许多代码的作者署名都是他。。。

其实用 nmap 扫一下原厂固件的时候就发现了,在某个端口的返回信息中也有他的署名,所以这才勾起的我深入研究的欲望。。。

适配篇

据说此板的原型是高通的 AP152 Reference Broad,加上 ath10k 的支持就好了。

固件适配没什么太多好讲的,就是改改灯的定义、按钮的定义和接口的定义,闪存布局什么的跟 AP152 也都一样,基本上就是改个名字的区别了。具体可以看:https://git.mr-cn.net/mr/openwrt/commit/16dda3ab84944253f800e508a289491738ec4a53

不过有一些题外话可以讲:

在上面的 commit 可以看到我是适配在了 ar71xx 分支下的。ar71xx 这代其实很特殊,ar71xx\ath79 其实都是他的分支,两个都可以工作。71xx 的支持非常多,大部分经典的高通的 CPU 都是在这个分支下面的。ath79 其实跟他基本上是一个东西,区别在于 ath79 是基于 DTS,Linux 的设备树来定义的设备信息,是 Linux 的一种定义嵌入式设备信息的一种流行的做法。ar71xx 可能是因为历史悠久,跨度比较长,可能在最开始 DTS 还没有发展起来,所以是 Openwrt 自己的一种定义方式,也就是 mach-xxxx.c 的文件定义的。

我当然希望适配最新的分支,所以一开始是基于 ath79 做的。可惜这个路由的闪存布局并不合理,内核与 rootfs 是分开的,所以内核的大小是有限制的。而 ath79 作为后续分支,内核版本比较新,功能更丰富,但是也带来了体积更大的问题,而我们 CSAC 路由的内核分区的大小就刚好卡在了这个边缘。据查询资料得知,4.14 之后的内核大小有一个明显提升,但 ATH79 是不支持 4.14 之前的内核的,而作为 “历史遗留” 的 ar71xx 却是可以支持 4.9 的,所以只好基于 ar71xx 重新适配。

我们路由器本身的闪存大小是足够的,只是分区限制了,说明还是有途径解决的。或许需要修改 MTD 分区表,或许还需要修改 Bootloader,也就意味着没法使用 Breed 了。所以暂时没有研究下去了,毕竟现在也可以用不是。

到这里固件就已经可以生成了,编译出来也确实可用。测了一下,网卡 Intel 9265ac,同样的位置 12M 穿一堵墙,这个路由的吞吐是我网件 R6400 三分之二。性能一般,但相较于价格而言我认为已经挺值了,也确实给我在校生活的品质带来了显著的提升,哈哈。

此外,这个路由自带的天线也比较拉跨(至少看起来是的),鉴于 5G 的天线接口时 IPEX 的,如果把天线更换成外置的有一定增益的,效果应该还能改善。2.4G 的就还是别折腾了吧,艹死都就那样了,焊接式的天线也不建议更换,天线这玩意应该还是有点讲究的,瞎焊可能会影响天线效果。

芯片还支持 802.11kvr,多搞几个可以组多 AP 漫游网(也就是所谓的 Mesh),还支持 MU-MIMO,openwrt 把这些功能全部解锁出来了。

此外,虽然 openwrt 可以支持到高达 30dbm,1000mw 的输出功率,但是十分不建议。一个是功放芯片本身只支持到 20dbm 的增益,发热巨大之外还可能烧功放;另外一个是光发射功率都顶到整整 1W 了。。。这个辐射还是有一定风险的。建议就开到 20dbm 就好了。这机器的瓶颈我觉得是那拉跨的天线,而不是发射功率。

榨干他

不过到这里还没完,我们还有改善的空间。之前适配虽然能用,但都是按照通用的套路去适配的,与机器相关的参数也只有一个从 ART 分区提取的 pre-cal 校准参数。据资料显示,如果加载原厂固件的 Board Data 而不是公版的 Board Data,信号质量理论上还可以获得提升。

下面的内容全网都找不到资料,可能只有高通内部的人有资料,本人在全网各种搜寻资料后将自己的理解分享出来,仅供参考

ath10k 与 ath9k 是有区别的,ath9k 只是单纯的网卡设备,而 ath10k 更像一个 SoC 了,其功能变得更加复杂,运行时也需要更复杂的固件,所以在初始化设备时,需要主机提供相关的固件下载到网卡中。此时下载的固件不单纯是网卡的工作代码,还有我们主机的主板的一些参数。总所周知,同样的芯片因为搭配的运放电路、IC 不同,效果会因主板而异,甚至是同一主板不同个体之间都可能不相同,所以才需要 ART 分区保存着的校准参数。这些校准参数应该也是在这个时候一同下载到网卡的。

来分析原厂固件的 log

[ 16.500296] PCI: Enabling device 0000:00:00.0 (0000 -> 0002) [ 16.506154] hif_pci_enable_bus: hif_enable_pci done *********** QCA9888 *************hif_pci_enable_bus: hif_type = 0xe, target_type = 0xchif_pci_enable_bus: hif_pci_probe_tgt_wakeup donehif_target_sync: Loop checking FW signalhif_target_sync: Got FW signal, retries = 0hif_config_ce: ce_init donehif_config_ce: X, ret = 0hif_set_hia: Ehif_set_hia_extnd: E [ 16.549333] chip_id 0xc chip_revision 0x0 [ 16.553665] [ 16.553665] CLOCK PLL skipped [ 16.558341] hif_set_hia_extnd: setting the target pll frac ffffffff intval ffffffff [ 16.566251] hif_set_hia_extnd: no frac provided, skipping pre-configuring PLL [ 16.576652] hif_pci_bus_configure: hif_set_hia donehif_configure_irq: Ehif_pci_configure_legacy_irq: Ehif_pci_configure_legacy_irq: X, ret = 0hif_enable: X OKhif_napi_create: NAPI structures initializedhif_napi_create: NAPI id 6 created for pipe 5qca_napi_create: napi instance 32 created on pipe 4 [ 16.604002] hif_napi_event: received evnt: CONF cmd; v = 1 (state=0x1)hif_napi_event: setting configuration to ON __ol_ath_attach() Allocated scn 86080420 [ 16.619839] __ol_ath_attach: dev name wifi1 [ 16.624195] ol_ath_attach interface_id 1 [ 16.628920] ol_target_init() BMI inited. [ 16.633118] ol_target_init() BMI Get Target Info. [ 16.637977] Chip id: 0xc, chip version: 0x1000000 [ 16.642853] [ 16.642853] CE WAR Disabled [ 16.647498] NUM_DEV=1 FWMODE=0x2 FWSUBMODE=0x0 FWBR_BUF 0 [ 16.653299] ol_target_init() configure Target . [ 16.658076] [ 16.658076] Target Version is 1000000 [ 16.663493] // 这上面都是启用设备的过程 [ 16.663493] Flash Download Address c0000 // 开始确定下载的地址了 [ 16.669337] ol_transfer_bin_file: flash data file defined [ 16.674920] ol_transfer_bin_file[3637] Get Caldata for wifi1. [ 16.680963] qdf_fs_read[59], Open File /tmp/wifi1.caldata SUCCESS!!file system magic:16914836super blocksize:4096inode 205file size:12064qc98xx_verify_checksum: flash checksum passed: 0x5bb1 // 第一次下载,载入了/tmp/wifi1.caldata // 在 rootfs/lib/preinit/81_load_board 发现将 art 分区中的校准参数保存到了/tmp/wifi1.caldata // 所以说其实第一步加载的是 art 分区 [ 16.698681] ol_transfer_bin_file 3698: Download Flash data len 12064 // Flash data 来自 art 分区 [ 16.705704] Board extended Data download address: 0x0 // 这里没有 log 不知道 Board extended Data 从哪来的 // 也可能是没有下载 Board extended Data 所以没有 log [ 16.734002] [ 16.734002] Board data initialized // Board extended Data [ 16.739185] ol_ath_download_firmware: Download OTP, flash download ADDRESS 0xc0000 [ 16.747020] [ 16.747020] Selecting OTP binary for CHIP Version 0 [ 16.812795] ol_transfer_bin_file 3518: downloading file 0, Download data len 9084 // 9084 这个 size 很少见 几乎可以肯定是来自 rootfs/lib/firmware/QCA9888/hw.2/otp.bin [ 16.855272] [ 16.855272] First OTP send param 8000 [ 17.101422] ol_ath_download_firmware :First OTP download and Execute is good address:0x4000 return param 4660 [ 17.111673] ol_ath_download_firmware:##Board Id 16 , CHIP Id 0 // 又一关键信息 Board Id 16 [ 17.117804] ol_ath_download_firmware: BOARDDATA DOWNLOAD TO address 0xc0000 [ 17.125019] // OTP 结束 来自 rootfs/lib/firmware/QCA9888/hw.2/otp.bin [ 17.125019] wifi1: Selecting board data file name boardData_2_0_QCA9888_5G_Y9690.bin [ 17.134651] ol_transfer_bin_file: Board Data File download to address=0xc0000 file name=QCA9888/hw.2/boardData_2_0_QCA9888_5G_Y9690.bin [ 17.147593] ol_transfer_bin_file 3518: downloading file 3, Download data len 12064 // 重新加载了 boardData?不是很懂原因 // 猜想大概是因为上面获得了 EMI Board ID 所以重新匹配? [ 17.155881] Board extended Data download address: 0x0 // 这应该是没有下载 [ 17.184361] ol_ath_download_firmware: Using 0x1234 for the remainder of init [ 17.191666] [ 17.191666] Selecting OTP binary for CHIP Version 0 [ 17.198614] ol_transfer_bin_file 3518: downloading file 0, Download data len 9084 // 又一次 OTP? [ 17.241076] [ 17.241076] [Flash] : Ignore Module param [ 17.246836] [ 17.246836] Second otp download Param 10000 // 确实是 second otp [ 17.503711] ol_ath_download_firmware : Second OTP download and Execute is good, param=0x0 [ 17.512254] [ 17.512254] Mission mode: Firmware CHIP Version 0 [ 17.660982] ol_swap_seg_alloc: Successfully allocated memory for SWAP size=262144 [ 17.673891] Swap: bytes_left to copy: fw:16; dma_page:27561 [ 17.679651] Swap: wrong length read:0 [ 17.683460] ol_swap_wlan_memory_expansion: Swap total_bytes copied: 234583 Target address 41a508 [ 17.692775] scn=86080420 target_write_addr=41a508 seg_info=86138010 [ 17.699425] ol_transfer_swap_struct:Code swap structure successfully downloaded for bin type =2 [ 17.708514] bin_filename=QCA9888/hw.2/athwlan.bin swap_filename=/lib/firmware/QCA9888/hw.2/athwlan.codeswap.bin // 下载 USB firmware // codeswap 不知道是干嘛的 [ 17.719098] ol_transfer_bin_file: Downloading firmware file: QCA9888/hw.2/athwlan.bin [ 18.077288] ol_transfer_bin_file 3518: downloading file 1, Download data len 372784 // 根据这个大小应该可以确定是 rootfs/lib/firmware/QCA9888/hw.2/athwlan.bin [ 19.516913] ol_target_init() Download FW done. // 下载过程完毕

根据这次启动过程,可以看到用到了四种关键的 bin 文件:1.broaddata 2.OTP 3.athwlan.bin 4.athwlan.codeswap.bin

其中 broaddata 用到了 QCA9888/hw.2/boardData_2_0_QCA9888_5G_Y9690.bin,ART 中提取的/tmp/wifi1.caldata,此外在前文提到过的/lib/preinit/81_load_board 中还可以发现涉及到了 9886_calData_20171012_edit.bin 这一文件,也就是/lib/firmware/QCA9888/hw.2/boarddata_0.bin 的来源,虽然在 log 中没有发现被使用但从命名来看我觉得也是有价值的,具体情况到底是用哪个目前我也还没有弄清楚;

OTP 文件一定是/lib/firmware/QCA9888/hw.2/otp.bin

athwlan.bin 文件一定是/lib/firmware/QCA9888/hw.2/athwlan.bin

ps:此机器的 802.11ac 芯片是 QCA9886,但 9886 与 9888 都是使用 9888 的驱动,其余芯片为 988X。

上面的启动过程是 qsdk 的,在 Openwrt 中并没有这么多的文件,只有 board-2.bin,board.bin,firmware-5.bin,其中 board.bin 还是一个空文件(文件实际上是一串 ASCII 文本 “../../cal-pci-0000:01:00.0.bin”),那么这些固件是怎么加载的呢?

上面的启动过程是 qsdk 的,在 Openwrt 中并没有这么多的文件,只有 board-2.bin,board.bin,firmware-5.bin,其中 board.bin 应该是一个符号链接链接到 cal 文件,那么这些固件是怎么加载的呢?

实际上是 OTP 与固件(athwlan.bin)封装成的 firmware-X.bin,其中 X 代表固件的 API 版本,这个 X 应该与无线芯片型号有关,在这里我的 QCA9886 是 5。

[1] 此外 broaddata 有很多版本,openwrt 将许多路由使用的 broaddata 都收集到了一起,都封装到了 board-2.bin 文件中,根据主板的 EMI Board ID 调用。

所以说,我们现在的目的就是加载正确的 broaddata。但是到底哪个是正确的,又如何让 Openwrt 选择我们希望的 broaddata 进行加载呢? 我目前暂无头绪。

ps:ath10k 的 firmware 现在有第三方公司在维护优化版本,即-ct 版本,在编译固件时可选用 CT 版本的驱动。普通版本的驱动搭配普通固件或者 ct 版本的固件使用,htt-mgt 版本的固件搭配 ct 驱动使用。

ath10k 驱动笔记

HTT-MGT 版本作用:[2]

The HTT-MGT variants transport management frames over the normal HTT tx path, just like data frames.This saves limitted WMI buffers which can become depleted if lots of management frames become stuck in TX queues due to peer that went away.In addition, at least for the wave-1 firmware, htt-mgt is required in order for 802.11r (fast roaming) authentication to function properly.

CT 固件-驱动对应关系:[2]

The htt-mgt firmware requires the use of the ath10k-ct driver. Normal non-htt-mgt ath10k-ct firmware should workwith stock drivers.

ath10k 启动流程:[3]

I recall qca4019 have the following flow: pre-cal -> otp get chip id -> get proper board file -> populate via otp (see commit 3d9195ea19e48).

所以说看来我之前的猜测是正确的。

openwrt 中的校准文件:

pre-cal 是来自 ART 的。cal 暂时不知道是来自哪里,cal 似乎不重要(可以缺失)。

参考资料:

https://github.com/erstrom/linux-ath/wiki/Firmware

https://patchwork.ozlabs.org/project/lede/patch/[email protected]/

https://lists.infradead.org/pipermail/ath10k/2016-November/008766.html

https://lists.infradead.org/pipermail/ath10k/2017-January/009025.html

ps: 邮件列表真是个好地方,大多数资料都是来自这里



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3