第二讲:WiFi芯片架构解析——MAC层与PHY层分工、基带处理器与射频前端、SDIO/USB/SPI主机接口、内部DMA与数据流

各位同学,今天我们来聊聊WiFi芯片的内部架构。说实话,很多做驱动的朋友,写了几年代码,对芯片内部到底怎么工作的,还是一知半解。我个人觉得,搞懂架构,比背一百个API都管用。

你想想看,WiFi芯片说白了就是个微型计算机。它有自己的CPU、内存、总线,还有专门的硬件加速器。只不过它的任务很专一——把数据变成电磁波发出去,再把电磁波变回数据收进来。

MAC层与PHY层的分工

WiFi芯片内部最核心的分工,就是MAC层和PHY层。这两层的关系,我习惯用一个比喻:MAC层是快递公司的调度中心,PHY层是送货的卡车司机

MAC层负责什么呢?它管的是“什么时候发、发给谁、发完没收到怎么办”。具体来说:

  • 帧封装与解析:把上层来的数据包,加上MAC头、FCS校验尾巴
  • CSMA/CA介质访问控制:监听信道,退避算法,避免碰撞
  • ACK确认与重传:发出去的帧没收到ACK,就得重传
  • 分片与聚合:大包拆小包,或者小包合并成大包
  • 加密与解密:WPA2/WPA3的加解密操作

而PHY层呢?它只管一件事——把MAC层交过来的比特流,变成无线电信号打出去。反过来,把天线收到的微弱信号,解调成比特流交给MAC层。

重要分界线:MAC层和PHY层之间,通常有一条明确的接口,叫MII(Media Independent Interface)。在驱动开发中,这条接口就是我们配置和监控PHY状态的关键通道。

我在项目中遇到过一个问题:某个WiFi模块在弱信号下频繁断连。查了半天,发现是MAC层的重传超时设置得太短,PHY层还在努力解调,MAC层已经放弃了。说白了,两层之间的参数配合没做好

基带处理器与射频前端

PHY层内部,又分成两大块:基带处理器(Baseband)射频前端(RF Front-End)

基带处理器干的是数字活。它把MAC层来的数字比特流,进行编码、调制、加扰、OFDM子载波映射……这些全是数学运算。我刚开始接触时,看到那些FFT、卷积编码的硬件模块,头都大了。后来发现,你不需要懂全部算法细节,但要知道每个模块的寄存器怎么配

射频前端干的是模拟活。它把基带处理好的数字信号,通过DAC变成模拟信号,再上变频到2.4GHz或5GHz,最后经过功率放大器(PA)送到天线。接收路径反过来:天线→低噪声放大器(LNA)→下变频→ADC→基带。

模块 工作性质 驱动关注点
基带处理器 数字信号处理 调制方式配置、信道带宽、AGC参数
射频前端 模拟信号处理 发射功率、接收灵敏度、频率校准

个人经验:调试射频前端时,千万别只看寄存器值。拿频谱仪看实际发射出来的信号,比读一百遍datasheet都管用。我曾经被一个PA的偏置电压问题坑了整整三天,寄存器读出来全是对的,但信号就是出不去。

SDIO/USB/SPI主机接口

WiFi芯片和主控CPU之间怎么通信?靠的就是主机接口。常见的三种:SDIO、USB、SPI

这三种接口,我按自己的理解排个序:

  • SDIO:吞吐量最高,延迟最低,适合高性能WiFi。但协议复杂,驱动开发最头疼。我记得第一次调SDIO WiFi驱动,光初始化序列就折腾了两周。
  • USB:通用性好,很多SoC都带USB主机。但USB的协议开销大,小包传输效率低。做物联网产品时,如果数据量不大,我建议慎用USB。
  • SPI:最简单,最省引脚,适合低功耗、低吞吐的场景。但SPI没有流控机制,数据量大时容易丢包。

选哪种接口,取决于你的产品定位。做路由器,SDIO是首选。做智能家居传感器,SPI就够了。做USB网卡,那当然用USB。

避坑指南:我曾经在一个项目里,为了省成本选了SPI接口的WiFi模块。结果产品上市后,用户反映视频传输卡顿。一查,SPI时钟频率跑不到理论值,因为PCB走线太长,信号完整性不行。嗯,这里要注意——接口选型不只是看协议,还要看硬件实现

内部DMA与数据流

数据在WiFi芯片内部怎么流动?这就要说到DMA了。

WiFi芯片内部通常有多个DMA引擎:

  • 主机接口DMA:负责在主机内存和芯片内部缓冲区之间搬运数据
  • MAC层DMA:负责在MAC层和PHY层之间搬运帧数据
  • 描述符DMA:负责搬运描述符(描述数据包位置和大小的元数据)

数据流的典型路径是这样的:

  1. 主机CPU把要发送的数据写到内存,构建一个发送描述符
  2. 主机接口DMA读到描述符,知道数据在哪,开始搬运到芯片内部的TX FIFO
  3. MAC层从TX FIFO取数据,加上MAC头,计算FCS,交给PHY层
  4. PHY层基带处理,射频前端发射

接收路径反过来:

  1. 射频前端收到信号,基带解调,得到比特流
  2. MAC层检查FCS,去掉MAC头,把数据放到RX FIFO
  3. 主机接口DMA从RX FIFO把数据搬回主机内存
  4. 主机CPU收到中断,知道有新数据到了

关键点:整个数据流中,描述符管理是驱动开发的核心。描述符写错了,数据就丢了。描述符用完了,DMA就停了。我见过太多驱动问题,最后都归结为描述符池管理不当。

举个例子,发送描述符的结构通常长这样:

struct tx_descriptor {
    uint32_t addr;      // 数据缓冲区物理地址
    uint16_t length;    // 数据长度
    uint16_t flags;     // 控制标志(是否需要ACK、加密方式等)
    uint32_t next;      // 下一个描述符的地址(链表结构)
};

驱动要做的事,就是维护一个描述符环(Descriptor Ring)。发送时,往环里塞描述符,通知DMA开始搬。接收时,从环里取回填好的描述符,把数据交给协议栈。

我记得有一次,一个同事调了三天,WiFi就是发不出数据。最后发现,描述符的地址字段写的是虚拟地址,不是物理地址。DMA只认物理地址,当然搬了个寂寞。这种坑,踩过一次就记住了。

好了,这一讲的内容就到这里。WiFi芯片架构,说白了就是一条数据流水线:主机→接口→MAC→基带→射频→天线。每一段都有它的寄存器、DMA、中断机制。搞懂了这条流水线,驱动开发就有了全局视野。

下一讲,我们会深入SDIO接口的驱动开发,到时候手把手教你写一个SDIO WiFi的初始化序列。