netpoll的目的是让内核在网络和I/O子系统尚不能完整可用时,依然能发送和接收数据包。主要用于网络控制台(net console)和远程内核调试(KGDBoE)中。实现netpoll功能,主要是要实现kernel中的poll_controller函数,该函数定义:void
(*poll_controller)(structnet_device *dev)。该函数的作用是在缺少设备中断的情况下,还能对控制器做出响应。几乎所有的poll_controller函数都定义成如下形式:
void my_poll_controller(structnet_device *dev) {
disable_device_interrupt();//
my_interrupt_handler();
enable_device_interrupt();
}
所以,poll_controller只是模拟了来自指定设备的中断。其实只是给netpoll机制提供调用中断函数处理的机会,实际的中断触发当然还是硬件。
下面的链接分析了netpoll
http://blog.csdn.net/lucien_cc/article/details/11731501
netconsole在内核/drivers/net下
netconsole.c文件,这个console主要是向远程端发送printk(用户层不行)打印信息。
在arm板上,你的内核要配置选上netpoll,也要加载netconsole.ko
下面看netconsole.ko装载:
http://linux.chinaunix.net/techdoc/system/2005/04/06/921980.shtml
下面的链接给了设置方法:
http://blog.csdn.net/sandflee/article/details/5745745
下面说ethtool,Ldd3的解释:
ethtool 是一个实用工具, 设计来给系统管理员以大量的控制网络接口的操作.
用 ethtool, 可能来控制各种接口参数, 包括速度,介质类型, 双工模式,DMA
环设置, 硬件校验和,LAN 唤醒操作, 等等,但是只有当 ethtool 被驱动支持.
ethtool 可以从 http://sf.net/projects/gkernel/. 下载.
下载也可以到我的资源里下:
先下载ethtool:
http://download.csdn.net/detail/xxxxxlllllxl/6919223
ethtool使用,看下面的链接:
http://www.baike.com/wiki/ethtool
ethtool移植
pc都会有ethtool软件,arm板就不一定了。
移植很简单,解压缩,然后cd进去
./configure
viMakefile
把里面的gcc(就三个地方)改成你的交叉编译工具就可以了,如arm-linux-gcc
make就会有ethtool了
ethtool在内核中的使用:
主要看ethtool_ops,对驱动来说,面对的就是它,在次我介绍一下它所拥有的成员的作用。功能实现还是要搞驱动本身。Linux-3.0.8;位置include/ethtool.h
struct ethtool_ops {
int (*get_settings)(struct net_device *, struct ethtool_cmd *);
//获取网卡信息,如duplex、;连接状态、速度等,看看struct ethtool_cmd就知道了
int (*set_settings)(struct net_device *, struct ethtool_cmd *);//设置网卡
void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *);//这个获取一些如驱动名称、版本等信息。
int (*get_regs_len)(struct net_device *);//为下面的get_regs获取缓存区长度
void (*get_regs)(struct net_device *, struct ethtool_regs *, void *);//获得设备寄存器
void (*get_wol)(struct net_device *, struct ethtool_wolinfo *);//获取wake-on-lan(一种电源管理功能)是否启用。
int (*set_wol)(struct net_device *, struct ethtool_wolinfo *);//开关wol
u32 (*get_msglevel)(struct net_device *);//报告驱动程序的消息级别
void (*set_msglevel)(struct net_device *, u32);//设置驱动程序的消息级别
int (*nway_reset)(struct net_device *);//重新启动自动协商
u32 (*get_link)(struct net_device *);//报告物理连接已经up
int (*get_eeprom_len)(struct net_device *);//为下面get_eeprom服务
int (*get_eeprom)(struct net_device *,
struct ethtool_eeprom *, u8 *);//读网卡设备的eeprom
int (*set_eeprom)(struct net_device *,
struct ethtool_eeprom *, u8 *);/写网卡设备的eeprom
int (*get_coalesce)(struct net_device *, struct ethtool_coalesce *);//获取中断凝聚参数,例如一个包到达到中断触发的时间
int (*set_coalesce)(struct net_device *, struct ethtool_coalesce *);//设置中断凝聚参数
void (*get_ringparam)(struct net_device *,
struct ethtool_ringparam *);//报告RX/TX ring参数
int (*set_ringparam)(struct net_device *,
struct ethtool_ringparam *);//设置RX/TX ring参数
void (*get_pauseparam)(struct net_device *,
struct ethtool_pauseparam*);
int (*set_pauseparam)(struct net_device *,
struct ethtool_pauseparam*);
// pauseparam对应网卡的溢出控制
u32 (*get_rx_csum)(struct net_device *);//报告接收csum是开还是关
int (*set_rx_csum)(struct net_device *, u32);//设置
u32 (*get_tx_csum)(struct net_device *);//类似rx_csum
int (*set_tx_csum)(struct net_device *, u32);
u32 (*get_sg)(struct net_device *);
int (*set_sg)(struct net_device *, u32);//分散聚合开关
u32 (*get_tso)(struct net_device *);
int (*set_tso)(struct net_device *, u32);// TCP分段卸载开关
void (*self_test)(struct net_device *, struct ethtool_test *, u64 *);//run特殊自测试
void (*get_strings)(struct net_device *, u32 stringset, u8 *);//返回一个请求对象的字串
int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state);//识别物理设备,例如通过一个led闪烁。enum ethtool_phys_id_state有指示停用开启、len开或关
void (*get_ethtool_stats)(struct net_device *,
struct ethtool_stats *, u64 *);//返回扩展统计信息,只有设备统计信息不在struct rtnl_link_stats64中才使用
int (*begin)(struct net_device *);//在任何操作开始前都会调用
void (*complete)(struct net_device *);除了begin其他任何操作失败都会调用这个
u32 (*get_ufo)(struct net_device *);
int (*set_ufo)(struct net_device *, u32);// UDP碎片卸载开关
u32 (*get_flags)(struct net_device *);
int (*set_flags)(struct net_device *, u32);//网卡的features读取设置,以及ethtool_flags开关
u32 (*get_priv_flags)(struct net_device *);
int (*set_priv_flags)(struct net_device *, u32);//特殊的feature设置
int (*get_sset_count)(struct net_device *, int);//获得get_stings要写的字串数量
int (*get_rxnfc)(struct net_device *,
struct ethtool_rxnfc *, void *);
int (*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *);//rx溢出分类法则开关,有很多命令,具体看struct ethtool_rxnfo
int (*flash_device)(struct net_device *, struct ethtool_flash *);//写一个固件镜像到设备的flash
int (*reset)(struct net_device *, u32 *);//设备复位
int (*set_rx_ntuple)(struct net_device *,
struct ethtool_rx_ntuple *);
int (*get_rx_ntuple)(struct net_device *, u32 stringset, void *);//这里是控制特殊的接收溢出过滤器,如tcp\tcp溢出。
int (*get_rxfh_indir)(struct net_device *,
struct ethtool_rxfh_indir *);
int (*set_rxfh_indir)(struct net_device *,
const struct ethtool_rxfh_indir *);//rx溢出hash表操作
void (*get_channels)(struct net_device *, struct ethtool_channels *);
int (*set_channels)(struct net_device *, struct ethtool_channels *);//获取驱动最多支持的网络通道数
//下面转储操作
int (*get_dump_flag)(struct net_device *, struct ethtool_dump *);
int (*get_dump_data)(struct net_device *,
struct ethtool_dump *, void *);
int (*set_dump)(struct net_device *, struct ethtool_dump *);
};
具体实现可以看看一些网卡的实现。
我虚拟网卡简单实现的
static int vnic_ethtool_get_settings(struct net_device *dev,
struct ethtool_cmd *cmd)
{
const struct vnic_dev_info *vnic = vnic_dev_info(dev);
return dev_ethtool_get_settings(vnic->real_dev, cmd);
}
static void vnic_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
strcpy(info->driver, "vnic");
strcpy(info->version, "v1.0");
strcpy(info->fw_version, "N/A");
}
static const struct ethtool_ops vnic_ethtool_ops = {
.get_settings = vnic_ethtool_get_settings,
.get_drvinfo = vnic_ethtool_get_drvinfo,
.get_link = ethtool_op_get_link,
};
调试如下:
网卡驱动7-netpoll和ethtool,以及ethtool移植和驱动简单实现
原文:http://blog.csdn.net/xxxxxlllllxl/article/details/19164057