DM9000A驱动问题

发布于 2022-10-15 04:07:54 字数 11697 浏览 30 评论 0

本帖最后由 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. }

复制代码

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

凉世弥音 2022-10-22 04:07:54

好多眼睛都看花了

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

z祗昰~ 2022-10-22 04:07:54

可以学习,呵呵

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

始终不够 2022-10-22 04:07:54

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

复制代码

眼中杀气 2022-10-22 04:07:54

+4,就是为了这里的reserve吧

美人迟暮 2022-10-22 04:07:54

回复 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字节。

   

萧瑟寒风 2022-10-22 04:07:54

我公司是DAVICOM正规代理商,有原厂技术支持,关于DM9000和DM9161技术方面的问题可以来信来电我们将详细为您解答联络方式:mike.lee@qftek.com.cn电话:18929384326   李生

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文