/*
* at91rm9200 - dm9161的中断处理
* at91rm9200 - dm9161 - 2.6.20
*/
这里的中断包括两个:一个是PHY对EMAC的中断,表示PHY的状态发生了变化,需要通知
EMAC,让MAC做相应处理或通知内核;另一个是MAC本身的中断,包括PHY管理完成(DONE)、
接收完成(RCOM)、缓冲区不可用(RBNA)、发送缓冲过载(TOVR)、发送缓冲欠载(TUND)、
重试超过(RTRY)、发送缓冲寄存器空(TBRE)、发送完成(TCOM)、发送空闲(TIDLE)、LINK
引脚发生变化(LINK可选)、接收过载(ROVR)、DMA放弃(ABT)。
irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id)是处理来自PHY的中
断处理例程。 当PHY的link, speed, duplex发生变化,并且在PHY寄存器中没有mask时
会产生中断,则网络驱动调用该例程处理。
at91ether_phy_interrupt(irq, void *dev_id)
|
struct net_device *dev = (struct net_device *)dev_id;
这个可以知道,中断例程的参数之一就是设备结构体,
可以在例程中使用设备了。
|
通过dev取得private
|
使能mii
|
读取MII_DSINTR_REG寄存器
读清除中断标记
|
---------------------------------------------------------------------------
| |
如果0 bit是1,则确实有中断 没有中断
| |
update_linkspeed(dev, 0) |
| |
mii_link_ok(&lp->mii) |
| |
是否连接上了 |
| |
------------------------------------------------------------------------- |
| | |
如果连接了 如果没有连接 |
| | |
读取MII_BMSR, netif_carrier_off(dev); |
MII_BMCR寄存器 | |
| | |
从寄存器中得到link | |
的speed, duplex类型 | |
| | |
将得到的state更新 | |
到EMAC寄存器中 | |
| | |
netif_carrier_on(dev) | |
通知内核,有连接(载波) | |
| | |
|<-------------------------------------------------------------------------|
| |
禁用mii<---------------------------------------------------------------|
|
返回IRQ_HANDLED
|
|<-------
irqreturn_t at91ether_interrupt(int irq, void *dev_id)则是处理EMAC的中断的包括
PHY管理完成(DONE)、接收完成(RCOM)、缓冲区不可用(RBNA)、发送缓冲过载(TOVR)、发
送缓冲欠载(TUND)、重试超过(RTRY)、发送缓冲寄存器空(TBRE)、发送完成(TCOM)、发送
空闲(TIDLE)、LINK引脚发生变化(LINK可选)、接收过载(ROVR)、DMA放弃(ABT)。
但是这里的处理例程好像只处理了其中几个,包括:RCOM, TCOM, TUND, RTRY, RBNA,
ROVR.
at91ether_interrupt(int irq, void *dev_id)
|
取得net_device和private数据
|
读取AT91_EMAC_ISR寄存器
取得中断号
|
如果有RCOM
|
调用at91ether_rx(dev)
进行接收数据到skb套接字缓冲区
|
---------
|
如果有TCOM
|
如果是发送错误,错误统计加一
|
释放skb
|
netif_wake_queue(dev)
唤醒发送队列
|
---------
|
如果有RBNA
|
读取AT91_EMAC_CTL寄存器
|
重新设置接收使能位
|
---------
|
如果有ROVR
|
打印"ROVR error"错误信息
|
---------
|
---------
|
返回 IRQ_HANDLED
|
|<-------