AM335x CPSW 寄存器模块详细功能说明

一、CPSW 子系统整体架构

AM335x 集成了一个三端口交换子系统(3-Port Switch, CPSW),由多个子模块协同完成以太网帧的收发、交换、地址学习和管理功能。

                          AM335x CPSW 子系统 (基地址 0x4A100000)
┌─────────────────────────────────────────────────────────────────────────────┐
│                                                                             │
│  ┌──────────┐    ┌──────────┐    ┌──────────────────────────┐               │
│  │ CPSW_SS  │    │ CPSW_WR  │    │      CPSW_PORT           │               │
│  │ 0x4A100000│    │ 0x4A101200│    │      0x4A100100          │               │
│  │ 系统控制  │    │ 中断控制  │    │  ┌──────┬──────┬──────┐  │               │
│  └──────────┘    └──────────┘    │  │ P0   │ P1   │ P2   │  │               │
│                                   │  │ Host │百兆口│千兆口│  │               │
│                                   │  └──┬───┴──┬───┴──┬───┘  │               │
│                                   └─────┼──────┼──────┼──────┘               │
│                                         │      │      │                      │
│                                    ┌────▼──────▼──────▼────┐                 │
│                                    │     CPSW_ALE          │                 │
│                                    │     0x4A100D00        │                 │
│                                    │   地址查找/交换引擎     │                 │
│                                    └───────────────────────┘                 │
│                                         │      │                             │
│                              ┌──────────▼──┐ ┌─▼───────────┐                │
│                              │  CPSW_SL1   │ │  CPSW_SL2   │                │
│                              │ 0x4A100D80  │ │ 0x4A100DC0  │                │
│                              │  百兆MAC    │ │  千兆MAC    │                │
│                              └──────┬──────┘ └──────┬──────┘                │
│                                     │               │                        │
│                                     │  RMII         │  RGMII2               │
│                                     ▼               ▼                        │
│                                  JL1111          RTL8211F                    │
│                                                                             │
│  ┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐               │
│  │  CPDMA   │    │ STATERAM │    │  STATS   │    │  MDIO    │               │
│  │ 0x4A100800│    │ 0x4A100A00│    │ 0x4A100900│    │ 0x4A101000│               │
│  │ DMA引擎  │    │ DMA状态  │    │ 统计信息  │    │ PHY管理  │               │
│  └────┬─────┘    └────┬─────┘    └──────────┘    └──────────┘               │
│       │               │                                                      │
│       ▼               ▼                                                      │
│  ┌──────────────────────────┐                                                │
│  │      CPPI RAM            │                                                │
│  │      0x4A102000          │                                                │
│  │   收发描述符内存 (8KB)    │                                                │
│  └──────────────────────────┘                                                │
│                                                                             │
│  ========= 外部模块 =========                                                │
│  ┌──────────┐    ┌──────────────┐                                            │
│  │Ctrl Module│    │    GPIO      │                                            │
│  │0x44E10000 │    │ 0x44E07000等 │                                            │
│  │Pin Mux等  │    │ PHY复位/中断 │                                            │
│  └──────────┘    └──────────────┘                                            │
└─────────────────────────────────────────────────────────────────────────────┘

二、各寄存器模块详细说明

2.1 CPSW_SS — 交换子系统控制 (0x4A100000)

功能概述:整个 CPSW 三端口交换子系统的顶层控制模块,负责全局复位和统计使能。

宏定义:

#define CPSW_SS___S___(ofs, val)    REG32___S___(0x4A100000 + (ofs), val)
#define CPSW_SS_M_S_WZ(ofs, mask, val) REG32_M_S_WZ(0x4A100000 + (ofs), mask, val)

代码中使用的关键寄存器:

偏移寄存器名读写功能说明代码中的使用场景
0x0CSTAT_PORT_ENR/W统计端口使能。bit0=P0(Host), bit1=P1(百兆), bit2=P2(千兆)。使能后对应端口的收发帧计数器才开始工作CpswSsReset():写 _B(0)|_B(1)|_B(2) 使能全部三个端口的统计

在数据流中的角色:SS模块本身不参与数据收发,而是作为全局开关。如果不执行SS复位,其他子模块的状态可能不确定,导致驱动行为异常。


2.2 CPSW_PORT — 端口配置 (0x4A100100)

功能概述:配置三个交换端口(P0=Host主机端口、P1=百兆外部端口、P2=千兆外部端口)的VLAN、MAC地址、FIFO策略和最大帧长度等参数。

宏定义:

#define CPSW_PORT___S___(ofs, val)       REG32___S___(0x4A100100 + (ofs), val)
#define CPSW_PORT_M_S___(ofs, mask, val) REG32_M_S___(0x4A100100 + (ofs), mask, val)
#define CPSW_PORT_M_G___(ofs, mask)      REG32_M_G___(0x4A100100 + (ofs), mask)

代码中使用的关键寄存器:

偏移寄存器名所属端口功能说明代码使用场景
0x14P0_PORT_VLANP0Host端口默认VLAN。bit[11:0]=VLAN ID, bit[15:13]=优先级设为0x0,Host端口不带VLAN标签
0x114P1_PORT_VLANP1百兆口默认VLAN设为0x1,百兆口默认VLAN ID = 1
0x120P1_SA_LOP1百兆口源MAC地址低16位。bit[15:8]=MAC[0], bit[7:0]=MAC[1]CpswPortMacSet(1, mac):写入百兆口MAC
0x124P1_SA_HIP1百兆口源MAC地址高32位。bit[31:24]=MAC[2], ..., bit[7:0]=MAC[5]同上
0x214P2_PORT_VLANP2千兆口默认VLAN(仅P4板)设为0x2,千兆口默认VLAN ID = 2
0x220P2_SA_LOP2千兆口源MAC地址低16位CpswPortMacSet(2, mac)
0x224P2_SA_HIP2千兆口源MAC地址高32位同上

在数据流中的角色:

发送路径: CPU → P0(Host Port) → ALE查找 → P1或P2(外部端口) → PHY → 网线
接收路径: 网线 → PHY → P1或P2(外部端口) → ALE查找 → P0(Host Port) → CPDMA → CPU

P0_TX_IN_CTL 的双MAC模式确保:
  - P1和P2各自有独立的发送FIFO队列
  - 不会因为一个端口阻塞而影响另一个端口的发送

VLAN隔离机制:

               VLAN 1 (百兆域)        VLAN 2 (千兆域)
               ┌─────────────┐       ┌─────────────┐
               │ P0 ←→ P1    │       │ P0 ←→ P2    │
               │ (Host  百兆) │       │ (Host  千兆) │
               └─────────────┘       └─────────────┘
  
  百兆口收到的包只能到P0(CPU),不会转发到P2(千兆口)
  千兆口收到的包只能到P0(CPU),不会转发到P1(百兆口)
  → 通过ALE VLAN表项实现端口隔离

2.3 CPDMA — DMA控制引擎 (0x4A100800)

功能概述:CPDMA(Communications Port DMA)是CPSW的DMA引擎,负责在主机内存和CPSW之间搬运以太网帧数据。它管理8个TX通道和8个RX通道的DMA传输控制、中断产生和帧缓冲区偏移配置。

宏定义:

#define CPDMA___S___(ofs, val)           REG32___S___(0x4A100800 + (ofs), val)
#define CPDMA_M_S___(ofs, mask, val)     REG32_M_S___(0x4A100800 + (ofs), mask, val)
#define CPDMA_M_S_WZ(ofs, mask, val)     REG32_M_S_WZ(0x4A100800 + (ofs), mask, val)

代码中使用的关键寄存器:

偏移寄存器名读写功能说明代码使用场景
0x14RX_CONTROLR/WRX DMA全局使能。bit0: 0=禁用, 1=启用接收DMACpdmaReset():写1启用。DeviceInit()中再次确认启用
0x1CCPDMA_SOFT_RESETR/WDMA软复位。写1触发,等待变0CpdmaReset():初始化首步
0x28RX_BUFFER_OFFSETR/W接收缓冲区偏移。bit[15:0]指定帧数据在缓冲区中的起始偏移CpdmaReset():写0,数据从缓冲区首字节开始
0x88TX_INTMASK_SETR/WTX中断掩码设置。每位对应一个TX通道CpdmaReset():写0,不启用TX中断(采用轮询方式检查发送完成)
0x94CPDMA_EOI_VECTORR/W中断结束向量。写入中断类型编号以确认中断处理完成,允许产生后续中断每次中断ISR结尾必须写入对应类型值
0xA8RX_INTMASK_SETR/WRX中断掩码设置。每位对应一个RX通道CpdmaReset():写bit0,仅启用通道0的RX中断

EOI_VECTOR 值定义(写入0x94偏移):

值宏定义含义使用场景
1AM335X_ETH_INTTYPE_RX_PULSERX包中断结束RX ISR结尾
2AM335X_ETH_INTTYPE_TX_PULSETX中断结束TX ISR结尾
3AM335X_ETH_INTTYPE_MISC_PULSEMISC中断结束MISC ISR结尾(PHY链路变化等)

在数据流中的角色:

发送流程:
  CPU填充描述符 → 写TX_HDP[ch]启动DMA → CPDMA读取描述符链 → 
  从m_Buf读数据 → 推入CPSW发送FIFO → 清除Ownership位 → 设置EOQ

接收流程:
  CPSW收到帧 → CPDMA查找空闲RX描述符(Ownership=1) → 
  写入m_Buf → 填写帧长和标志 → 清除Ownership → 触发RX中断 → 
  CPU读取数据 → 回收描述符(重设Ownership=1, 重新挂入链表尾部)

2.4 CPDMA_STATERAM — DMA状态寄存器 (0x4A100A00)

功能概述:维护每个DMA通道的头描述符指针(HDP)和完成指针(CP)。HDP是DMA引擎的"发令枪",写入非零地址即启动该通道的DMA操作;CP用于中断确认和发送完成检测。

宏定义:

#define CPSW_TX_HDP___G___(ch)   REG32___G___(0x4A100A00 + (ch) * 4)
#define CPSW_TX_HDP___S___(ch, val) REG32___S___(0x4A100A00 + (ch) * 4, val)
#define CPSW_RX_HDP___G___(ch)   REG32___G___(0x4A100A20 + (ch) * 4)
#define CPSW_RX_HDP___S___(ch, val) REG32___S___(0x4A100A20 + (ch) * 4, val)
#define CPSW_TX_CP___G___(ch)    REG32___G___(0x4A100A40 + (ch) * 4)
#define CPSW_TX_CP___S___(ch, val)  REG32___S___(0x4A100A40 + (ch) * 4, val)
#define CPSW_RX_CP___G___(ch)    REG32___G___(0x4A100A60 + (ch) * 4)
#define CPSW_RX_CP___S___(ch, val)  REG32___S___(0x4A100A60 + (ch) * 4, val)

完整寄存器映射:

偏移范围寄存器组通道数说明
0xA20~0xA3CRX_HDP[0~7]8RX头描述符指针。写入描述符地址启动接收
0xA40~0xA5CTX_CP[0~7]8TX完成指针。DMA完成后硬件更新
0xA60~0xA7CRX_CP[0~7]8RX完成指针。DMA完成后硬件更新,写回以确认

本驱动的通道使用方案:

通道TX用途RX用途
1Port2(千兆)发送未使用
2~7未使用未使用

HDP/CP 在收发中的工作机制:

TX发送启动:
  ┌──────────────────────────────────────────────────────┐
  │ 1. CPU准备好描述符链(设置SOP/EOP/Ownership/To_Port) │
  │ 2. 写 TX_HDP[ch] = 第一个描述符的地址                 │
  │ 3. DMA引擎开始遍历描述符链,逐个发送                   │
  │ 4. 发送完成后,DMA清除Ownership位                     │
  │ 5. 到达链尾(NextDesc=NULL),DMA设置EOQ位并停止        │
  │ 6. TX_HDP[ch] 自动变为0                              │
  └──────────────────────────────────────────────────────┘

RX接收启动:
  ┌──────────────────────────────────────────────────────┐
  │ 1. CPU准备好空描述符链(设置Ownership=1, BufLen)      │
  │ 2. 写 RX_HDP[0] = 第一个描述符的地址                  │
  │ 3. 收到帧 → DMA写入缓冲区,填写帧长/From_Port等       │
  │ 4. DMA清除Ownership位,更新RX_CP[0]                  │
  │ 5. 触发RX中断                                        │
  │ 6. ISR中:读RX_CP[0],写回RX_CP[0]确认                │
  │ 7. CPU处理数据后,回收描述符挂到链尾                    │
  └──────────────────────────────────────────────────────┘

2.5 CPSW_ALE — 地址查找引擎 (0x4A100D00)

功能概述:ALE(Address Lookup Engine)是CPSW的核心交换引擎,负责根据MAC地址和VLAN进行帧转发决策。它维护一个1024条目的地址表,支持学习、老化、VLAN过滤和多播/广播泛洪。

宏定义:

#define CPSW_ALE___S___(ofs, val)        REG32___S___(0x4A100D00 + (ofs), val)
#define CPSW_ALE_M_S___(ofs, mask, val)  REG32_M_S___(0x4A100D00 + (ofs), mask, val)
#define CPSW_ALE___G___(ofs)             REG32___G___(0x4A100D00 + (ofs))

代码中使用的关键寄存器:

偏移寄存器名功能说明代码使用场景
0x10ALE_PRESCALEALE预分频器。bit[19:0]控制老化和速率限制的时间基准初始化时设为0xFFFFF
0x20ALE_TBLCTL表控制。bit31=写(1)/读(0), bit[9:0]=表项索引读写ALE表项时使用
0x34ALE_TBLW2表字2 (bit 71:64)写入/读出ALE表项的高8位
0x38ALE_TBLW1表字1 (bit 63:32)写入/读出ALE表项的中32位
0x3CALE_TBLW0表字0 (bit 31:0)写入/读出ALE表项的低32位
0x40+n*4ALE_PORTCTL[n]端口n控制。bit[1:0]=转发状态(0x03=Forward), bit11=MAC_ONLY所有端口设为Forward模式

ALE 表项结构(72位):

本驱动使用两种表项类型:

VLAN 表项 (EntryType=2):

  71       62  61-60  59--------48  47---27  26----24  23-19  18---16  15-11  10---8  7-3  2---0
┌─────────┬──────┬───────────────┬────────┬─────────┬──────┬────────┬──────┬───────┬─────┬──────┐
│Reserved │Type=2│   VLAN ID     │Reserved│ForceUntag│Rsrvd │RegMcast│Rsrvd │UnregMc│Rsrvd│Member│
│         │      │   (12bit)     │        │ Egress  │      │FloodMsk│      │FldMsk │     │ List │
└─────────┴──────┴───────────────┴────────┴─────────┴──────┴────────┴──────┴───────┴─────┴──────┘
表项索引VLAN ID成员端口说明
22P0+P2 (0x05)千兆VLAN:Host端口和Port2互通

VLAN 单播表项 (EntryType=3):

  71-68  67---66  65  64  63-62  61-60  59--------48  47-----------------------------------------0
┌──────┬────────┬────┬──────┬──────┬──────┬───────────────┬──────────────────────────────────────────┐
│Rsrvd │PortNum │Blk │Secure│UcType│Type=3│   VLAN ID     │          48-bit MAC Address              │
│      │(转发至) │    │      │      │      │   (12bit)     │                                          │
└──────┴────────┴────┴──────┴──────┴──────┴───────────────┴──────────────────────────────────────────┘
表项索引VLAN IDMAC地址PortNum说明
32D2:72:22:50:00:810 (Host)千兆口MAC,收到目标为此MAC的帧转发到CPU

ALE在数据流中的角色:

接收帧到达时:
  帧进入Port1/Port2 → ALE提取源MAC和目标MAC →
  ┌─ 目标MAC匹配单播表项 → 转发到表项指定的端口(Host Port 0)
  ├─ 目标MAC是广播地址 → 按VLAN成员列表泛洪
  ├─ 目标MAC是多播地址 → 按多播泛洪掩码转发
  └─ 目标MAC未匹配 → 按未注册多播泛洪掩码处理

发送帧离开时:
  CPU通过CPDMA发送 → 描述符中To_Port_En=1, To_Port=1或2 →
  ALE仍执行查找,但定向发送优先 → 帧从指定端口发出

2.6 CPSW_SL1 / CPSW_SL2 — MAC Sliver (0x4A100D80 / 0x4A100DC0)

功能概述:Sliver(薄片)是每个外部端口的MAC层控制器,负责管理物理链路参数:速度、双工模式、GMII使能、流控和环回等。每个外部端口有一个独立的Sliver。

宏定义:

// slIdx: 0=SL1(百兆), 1=SL2(千兆)
#define CPSW_SL_M_S___(slIdx, ofs, mask, val)  REG32_M_S___(0x4A100D80 + (slIdx)*0x40 + (ofs), mask, val)
#define CPSW_SL_M_S_WZ(slIdx, ofs, mask, val)  REG32_M_S_WZ(0x4A100D80 + (slIdx)*0x40 + (ofs), mask, val)

地址映射:

Sliver基地址slIdx对应端口
SL20x4A100DC01Port2 千兆口

代码中使用的关键寄存器:

偏移寄存器名功能说明代码使用场景
0x0CSOFT_RESETSliver软复位。写1,等待变0CpswSlReset():端口初始化时复位MAC层

MACCONTROL 各位详解(偏移 0x04):

位字段说明10M半双工10M全双工100M半双工100M全双工1000M半双工1000M全双工
16IFCTL_BRMII速度选择:0=10M, 1=100M001100
15IFCTL_ARMII速度选择(与IFCTL_B相同)001100
7GIG千兆模式:0=10/100M, 1=1000M000011
5GMII_ENMAC收发使能(所有模式必须=1)111111
0FULLDUPLEX双工选择:0=半双工, 1=全双工010101

在数据流中的角色:

Sliver是MAC层的"最后一道关卡"。GMII_EN=0时,无论CPDMA如何操作,帧都无法从物理端口发出或接收。PHY线程检测到链路变化后,通过此寄存器告知MAC当前链路的速度和双工模式,MAC据此调整时序。

PHY线程检测到链路UP(100M全双工) →
  CpswSlLinkModeSet(slIdx=0, kEthLinkMode100MFullDuplex) →
    写 SL1 MACCONTROL = IFCTL_B | IFCTL_A | GMII_EN | FULLDUPLEX
    即 bit16 | bit15 | bit5 | bit0 = 0x18021

2.7 MDIO — PHY管理接口 (0x4A101000)

功能概述:MDIO(Management Data Input/Output)模块通过两线串行总线(MDC/MDIO)访问外部PHY芯片的寄存器,用于PHY配置、状态查询和链路监控。两个PHY共享同一个MDIO控制器,通过不同的PHY地址区分。

宏定义:

#define MDIO___S___(ofs, val)           REG32___S___(0x4A101000 + (ofs), val)
#define MDIO_M_S___(ofs, mask, val)     REG32_M_S___(0x4A101000 + (ofs), mask, val)
#define MDIO_M_G___(ofs, mask)          REG32_M_G___(0x4A101000 + (ofs), mask)
#define MDIO_M___WZ(ofs, mask)          REG32_M___WZ(0x4A101000 + (ofs), mask)

代码中使用的关键寄存器:

偏移寄存器名功能说明代码使用场景
0x10LINKINTRAW链路中断原始状态。bit0=PHYSEL0(百兆PHY), bit1=PHYSEL1(千兆PHY)。写1清除MiscIntDeal():判断哪个PHY产生链路变化
0x20USERINTRAW用户命令完成中断原始状态。bit0=ACCESS0完成, bit1=ACCESS1完成。写1清除MdioUserIntClr()
0x80USERACCESS0用户访问寄存器0。bit31=GO(启动), bit30=WRITE(写模式), bit29=ACK(读确认), bit[25:21]=RegAddr, bit[20:16]=PhyAddr, bit[15:0]=DataMdioRead()/MdioWrite():读写PHY寄存器
0x84USERPHYSEL0PHY选择0。bit6=链路中断使能, bit[4:0]=监控的PHY地址MdioConfigPhyMonitor(1,1):监控PHY地址1(百兆)
0x8CUSERPHYSEL1PHY选择1。同上MdioConfigPhyMonitor(2,2):监控PHY地址2(千兆)

MDIO读写时序:

MDIO读操作 (MdioRead):
  1. 等待 USERACCESS0.GO == 0 (上次操作完成)
  2. 写 USERACCESS0 = GO(1) | WRITE(0) | RegAddr | PhyAddr
  3. 等待 USERACCESS0.GO == 0 (本次操作完成)
  4. 检查 ACK位: 
     ACK=1 → 读取 DATA[15:0] 返回
     ACK=0 → 返回-1 (PHY无应答)

MDIO写操作 (MdioWrite):
  1. 等待 USERACCESS0.GO == 0
  2. 写 USERACCESS0 = GO(1) | WRITE(1) | RegAddr | PhyAddr | Data
  3. 等待 USERACCESS0.GO == 0

PHY监控机制:

MDIO控制器内置PHY链路监控状态机:
  ┌────────────────────────────────────────────────────────┐
  │ USERPHYSEL0 (偏移0x84)                                 │
  │   监控 PHY地址=1 (百兆JL1111)                           │
  │   链路状态变化 → 置位 LINKINTRAW.bit0                    │
  │                → 触发 CPSW_WR MISC中断                  │
  │                → EthCpswMiscIsr                         │
  │                → EthPhyEventSend(1)                     │
  │                → PHY线程被唤醒,读取PHY寄存器确认链路状态  │
  ├────────────────────────────────────────────────────────┤
  │ USERPHYSEL1 (偏移0x8C)                                 │
  │   监控 PHY地址=2 (千兆RTL8211F)                         │
  │   链路状态变化 → 置位 LINKINTRAW.bit1                    │
  │                → 同上流程,EthPhyEventSend(2)            │
  └────────────────────────────────────────────────────────┘

2.8 CPSW_WR — 中断包装器 (0x4A101200)

功能概述:WR(Wrapper)模块是CPSW中断系统的路由和使能控制器。它将CPDMA产生的各类中断(RX/TX/Threshold/Misc)路由到ARM Cortex-A8的中断控制器,并提供中断状态查询接口。

宏定义:

#define CPSW_WR_M_S___(ofs, mask, val) REG32_M_S___(0x4A101200 + (ofs), mask, val)
#define CPSW_WR_M_G___(ofs, mask)      REG32_M_G___(0x4A101200 + (ofs), mask)
#define CPSW_WR_M_S_WZ(ofs, mask, val) REG32_M_S_WZ(0x4A101200 + (ofs), mask, val)

代码中使用的关键寄存器:

偏移寄存器名功能说明代码使用场景
0x14C0_RX_ENCore0 RX中断使能。bit[7:0]每位对应一个RX通道写bit0:仅使能RX通道0的中断到CPU
0x1CC0_MISC_ENCore0 Misc中断使能。bit4=event, bit3=stat, bit2=host, bit1=mdio_link, bit0=mdio_user写bit1:仅使能MDIO链路变化中断
0x4CC0_MISC_STATCore0 Misc中断状态(只读)。位定义同C0_MISC_ENCpswWrMiscStatus():MISC ISR中读取,判断中断源

中断路由架构:

  CPDMA/MDIO 中断源                CPSW_WR 路由                ARM INTC
  ┌─────────────────┐          ┌──────────────┐          ┌──────────────┐
  │ RX CH0 完成     ├─────────►│ C0_RX_EN.b0  ├─────────►│ CPSW_RX_INT0 │
  │ RX CH1 完成     │     ╳    │ C0_RX_EN.b1  │          │              │
  │ ...             │          │ ...           │          │              │
  ├─────────────────┤          ├──────────────┤          ├──────────────┤
  │ TX CH0 完成     │     ╳    │ C0_TX_EN.b0  │          │ CPSW_TX_INT0 │
  │ ...             │          │ ...           │          │              │
  ├─────────────────┤          ├──────────────┤          ├──────────────┤
  │ MDIO Link变化   ├─────────►│C0_MISC_EN.b1 ├─────────►│CPSW_MISC0_INT│
  │ MDIO User完成   │     ╳    │C0_MISC_EN.b0 │          │              │
  │ Host错误        │     ╳    │C0_MISC_EN.b2 │          │              │
  │ Stat溢出        │     ╳    │C0_MISC_EN.b3 │          │              │
  └─────────────────┘          └──────────────┘          └──────────────┘
                                ╳ = 未使能(本驱动未使用)

2.9 CPSW_STATS — 统计寄存器 (0x4A100900)

功能概述:统计模块维护每个端口的以太网帧收发计数器,用于网络诊断和性能监控。读取后写回相同值可清零对应计数器。

宏定义:

#define CPSW_STATS___G___(ofs)      REG32___G___(0x4A100900 + (ofs))
#define CPSW_STATS___S___(ofs, val) REG32___S___(0x4A100900 + (ofs), val)

统计寄存器映射(按 EthCpswStats 结构体顺序):

偏移字段名说明诊断用途
0x04BroadcastRxFrames接收到的广播帧总数广播风暴检测
0x08MulticastRxFrames接收到的多播帧总数多播流量监控
0x0CPauseRxFrames接收到的暂停帧数流控诊断
0x10RxCrcErrorsCRC错误帧数物理层/线缆质量
0x14RxAlignOrCodeErrors对齐/编码错误帧数物理层/PHY问题
0x18OversizeRxFrames超大帧数MTU配置问题
0x1CRxJabbersJabber帧数PHY硬件故障
0x20UndersizeRxFrames欠大小帧数碰撞/截断
0x24RxFragments帧片段数碰撞残留
0x28RxOctets接收总字节数带宽统计
0x2CGoodTxFrames发送的良好帧总数基础发包计数
0x30BroadcastTxFrames发送的广播帧总数—
0x34MulticastTxFrames发送的多播帧总数—
0x38PauseTxFrames发送的暂停帧数流控诊断
0x3CDeferredTxFrames延迟发送帧数半双工竞争
0x40Collisions碰撞总次数半双工模式碰撞
0x44SingleCollisionTxFrames单次碰撞后成功帧数—
0x48MultipleCollisionTxFrames多次碰撞后成功帧数—
0x4CExcessiveCollisions因过度碰撞丢弃的帧数严重碰撞问题
0x50LateCollisions因晚碰撞丢弃的帧数线缆过长/双工不匹配
0x54TxUnderrun发送欠载数DMA/CPU性能不足
0x58CarrierSenseErrors载波侦测错误数物理连接问题
0x5CTxOctets发送总字节数带宽统计
0x60RxTx0T64OctetFrames0~64字节帧数帧长分布
0x64RxTx65T127OctetFrames65~127字节帧数—
0x68RxTx128T255OctetFrames128~255字节帧数—
0x6CRxTx256T511OctetFrames256~511字节帧数—
0x70RxTx512T1023OctetFrames512~1023字节帧数—
0x74RxTx1024UpOctetFrames1024+字节帧数—
0x78NetOctets收发总字节数总带宽
0x7CRxStartOfFrameOverrunsSOF溢出数CPDMA来不及处理
0x80RxMiddleofFrameOverrunsMOF溢出数CPDMA处理中溢出
0x84RxDmaOverrunsDMA溢出数描述符耗尽

代码中特别关注的两个计数器:

#define CPSW_STAT_TX_UNDERRUN    0x54  // 发送欠载
#define CPSW_STAT_RX_UNDERRUN    0x84  // DMA溢出(代码中命名为RxUnderrun实为RxDmaOverruns)

// EthHwApi 提供给上层的接口:
uint32_t EthHwApi::CpswGetTxErrCount() → 读 0x54 并清零
uint32_t EthHwApi::CpswGetRxErrCount() → 读 0x84 并清零

2.10 CPPI RAM — 描述符内存 (0x4A102000)

功能概述:CPPI RAM是CPSW内部的8KB SRAM,专门用于存放DMA描述符(Buffer Descriptor)。描述符不能放在外部DDR中,必须位于此区域。实际的帧数据缓冲区则位于DDR中。

地址范围:0x4A102000 ~ 0x4A103FFF (8192字节)

宏定义:

#define AM335X_CPSW_CPPI_RAM_REGS  (0x4A102000)
#define AM335X_CPSW_CPPI_RAM_SIZE  (8192)

访问约束:只能32位对齐访问,不支持字节或半字访问。

内存布局(本驱动):

0x4A102000 ┌──────────────────────────────────────┐
           │  TX 描述符区 (4096 字节)                │
           │                                        │
           │  ┌── Port1 TX描述符 ──────────────────┐│
           │  │ Desc[0]: NextDesc|Buf|BufLen|Flag  ││  每个描述符16字节
           │  │ Desc[1]: ...                       ││  共 CPSW_TX_DESC_NUMS/2 个
           │  │ ...                                ││  = 4096/16/2 = 128 个
           │  └────────────────────────────────────┘│
           │  ┌── Port2 TX描述符 ──────────────────┐│
           │  │ Desc[0]: NextDesc|Buf|BufLen|Flag  ││
           │  │ ...                                ││  同样128个
           │  └────────────────────────────────────┘│
0x4A103000 ├──────────────────────────────────────┤
           │  RX 描述符区 (4096 字节) - 共享        │
           │                                        │
           │  ┌── 共享RX描述符链 ─────────────────┐ │
           │  │ Desc[0] → Desc[1] → ... → Desc[N] │ │
           │  │                             ↓ NULL │ │  共 256 个
           │  └────────────────────────────────────┘│
0x4A103FFF └──────────────────────────────────────┘

描述符字段与硬件交互:

单个描述符 (EthDesc, 16字节):
  +0  m_NextDesc   ← CPU设置链表关系,DMA遍历
  +4  m_Buf        ← CPU设置,指向DDR中的数据缓冲区
  +8  m_BufLenOrOfs ← CPU设置长度,DMA可能在RX时覆写
  +12 m_DescFlag   ← CPU和DMA都会读写

TX描述符标志位 (m_DescFlag):
  bit31 SOP          CPU设置   帧起始
  bit30 EOP          CPU设置   帧结束
  bit29 Ownership    CPU设置1→DMA清0   所有权转移
  bit28 EOQ          DMA设置   队列结束(用于追加检测)
  bit20 To_Port_En   CPU设置   定向发送使能
  bit[17:16] To_Port CPU设置   目标端口(1=百兆, 2=千兆)
  bit[10:0] Pkt_Len  CPU设置   帧总长度

RX描述符标志位 (m_DescFlag):
  bit31 SOP          DMA设置   帧起始
  bit30 EOP          DMA设置   帧结束
  bit29 Ownership    CPU设置1→DMA清0   所有权转移
  bit28 EOQ          DMA设置   队列结束
  bit[18:16] From_Port  DMA设置   来源端口(1=百兆, 2=千兆)
  bit[10:0] Pkt_Len  DMA设置   帧总长度

2.11 Control Module — 引脚复用与系统控制 (0x44E10000)

功能概述:Control Module是AM335x的系统级配置模块,包含引脚复用(Pin Mux)、器件ID、安全控制、时钟控制等。以太网驱动中主要使用它的Pin Mux功能和GMII接口选择。

宏定义:

#define CTLM___S___(ofs, val)           REG32___S___(0x44E10000 + (ofs), val)
#define CTLM_M_S___(ofs, mask, val)     REG32_M_S___(0x44E10000 + (ofs), mask, val)

以太网相关关键寄存器:

偏移寄存器名功能说明代码使用场景
0x800~0xB48CONF_xxx引脚复用配置(约200个)Pin Mux初始化

GMII_SEL 寄存器 (偏移 0x650) 位域:

位字段说明本驱动配置
3:2GMII2_SELPort2接口模式:同上10 (RGMII) — 仅P4板
5RGMII2_IDMODEPort2 RGMII内部延迟模式1 — 仅P4板
6RMII1_IO_CLK_ENPort1 RMII参考时钟来源:0=内部, 1=外部1 (外部50MHz晶体)

引脚复用寄存器通用格式:

所有 CONF_xxx 寄存器共用同一位域结构(参见引脚文档),通过 MuxApi::Init() 在启动时批量配置。以太网相关引脚的Mux配置在 kP1P2P3Cfgs[] 和 kP4Cfgs[] 数组中。


2.12 GPIO — 通用输入输出 (0x44E07000 / 0x4804C000 / 0x481AC000 / 0x481AE000)

功能概述:AM335x有4组GPIO(GPIO0~GPIO3),每组32个引脚。以太网驱动中GPIO用于PHY硬件复位、缓冲器控制和LED指示。

各Bank基地址:

GPIO Bank基地址以太网相关引脚
GPIO10x4804C000GPIO1_16: CPU LED(非P4板), GPIO1_28: M3_RTCIn(P4板)
GPIO20x481AC000未使用
GPIO30x481AE000GPIO3_9: RGMII2缓冲器使能+RTL8211F复位, GPIO3_7: CPU LED(P4板)

GPIO寄存器偏移(每个Bank内部相同):

偏移寄存器名功能代码使用场景
0x138GPIO_DATAIN输入数据读取(只读)Get():读取引脚电平
0x190GPIO_CLEARDATAOUT输出清零。写1清除对应位Clr():GPIO3_9拉低(复位PHY)
0x194GPIO_SETDATAOUT输出置位。写1设置对应位Set():GPIO3_9拉高(释放复位)

GPIO3_9 在千兆口初始化中的操作序列:

// 代码位于 EthGmiiSel() 中 port==2 分支
auto* pin = &s_EnableRgmii2Pin;    // PintGp{3, 9} → GPIO3 Bank, Pin 9
pin->ConfigOutput();                // GPIO3_OE bit9 = 0 (设为输出)
pin->Clr();                        // GPIO3_CLEARDATAOUT = _B(9) → 拉低
Gtc::MsDelay(20);                  // 保持20ms:复位PHY + 禁用缓冲器
pin->Set();                        // GPIO3_SETDATAOUT = _B(9) → 拉高  
Gtc::MsDelay(100);                 // 等待100ms:PHY从复位恢复

三、寄存器模块在数据收发中的协作关系

3.1 发送一帧数据的完整寄存器交互

用户调用 EthTx(dev, pbuf)
  │
  │ ① CPU操作 CPPI RAM (0x4A102000)
  │    填写TX描述符: NextDesc, Buf指针, BufLen, DescFlag
  │    DescFlag = SOP|EOP|Ownership|To_Port_En|To_Port=port|PktLen
  │
  │ ② CPU写 STATERAM TX_HDP[ch] (0x4A100A00+ch*4)
  │    写入描述符地址,启动DMA发送
  │
  │ ③ CPDMA (0x4A100800) DMA引擎工作
  │    读取描述符 → 从DDR搬运帧数据 → 推入CPSW发送FIFO
  │
  │ ④ ALE (0x4A100D00) 地址查找
  │    根据To_Port定向发送 → 确定出口端口
  │    检查VLAN成员关系
  │
  │ ⑤ CPSW_SL (0x4A100D80/DC0) MAC层发送
  │    根据MACCONTROL寄存器的速度/双工设置
  │    通过RMII/RGMII物理接口发出帧
  │
  │ ⑥ CPDMA 完成
  │    清除描述符Ownership位
  │    如果是链尾,设置EOQ位
  │    STATERAM TX_HDP[ch] 变为0
  │
  │ ⑦ STATS (0x4A100900) 更新
  │    GoodTxFrames++, TxOctets+=帧长, ...
  ▼

3.2 接收一帧数据的完整寄存器交互

网线上有数据到达
  │
  │ ① PHY → CPSW_SL (0x4A100D80/DC0)
  │    RMII/RGMII接口接收物理层数据
  │    MAC层去除前导码、检查CRC
  │
  │ ② ALE (0x4A100D00) 地址查找
  │    提取目标MAC → 查找ALE表
  │    匹配VLAN单播条目 → 转发到P0(Host Port)
  │    填写From_Port字段
  │
  │ ③ CPDMA (0x4A100800) DMA引擎工作
  │    从发送FIFO取出帧数据
  │    查找CPPI RAM中Ownership=1的RX描述符
  │    将帧数据写入描述符指向的DDR缓冲区
  │    填写BufLen、DescFlag(SOP|EOP|From_Port|PktLen)
  │    清除Ownership位
  │
  │ ④ STATERAM RX_CP[0] (0x4A100A60) 更新
  │    指向最后完成的描述符
  │
  │ ⑤ CPSW_WR (0x4A101200) 中断路由
  │    C0_RX_EN.bit0=1 → 触发CPSW_RX_INT0到ARM
  │
  │ ⑥ ARM INTC → EthCpswRxIsr
  │    读 RX_CP[0]
  │    调用 eth_device_ready() 通知协议栈
  │    写回 RX_CP[0] 确认
  │    写 CPDMA EOI_VECTOR = 1 (RX_PULSE)
  │
  │ ⑦ 协议栈线程调用 EthRx
  │    读取CPPI RAM描述符的From_Port字段
  │    分配pbuf,从DDR缓冲区拷贝数据
  │    回收描述符(重设Ownership=1,挂回链尾)
  │    如果EOQ被设置,重新写RX_HDP[0]重启接收
  │
  │ ⑧ STATS (0x4A100900) 更新
  │    GoodRxFrames++, RxOctets+=帧长, ...
  ▼

3.3 PHY链路变化的完整寄存器交互

网线插入/拔出
  │
  │ ① PHY硬件检测到链路变化
  │
  │ ② MDIO (0x4A101000) 链路监控状态机
  │    USERPHYSEL0/1 持续监控指定PHY地址的链路状态
  │    检测到变化 → 置位 LINKINTRAW.bit0 或 bit1
  │
  │ ③ CPSW_WR (0x4A101200) 中断路由
  │    C0_MISC_EN.bit1=1 → 触发CPSW_MISC0_INT到ARM
  │
  │ ④ ARM INTC → EthCpswMiscIsr
  │    读 WR C0_MISC_STAT (0x4C) → 判断是MDIO_LINKINT
  │    读 MDIO LINKINTRAW (0x10) → 判断是哪个PHY
  │    清除 LINKINTRAW 对应位
  │    发送事件 EthPhyEventSend(port)
  │    写 CPDMA EOI_VECTOR = 3 (MISC_PULSE)
  │
  │ ⑤ PHY线程被事件唤醒
  │    通过 MDIO USERACCESS0 (0x80) 读取PHY寄存器:
  │      BMSR (Reg 0x01) → 链路状态和自协商完成
  │      GBSR (Reg 0x0A) → 千兆协商结果
  │      ANLPAR (Reg 0x05) → 百兆协商结果
  │
  │ ⑥ 根据协商结果配置 CPSW_SL MACCONTROL (0x04)
  │    设置 GIG/IFCTL/GMII_EN/FULLDUPLEX 等位
  │
  │ ⑦ 通知协议栈 eth_device_linkchange(UP/DOWN)
  ▼

四、寄存器基地址完整汇总表

模块基地址大小类别数据流角色初始化顺序
GPIO00x44E070004KB系统中断/通用IO—
GPIO10x4804C0004KB系统LED/M3_RTCIn—
GPIO20x481AC0004KB系统未使用—
GPIO30x481AE0004KB系统PHY复位/RGMII2缓冲器①
CPSW_SS0x4A100000256B交换全局复位/统计使能②
CPSW_PORT0x4A100100768B交换端口VLAN/MAC/FIFO配置⑥
CPDMA0x4A100800256BDMADMA引擎控制/中断/复位④
CPSW_STATS0x4A100900144B统计收发帧计数器(诊断用)(运行时读取)
CPDMA_STATERAM0x4A100A00128BDMAHDP/CP指针(启动/确认DMA)④
CPPI RAM0x4A1020008KBDMA收发描述符存储④
CPSW_ALE0x4A100D00128B交换地址查找/VLAN/转发决策⑤⑦
CPSW_SL10x4A100D8064BMAC百兆口MAC层控制⑥
CPSW_SL20x4A100DC064BMAC千兆口MAC层控制⑥
MDIO0x4A101000256B管理PHY寄存器读写/链路监控⑤
CPSW_WR0x4A101200256B中断中断路由/使能/状态③
初始化顺序编号对应 EthRegApi::Init() 中的调用顺序: ⓪ Pin Mux (MuxApi::Init) → ① GPIO (EthGmiiSel) → ② SS复位 → ③ WR复位 → ④ CPDMA复位(含CPPI RAM和STATERAM) → ⑤ MDIO复位+ALE初始化 → ⑥ SL复位+Port配置 → ⑦ ALE表项添加+MDIO PHY监控