DM9000驱动之接受
/*分析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驱动之接受相关推荐
- 基于4412的dm9000驱动移植
1 概述 以太网高速稳定的特性比Wifi无线传输有一定的优势,当无线传输无法满足一些智能设备,需要开发设计以太网模块.Linux支持以太网系统,结合4412开发板,重点学习dm9000驱动的设计与实现 ...
- 【linux驱动分析】之dm9000驱动分析
[linux驱动分析]之dm9000驱动分析(一):dm9000原理及硬件分析 [linux驱动分析]之dm9000驱动分析(一):dm9000原理及硬件分析 [linux驱动分析]之dm9000驱动 ...
- 【linux驱动分析】之dm9000驱动分析(三):sk_buff结构分析
[linux驱动分析]之dm9000驱动分析(一):dm9000原理及硬件分析 [linux驱动分析]之dm9000驱动分析(二):定义在板文件里的资源和设备以及几个宏 [linux驱动分析]之dm9 ...
- DM9000驱动移植在mini2440(linux2.6.29)和FS4412(linux3.14.78)上的实现(deep dive)
关于dm9000的驱动移植分为两篇,第一篇在mini2440上实现,基于linux2.6.29,也成功在在6410上移植了一遍,和2440非常类似,第二篇在fs4412(Cortex A9)上实现,基 ...
- Y410P用虚拟机装Linux系统,OK6410、Linux2.6.36内核移植,DM9000 驱动移植
对照这个结构体 将那些进行修改,注意 by acanoe 的语句为修改重点. // add by acanoe 2 &s3c_device_nand,//这一语句为添加nand 设 ...
- x210ii DM9000驱动调试成功-基于x210ii/s5pv210开发板
//-------------------------------------------------------------------------------------------------- ...
- X210开发板(S5PV210芯片)uboot移植DM9000驱动移植
前言 本文是介绍在uboot中如何移植DM9000的驱动,并不深入去讲解DM9000芯片的操作时序和内部寄存器,想要读懂驱动代码要仔细阅读DM9000芯片的数据手册.移植的基础是手里有DM9000芯片 ...
- 为LWIP移植DM9000驱动
以前设计了一个stm32F407+DM9000的板子,跑的是UIP网络协议栈,但在使用中遇到了各种问题,经过很多次补丁才算稳定,但性能还是不尽如人意.现在转来研究下LWIP,正好开发板有个freeRT ...
- 基于linux2.6.30.4内核的DM9000网卡驱动编译成模块成功ping通
基于linux2.6.30.4内核的DM9000网卡驱动编译成模块成功ping通 最近有个学生毕业设计需要实现基于ARM的DM9000网卡通信,但是linux2.6.30.4内核已经把DM9000网卡 ...
- Linux 网络设备驱动(dm9000)
网络设备驱动的分层 网络协议接口层 ------------------ 数据链路层 网络接口层 ------------------------ 数据链路层 设备驱动功能层 ------------ ...
最新文章
- Docker容器私有仓库——Harbor私有仓库的搭建
- exit命令的返回值
- 修改docker镜像的存储地址的方法(--graph)
- Spring+Mybatis多数据源配置(一)——MySQL与Oracle通过配置切换
- 编程细节 —— 按值传递、按引用传递(final、const)
- viper4android脉冲样本,v4a脉冲反馈样本官方版
- Java 高淇300集资源分享
- TC8:IPv4_REASSEMBLY_01-13
- 【深入理解C++】头文件防卫式声明
- ubuntu20+PHP项目运行环境搭建
- 朋友圈广告投放优势及广告投放案例分享
- 加密市场中的14个心智模型
- 陶瓷电容器的结构(Ceramic Capacitor Structure)
- 用 Python 将 matplotlib 图表集成到 PDF 中
- (复健计划)python中的字典
- jQuery的滑动效果(slideDown(),slideUp(),slideToggle())的应用方法
- 【第一章】浅谈NB-IoT技术及介绍NB-IoT模组BC95的特点
- selenium工具启动Chrome浏览器时配置选项详解
- 奋斗于软件测试(by leo)
- Markdown 文本换行
热门文章
- c++值传递和引用及指针传递区别
- EasyRTMP实现对接海康、大华等IPCamera SDK进行RTMP推送直播功能
- jsp中target=_blank的用法
- Extjs中设置只读的样式问题
- JavaScript 中的事件对象(读书笔记思维导图)
- CA SDK 使用简介
- 获取MOSS页面中控件使用的样式(转)
- android 通过串口来控制pwm的输出_ESP8266_07基于PWM的呼吸灯
- Hexo Next底部powered by的logo栏更改以及注意事项(附官方文档,文末有福利链)
- Eclipse问题提示