|

mhsxbbxr04l64066433858.gif
: c! f/ @/ f1 t4 b5 M- p, Y% W点击上方蓝色字体,关注我们1 Y! y% ?4 J+ Q: B' u
来源于小伙伴提问:
' }5 Q+ Y8 ?+ P4 v. _( X3 d4 x. Q2 H, Z% B& w
ocsbogin2pq64066433958.png
" f" a0 P- @6 q8 ^! ^, F. }; a
8 S# q/ E# h- N2 E2 q3 y
以太网驱动开发中出现的问题通常涉及硬件、驱动代码、网络协议栈等多个层面。
6 s, q5 C9 W' s9 p8 w' y2 P3 v# ~4 ]$ u+ o. T
npxh0z05dno64066434059.png
4 e6 S8 D+ D; r% i
9 o4 I- R1 [7 X& P% j9 b; m M/ V1' e. ?/ ~% K) n4 U& D
问题现象
" }" Z2 W1 O) z N0 e! W板卡有两个网口。一个网口在拔掉另一个网口后,不再接收数据。通过打印发现,没有收到中断信号。
% a8 D5 T4 O8 P! N0 f( B& H) E' `3 k
7 M6 d, @" u+ I" m2 r7 Q可能原因分析 L% `" y$ |7 R1 U
硬件连接问题8 f( O% ?3 Z5 r' F
两个网口是否共享某些硬件资源,如中断线、PHY地址或电源。是否存在硬件级的干扰或竞争。% O! l* h/ N0 q
$ G1 k2 [4 X3 a" A: s' s$ Q
9 s6 X# d8 [. u/ p4 x$ Q
PHY管理与初始化问题1 n& x3 T$ m; |' A& L2 ?6 M
PHY可能被误操作,导致一个网口拔掉另一个网口后,PHY状态异常。网口的 PHY 地址冲突或配置问题可能会导致链路状态检测混乱。3 I" A. V+ c; s2 K# F8 V+ C
1 [( l3 S O8 M9 d* k3 H0 d$ `
驱动代码问题
0 N. O# A2 D7 G' U+ k+ m中断配置问题:中断可能被错误屏蔽或未正确清理。驱动初始化逻辑问题:拔掉一个网口后,另一个网口的中断或数据路径可能被异常清理或复位。驱动对多网口的状态管理不当,例如某些全局变量被错误共享。% I8 x2 h4 h, P. r
2 D4 c7 i! k7 Y网络协议栈问题8 T" ?! F6 Y0 \4 B+ x
网络栈是否正确处理了链路变化的通知。某些情况下,协议栈可能进入异常状态,导致收不到数据。6 B& ~5 G7 H3 w& {- Z" V5 i
; s% f( s9 i1 C2 H2- g- u6 _" |0 I+ M! |$ ?( `
具体排查步骤
# ^0 _, L3 q5 r& V# a1. 硬件层面
2 `7 l7 N% U' H. s检查硬件共享资源:) s9 b1 H" @9 T5 u A& n' ~2 [
检查网口是否使用独立的 PHY 和中断线。用万用表测量中断线是否独立或在 PCB 上共享。确保 PHY 的电源、时钟源等是独立的。2 f" }' ?& V' c/ n- R
/ }1 Q# H4 Z# V2 Q
链路状态检查:
6 F2 R6 z' G, g0 a2 g) J0 B使用示波器观察拔掉网口时的 MDIO(管理数据接口)总线通信情况,看是否有错误信号或意外操作。网口拔插行为验证:测试单独使用一个网口(不接另一个网口)是否能够正常工作。
% \4 F% g! O# j8 U/ y! _: c! K
! L* R6 L# I5 W, r# u, l! m2. 驱动层面" ]; g1 n; v# H0 P( H7 B" T
中断管理
1 r6 }8 A+ o' C3 U& [确认中断是否被触发:查看中断处理函数是否被调用。! v( R/ }, E" n# O, g1 s; _
. R6 O$ K* K( X5 U
在中断服务程序(ISR)中加入统计计数和详细打印,确认拔插操作后是否仍能收到中断信号。
; `, H2 B) }$ u( V7 V* {
- D/ n: k' u4 T% e K. Ustatic int irq_count = 0;
& t ^% m6 ~ Y: Y9 E8 y vvoid eth_rx_irq_handler(void) { irq_count++; printk("IRQ triggered, count = %d
0 ]8 K& z3 j3 t", irq_count); ...}, A/ h5 I* N( Q& m5 v
中断绑定问题:确保每个网口的中断绑定到正确的设备。检查中断号是否被其他设备错误占用。: k5 b. E$ W. `: ?* B0 o0 [( \2 O
$ o1 ?# Z0 H, U1 z
PHY 状态管理
- Y3 b5 Q9 S; k检查 PHY 链路状态:使用 MII/MDIO 接口读取 PHY 状态寄存器(如 BMSR 寄存器)。确保拔掉一个网口时,另一个网口的 PHY 状态未被错误修改。; i9 X: G8 R' B3 y3 ^6 ^: t
, g/ u, [& e0 b4 K( ]int phy_status = read_phy_register(PHY_ADDR, PHY_BMSR);printk("PHY status: 0x%x o3 g3 H6 h6 z9 _
", phy_status);
0 j& x8 p2 a2 c- Z# v4 e2 i, O在驱动中打印 PHY 状态的变化,确认拔插时链路状态是否异常变化。) \0 B8 M/ K& {+ i; w. N# H0 {3 P4 v
5 f1 v$ d$ _( e% l$ P. s# W驱动逻辑排查
) E8 \* q8 y9 M) y* `: E, H复用变量问题:检查是否有共享变量影响了两个网口的状态。1 W# t" q) _, X; Q
. B* p% v7 s8 \' k3 [
确认驱动中是否有特定逻辑误将两个网口视为同一个设备。
) ~: C: q7 N$ z/ x$ W" a
4 p" l6 w) e3 W9 p' M确认网口复位过程中没有影响其他网口的硬件或软件状态。
, d, ]. m" o5 q/ E39 K# C" W0 ]7 t* x4 A/ M) l
网络协议栈层面) v/ w6 d0 u& `( G5 \
调试网络栈接口:确认网口数据路径是否被正常处理(如 NAPI 机制或 Rx 描述符队列)。链路通知事件:检查拔掉一个网口后,另一个网口是否错误地收到链路断开通知。) T: f7 [1 |' `9 ]
1 C; U, k' B$ Z( C3 \6 C2 e& m' j/ D48 P: S1 ]& k( V, F2 ?0 Z. ]' c
系统与调试工具
1 ^5 t0 q/ C' S7 I3 P2 R使用工具监控流量:) T r' N% n2 w1 y0 P. K3 V1 _' P
使用 Wireshark 或 tcpdump 捕获数据包,观察收发情况。查看是否有中断丢失导致数据包未被正确处理。( W5 |9 f+ l3 b( }7 R ?
& c& }0 W8 L5 X2 g/ d+ _
使用寄存器对比状态:比较两个网口的中断寄存器、PHY 状态寄存器、DMA 描述符等,找到差异。
; ]* T* X h4 c/ D: ~+ `7 k" c
5 k( N% H# |% R8 |- ], B0 h+ k( _/ B" h. U) Z# [. L
打印驱动日志:在驱动中添加详细日志,包括中断状态、链路状态、数据队列状态等。4 C w. q, M) f! y2 N
5& S" h1 }8 K9 B0 _ W
解决方向建议
5 u9 {) q1 X7 {确保硬件设计没有资源冲突,尤其是中断线、PHY 地址等。在驱动中分离两个网口的状态管理,避免复用变量或错误逻辑干扰。优化链路状态管理逻辑,确保 PHY 和协议栈能正确处理链路变化。增加打印和调试工具的使用,定位问题根因。4 j5 O- }- A/ D" a, \5 R* T
9 S, ? \9 t& t
如果有具体代码片段或更详细的硬件架构描述,可以进一步帮助分析。1 w' f1 A, a5 r. i2 I4 E
dmeyqqztjtf64066434159.jpg
& p; i! S; ], w! k. ~' a
isnlxj5an4564066434259.gif
! ]% K' h, I8 Z7 [
点击阅读原文,更精彩~ |
|