/*分析DM9000收到一个数据包后,应该做何处理?*//*当收到一个数据包后,DM9000就会触发一次发送中断,跳到中断处理函数处理*/
static irqreturn_t dm9000_interrupt(int irq, void *dev_id)
{/* Received the coming packet */  //当接受到一个数据包后if (int_status & ISR_PRS)dm9000_rx(dev);
}/*处理发送函数*/
/**  Received a packet and pass to upper layer*/
static void dm9000_rx(struct net_device *dev)
{board_info_t *db = netdev_priv(dev);struct dm9000_rxhdr rxhdr;struct sk_buff *skb;u8 rxbyte, *rdptr;bool GoodPacket;int RxLen;/* Check packet ready or not */do {ior(db, DM9000_MRCMDX);  /* Dummy read */    //空读一会,以使得数据完全接受/* Get most updated data */rxbyte = readb(db->io_data);  ///* Status check: this byte must be 0 or 1 */if (rxbyte & DM9000_PKT_ERR) {                                            //判断接受数据是否有误dev_warn(db->dev, "status check fail: %d\n", rxbyte);iow(db, DM9000_RCR, 0x00);    /* Stop Device */iow(db, DM9000_ISR, IMR_PAR);  /* Stop INT request */return;}if (!(rxbyte & DM9000_PKT_RDY))   //是否接受完全return;/* A packet ready now  & Get status/length */GoodPacket = true;writeb(DM9000_MRCMD, db->io_addr);(db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));  //获取长度和状态RxLen = le16_to_cpu(rxhdr.RxLen);if (netif_msg_rx_status(db))dev_dbg(db->dev, "RX: status %02x, length %04x\n",rxhdr.RxStatus, RxLen);//检测长度和状态是否合法/* Packet Status check */if (RxLen < 0x40) {GoodPacket = false;if (netif_msg_rx_err(db))dev_dbg(db->dev, "RX: Bad Packet (runt)\n");}if (RxLen > DM9000_PKT_MAX) {dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen);}/* rxhdr.RxStatus is identical to RSR register. */if (rxhdr.RxStatus & (RSR_FOE | RSR_CE | RSR_AE |RSR_PLE | RSR_RWTO |RSR_LCS | RSR_RF)) {GoodPacket = false;if (rxhdr.RxStatus & RSR_FOE) {if (netif_msg_rx_err(db))dev_dbg(db->dev, "fifo error\n");dev->stats.rx_fifo_errors++;}if (rxhdr.RxStatus & RSR_CE) {if (netif_msg_rx_err(db))dev_dbg(db->dev, "crc error\n");dev->stats.rx_crc_errors++;}if (rxhdr.RxStatus & RSR_RF) {if (netif_msg_rx_err(db))dev_dbg(db->dev, "length error\n");dev->stats.rx_length_errors++;}}/* Move data from DM9000 *//*分配skb结构*/if (GoodPacket &&((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {skb_reserve(skb, 2);rdptr = (u8 *) skb_put(skb, RxLen - 4);/* Read received packet from RX SRAM *///从RX中读取数据(db->inblk)(db->io_data, rdptr, RxLen);dev->stats.rx_bytes += RxLen;/* Pass to upper layer */skb->protocol = eth_type_trans(skb, dev); //获取网络协议if (dev->features & NETIF_F_RXCSUM) {if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0)skb->ip_summed = CHECKSUM_UNNECESSARY;elseskb_checksum_none_assert(skb);}netif_rx(skb);                                      //发送数据到上层去dev->stats.rx_packets++;} else {/* need to dump the packet's data */(db->dumpblk)(db->io_data, RxLen);}} while (rxbyte & DM9000_PKT_RDY);
}/*这里需要详细说明分配skb这块的细节问题*//*第一个问题: 为什么分配的RxLen+4?   dev_alloc_skb(RxLen + 4)*//*答: 因为skb结构前面要带有MAC头, IP头, 网络包的头共4个字节。 所以要多分配4个字节*//*第二个问题: 为什么skb->data 和 tail指针要加2 ? skb_reserve(skb, 2); *//*答:因为IP包要求4字节对齐的缘故 *//*第三个问题: 为什么Rxelen-4 ?  skb_put(skb, RxLen - 4);*/
/*答: 设置tail指针的位置,去掉后面4字节的校验*/

DM9000驱动之接受相关推荐

  1. 基于4412的dm9000驱动移植

    1 概述 以太网高速稳定的特性比Wifi无线传输有一定的优势,当无线传输无法满足一些智能设备,需要开发设计以太网模块.Linux支持以太网系统,结合4412开发板,重点学习dm9000驱动的设计与实现 ...

  2. 【linux驱动分析】之dm9000驱动分析

    [linux驱动分析]之dm9000驱动分析(一):dm9000原理及硬件分析 [linux驱动分析]之dm9000驱动分析(一):dm9000原理及硬件分析 [linux驱动分析]之dm9000驱动 ...

  3. 【linux驱动分析】之dm9000驱动分析(三):sk_buff结构分析

    [linux驱动分析]之dm9000驱动分析(一):dm9000原理及硬件分析 [linux驱动分析]之dm9000驱动分析(二):定义在板文件里的资源和设备以及几个宏 [linux驱动分析]之dm9 ...

  4. DM9000驱动移植在mini2440(linux2.6.29)和FS4412(linux3.14.78)上的实现(deep dive)

    关于dm9000的驱动移植分为两篇,第一篇在mini2440上实现,基于linux2.6.29,也成功在在6410上移植了一遍,和2440非常类似,第二篇在fs4412(Cortex A9)上实现,基 ...

  5. Y410P用虚拟机装Linux系统,OK6410、Linux2.6.36内核移植,DM9000 驱动移植

    对照这个结构体  将那些进行修改,注意  by  acanoe   的语句为修改重点. // add by acanoe 2 &s3c_device_nand,//这一语句为添加nand  设 ...

  6. x210ii DM9000驱动调试成功-基于x210ii/s5pv210开发板

    //-------------------------------------------------------------------------------------------------- ...

  7. X210开发板(S5PV210芯片)uboot移植DM9000驱动移植

    前言 本文是介绍在uboot中如何移植DM9000的驱动,并不深入去讲解DM9000芯片的操作时序和内部寄存器,想要读懂驱动代码要仔细阅读DM9000芯片的数据手册.移植的基础是手里有DM9000芯片 ...

  8. 为LWIP移植DM9000驱动

    以前设计了一个stm32F407+DM9000的板子,跑的是UIP网络协议栈,但在使用中遇到了各种问题,经过很多次补丁才算稳定,但性能还是不尽如人意.现在转来研究下LWIP,正好开发板有个freeRT ...

  9. 基于linux2.6.30.4内核的DM9000网卡驱动编译成模块成功ping通

    基于linux2.6.30.4内核的DM9000网卡驱动编译成模块成功ping通 最近有个学生毕业设计需要实现基于ARM的DM9000网卡通信,但是linux2.6.30.4内核已经把DM9000网卡 ...

  10. Linux 网络设备驱动(dm9000)

    网络设备驱动的分层 网络协议接口层 ------------------ 数据链路层 网络接口层 ------------------------ 数据链路层 设备驱动功能层 ------------ ...

最新文章

  1. Docker容器私有仓库——Harbor私有仓库的搭建
  2. exit命令的返回值
  3. 修改docker镜像的存储地址的方法(--graph)
  4. Spring+Mybatis多数据源配置(一)——MySQL与Oracle通过配置切换
  5. 编程细节 —— 按值传递、按引用传递(final、const)
  6. viper4android脉冲样本,v4a脉冲反馈样本官方版
  7. Java 高淇300集资源分享
  8. TC8:IPv4_REASSEMBLY_01-13
  9. 【深入理解C++】头文件防卫式声明
  10. ubuntu20+PHP项目运行环境搭建
  11. 朋友圈广告投放优势及广告投放案例分享
  12. 加密市场中的14个心智模型
  13. 陶瓷电容器的结构(Ceramic Capacitor Structure)
  14. 用 Python 将 matplotlib 图表集成到 PDF 中
  15. (复健计划)python中的字典
  16. jQuery的滑动效果(slideDown(),slideUp(),slideToggle())的应用方法
  17. 【第一章】浅谈NB-IoT技术及介绍NB-IoT模组BC95的特点
  18. selenium工具启动Chrome浏览器时配置选项详解
  19. 奋斗于软件测试(by leo)
  20. Markdown 文本换行

热门文章

  1. c++值传递和引用及指针传递区别
  2. EasyRTMP实现对接海康、大华等IPCamera SDK进行RTMP推送直播功能
  3. jsp中target=_blank的用法
  4. Extjs中设置只读的样式问题
  5. JavaScript 中的事件对象(读书笔记思维导图)
  6. CA SDK 使用简介
  7. 获取MOSS页面中控件使用的样式(转)
  8. android 通过串口来控制pwm的输出_ESP8266_07基于PWM的呼吸灯
  9. Hexo Next底部powered by的logo栏更改以及注意事项(附官方文档,文末有福利链)
  10. Eclipse问题提示