ath10k Openwrt 适配

ath10k Openwrt 适配(QCA9563+QCA9886)

来源 https://www.mr-cn.net/2020/06/08/ath10k-router-openwrt/

 

宿舍设备密度太太太大,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 Flash
2.4G: CPU自带2.4G功能+SKY85310-21独立功放
5G: QCA9886+MSC589H功放
全千兆网口

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

DC_POWER

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

CASE

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

PCB-PS

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

用料还可以,该有的都有,主要芯片还给上了散热片。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=1088
5G: /tmp/wifi1.caldata 来自ART分区 skip=20480 count=12064
Board 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.bin
Code swap structure:
bin_filename=QCA9888/hw.2/athwlan.bin swap_filename=/lib/firmware/QCA9888/hw.2/athwlan.codeswap.bin

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

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

Code

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

番外篇

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

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

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

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

1

2

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

3

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

4

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

其实用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

  1. [ 16.500296] PCI: Enabling device 0000:00:00.0 (0000 -> 0002)
  2. [ 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
  3. [ 16.549333] chip_id 0xc chip_revision 0x0
  4. [ 16.553665]
  5. [ 16.553665] CLOCK PLL skipped
  6. [ 16.558341] hif_set_hia_extnd: setting the target pll frac ffffffff intval ffffffff
  7. [ 16.566251] hif_set_hia_extnd: no frac provided, skipping pre-configuring PLL
  8. [ 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
  9. [ 16.604002] hif_napi_event: received evnt: CONF cmd; v = 1 (state=0x1)hif_napi_event: setting configuration to ON
  10. __ol_ath_attach() Allocated scn 86080420
  11. [ 16.619839] __ol_ath_attach: dev name wifi1
  12. [ 16.624195] ol_ath_attach interface_id 1
  13. [ 16.628920] ol_target_init() BMI inited.
  14. [ 16.633118] ol_target_init() BMI Get Target Info.
  15. [ 16.637977] Chip id: 0xc, chip version: 0x1000000
  16. [ 16.642853]
  17. [ 16.642853] CE WAR Disabled
  18. [ 16.647498] NUM_DEV=1 FWMODE=0x2 FWSUBMODE=0x0 FWBR_BUF 0
  19. [ 16.653299] ol_target_init() configure Target .
  20. [ 16.658076]
  21. [ 16.658076] Target Version is 1000000
  22. [ 16.663493]
  23. // 这上面都是启用设备的过程
  24. [ 16.663493] Flash Download Address c0000
  25. // 开始确定下载的地址了
  26. [ 16.669337] ol_transfer_bin_file: flash data file defined
  27. [ 16.674920] ol_transfer_bin_file[3637] Get Caldata for wifi1.
  28. [ 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
  29. // 第一次下载载入了/tmp/wifi1.caldata
  30. // 在rootfs/lib/preinit/81_load_board发现将art分区中的校准参数保存到了/tmp/wifi1.caldata
  31. // 所以说其实第一步加载的是art分区
  32. [ 16.698681] ol_transfer_bin_file 3698: Download Flash data len 12064
  33. // Flash data 来自art分区
  34. [ 16.705704] Board extended Data download address: 0x0
  35. // 这里没有log 不知道Board extended Data从哪来的
  36. // 也可能是没有下载Board extended Data 所以没有log
  37. [ 16.734002]
  38. [ 16.734002] Board data initialized
  39. // Board extended Data
  40. [ 16.739185] ol_ath_download_firmware: Download OTP, flash download ADDRESS 0xc0000
  41. [ 16.747020]
  42. [ 16.747020] Selecting OTP binary for CHIP Version 0
  43. [ 16.812795] ol_transfer_bin_file 3518: downloading file 0, Download data len 9084
  44. // 9084 这个size很少见 几乎可以肯定是来自rootfs/lib/firmware/QCA9888/hw.2/otp.bin
  45. [ 16.855272]
  46. [ 16.855272] First OTP send param 8000
  47. [ 17.101422] ol_ath_download_firmware :First OTP download and Execute is good address:0x4000 return param 4660
  48. [ 17.111673] ol_ath_download_firmware:##Board Id 16 , CHIP Id 0
  49. // 又一关键信息 Board Id 16
  50. [ 17.117804] ol_ath_download_firmware: BOARDDATA DOWNLOAD TO address 0xc0000
  51. [ 17.125019]
  52. // OTP结束 来自rootfs/lib/firmware/QCA9888/hw.2/otp.bin
  53. [ 17.125019] wifi1: Selecting board data file name boardData_2_0_QCA9888_5G_Y9690.bin
  54. [ 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
  55. [ 17.147593] ol_transfer_bin_file 3518: downloading file 3, Download data len 12064
  56. // 重新加载了boardData不是很懂原因
  57. // 猜想大概是因为上面获得了EMI Board ID所以重新匹配
  58. [ 17.155881] Board extended Data download address: 0x0
  59. // 这应该是没有下载
  60. [ 17.184361] ol_ath_download_firmware: Using 0x1234 for the remainder of init
  61. [ 17.191666]
  62. [ 17.191666] Selecting OTP binary for CHIP Version 0
  63. [ 17.198614] ol_transfer_bin_file 3518: downloading file 0, Download data len 9084
  64. // 又一次OTP?
  65. [ 17.241076]
  66. [ 17.241076] [Flash] : Ignore Module param
  67. [ 17.246836]
  68. [ 17.246836] Second otp download Param 10000
  69. // 确实是second otp
  70. [ 17.503711] ol_ath_download_firmware : Second OTP download and Execute is good, param=0x0
  71. [ 17.512254]
  72. [ 17.512254] Mission mode: Firmware CHIP Version 0
  73. [ 17.660982] ol_swap_seg_alloc: Successfully allocated memory for SWAP size=262144
  74. [ 17.673891] Swap: bytes_left to copy: fw:16; dma_page:27561
  75. [ 17.679651] Swap: wrong length read:0
  76. [ 17.683460] ol_swap_wlan_memory_expansion: Swap total_bytes copied: 234583 Target address 41a508
  77. [ 17.692775] scn=86080420 target_write_addr=41a508 seg_info=86138010
  78. [ 17.699425] ol_transfer_swap_struct:Code swap structure successfully downloaded for bin type =2
  79. [ 17.708514] bin_filename=QCA9888/hw.2/athwlan.bin swap_filename=/lib/firmware/QCA9888/hw.2/athwlan.codeswap.bin
  80. // 下载USB firmware
  81. // codeswap不知道是干嘛的
  82. [ 17.719098] ol_transfer_bin_file: Downloading firmware file: QCA9888/hw.2/athwlan.bin
  83. [ 18.077288] ol_transfer_bin_file 3518: downloading file 1, Download data len 372784
  84. // 根据这个大小应该可以确定是 rootfs/lib/firmware/QCA9888/hw.2/athwlan.bin
  85. [ 19.516913] ol_target_init() Download FW done.
  86. // 下载过程完毕

根据这次启动过程,可以看到用到了四种关键的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 work
with 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似乎不重要(可以缺失)。

参考资料:

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

    2. https://patchwork.ozlabs.org/project/lede/patch/1521585595-23155-4-git-send-email-greearb@candelatech.com/

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

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

 

============== End

 

posted @ 2022-09-15 00:19  lsgxeva  阅读(1096)  评论(0编辑  收藏  举报