DM9000A驱动问题
本帖最后由 embeddedlwp 于 2011-06-16 21:03 编辑
Linux 2.6.30.4内核
- /* Move data from DM9000 */
- 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 */
- (db->inblk)(db->io_data, rdptr, RxLen);
- dev->stats.rx_bytes += RxLen;
- /* Pass to upper layer */
- skb->protocol = eth_type_trans(skb, dev);
- 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);
复制代码不知道这里的
- if (GoodPacket
- && ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {
- skb_reserve(skb, 2);
- rdptr = (u8 *) skb_put(skb, RxLen - 4);
复制代码是什么意思,为什么要这样分配啊,为什么RxLen要加4,为什么下移2octet,又下移RxLen-4?
这个是网卡接收数据函数中的,接收数据函数dm9000_rx的完整代码如下:
- 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_RDY) {
- 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 */
- 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 */
- (db->inblk)(db->io_data, rdptr, RxLen);
- dev->stats.rx_bytes += RxLen;
- /* Pass to upper layer */
- skb->protocol = eth_type_trans(skb, dev);
- 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);
- }
复制代码
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
好多眼睛都看花了
--------------------------------------------------------------------------------
爱欣文科技公司提供DM9000/DM9161/DM9620/DM9003/DM8606的技术支持及产品,欢迎咨询
联系任先生E-mail:bab_ren@axwdragon.com qq1870232565
可以学习,呵呵
--------------------------------------------------------------------------------
爱欣文科技公司提供DM9000/DM9161/DM9620/DM9003/DM8606的技术支持及产品,欢迎咨询
联系任先生E-mail:bab_ren@axwdragon.com qq1870232565
在drivers/net/3c515.c中:
复制代码
+4,就是为了这里的reserve吧
回复 1# embeddedlwp
1、对于第一个问题:为什么RxLen要加4?
因为DM9000从网络中接到一个数据包后,会在数据前面加上4个字节,分别为:“01H”、“status”、“LENL”(数据包长度的低8位)、“LENH”(数据包长度高8位);RXLen的长度=以太网头部+以太网净荷+FCS,所以dev_alloc_skb(RXLen+4)分配的空间可以保存 01H | status | LENL | LENH | 以太网头部 | 以太网净荷 | FCS。事实上多出的4个字节并没有保存 01H | status | LENL | LENH ,因为其对于skb没有意义。
2、对于第二个问题:为什么下移2octet?
skb_reserve(skb,2)在数据包缓冲的起始和载荷的开始之间增加一个2B的填充位,这使得IP头能在16B边界处开始。
3、对于第三个问题:又下移RxLen-4?
因为实际上接收到的数据包的长度为RxLen-4,即去掉了FCS的4字节。
我公司是DAVICOM正规代理商,有原厂技术支持,关于DM9000和DM9161技术方面的问题可以来信来电我们将详细为您解答联络方式:mike.lee@qftek.com.cn电话:18929384326 李生