文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>Intel 82575/82576千兆网卡驱动IGB分析──2──..

Intel 82575/82576千兆网卡驱动IGB分析──2──..

时间:2009-03-11  来源:tubocurarine


     真正开始之前,我们有必要先了解一下基本的概念和数据结构。其实我也不时太了解这些,尽管自己最近一直在看,而且查了不少的资料,但是也不敢保证自己的理解就是正确的,如果有什么错误,欢迎指正。

1. Kset,Kobject 和Ktype

如果仅仅是想要了解驱动的话,这三个结构可以暂时不考虑。但是如果你想要进一步的了解内核的话,那么至少应该对它们了解一些。Linux源码目录下的Documentation里面有一个kobject.txt文件,针对它们作了一些介绍。kobject是一个结构,通常被嵌入其他的结构中;每个kobject中包含一个名字,一个引用数量(referenced count)。ktype为kobject中的一个变量,由于标识一个kobject的类型;而kset则为一系列的kobject,这些kobject的ktype可以相同,也可以不同。关于其具体内容请参阅前面提到的文档。

这些东西和驱动编写没有太直接的关系,但之所以在这里提到这些,是因为系统启动的时候会扫描与其链接的总线(bus)和设备(device)并建立这些kset用于保存这些信息。例如对于一个PCI总线,Linux启动后会扫描所有挂载在该总线上的设备,并用一个队列来描述它们;同时,系统还维护一个driver的列队,只有设备列队上的设备有相应的驱动的时候,系统才可以正常的使用这个设备。

(个人对前面提到的这些仅限于了解,或者连了解也称不上,因此不多说,有兴趣的可以自行查阅相关资料。)

2. bus,pci_bus

<STYLE type="text/css"> </STYLE>

总线是CPU与外设沟通的重要手段,是计算机的重要组成部分。而PCI总线作为目前主流的总线之一,与作为PCI设备的网卡有关的几个结构为:bus_type和pci_bus_type。其中bus_type用来表示一个bus的类型,如ISA、PCI等等,其定义如下

struct bus_type {
    const char        *name;
    struct bus_attribute    *bus_attrs;
    struct device_attribute    *dev_attrs;
    struct driver_attribute    *drv_attrs;

    int (*match)(struct device *dev, struct device_driver *drv);
    int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
    int (*probe)(struct device *dev);
    int (*remove)(struct device *dev);
    void (*shutdown)(struct device *dev);

    int (*suspend)(struct device *dev, pm_message_t state);
    int (*suspend_late)(struct device *dev, pm_message_t state);
    int (*resume_early)(struct device *dev);
    int (*resume)(struct device *dev);

    struct pm_ext_ops *pm;
    struct bus_type_private *p;
};

<STYLE type="text/css"> </STYLE>

pci_bus_type作为bus_type的一个实例,规定了自己的一些特殊的操作,其定义如下:

struct bus_type pci_bus_type = {
    .name        = "pci",
    .match        = pci_bus_match,
    .uevent        = pci_uevent,
    .probe        = pci_device_probe,
    .remove        = pci_device_remove,
    .shutdown    = pci_device_shutdown,
    .dev_attrs    = pci_dev_attrs,
    .pm        = PCI_PM_OPS_PTR,
};

<STYLE type="text/css"> </STYLE>

上面这个定义里面的相关动作的句柄在涉及到PCI总线的特定操作的时候将会被调用,例如当试图将设备注册到PCI层的时候,pci_bus_match将会被调用。这个过程将会在后面的相关文章中给出。

3. Device,pci_dev,pci_evice_id和net_device

<STYLE type="text/css"> </STYLE>

3.1 device

device顾名思义是用来描述一个设备的,其构成比较复杂,这里仅仅给出定义,与PCI设备和驱动相关的部分将会在后文涉及到的时候详细介绍。其定义为:

struct device {
    struct klist        klist_children;
    struct klist_node    knode_parent;    /* node in sibling list */
    struct klist_node    knode_driver;
    struct klist_node    knode_bus;
    struct device        *parent;
    struct kobject kobj;
    char    bus_id[BUS_ID_SIZE];    /* position on parent bus */
    const char        *init_name; /* initial name of the device */
    struct device_type    *type;
    unsigned        uevent_suppress:1;
    struct semaphore    sem;    /* semaphore to synchronize calls to its driver. */
    struct bus_type    *bus;        /* type of bus device is on */
    struct device_driver *driver;    /* which driver has allocated this device */
    void        *driver_data;    /* data private to the driver */
    void        *platform_data;    /* Platform specific data, device
                     core doesn't touch it */
    struct dev_pm_info    power;

#ifdef CONFIG_NUMA
    int        numa_node;    /* NUMA node this device is close to */
#endif
    u64        *dma_mask;    /* dma mask (if dma'able device) */
    u64        coherent_dma_mask;/* Like dma_mask, but for     alloc_coherent mappings as
                     not all hardware supports
                     64 bit addresses for consistent
    struct device_dma_parameters *dma_parms;

    struct list_head    dma_pools;    /* dma pools (if dma'ble) */

    struct dma_coherent_mem    *dma_mem; /* internal for coherent mem override */
    /* arch specific additions */
    struct dev_archdata    archdata;
        spinlock_t        devres_lock;
    struct list_head    devres_head;

    struct klist_node    knode_class;
    struct class        *class;
    dev_t            devt;    /* dev_t, creates the sysfs "dev" */
    struct attribute_group    **groups;    /* optional groups */

    void    (*release)(struct device *dev);
};

<STYLE type="text/css"> </STYLE>

3.2 pci_device

pci_dev作为一种特殊的device,内核中专门给出来定义,其需要注意的细节也会在以后需要的地方给出。

struct pci_dev {
    struct list_head bus_list;    /* node in per-bus list */
    struct pci_bus    *bus;        /* bus this device is on */
    struct pci_bus    *subordinate;    /* bus this device bridges to */

    void        *sysdata;    /* hook for sys-specific extension */
    struct proc_dir_entry *procent;    /* device entry in /proc/bus/pci */
    struct pci_slot    *slot;        /* Physical slot this device is in */

    unsigned int    devfn;        /* encoded device & function index */
    unsigned short    vendor;
    unsigned short    device;
    unsigned short    subsystem_vendor;
    unsigned short    subsystem_device;
    unsigned int    class;        /* 3 bytes: (base,sub,prog-if) */
    u8        revision;    /* PCI revision, low byte of class word */
    u8        hdr_type;    /* PCI header type (`multi' flag masked out) */
    u8        pcie_type;    /* PCI-E device/port type */
    u8        rom_base_reg;    /* which config register controls the ROM */
    u8        pin;         /* which interrupt pin this device uses */

    struct pci_driver *driver;    /* which driver has allocated this device */
    u64        dma_mask;    /* Mask of the bits of bus address this
                     device implements. Normally this is
                     0xffffffff. You only need to change
                     this if your device has broken DMA
                     or supports 64-bit transfers. */

    struct device_dma_parameters dma_parms;

    pci_power_t current_state; /* Current operating state. In ACPI-speak,
                     this is D0-D3, D0 being fully functional,
                     and D3 being off. */
    int        pm_cap;        /* PM capability offset in the
                     configuration space */
    unsigned int    pme_support:5;    /* Bitmask of states from which PME#
                     can be generated */
    unsigned int    d1_support:1;    /* Low power state D1 is supported */
    unsigned int    d2_support:1;    /* Low power state D2 is supported */
    unsigned int    no_d1d2:1;    /* Only allow D0 and D3 */

#ifdef CONFIG_PCIEASPM
    struct pcie_link_state    *link_state;    /* ASPM link state. */
#endif

    pci_channel_state_t error_state;    /* current connectivity state */
    struct    device    dev;        /* Generic device interface */

    int        cfg_size;    /* Size of configuration space */

    /*
     * Instead of touching interrupt line and base address registers
     * directly, use the values stored here. They might be different!
     */
    unsigned int    irq;
    struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */

    /* These fields are used by common fixups */
    unsigned int    transparent:1;    /* Transparent PCI bridge */
    unsigned int    multifunction:1;/* Part of multi-function device */
    /* keep track of device state */
    unsigned int    is_added:1;
    unsigned int    is_busmaster:1; /* device is busmaster */
    unsigned int    no_msi:1;    /* device may not use msi */
    unsigned int    block_ucfg_access:1;    /* userspace config space access is blocked */
    unsigned int    broken_parity_status:1;    /* Device generates false positive parity */
    unsigned int     msi_enabled:1;
    unsigned int    msix_enabled:1;
    unsigned int    ari_enabled:1;    /* ARI forwarding */
    unsigned int    is_managed:1;
    unsigned int    is_pcie:1;
    pci_dev_flags_t dev_flags;
    atomic_t    enable_cnt;    /* pci_enable_device has been called */

    u32        saved_config_space[16]; /* config space saved at suspend time */
    struct hlist_head saved_cap_space;
    struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
    int rom_attr_enabled;        /* has display of the rom attribute been enabled? */
    struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
    struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
#ifdef CONFIG_PCI_MSI
    struct list_head msi_list;
#endif
    struct pci_vpd *vpd;
};

3.3 pci_device_id

每一个设备上都有其生产厂家以及产品型号的标志,对于PCI设备来讲,内核用pci_device_id来表示,其定义和含义如下:


     真正开始之前,我们有必要先了解一下基本的概念和数据结构。其实我也不时太了解这些,尽管自己最近一直在看,而且查了不少的资料,但是也不敢保证自己的理解就是正确的,如果有什么错误,欢迎指正。

1. Kset,Kobject 和Ktype

如果仅仅是想要了解驱动的话,这三个结构可以暂时不考虑。但是如果你想要进一步的了解内核的话,那么至少应该对它们了解一些。Linux源码目录下的Documentation里面有一个kobject.txt文件,针对它们作了一些介绍。kobject是一个结构,通常被嵌入其他的结构中;每个kobject中包含一个名字,一个引用数量(referenced count)。ktype为kobject中的一个变量,由于标识一个kobject的类型;而kset则为一系列的kobject,这些kobject的ktype可以相同,也可以不同。关于其具体内容请参阅前面提到的文档。

这些东西和驱动编写没有太直接的关系,但之所以在这里提到这些,是因为系统启动的时候会扫描与其链接的总线(bus)和设备(device)并建立这些kset用于保存这些信息。例如对于一个PCI总线,Linux启动后会扫描所有挂载在该总线上的设备,并用一个队列来描述它们;同时,系统还维护一个driver的列队,只有设备列队上的设备有相应的驱动的时候,系统才可以正常的使用这个设备。

(个人对前面提到的这些仅限于了解,或者连了解也称不上,因此不多说,有兴趣的可以自行查阅相关资料。)

2. bus,pci_bus

<STYLE type="text/css"> </STYLE>

总线是CPU与外设沟通的重要手段,是计算机的重要组成部分。而PCI总线作为目前主流的总线之一,与作为PCI设备的网卡有关的几个结构为:bus_type和pci_bus_type。其中bus_type用来表示一个bus的类型,如ISA、PCI等等,其定义如下

struct bus_type {
    const char        *name;
    struct bus_attribute    *bus_attrs;
    struct device_attribute    *dev_attrs;
    struct driver_attribute    *drv_attrs;

    int (*match)(struct device *dev, struct device_driver *drv);
    int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
    int (*probe)(struct device *dev);
    int (*remove)(struct device *dev);
    void (*shutdown)(struct device *dev);

    int (*suspend)(struct device *dev, pm_message_t state);
    int (*suspend_late)(struct device *dev, pm_message_t state);
    int (*resume_early)(struct device *dev);
    int (*resume)(struct device *dev);

    struct pm_ext_ops *pm;
    struct bus_type_private *p;
};

<STYLE type="text/css"> </STYLE>

pci_bus_type作为bus_type的一个实例,规定了自己的一些特殊的操作,其定义如下:

struct bus_type pci_bus_type = {
    .name        = "pci",
    .match        = pci_bus_match,
    .uevent        = pci_uevent,
    .probe        = pci_device_probe,
    .remove        = pci_device_remove,
    .shutdown    = pci_device_shutdown,
    .dev_attrs    = pci_dev_attrs,
    .pm        = PCI_PM_OPS_PTR,
};

<STYLE type="text/css"> </STYLE>

上面这个定义里面的相关动作的句柄在涉及到PCI总线的特定操作的时候将会被调用,例如当试图将设备注册到PCI层的时候,pci_bus_match将会被调用。这个过程将会在后面的相关文章中给出。

3. Device,pci_dev,pci_evice_id和net_device

<STYLE type="text/css"> </STYLE>

3.1 device

device顾名思义是用来描述一个设备的,其构成比较复杂,这里仅仅给出定义,与PCI设备和驱动相关的部分将会在后文涉及到的时候详细介绍。其定义为:

struct device {
    struct klist        klist_children;
    struct klist_node    knode_parent;    /* node in sibling list */
    struct klist_node    knode_driver;
    struct klist_node    knode_bus;
    struct device        *parent;
    struct kobject kobj;
    char    bus_id[BUS_ID_SIZE];    /* position on parent bus */
    const char        *init_name; /* initial name of the device */
    struct device_type    *type;
    unsigned        uevent_suppress:1;
    struct semaphore    sem;    /* semaphore to synchronize calls to its driver. */
    struct bus_type    *bus;        /* type of bus device is on */
    struct device_driver *driver;    /* which driver has allocated this device */
    void        *driver_data;    /* data private to the driver */
    void        *platform_data;    /* Platform specific data, device
                     core doesn't touch it */
    struct dev_pm_info    power;

#ifdef CONFIG_NUMA
    int        numa_node;    /* NUMA node this device is close to */
#endif
    u64        *dma_mask;    /* dma mask (if dma'able device) */
    u64        coherent_dma_mask;/* Like dma_mask, but for     alloc_coherent mappings as
                     not all hardware supports
                     64 bit addresses for consistent
    struct device_dma_parameters *dma_parms;

    struct list_head    dma_pools;    /* dma pools (if dma'ble) */

    struct dma_coherent_mem    *dma_mem; /* internal for coherent mem override */
    /* arch specific additions */
    struct dev_archdata    archdata;
        spinlock_t        devres_lock;
    struct list_head    devres_head;

    struct klist_node    knode_class;
    struct class        *class;
    dev_t            devt;    /* dev_t, creates the sysfs "dev" */
    struct attribute_group    **groups;    /* optional groups */

    void    (*release)(struct device *dev);
};

<STYLE type="text/css"> </STYLE>

3.2 pci_device

pci_dev作为一种特殊的device,内核中专门给出来定义,其需要注意的细节也会在以后需要的地方给出。

struct pci_dev {
    struct list_head bus_list;    /* node in per-bus list */
    struct pci_bus    *bus;        /* bus this device is on */
    struct pci_bus    *subordinate;    /* bus this device bridges to */

    void        *sysdata;    /* hook for sys-specific extension */
    struct proc_dir_entry *procent;    /* device entry in /proc/bus/pci */
    struct pci_slot    *slot;        /* Physical slot this device is in */

    unsigned int    devfn;        /* encoded device & function index */
    unsigned short    vendor;
    unsigned short    device;
    unsigned short    subsystem_vendor;
    unsigned short    subsystem_device;
    unsigned int    class;        /* 3 bytes: (base,sub,prog-if) */
    u8        revision;    /* PCI revision, low byte of class word */
    u8        hdr_type;    /* PCI header type (`multi' flag masked out) */
    u8        pcie_type;    /* PCI-E device/port type */
    u8        rom_base_reg;    /* which config register controls the ROM */
    u8        pin;         /* which interrupt pin this device uses */

    struct pci_driver *driver;    /* which driver has allocated this device */
    u64        dma_mask;    /* Mask of the bits of bus address this
                     device implements. Normally this is
                     0xffffffff. You only need to change
                     this if your device has broken DMA
                     or supports 64-bit transfers. */

    struct device_dma_parameters dma_parms;

    pci_power_t current_state; /* Current operating state. In ACPI-speak,
                     this is D0-D3, D0 being fully functional,
                     and D3 being off. */
    int        pm_cap;        /* PM capability offset in the
                     configuration space */
    unsigned int    pme_support:5;    /* Bitmask of states from which PME#
                     can be generated */
    unsigned int    d1_support:1;    /* Low power state D1 is supported */
    unsigned int    d2_support:1;    /* Low power state D2 is supported */
    unsigned int    no_d1d2:1;    /* Only allow D0 and D3 */

#ifdef CONFIG_PCIEASPM
    struct pcie_link_state    *link_state;    /* ASPM link state. */
#endif

    pci_channel_state_t error_state;    /* current connectivity state */
    struct    device    dev;        /* Generic device interface */

    int        cfg_size;    /* Size of configuration space */

    /*
     * Instead of touching interrupt line and base address registers
     * directly, use the values stored here. They might be different!
     */
    unsigned int    irq;
    struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */

    /* These fields are used by common fixups */
    unsigned int    transparent:1;    /* Transparent PCI bridge */
    unsigned int    multifunction:1;/* Part of multi-function device */
    /* keep track of device state */
    unsigned int    is_added:1;
    unsigned int    is_busmaster:1; /* device is busmaster */
    unsigned int    no_msi:1;    /* device may not use msi */
    unsigned int    block_ucfg_access:1;    /* userspace config space access is blocked */
    unsigned int    broken_parity_status:1;    /* Device generates false positive parity */
    unsigned int     msi_enabled:1;
    unsigned int    msix_enabled:1;
    unsigned int    ari_enabled:1;    /* ARI forwarding */
    unsigned int    is_managed:1;
    unsigned int    is_pcie:1;
    pci_dev_flags_t dev_flags;
    atomic_t    enable_cnt;    /* pci_enable_device has been called */

    u32        saved_config_space[16]; /* config space saved at suspend time */
    struct hlist_head saved_cap_space;
    struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */
    int rom_attr_enabled;        /* has display of the rom attribute been enabled? */
    struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
    struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
#ifdef CONFIG_PCI_MSI
    struct list_head msi_list;
#endif
    struct pci_vpd *vpd;
};

3.3 pci_device_id

每一个设备上都有其生产厂家以及产品型号的标志,对于PCI设备来讲,内核用pci_device_id来表示,其定义和含义如下:

     * (i.e. as seen by users in the "Space.c" file). It is the name
     * the interface.
     */
    char            name[IFNAMSIZ];
    /* device name hash chain */
    struct hlist_node    name_hlist;
    /* snmp alias */
    char             *ifalias;

    /*
     *    I/O specific fields
     *    FIXME: Merge these and struct ifmap into one
     */
    unsigned long        mem_end;    /* shared mem end    */
    unsigned long        mem_start;    /* shared mem start    */
    unsigned long        base_addr;    /* device I/O address    */
    unsigned int        irq;        /* device IRQ number    */

    /*
     *    Some hardware also needs these fields, but they are not
     *    part of the usual set specified in Space.c.
     */

    unsigned char        if_port;    /* Selectable AUI, TP,..*/
    unsigned char        dma;        /* DMA channel        */

    unsigned long        state;

    struct list_head    dev_list;
#ifdef CONFIG_NETPOLL
    struct list_head    napi_list;
#endif
    
    /* The device initialization function. Called only once. */
    int            (*init)(struct net_device *dev);

    /* ------- Fields preinitialized in Space.c finish here ------- */

    /* Net device features */
    unsigned long        features;
#define NETIF_F_SG        1    /* Scatter/gather IO. */
#define NETIF_F_IP_CSUM        2    /* Can checksum TCP/UDP over IPv4. */
#define NETIF_F_NO_CSUM        4    /* Does not require checksum. F.e. loopack. */
#define NETIF_F_HW_CSUM        8    /* Can checksum all the packets. */
#define NETIF_F_IPV6_CSUM    16    /* Can checksum TCP/UDP over IPV6 */
#define NETIF_F_HIGHDMA        32    /* Can DMA to high memory. */
#define NETIF_F_FRAGLIST    64    /* Scatter/gather IO. */
#define NETIF_F_HW_VLAN_TX    128    /* Transmit VLAN hw acceleration */
#define NETIF_F_HW_VLAN_RX    256    /* Receive VLAN hw acceleration */
#define NETIF_F_HW_VLAN_FILTER    512    /* Receive filtering on VLAN */
#define NETIF_F_VLAN_CHALLENGED    1024    /* Device cannot handle VLAN packets */
#define NETIF_F_GSO        2048    /* Enable software GSO. */
#define NETIF_F_LLTX        4096    /* LockLess TX - deprecated. Please */
                    /* do not use LLTX in new drivers */
#define NETIF_F_NETNS_LOCAL    8192    /* Does not change network namespaces */
#define NETIF_F_LRO        32768    /* large receive offload */

    /* Segmentation offload features */
#define NETIF_F_GSO_SHIFT    16
#define NETIF_F_GSO_MASK    0xffff0000
#define NETIF_F_TSO        (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT)
#define NETIF_F_UFO        (SKB_GSO_UDP << NETIF_F_GSO_SHIFT)
#define NETIF_F_GSO_ROBUST    (SKB_GSO_DODGY << NETIF_F_GSO_SHIFT)
#define NETIF_F_TSO_ECN        (SKB_GSO_TCP_ECN << NETIF_F_GSO_SHIFT)
#define NETIF_F_TSO6        (SKB_GSO_TCPV6 << NETIF_F_GSO_SHIFT)

    /* List of features with software fallbacks. */
#define NETIF_F_GSO_SOFTWARE    (NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6)

#define NETIF_F_GEN_CSUM    (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM)
#define NETIF_F_V4_CSUM        (NETIF_F_GEN_CSUM | NETIF_F_IP_CSUM)
#define NETIF_F_V6_CSUM        (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM)
#define NETIF_F_ALL_CSUM    (NETIF_F_V4_CSUM | NETIF_F_V6_CSUM)

    /*
     * If one device supports one of these features, then enable them
     * for all in netdev_increment_features.
     */
#define NETIF_F_ONE_FOR_ALL    (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \
                 NETIF_F_SG | NETIF_F_HIGHDMA | \
                 NETIF_F_FRAGLIST)

    /* Interface index. Unique device identifier    */
    int            ifindex;
    int            iflink;

    struct net_device_stats* (*get_stats)(struct net_device *dev);
    struct net_device_stats    stats;

#ifdef CONFIG_WIRELESS_EXT
    /* List of functions to handle Wireless Extensions (instead of ioctl).
     * See <net/iw_handler.h> for details. Jean II */
    const struct iw_handler_def *    wireless_handlers;
    /* Instance data managed by the core of Wireless Extensions. */
    struct iw_public_data *    wireless_data;
#endif
    const struct ethtool_ops *ethtool_ops;

    /* Hardware header description */
    const struct header_ops *header_ops;

    /*
     * This marks the end of the "visible" part of the structure. All
     * fields hereafter are internal to the system, and may change at
     * will (read: may be cleaned up at will).
     */

    unsigned int        flags;    /* interface flags (a la BSD)    */
    unsigned short        gflags;
        unsigned short priv_flags; /* Like 'flags' but invisible to userspace. */
    unsigned short        padded;    /* How much padding added by alloc_netdev() */

    unsigned char        operstate; /* RFC2863 operstate */
    unsigned char        link_mode; /* mapping policy to operstate */

    unsigned        mtu;    /* interface MTU value        */
    unsigned short        type;    /* interface hardware type    */
    unsigned short        hard_header_len;    /* hardware hdr length    */

    /* extra head- and tailroom the hardware may need, but not in all cases
     * can this be guaranteed, especially tailroom. Some cases also use
     * LL_MAX_HEADER instead to allocate the skb.
     */
    unsigned short        needed_headroom;
    unsigned short        needed_tailroom;

    struct net_device    *master; /* Pointer to master device of a group,
                     * which this device is member of.
                     */

    /* Interface address info. */
    unsigned char        perm_addr[MAX_ADDR_LEN]; /* permanent hw address */
    unsigned char        addr_len;    /* hardware address length    */
    unsigned short dev_id;        /* for shared network cards */

    spinlock_t        addr_list_lock;
    struct dev_addr_list    *uc_list;    /* Secondary unicast mac addresses */
    int            uc_count;    /* Number of installed ucasts    */
    int            uc_promisc;
    struct dev_addr_list    *mc_list;    /* Multicast mac addresses    */
    int            mc_count;    /* Number of installed mcasts    */
    unsigned int        promiscuity;
    unsigned int        allmulti;

    /* Protocol specific pointers */
    
#ifdef CONFIG_NET_DSA
    void            *dsa_ptr;    /* dsa specific data */
#endif
    void             *atalk_ptr;    /* AppleTalk link     */
    void            *ip_ptr;    /* IPv4 specific data    */
    void *dn_ptr; /* DECnet specific data */
    void *ip6_ptr; /* IPv6 specific data */
    void            *ec_ptr;    /* Econet specific data    */
    void            *ax25_ptr;    /* AX.25 specific data */
    struct wireless_dev    *ieee80211_ptr;    /* IEEE 802.11 specific data,
                         assign before registering */

/*
 * Cache line mostly used on receive path (including eth_type_trans())
 */
    unsigned long        last_rx;    /* Time of last Rx    */
    /* Interface address info used in eth_type_trans() */
    unsigned char        dev_addr[MAX_ADDR_LEN];    /* hw address, (before bcast
                            because most packets are unicast) */

    unsigned char        broadcast[MAX_ADDR_LEN];    /* hw bcast add    */

    struct netdev_queue    rx_queue;

    struct netdev_queue    *_tx ____cacheline_aligned_in_smp;

    /* Number of TX queues allocated at alloc_netdev_mq() time */
    unsigned int        num_tx_queues;

    /* Number of TX queues currently active in device */
    unsigned int        real_num_tx_queues;

    unsigned long        tx_queue_len;    /* Max frames per queue allowed */
    spinlock_t        tx_global_lock;
/*
 * One part is mostly used on xmit path (device)
 */
    void            *priv;    /* pointer to private data    */
    int            (*hard_start_xmit) (struct sk_buff *skb,
                         struct net_device *dev);
    /* These may be needed for future network-power-down code. */
    unsigned long        trans_start;    /* Time (in jiffies) of last Tx    */

    int            watchdog_timeo; /* used by dev_watchdog() */
    struct timer_list    watchdog_timer;

/*
 * refcnt is a very hot point, so align it on SMP
 */
    /* Number of references to this device */
    atomic_t        refcnt ____cacheline_aligned_in_smp;

    /* delayed register/unregister */
    struct list_head    todo_list;
    /* device index hash chain */
    struct hlist_node    index_hlist;

    struct net_device    *link_watch_next;

    /* register/unregister state machine */
    enum { NETREG_UNINITIALIZED=0,
     NETREG_REGISTERED,    /* completed register_netdevice */
     NETREG_UNREGISTERING,    /* called unregister_netdevice */
     NETREG_UNREGISTERED,    /* completed unregister todo */
     NETREG_RELEASED,        /* called free_netdev */
    } reg_state;

    /* Called after device is detached from network. */
    void            (*uninit)(struct net_device *dev);
    /* Called after last user reference disappears. */
    void            (*destructor)(struct net_device *dev);

    /* Pointers to interface service routines.    */
    int            (*open)(struct net_device *dev);
    int            (*stop)(struct net_device *dev);
#define HAVE_NETDEV_POLL
#define HAVE_CHANGE_RX_FLAGS
    void            (*change_rx_flags)(struct net_device *dev,
                         int flags);
#define HAVE_SET_RX_MODE
    void            (*set_rx_mode)(struct net_device *dev);
#define HAVE_MULTICAST            
    void            (*set_multicast_list)(struct net_device *dev);
#define HAVE_SET_MAC_ADDR         
    int            (*set_mac_address)(struct net_device *dev,
                         void *addr);
#define HAVE_VALIDATE_ADDR
    int            (*validate_addr)(struct net_device *dev);
#define HAVE_PRIVATE_IOCTL
    int            (*do_ioctl)(struct net_device *dev,
                     struct ifreq *ifr, int cmd);
#define HAVE_SET_CONFIG
    int            (*set_config)(struct net_device *dev,
                     struct ifmap *map);
#define HAVE_CHANGE_MTU
    int            (*change_mtu)(struct net_device *dev, int new_mtu);

#define HAVE_TX_TIMEOUT
    void            (*tx_timeout) (struct net_device *dev);

    void            (*vlan_rx_register)(struct net_device *dev,
                         struct vlan_group *grp);
    void            (*vlan_rx_add_vid)(struct net_device *dev,
                         unsigned short vid);
    void            (*vlan_rx_kill_vid)(struct net_device *dev,
                         unsigned short vid);

    int            (*neigh_setup)(struct net_device *dev, struct neigh_parms *);
#ifdef CONFIG_NETPOLL
    struct netpoll_info    *npinfo;
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
    void (*poll_controller)(struct net_device *dev);
#endif

    u16            (*select_queue)(struct net_device *dev,
                        struct sk_buff *skb);

#ifdef CONFIG_NET_NS
    /* Network namespace this network device is inside */
    struct net        *nd_net;
#endif

    /* mid-layer private */
    void            *ml_priv;

    /* bridge stuff */
    struct net_bridge_port    *br_port;
    /* macvlan */
    struct macvlan_port    *macvlan_port;
    /* GARP */
    struct garp_port    *garp_port;

    /* class/net/name entry */
    struct device        dev;
    /* space for optional statistics and wireless sysfs groups */
    struct attribute_group *sysfs_groups[3];

    /* rtnetlink link ops */
    const struct rtnl_link_ops *rtnl_link_ops;

    /* VLAN feature mask */
    unsigned long vlan_features;

    /* for setting kernel sock attribute on TCP connection setup */
#define GSO_MAX_SIZE        65536
    unsigned int        gso_max_size;
};

排行榜 更多 +
终极躲避球

终极躲避球

休闲益智 下载
趣味跑酷竞赛

趣味跑酷竞赛

休闲益智 下载
米乐星球课

米乐星球课

学习教育 下载