QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2607|回复: 0

哪位大哥对网卡驱动熟悉啊,看e100驱动时碰到一个问题

[复制链接]
发表于 2007-5-25 15:56:11 | 显示全部楼层 |阅读模式
我最近在学习e100代码时,有个地方不能理解,哪位大哥帮我解答一下?

e100发送数据的函数是:static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
其中它调用了err = e100_exec_cb(nic, skb, e100_xmit_prepare);

e100_exec_cb的定义如下:
static int e100_exec_cb(struct nic *nic, struct sk_buff *skb,
        void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *))
{
        struct cb *cb;
        unsigned long flags;
        int err = 0;

        spin_lock_irqsave(&nic->cb_lock, flags);

        if(unlikely(!nic->cbs_avail)) {
                err = -ENOMEM;
                goto err_unlock;
        }

        cb = nic->cb_to_use;
        nic->cb_to_use = cb->next;
        nic->cbs_avail--;
        cb->skb = skb;

        if(unlikely(!nic->cbs_avail))
                err = -ENOSPC;

        cb_prepare(nic, cb, skb);

        /* Order is important otherwise we'll be in a race with h/w:
         * set S-bit in current first, then clear S-bit in previous. */
        cb->command |= cpu_to_le16(cb_s);
        wmb();
        cb->prev->command &= cpu_to_le16(~cb_s);

        while(nic->cb_to_send != nic->cb_to_use) {
                if(unlikely(e100_exec_cmd(nic, nic->cuc_cmd,
                        nic->cb_to_send->dma_addr))) {
                        /* Ok, here's where things get sticky.  It's
                         * possible that we can't schedule the command
                         * because the controller is too busy, so
                         * let's just queue the command and try again
                         * when another command is scheduled. */
                        if(err == -ENOSPC) {
                                //request a reset
                                schedule_work(&nic->tx_timeout_task);
                        }
                        break;
                } else {
                        nic->cuc_cmd = cuc_resume;
                        nic->cb_to_send = nic->cb_to_send->next;
                }
        }

err_unlock:
        spin_unlock_irqrestore(&nic->cb_lock, flags);

        return err;
}

e100_xmit_prepare的定义如下:
static void e100_xmit_prepare(struct nic *nic, struct cb *cb,
        struct sk_buff *skb)
{
        cb->command = nic->tx_command;
        /* interrupt every 16 packets regardless of delay */
        if((nic->cbs_avail & ~15) == nic->cbs_avail)
                cb->command |= cpu_to_le16(cb_i);
        cb->u.tcb.tbd_array = cb->dma_addr + offsetof(struct cb, u.tcb.tbd);
        cb->u.tcb.tcb_byte_count = 0;
        cb->u.tcb.threshold = nic->tx_threshold;
        cb->u.tcb.tbd_count = 1;
        cb->u.tcb.tbd.buf_addr = cpu_to_le32(pci_map_single(nic->pdev,
                skb->data, skb->len, PCI_DMA_TODEVICE));
        /* check for mapping failure? */
        cb->u.tcb.tbd.size = cpu_to_le16(skb->len);
}

从e100_exec_cb中可以看到发送数据用的DMA 地址是:nic->cb_to_send->dma_addr

但是在e100_xmit_prepare中,它把要发送的数据的地址映射到cb->u.tcb.tbd.buf_addr。

到底是怎么回事啊?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-5-15 01:28 , Processed in 0.159858 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表