Linux網(wǎng)絡(luò)驅(qū)動(dòng)程序功能分析
//初始化定時(shí)器本文引用地址:http://www.ex-cimer.com/article/148970.htm
init_timer(tp->timer);
tp->timer.expires = jiffies + tp->timer_offset;
tp->timer.data = (unsigned long) tp;
tp->timer.function = tg3_timer; //超時(shí)回調(diào)函數(shù)
add_timer(tp->timer);
//允許網(wǎng)卡開始傳輸包
netif_start_queue(dev);
}
5.關(guān)閉網(wǎng)絡(luò)設(shè)備
static int tg3_close(struct net_device *dev)
{
//停止網(wǎng)卡傳輸包
netif_stop_queue(dev);
netif_carrier_off(tp->dev);
//去除定時(shí)器
del_timer_sync(tp->timer);
//釋放收包和發(fā)包的緩沖區(qū)
tg3_free_rings(tp);
//釋放中斷
free_irq(dev->irq, dev);
}
[NextPage]
6.硬件處理數(shù)據(jù)包發(fā)送
static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
len = (skb->len - skb->data_len);
//以DMA方式向網(wǎng)卡物理設(shè)備傳輸包。如果是wireless的話,需要根據(jù)802.11協(xié)議及硬件的規(guī)范從新填充
//硬件幀頭,然后提交給硬件發(fā)送。
mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
tp->tx_buffers[entry].skb = skb;
pci_unmap_addr_set(tp->tx_buffers[entry], mapping, mapping);
//硬件發(fā)送
tg3_set_txd(tp, entry, mapping, len, base_flags, mss_and_is_end);
//記錄發(fā)包開始時(shí)間
dev->trans_start = jiffies;
}
7.中斷處理收包,發(fā)包
static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
//如果要收包
tg3_rx(tp);
//如果要發(fā)包
tg3_tx(tp);
}
8.發(fā)包
static void tg3_tx(struct tg3 *tp)
{
struct tx_ring_info *ri = tp->tx_buffers[sw_idx];
struct sk_buff *skb = ri->skb;
//以DMA方式向網(wǎng)卡傳輸包完畢
pci_unmap_single(tp->pdev, pci_unmap_addr(ri, mapping),
(skb->len - skb->data_len), PCI_DMA_TODEVICE);
ri->skb = NULL;
dev_kfree_skb_irq(skb);
}
9.收包
static int tg3_rx(struct tg3 *tp, int budget)
{
struct sk_buff *copy_skb;
//分配一個(gè)包
copy_skb = dev_alloc_skb(len + 2);
copy_skb->dev = tp->dev;
//修改包頭空間
skb_reserve(copy_skb, 2);
//加入數(shù)據(jù)到包中
skb_put(copy_skb, len);
//以DMA方式從網(wǎng)卡傳輸回?cái)?shù)據(jù)
pci_dma_sync_single(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
memcpy(copy_skb->data, skb->data, len);
skb = copy_skb;
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)
評(píng)論