ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

高通WiFi驱动调试指南:从wlan.ko到固件与校准数据

高通WiFi驱动调试指南:从wlan.ko到固件与校准数据 简介《高通WiFi驱动编程指南》是一份由高通官方发布的无线局域网驱动技术文档主要面向接入点设备开发者、嵌入式系统工程师及网络运维人员。其核心价值在于帮助读者理解驱动与硬件之间的协作机制掌握驱动安装配置、性能优化和故障排查方法并针对实际设备调试中的常见问题给出解决思路。压缩包内共1个文件为PDF格式大小约87.21MB该文档收录了驱动定义、Split MAC分层设计、多用户多输入多输出等关键章节同时包含QCA网络更新版本中的新特性说明。已有2925人浏览学习。文档从驱动基础概念逐步深入到物理层与媒体访问控制层拆分、射频管理、命令行工具使用、数据统计查询等实操内容并附修订历史与合规声明便于开发者了解版本演进、规避文档使用风险是一份不可多得的WiFi驱动开发参考资料。1. 高通WiFi驱动的指导文档在讲什么从WiFi打不开说起新板子第一次点亮系统起来了屏幕亮了但WiFi图标永远是灰色。你打开dmesg满屏都是wlan firmware load failed。这时候你缺的不是一篇科普而是一条能顺着查下去的高通WiFi驱动排查路径。高通的WiFi方案和PC上那种装完一个inf就完事的通用驱动完全不同它由四层组成跑在应用处理器上的Host Driver内核模块、跑在WiFi芯片内部处理器上的固件、描述板级射频特征的bdwlan.bin、以及产线校准数据。任何一层不对齐现象都一样——WiFi打不开。这篇指导文档写给做设备BSP、方案集成和现场FAE的朋友目标是帮你把从源码编译、固件部署到现场排障的整条链路走通少踩几个不必要的坑。2. 高通WiFi驱动的架构与源码从CAF kernel到wlan.ko的完整链路2.1 驱动栈的四个层次Host驱动、固件、板级数据和校准数据很多人拿到高通方案第一件事是找“WiFi驱动安装包”但高通平台的WiFi驱动从来不是一个包而是一组互相咬合的组件。最上层的Host Driver就是编译出来的wlan.ko它跑在应用处理器AP的内核态基于mac80211和CFG80211框架实现。它的职责是承上启下向上为wpa_supplicant提供NL80211接口向下把扫描、连接、断开、漫游这些请求翻译成固件能理解的命令通过CNSS总线送进芯片。第二层是WLAN固件。高通的中高端方案里WiFi芯片比如WCN3990系列自带处理器固件就跑在这个内部处理器上。信道扫描的时序、速率选择、省电模式的切换、帧聚合的调度这些对时间敏感的工作全部由固件完成。固件一旦跑飞或者版本不对Host驱动状态再好上层看到的还是WiFi不可用。所以排查时不能只盯内核模块。第三层是板级数据最常见的就是bdwlan.bin。同一颗WiFi芯片装在不同的主板上天线增益、PA匹配、频段开关都不同这些差异就记录在bdwlan.bin里。换句话说参考板上能用的驱动换到你自己的板子上未必能用大概率就差在这个文件上。第四层是校准数据。产线会用高通的XTT等射频校准工具对每一块板子做发射功率和接收链路的校准结果写进NV分区或者eFuse。驱动和固件启动时会读这些数据做个体修正。这就是为什么同一个型号的手机WiFi性能也有差异。所以“驱动”这个词在高通语境下包含四个东西缺一不可你修复“WiFi打不开”时优先级最高的往往不是wlan.ko而是固件和板级文件。这个反直觉的结论后文会反复用到。2.2 源码去哪找CAF kernel、qcacld-3.0与prima的对应关系高通维护的CAF kernel代码树是起步的第一站也就是Code Aurora Forum发布的内核。你可以直接从CAF拉代码也可以从方案商的BSP包拿多数厂商会在BSP里固定好仓库地址和分支。关键在于qcacld-3.0驱动并不总在kernel主目录里。新平台常见的情况是它挂在kernel/drivers/staging/qcacld-3.0或者以独立仓库的形式放在vendor/qcom/opensource/wlan/qcacld-3.0编译的时候用Kbuild外部模块的方式并进最终镜像。遇到找不到驱动源码的情况先看BSP里wlan目录在哪再决定编译入口。老平台的路径差别很大。以MSM8916、APQ8016这一代为例常见的是prima驱动源码在drivers/net/wireless/qualcomm/下面对应的固件路径通常是/etc/firmware/wlan/prima/配置文件叫WCNSS_qcom_cfg.iniNV数据在WCNSS_qcom_wlan_nv.bin。如果你维护的是这类老平台网上搜“prima wlan”比搜“qcacld”更有用。选源码时最怕的是分支错配。qcacld-3.0的某个分支对应特定的内核版本和Android版本不能看到新功能就乱换。最省事的对齐方式是从BSP自带的manifest文件反查manifest里列出每个仓库的分支和commit号照它拉代码基本不会翻车。我见过太多人从CAF主干拉一份最新qcacld塞进老内核编出来的模块insmod直接报unknown symbol这就是版本错配的典型症状。2.3 设备树与内核开关驱动能不能被枚举出来的两个前提驱动编译完还要能被设备树正确枚举。高通平台通常会在dtsi里定义WiFi控制器节点比如wcn3990系列会有对应的节点包含中断、寄存器地址和电源相关属性。只要dtsi里少一个节点、或者中断号配错驱动在probe阶段就失败。判断方法很简单开机后lsmod里没有wlan/sys/class/ieee80211/下没有phy目录基本就是枚举或probe失败跟固件还没关系。第二个前提是内核defconfig里的开关。和WiFi相关的常见项包括WLAN vendor开关CONFIG_WLAN_VENDOR_QCOM、qcacld驱动模块选项CONFIG_QCACLD_WLAN以及外围的CNSS/ICNSS模块开关。这些项必须被正确启用而且最好编成模块m而不是内置y。检查方法grep -E WLAN|QCA|QCACLD|CNSS .config | grep -v ^#这条命令的作用是列出所有和WiFi相关的非注释配置项。如果输出里看不到CONFIG_QCACLD_WLAN先确认defconfig有没有正确导入。有些产品的defconfig不只是一个文件而是主defconfig加上平台fragment拼出来的比如某平台的defconfig可能还要include额外的sdm845相关配置片段。直接make vendor_defconfig并不代表这些fragment一定生效要看BSP编包脚本怎么组装.config。除了开关本身依赖关系也要留意。CNSS是WiFi固件下载和子系统管理的公共模块wlan.ko要正常加载CNSS模块必须先就位。如果开机后发现wlan.ko自动加载失败先手动modprobe cnss再试能帮助快速定位依赖缺失。设备树和内核开关这两项检查完驱动才能真正进入固件加载阶段这也是后文所有配置生效的前提。3. 把驱动编出来从源码到可加载wlan.ko的完整命令3.1 准备工作确认工具链和kernel源码的对应关系在AOSP或CAF的整机构建流程里wlan.ko一般会被自动编进dlkm或者vendor_dlkm镜像不太需要手动单独编。手动单编主要用在两种场景一是改了驱动源码想快速验证二是在没有完整build环境的产品里做增量升级。无论哪种都建议直接用BSP自带的交叉编译工具链通常位于prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin这类目录。不要图省事拿系统GCC来编模块编译用的头文件和内核符号表版本若对不上insmod时会出现struct布局不一致导致的各种玄学问题。开始之前先确认你手上的kernel源码版本和qcacld-3.0仓库是对应关系。最简单的方法是看BSP的manifest文件确认qcacld-3.0所在的revision。如果kernel源码和qcacld各自来自不同的tag编译可能通过但运行期行为会异常。这一步花五分钟后面能省五小时。3.2 单独编译wlan.ko最小命令和参数含义以典型的ARM64平台为例手动编译wlan.ko的完整流程分两步。第一步生成配置cd kernel_source_root export ARCHarm64 export CROSS_COMPILEyour_toolchain/aarch64-linux-android- # 用产品的defconfig生成.config make product_defconfig # 检查wlan相关开关 grep -E WLAN|QCA|QCACLD|CNSS .config | grep -v ^#ARCHarm64告诉构建系统目标架构是64位ARMCROSS_COMPILE指定交叉编译器的前缀如果工具链实际名字是aarch64-linux-android-gcc那么前缀就是aarch64-linux-android-注意最后的短横线不能省。make _defconfig会用产品特定的配置生成.config这一步成功的前提是defconfig文件确实存在于arch/arm64/configs/下。如果BSP的构建系统用的是拼接式配置这一步就要替换成BSP自带的配置生成脚本。第二步编译模块# 先prepare再编模块避免用到旧的生成文件 make modules_prepare -j16 make modules -j16 # 找到wlan.ko find . -name wlan*.ko -type f 2/dev/nullmake modules_prepare会生成模块编译需要的基本头文件和符号表漏掉这步最常见报错是找不到generated/utsrelease.h或者include/generated/autoconf.h这些文件必须由prepare阶段产生。make modules会编译内核配置里标记为M的所有模块产物不止wlan.ko还会把cfg80211.ko、mac80211.ko这样的依赖模块一起编出来。find命令里的通配符wlan*.ko覆盖了qca_cld系列模块常见的命名习惯实际文件名以你的BSP为准。如果只想编wlan模块不编整棵树可以进到qcacld-3.0源码目录直接用它的Kbuild做外部模块编译但那样需要手动指定KDIR和模块输出目录依赖关系容易乱。我一般先整树编一次确认链路通了再在增量调试时只编译改动过的子目录。3.3 部署到设备并验证加载编出来的wlan.ko要进到设备里才能验证。最小可行的部署流程adb root adb remount adb push kernel_source_root/drivers/staging/qcacld-3.0/wlan.ko /vendor/lib/modules/ # 如果qcacld在独立仓库push路径换成实际构建输出目录 adb reboot # 查看模块加载状态 adb shell lsmod | grep wlan adb shell dmesg | grep -i wlan | tail -n 30adb root和adb remount只在userdebug版本上可用。如果设备是user版本/vendor分区不可写这时的做法是做成整包升级或者刷vendor_boot把wlan.ko替换进vendor_dlkm镜像。push到/vendor/lib/modules/是vendor_dlkm常见的挂载路径但不同平台可能挂载到其他目录先执行adb shell mount | grep dlkm确认实际挂载点再决定push目的地。另一种快速验证方法是直接往数据分区推adb push wlan.ko /data/local/tmp/ adb shell insmod /data/local/tmp/wlan.ko如果insmod报unknown symbol说明它的依赖模块还没加载。先用modinfo查看依赖比如modinfo wlan.ko | grep depends字段会列出需要先加载的模块然后按顺序insmod cfg80211.ko、mac80211.ko这类依赖项最后再加载wlan.ko。成功标准有三个lsmod里能看到wlandmesg里有驱动的init/probe成功日志/sys/class/ieee80211/下出现了phy0节点。三者缺一就要回头查前面的步骤。4. 固件、板级参数与校准文件驱动加载后决定能不能出网的三件套4.1 运行时固件文件清单三个关键文件的路径与验证方法wlan.ko加载成功不等于WiFi就能用。驱动probe之后还要从固件分区把三样东西读出来固件本体、板级数据、MAC地址。这三个文件通常放在/vendor/firmware/wlan/qca_cld/目录下具体文件名以方案的发布包为准常见的是类似WLAN_TARGET_LS.bin的固件镜像、bdwlan.bin和wlan_mac.bin。三者的关系可以这样理解固件是芯片上运行的代码bdwlan.bin是这块主板的射频属性wlan_mac.bin是这设备的身份标识。文件常见路径作用出错表现固件本体如WLAN_TARGET_LS.bin/vendor/firmware/wlan/qca_cld/跑在WiFi芯片内部处理器上固件下载超时、WiFi反复关闭bdwlan.bin/vendor/firmware/wlan/qca_cld/板级射频配置频段掩码、天线增益、功率信号弱、扫描不到5G、RSSI异常wlan_mac.bin/vendor/firmware/wlan/qca_cld/MAC地址与CRC校验MAC全0、连上后无法获取IP老平台QCA6174、APQ8016那批用prima驱动的设备路径通常是/etc/firmware/wlan/prima/下对应的文件是WCNSS_qcom_cfg.ini、WCNSS_qcom_wlan_nv.bin。新版平台的区分点主要在“qca_cld”目录和bdwlan.bin命名看到bdwlan基本可以确定是qca_cld体系。拿到这些文件后第一件事不是拷贝而是校验。用md5sum和参考板或者发布包里的清单做对比确认固件没被传输截断再用strings命令看固件头部是否存在版本字符串能帮你快速定位固件和驱动是否来自同一个发布周期。文件权限也要看固件目录如果没了读权限驱动会在固件下载阶段报IO错误。4.2 bdwlan.bin里的参数边界哪些能改、哪些不能动bdwlan.bin是一个二进制文件不是文本配置。它里面记录着board_id、天线增益、频段掩码、TX功率相关的板级参数。很多新手拿到它第一反应是用十六进制编辑器打开改字节这个动作风险极高文件内部有CRC校验硬改字节会让驱动拒绝加载而且bin文件的字节序和字段长度没有文档看不出来改错一个位可能把2.4G频段配成5G整块板直接无信号。正规的做法是让模组厂或者射频工程师根据你的主板输出一份匹配的bdwlan.bin或者用高通/方案商提供的工具从参考配置重新生成。开发调试阶段最稳的是从同款参考板直接拷贝一份保证驱动先跑起来射频细调再交给工具链。常见故障里扫描不到5G、信号强度特别弱、某几个信道完全无数据十有八九跟bdwlan.bin里的频段掩码或增益配置有关。还有一个经常被忽略的变量是regulatory domain也就是国家码。即使bdwlan.bin里打开了5Gcfg80211还会按当前国家码决定哪些信道允许使用。设备没设置国家码时驱动会退回默认的regulatory规则某些地区默认规则不开放5G高频段结果就是5G扫描不到或者某些信道不可用。可以在设备上执行iw reg get看当前生效的国家码iw reg set后用driver重新加载再验证。量产前国家码的默认值要由法规认证团队确认开发阶段不要随意固化。4.3 wlan_mac.bin与MAC地址全0现象和校准数据的来龙去脉wlan_mac.bin不是把6字节MAC写进文件就完事的。它带校验机制写入时要用正确工具生成不能靠echo写文本。比较典型的故障是设备能连上WiFi但拿不到IP路由器上看到来源MAC是全0或者02:00:00:00:00:00这种无效地址多数就是wlan_mac.bin缺失或者内容损坏。开发阶段最省事的做法是从同型号参考板的固件分区里dd一份wlan_mac.bin出来push到目标设备临时用。注意这只是让调试继续不能当量产方案。量产时必须由产线工位对每台设备写入唯一MAC这属于生产流程的一部分不会在研发环境里出现。再说校准数据。产线会用XTT这类高通的射频校准工具对每一块板子做发射功率、IQ失衡、接收灵敏度等项目的校准结果写进NV分区或者eFuse。没有校准数据WiFi可能能连上但吞吐量忽高忽低板间一致性差得离谱。遇到这种“能用但不稳定”的情况先确认设备有没有做过校准而不是急着改驱动参数。一个常见误区是把bdwlan.bin当成校准文件。bdwlan.bin是方案级默认参数描述的是这一型号主板的共同特征校准数据是单台设备的个体修正。两者在WiFi驱动里的角色不同改bdwlan.bin绝对代替不了产线校准。总体上固件三件套、bdwlan.bin、NV校准数据这三样东西在排障时永远是并排查看的少看一样都会走弯路。5. 常见问题排查WiFi打不开、扫描不到、连上掉线的几类现场5.1 固件加载失败dmesg里的CNSS错误码怎么看现象WiFi开关打不开设置页里WiFi反复转圈最后自动关闭整个WiFi相关功能不可用。原因固件文件缺失、路径不对、文件权限不足、固件与驱动版本不匹配都会导致CNSS子系统的固件下载流程失败。CNSS是高通平台负责WiFi/蓝牙公共子系统的模块它先通过总线把固件搬进芯片芯片跑起来后驱动才能继续初始化。解决第一步抓dmesg搜索cnss、wlan、firmware、timeout这些关键字记下具体错误行。然后核对固件目录路径和驱动期望的路径是否一致很多时候只是文件名不同导致加载失败。驱动一般有fw_path之类的加载参数可以通过modinfo查看必要时用参数覆盖路径。最后核对固件哈希和发布包里的哈希排除下载截断。调试时记得先抓日志再重启重启会把能证明问题的现场丢掉。5.2 扫描不到任何AP先分RF问题还是驱动问题现象WiFi能打开、状态正常但扫描列表永远是空的周围明明有AP。原因这个问题一半出在RF通路一半出在协议栈。RF通路的问题包括天线没贴好、频段被bdwlan.bin的掩码关掉、校准数据异常协议栈的问题包括扫描请求没下发到固件、固件扫描超时、wpa_supplicant上报失败。解决把设备放到AP旁边一米内再扫描排除信号强度干扰。然后手动触发一次扫描iw dev wlan0 scan看返回结果如果有结果但UI列表空问题在上层spplicant到框架的链路如果手动扫描也是空优先替换bdwlan.bin和校准数据再怀疑天线。这两个方向二选一比看到扫描不到就拆机测天线高效得多。注意iw命令需要root权限用户版本上要先用adb root。5.3 锁屏就掉线省电策略与电源域配置现象屏幕亮着时一切正常锁屏几分钟后WiFi断连亮屏立刻恢复。原因WiFi省电模式PS mode的配置不对或者设备树里WiFi的电源域在系统suspend时被直接关掉导致固件来不及处理断开流程。这个现象在低端板子和电池供电设备上尤其常见。解决调试时先临时关掉省电iw dev wlan0 set power_save off然后锁屏复测。如果关闭后不再掉线说明是省电参数问题重点查DTIM周期、wowlan配置和固件里的睡眠策略如果仍然掉线就查设备树里的电源域注册和CNSS的suspend回调。另外有些平台的WiFi休眠策略由Android框架层控制要查framework的wifi suspend设置不能只盯内核。5.4 驱动、固件、校准数据的“版本三角”最常见的玄学现象同一份镜像在参考板上一切正常在另一块板子上偶发连不上或者传输吞吐量掉到参考板的1/3dmesg里又没有明显报错。原因wlan.ko、固件二进制、校准数据分别来自不同的发布阶段三者对不上。驱动接口变了而固件还是旧的或者固件新了而驱动还停在老版本这种错配不会报编译错误只会在运行期以吞吐异常、偶发断连的方式暴露。解决把三者来源统一。固件必须来自和wlan.ko同一次发布校准数据和board data要来自同一个方案阶段。维护一张版本清单记录wlan.ko的git commit号、固件文件的md5、bdwlan.bin的来源和日期。出问题时先对着清单逐一核对。这类问题是最典型的黑匣子靠肉眼和经验很难一次看穿只能靠记录把变量锁死。我经历过吞吐量只有1/3的情况排查了三天最后发现就是固件差了一个tag。5.5 调试失控后的恢复NV分区、9008模式和备份意识现象改NV或者eFuse里的校准数据时手滑写坏WiFi失灵严重时系统无法正常进入。原因NV区域记录了射频校准、MAC、以及其他平台关键参数写坏后驱动和固件启动时读到脏数据初始化直接失败。解决如果只是WiFi异常且系统能进尝试用原厂工具重新写回备份的NV数据如果分区表或者bootloader也被破坏只能走QDLoader 9008模式。9008模式下设备作为下载端口连接电脑先装好对应的QDLoader USB驱动再用刷机工具全量恢复镜像恢复后必须重新校准。这里最容易卡住的不是刷机本身而是宿主机识别不到9008设备通常要重新安装正确版本的驱动并检查USB枚举。注意任何NV/eFuse操作之前必须导出原始分区备份。没有备份的后悔药非常贵这也是老工程师会反复叮嘱的习惯。6. 验证驱动的三个硬指标与抓日志的稳妥姿势驱动部署完成、WiFi能连上只算做到一半。真正判断驱动有没有干活我用三个硬指标吞吐量、丢包率、待机恢复。指标工具判断基准TCP吞吐量iperf3与参考板同频段同位置对比偏差超过20%就要查丢包率ping同一AP下ping 1000次丢包率低于1%待机恢复锁屏10分钟再唤醒从唤醒到WiFi重连完成低于3秒测吞吐量时手机端和服务端要分别跑iperf3注意天线方向和距离保持一致。丢包测试前记得关掉WiFi省电否则锁屏后测试数据会被省电策略干扰。待机恢复则相反要开着省电测真实还原用户使用场景。除了这三个指标我还习惯在传输数据时看/proc/interrupts里wlan相关的中断计数传输前后计数增长明显说明数据确实走了WiFi通路计数不动而吞吐为0问题基本在协议栈而不是射频。抓日志的姿势也有讲究。内核侧用adb shell dmesg -w实时看配合logcat -s WifiHW WifiStateMachine wpa_supplicant抓上层状态两个时间线对齐才能定位是框架层还是驱动层的问题。需要抓包时adb shell tcpdump -i wlan0 -w /data/local/tmp/cap.pcap抓完拉到本地用Wireshark分析注意抓包时长控制在30秒内否则文件太大。我自己的习惯是每次调试都先记录三件事wlan.ko的commit号、固件文件的md5、bdwlan.bin的来源。这个清单帮我挡掉过好几次“昨晚还好好的今天又不行了”的返工。希望帮到你。本文还有配套的精品资源点击获取
返回列表