网络设备驱动第一课--------接口与定义

概述

与字符和块设备不同,网络设备没有设备文件。
但与块设备在读写上有类似之处,
对用户层来讲,用户的IO请求只是入队,内核对入队的IO请求用调度算法进行均匀
化,瓜分成很多个小的任务块放入到一个请求队列中;对于驱动来讲,驱动只要从请求队列中出队一个小的任务块(称作“请求”)进行处理。

网卡操作:

1、网卡信息:

<include/uapi/linux/if.h>

struct ifreq {
#define IFHWADDRLEN 6
    union
    {
        char    ifrn_name[IFNAMSIZ];    //物理接口名(网卡名)
    } ifr_ifrn;

    union {
        struct  sockaddr ifru_addr;     //ip地址
        struct  sockaddr ifru_dstaddr;  //目标地址
        struct  sockaddr ifru_broadaddr;//广播地址
        struct  sockaddr ifru_netmask;  //子网掩码
        struct  sockaddr ifru_hwaddr;   //MAC
        short   ifru_flags;             //标志
        int ifru_ivalue;
        int ifru_mtu;                   //最大包长
        struct  ifmap ifru_map;
        char    ifru_slave[IFNAMSIZ];
        char    ifru_newname[IFNAMSIZ];
        void __user *   ifru_data;
        struct  if_settings ifru_settings;
    } ifr_ifru;
};

2.读取或设置网卡参数:

对以上结构体中成员进行赋值或读取其状态的函数是ioctl(),如:
if (ioctl(sock, SIOCGIFADDR, &device) < 0)
对应的命令码已经被内核封装成宏,在<include/uapi/linux/sockios.h>,例如:
#define SIOCGIFBRDADDR  0x8919      /* get broadcast PA address */
#define SIOCSIFBRDADDR  0x891a      /* set broadcast PA address */
#define SIOCGIFNETMASK  0x891b      /* get network PA mask      */

3.使能和关闭网卡:

/*使能网卡的shell命令*/
strace ifconfig eth0 up
/*关闭网卡的shell命令*/
strace ifconfig eth0 down

net_device 结构体:

<include/linux/netdevice.h>

struct net_device {
    char            name[IFNAMSIZ];   //物理接口名(网卡名)
    struct hlist_node   name_hlist;
    char            *ifalias;
    /*物理信息:IO地址、中断号*/
    unsigned long       mem_end;     //缓存结束
    unsigned long       mem_start;   //缓存起始
    unsigned long       base_addr;   //基地址
    int         irq;                 //中断
    netdev_features_t   features;    //可变特性,DMA,校验等一系列附加特性
    netdev_features_t   hw_features; //用户不能改变的私有特性
    unsigned int        flags;       //可变标准
    unsigned int        priv_flags;  //用户不能改变的标准
    const struct net_device_ops *netdev_ops;   //操作方法集
    const struct ethtool_ops *ethtool_ops;     //eth工具集操作方法集
    const struct header_ops *header_ops;       //协议头操作方法集
    unsigned char       if_port;               //接口类型
    unsigned int        mtu;                   //最大包长      
    unsigned short      type;                  //网络包类型
    unsigned short      hard_header_len;       //硬件协议头长度
    unsigned char   perm_addr[MAX_ADDR_LEN];   //MAC地址
    unsigned char       addr_len;              //MAC地址长度
    unsigned short          dev_id;            //指向mac地址
    struct in_device __rcu  *ip_ptr;           //ip地址
    ...
};

操作方法集:

<include/linux/netdevcice.h>

struct net_device_ops {
    int     (*ndo_init)(struct net_device *dev);  //构造初始化对象
    void    (*ndo_uninit)(struct net_device *dev);//析构函数,回收清理
    int     (*ndo_open)(struct net_device *dev);  //打开设备
    int     (*ndo_stop)(struct net_device *dev);  //停止
    netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb,
                          struct net_device *dev);//发送
    int     (*ndo_set_mac_address)(struct net_device *dev,
                               void *addr);      //设置mac地址
    int  (*ndo_validate_addr)(struct net_device *dev);//检查MAC是否有效
    int     (*ndo_do_ioctl)(struct net_device *dev,
                            struct ifreq *ifr, int cmd);//ioctl
    int (*ndo_set_config)(struct net_device *dev,
                          struct ifmap *map);//修改网卡io地址、中断等网卡物理信息
    int         (*ndo_change_mtu)(struct net_device *dev,
                          int new_mtu);   //设置最大包长
    void    (*ndo_tx_timeout) (struct net_device *dev);  //超时重发
    ...

重要的回调函数接口:

1.发送回调函数

当用户用send函数往网卡发数据时,系统经过VFS文件系统找到相应的struct net_device网络设备句柄,
然后找到这个句柄中的操作方法集,再进一步找到相应的回调函数指针ndo_start_xmit,最终回调了驱动层的函数。
/*
* 功能:把套接字缓冲区中的数据写网卡
* 输入参数:struct sk_buff *skb:网卡的缓存
*         struct net_device *dev:设备句柄
* 返回值:
*/
netdev_tx_t (*ndo_start_xmit)(struct sk_buff *skb,
                struct net_device *dev);

2.接收数据:

操作方法集中没有,因为接收是靠中断来实现的。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xxgui1992

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值