|
mhsxbbxr04l64066433858.gif
# V& S1 W' S$ @
点击上方蓝色字体,关注我们- L6 k7 L: E" j/ g7 M
来源于小伙伴提问:4 R# a8 h# n& B2 M0 ]! u
7 ]4 V2 Y- i; u4 R& ]: p/ x
ocsbogin2pq64066433958.png
2 o9 w8 ]& l: k# z8 Q
+ E8 f' W* _1 L) m) J( b: n! ~以太网驱动开发中出现的问题通常涉及硬件、驱动代码、网络协议栈等多个层面。
: z% @ U0 t0 V3 M7 ]- q+ ]
3 y% E, N& c* U T
npxh0z05dno64066434059.png
2 z, O; r q1 r
6 u" u8 d! p& O6 d/ H
12 C1 v! G2 [" G! z
问题现象1 ^# k' B/ k3 ]! C
板卡有两个网口。一个网口在拔掉另一个网口后,不再接收数据。通过打印发现,没有收到中断信号。
) Y1 A% j( R' F0 ~! a
! x! @$ S, Q% t) w+ ~可能原因分析
h4 T1 L" z5 H硬件连接问题
5 Z1 D6 j/ d* n6 K两个网口是否共享某些硬件资源,如中断线、PHY地址或电源。是否存在硬件级的干扰或竞争。
+ u, d$ n. a6 I C |
$ `: W0 U. ?5 I& _- s
& E5 g: x+ a* T6 SPHY管理与初始化问题& [' @2 W' g7 j0 v+ e& |* `* i! Y
PHY可能被误操作,导致一个网口拔掉另一个网口后,PHY状态异常。网口的 PHY 地址冲突或配置问题可能会导致链路状态检测混乱。
% Y2 t/ F, S1 \/ o( f& V
7 A9 T. ~4 p" Y& u0 r0 J驱动代码问题0 {8 I- f, ?# P% Z' R; B* a
中断配置问题:中断可能被错误屏蔽或未正确清理。驱动初始化逻辑问题:拔掉一个网口后,另一个网口的中断或数据路径可能被异常清理或复位。驱动对多网口的状态管理不当,例如某些全局变量被错误共享。) N; N* ]8 l3 J, D$ P: n4 H
, f; g6 E0 i* L) A% m& Y网络协议栈问题
) j# D+ C+ c/ q4 _1 n. q, g网络栈是否正确处理了链路变化的通知。某些情况下,协议栈可能进入异常状态,导致收不到数据。
5 Y- ~/ h3 K( w: }/ k8 ~4 X. Q8 y6 T, Z9 g6 h
20 \4 p3 v' m6 r- I2 U* \
具体排查步骤6 }/ ^- r" P& \5 X
1. 硬件层面! x: u3 g, b, d. C. C% v: r. W1 P
检查硬件共享资源:
" V0 ]5 a0 \0 ^9 n; h# z检查网口是否使用独立的 PHY 和中断线。用万用表测量中断线是否独立或在 PCB 上共享。确保 PHY 的电源、时钟源等是独立的。
# U) f9 L9 K) r0 |+ i k' L ?
* e. A0 |9 z0 S" ^' P- s链路状态检查:
% L: S2 q; L, t使用示波器观察拔掉网口时的 MDIO(管理数据接口)总线通信情况,看是否有错误信号或意外操作。网口拔插行为验证:测试单独使用一个网口(不接另一个网口)是否能够正常工作。
" i9 C2 m7 L) j6 q. R6 \& l
/ Q0 Q5 O: j- j& }0 E& B, l: W2. 驱动层面5 j# G9 N9 Q8 b l4 s
中断管理
) Z% |: G8 h' g+ Y/ z1 B6 }确认中断是否被触发:查看中断处理函数是否被调用。
5 q3 h* J- ~4 W/ a! Y
: S- Y& ]& S. C6 A7 ]; W在中断服务程序(ISR)中加入统计计数和详细打印,确认拔插操作后是否仍能收到中断信号。
1 y. g, G: k3 r7 M3 s7 W- a5 j, J7 e# \9 g. l
static int irq_count = 0;
, Y% `, J4 |6 k# ~7 I( M; B6 kvoid eth_rx_irq_handler(void) { irq_count++; printk("IRQ triggered, count = %d
( s2 @8 G. ]0 B2 b5 c7 G) X", irq_count); ...}
( l- q3 J# P# u% G7 e6 h中断绑定问题:确保每个网口的中断绑定到正确的设备。检查中断号是否被其他设备错误占用。
5 A9 l8 R) J1 U Z! Z) g3 L0 p' i' l" m4 }7 R
PHY 状态管理) e2 s4 a, m$ o
检查 PHY 链路状态:使用 MII/MDIO 接口读取 PHY 状态寄存器(如 BMSR 寄存器)。确保拔掉一个网口时,另一个网口的 PHY 状态未被错误修改。. L/ m3 W5 }. X
% i% s1 X* B% h: H; \4 L1 B4 mint phy_status = read_phy_register(PHY_ADDR, PHY_BMSR);printk("PHY status: 0x%x
6 s- E0 e0 B7 V5 ?", phy_status);( X$ T( m" {6 \ n
在驱动中打印 PHY 状态的变化,确认拔插时链路状态是否异常变化。
7 p D1 [- K( k- r' s% D) f( c! u3 u4 C
驱动逻辑排查
/ |( t5 V0 X, G复用变量问题:检查是否有共享变量影响了两个网口的状态。: I8 @! M k% F3 K4 x N; n0 L* V: w( v
7 l1 Z$ l; h* A, ]/ P& d/ h
确认驱动中是否有特定逻辑误将两个网口视为同一个设备。* r6 Q c! [: N# j% O# @
' R" G- V% a1 I确认网口复位过程中没有影响其他网口的硬件或软件状态。
9 C2 T/ Y# g1 P) O36 j: t7 p6 z$ p
网络协议栈层面; J/ v f$ ?/ ?& J
调试网络栈接口:确认网口数据路径是否被正常处理(如 NAPI 机制或 Rx 描述符队列)。链路通知事件:检查拔掉一个网口后,另一个网口是否错误地收到链路断开通知。! H+ w1 E% [ R9 p2 Y8 G
& I. }# P, v+ K4 f1 |7 F
4
. v% n( t! D M7 @ {4 C系统与调试工具/ f* ?9 e4 I% @) n
使用工具监控流量:9 ~$ e& D% i7 `9 |1 ^
使用 Wireshark 或 tcpdump 捕获数据包,观察收发情况。查看是否有中断丢失导致数据包未被正确处理。+ w- O* m5 O6 u4 F' O3 v
, F1 F" t: u5 n/ K使用寄存器对比状态:比较两个网口的中断寄存器、PHY 状态寄存器、DMA 描述符等,找到差异。
! e: M8 _2 A- V% r7 u, S5 s% }- p) {. `5 C$ p" p
2 c: C% Z7 U4 B# L6 a7 R) `打印驱动日志:在驱动中添加详细日志,包括中断状态、链路状态、数据队列状态等。1 Q- Y; \0 W/ S9 c$ e6 |
5
) B' |" [, \/ \: f( M e解决方向建议5 X* t+ L: K5 x6 G( _: e3 D% ~ k
确保硬件设计没有资源冲突,尤其是中断线、PHY 地址等。在驱动中分离两个网口的状态管理,避免复用变量或错误逻辑干扰。优化链路状态管理逻辑,确保 PHY 和协议栈能正确处理链路变化。增加打印和调试工具的使用,定位问题根因。
# S+ x J" ^& v2 z: O% t! i) Q
, D) L( S K& \& S( a4 i) `1 i. }9 v如果有具体代码片段或更详细的硬件架构描述,可以进一步帮助分析。
5 L& r, j% g0 j2 q- X4 f
dmeyqqztjtf64066434159.jpg
0 E! y/ a j1 W8 {' E
isnlxj5an4564066434259.gif
' z# d: x7 S/ h: F$ p点击阅读原文,更精彩~ |
|