younglee 发表于 2007-5-25 15:56:11

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

我最近在学习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。

到底是怎么回事啊?
页: [1]
查看完整版本: 哪位大哥对网卡驱动熟悉啊,看e100驱动时碰到一个问题