免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4600 | 回复: 6
上一主题 下一主题

DM9000A驱动问题 [复制链接]

论坛徽章:
16
2015亚冠之吉达阿赫利
日期:2015-08-17 11:21:462015年迎新春徽章
日期:2015-03-04 09:58:11酉鸡
日期:2014-12-07 09:06:19水瓶座
日期:2014-11-04 14:23:29天秤座
日期:2014-03-02 08:57:52双鱼座
日期:2014-02-22 13:07:56午马
日期:2014-02-14 11:08:18双鱼座
日期:2014-02-13 11:09:37卯兔
日期:2014-02-06 15:10:34子鼠
日期:2014-01-20 14:48:19戌狗
日期:2013-12-19 09:37:46射手座
日期:2013-12-19 09:33:47
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-06-16 21:01 |只看该作者 |倒序浏览
本帖最后由 embeddedlwp 于 2011-06-16 21:03 编辑

Linux 2.6.30.4内核
  1. /* Move data from DM9000 */
  2.                 if (GoodPacket
  3.                     && ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {
  4.                         skb_reserve(skb, 2);
  5.                         rdptr = (u8 *) skb_put(skb, RxLen - 4);

  6.                         /* Read received packet from RX SRAM */

  7.                         (db->inblk)(db->io_data, rdptr, RxLen);
  8.                         dev->stats.rx_bytes += RxLen;

  9.                         /* Pass to upper layer */
  10.                         skb->protocol = eth_type_trans(skb, dev);
  11.                         netif_rx(skb);
  12.                         dev->stats.rx_packets++;

  13.                 } else {
  14.                         /* need to dump the packet's data */

  15.                         (db->dumpblk)(db->io_data, RxLen);
  16.                 }
  17.         } while (rxbyte == DM9000_PKT_RDY);
复制代码
不知道这里的
  1. if (GoodPacket
  2.                     && ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {
  3.                         skb_reserve(skb, 2);
  4.                         rdptr = (u8 *) skb_put(skb, RxLen - 4);
复制代码
是什么意思,为什么要这样分配啊,为什么RxLen要加4,为什么下移2octet,又下移RxLen-4?
这个是网卡接收数据函数中的,接收数据函数dm9000_rx的完整代码如下:
  1. static void
  2. dm9000_rx(struct net_device *dev)
  3. {
  4.         board_info_t *db = netdev_priv(dev);
  5.         struct dm9000_rxhdr rxhdr;
  6.         struct sk_buff *skb;
  7.         u8 rxbyte, *rdptr;
  8.         bool GoodPacket;
  9.         int RxLen;

  10.         /* Check packet ready or not */
  11.         do {
  12.                 ior(db, DM9000_MRCMDX);        /* Dummy read */

  13.                 /* Get most updated data */
  14.                 rxbyte = readb(db->io_data);

  15.                 /* Status check: this byte must be 0 or 1 */
  16.                 if (rxbyte > DM9000_PKT_RDY) {
  17.                         dev_warn(db->dev, "status check fail: %d\n", rxbyte);
  18.                         iow(db, DM9000_RCR, 0x00);        /* Stop Device */
  19.                         iow(db, DM9000_ISR, IMR_PAR);        /* Stop INT request */
  20.                         return;
  21.                 }

  22.                 if (rxbyte != DM9000_PKT_RDY)
  23.                         return;

  24.                 /* A packet ready now  & Get status/length */
  25.                 GoodPacket = true;
  26.                 writeb(DM9000_MRCMD, db->io_addr);

  27.                 (db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));

  28.                 RxLen = le16_to_cpu(rxhdr.RxLen);

  29.                 if (netif_msg_rx_status(db))
  30.                         dev_dbg(db->dev, "RX: status %02x, length %04x\n",
  31.                                 rxhdr.RxStatus, RxLen);

  32.                 /* Packet Status check */
  33.                 if (RxLen < 0x40) {
  34.                         GoodPacket = false;
  35.                         if (netif_msg_rx_err(db))
  36.                                 dev_dbg(db->dev, "RX: Bad Packet (runt)\n");
  37.                 }

  38.                 if (RxLen > DM9000_PKT_MAX) {
  39.                         dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen);
  40.                 }

  41.                 /* rxhdr.RxStatus is identical to RSR register. */
  42.                 if (rxhdr.RxStatus & (RSR_FOE | RSR_CE | RSR_AE |
  43.                                       RSR_PLE | RSR_RWTO |
  44.                                       RSR_LCS | RSR_RF)) {
  45.                         GoodPacket = false;
  46.                         if (rxhdr.RxStatus & RSR_FOE) {
  47.                                 if (netif_msg_rx_err(db))
  48.                                         dev_dbg(db->dev, "fifo error\n");
  49.                                 dev->stats.rx_fifo_errors++;
  50.                         }
  51.                         if (rxhdr.RxStatus & RSR_CE) {
  52.                                 if (netif_msg_rx_err(db))
  53.                                         dev_dbg(db->dev, "crc error\n");
  54.                                 dev->stats.rx_crc_errors++;
  55.                         }
  56.                         if (rxhdr.RxStatus & RSR_RF) {
  57.                                 if (netif_msg_rx_err(db))
  58.                                         dev_dbg(db->dev, "length error\n");
  59.                                 dev->stats.rx_length_errors++;
  60.                         }
  61.                 }

  62.                 /* Move data from DM9000 */
  63.                 if (GoodPacket
  64.                     && ((skb = dev_alloc_skb(RxLen + 4)) != NULL)) {
  65.                         skb_reserve(skb, 2);
  66.                         rdptr = (u8 *) skb_put(skb, RxLen - 4);

  67.                         /* Read received packet from RX SRAM */

  68.                         (db->inblk)(db->io_data, rdptr, RxLen);
  69.                         dev->stats.rx_bytes += RxLen;

  70.                         /* Pass to upper layer */
  71.                         skb->protocol = eth_type_trans(skb, dev);
  72.                         netif_rx(skb);
  73.                         dev->stats.rx_packets++;

  74.                 } else {
  75.                         /* need to dump the packet's data */

  76.                         (db->dumpblk)(db->io_data, RxLen);
  77.                 }
  78.         } while (rxbyte == DM9000_PKT_RDY);
  79. }
复制代码

论坛徽章:
0
2
发表于 2011-11-04 17:17
好多眼睛都看花了








--------------------------------------------------------------------------------
爱欣文科技公司提供DM9000/DM9161/DM9620/DM9003/DM8606的技术支持及产品,欢迎咨询
联系任先生E-mail:bab_ren@axwdragon.com  qq1870232565

论坛徽章:
0
3
发表于 2011-11-04 17:18
可以学习,呵呵







--------------------------------------------------------------------------------
爱欣文科技公司提供DM9000/DM9161/DM9620/DM9003/DM8606的技术支持及产品,欢迎咨询
联系任先生E-mail:bab_ren@axwdragon.com  qq1870232565

论坛徽章:
0
4 [报告]
发表于 2011-11-04 23:57 |只看该作者
在drivers/net/3c515.c中:
  1. skb = dev_alloc_skb(pkt_len + 5 + 2);
  2.                         if (corkscrew_debug > 4)
  3.                                 pr_debug("Receiving packet size %d status %4.4x.\n",
  4.                                      pkt_len, rx_status);
  5.                         if (skb != NULL) {
  6.                                 skb_reserve(skb, 2);        /* Align IP on 16 byte boundaries */
复制代码

论坛徽章:
0
5 [报告]
发表于 2011-11-05 00:04 |只看该作者
+4,就是为了这里的reserve吧

论坛徽章:
0
6 [报告]
发表于 2013-07-30 21:20 |只看该作者
回复 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字节。

   

论坛徽章:
0
7
发表于 2013-11-05 13:41
我公司是DAVICOM正规代理商,有原厂技术支持,关于DM9000和DM9161技术方面的问题可以来信来电我们将详细为您解答联络方式:mike.lee@qftek.com.cn电话:18929384326   李生
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP