学习帮Linux网络设备驱动编程(4)

7,中断处理收包,发包
static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
//如果要收包
tg3_rx(tp);
//如果要发包
tg3_tx(tp);
}

8,发包
static void tg3_tx(struct tg3 *tp)
{
struct tx_ring_info *ri = &tp->tx_buffers[sw_idx];
struct sk_buff *skb = ri->skb;
//以DMA方式向网卡传输包完毕
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;
//分配一个包
copy_skb = dev_alloc_skb(len + 2);
copy_skb->dev = tp->dev;
//修改包头空间
skb_reserve(copy_skb, 2);
//加入数据到包中
skb_put(copy_skb, len);
//以DMA方式从网卡传输回数据
pci_dma_sync_single(tp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
memcpy(copy_skb->data, skb->data, len);
skb = copy_skb;
//解析包的协议
skb->protocol = eth_type_trans(skb, tp->dev);
//把包送到协议层
netif_rx(skb);
//记录收包时间
tp->dev->last_rx = jiffies;
}

10, 读取包的网卡收发包的状态,统计数据
static struct net_device_stats *tg3_get_stats(struct net_device *dev)
{
//从硬件相关的寄存器读取数据,累加
//stats->rx_packets, stats->tx_packets, stats->rx_bytes, stats->tx_bytes等
}

11, 用户的ioctl命令系统调用
static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
switch(cmd) {
//ethtool程序命令的调用
case SIOCETHTOOL:
return tg3_ethtool_ioctl(dev, (void *) ifr->ifr_data);
//mii程序命令的调用
case SIOCGMIIREG: {
err = tg3_readphy(tp, data->reg_num & 0x1f, &mii_regval)
data->val_out = mii_regval;
return err;
}
……
}
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwpdwj.html