9200中网络MAC中断处理

来源:互联网 发布:牛客网算法视频百度云 编辑:程序博客网 时间:2024/06/06 04:39

原文:http://blog.tianya.cn/blogger/post_show.asp?idWriter=0&Key=0&BlogID=803354&PostID=20610088

 

/*
* 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
         |
|<-------