发布网友 发布时间:2022-11-02 18:33
共1个回答
热心网友 时间:2023-10-24 09:35
从网络设备驱动的结构分析可知,Linux 网络子系统在发送数据包时,会调用驱动程序提供的 hard_start_transmit( ) 函数,该函数用于启动数据包的发送。在设备初始化的时候,这个函数指针需被初始化以指向设备的 xxx_tx( )函数。
网络设备驱动完成数据包发送的流程如下。
网络设备驱动程序从上层协议传递过来的 sk_buff 参数获得数据包的有效数据和长度,将有效数据放入临时缓冲区。
对于以太网,如果有效数据的长度小于以太网冲突检测所要求数据帧的最小长度ETH_ZLEN,则给临时缓冲区的末尾填充 0。
设置硬件的寄存器,驱使网络设备进行数据发送操作。
完成上述3个步骤的网络设备驱动程序的数据包发送函数模板如下所示:
int xxx_tx(struct sk_buff *skb, struct net_device *dev)
{
int len;
char *data, shortpkt[ETH_ZLEN];
if (xxx_send_available(···)) { /* 发送队列未满,可以发送 */
/* 获得有效数据指针和长度*/
data = skb->data;
len = skb->len;
if (len < ETH_ZLEN) {
/* 如果帧长小于以太网帧最小长度, 补0 */
memset(shortpkt, 0, ETH_ZELN);
memcpy(shortpkt, skb->data, skb->len);
len = ETH_ZLEN;
data = shortpkt;
}
dev->trans_start = jiffies; /* 记录发送时间戳 */
if (avail) { /* 设置硬件寄存器,让硬件把数据包发送出去 */
xxx_hw_tx(data, len, dev);
} else {
netif_stop_queue(dev);
···
}
}
}