Deep understanding of Linux Network Technology Insider--PCI layer and network interface card

Source: Internet
Author: User

Overviewthe kernel's PCI subsystem, or PCI layer, provides a number of common features for different devices to simplify various device drivers.
The important structure of the PCI layer is as follows:
pci_device_id
device identification, based on the ID defined by the PCI flag, instead of Linux Local.
Pci_dev
a net_device similar to a network device. Each PCI is assigned a Net_dev instance.
Pci_driverinterface between the PCI layer and the device driver. Mainly consists of some function pointers. As shown below:
struct Pci_driver {    struct list_head node;                                                                                                   Char *name; Driver name    const struct PCI_DEVICE_ID *id_table;   /* ID vector, the kernel is used to associate the device to this driver */    int  (*probe)  (struct Pci_dev *dev, const struct pci_device_id *id);   /* New Device inserted */    void (*remove) (struct Pci_dev *dev);   /* Device removed (NULL if not a hot-plug capable driver) */    int  (*suspend) (struct Pci_dev *dev, pm_message_t s Tate);  /* Device suspended */    int  (*suspend_late) (struct Pci_dev *dev, pm_message_t state);    int  (*resume_early) (struct Pci_dev *dev);    int  (*resume) (struct Pci_dev *dev);                   /* Device Woken up */    void (*shutdown) (struct Pci_dev *dev);    struct Pci_error_handlers *err_handler;    struct device_driver    driver;    struct pci_dynids dynids;};



registration of PCI NIC devicesthe PCI device isPCI_DEVICE_ID (the member common) unique identity.
struct PCI_DEVICE_ID {    __u32 vendor, device;       /* Vendor and device ID or pci_any_id*///usually Vendor, the device is sufficient to identify devices    __u32 Subvendor, subdevice;/* Subsystem ID ' s or PC i_any_id *///rarely used    __u32 class, Class_mask;    /* (CLASS,SUBCLASS,PROG-IF) triplet *///device belongs to class, such as Network class    kernel_ulong_t driver_data; * * Data Private to the driver */ Does not belong to the PCI identity section, but drives the private parameter};


Each device driver registers aa vector of pci_device_id instances (that is, a series ofpci_device_id Instances), this vector contains the ID of the device that the driver can handle. The following are the registration and deletion functions of the device driver:
int __pci_register_driver (struct pci_driver *drv, struct module *owner, const char *mod_name) void Pci_unregister_driver ( struct Pci_driver *drv) pci_module_init ()//On some drivers as __pci_register_driver aliases

The kernel queries the device's driver based on the device ID, which is a detection mechanism. There are two ways of probing: static and dynamic. Static:
Given the ID of a PCI, the kernel queries the corresponding driver from the id_table vector based on the ID .
Dynamic:based on the user's manually configured ID, it is less used and requires kernel compilation to support hot-swapping.
power management and wake on LANPCI power management events are performed with Pci_driver suspend and resume. These two functions are responsible for the preservation and recovery of PCI State respectively. If you encounter a NIC, you need to perform the following steps separately:
suspend: Stop the device exit queue so that the device can no longer be transferred:
Resume: Restarts the egress queue, where the device can continue to transmit.

The wake on LAN feature allows the NIC to wake the system when it receives a particular frame. This feature is usually disabled, butThis feature can be opened or closed with Pci_enable_wake. On this Part I found that linux-3.12.36 does not seem to have this function, may have used other network wake-up method, save later added.

    example of PCI NIC driver registration

The Intel pro/100 Ethernet driver describes the registration of the NIC device driver, and the source file is drivers/net/e100.c.

Initialize pci_device_id content:

#define Intel_8255x_ethernet_device (device_id, ich) {\ Pci_vendor_id_intel, device_id, pci_any_id, pci_any_id, \ P Ci_class_network_ethernet << 8, 0xffff00, ich}/************************************************************* /#define DEFINE_PCI_DEVICE_TABLE (_table) \ const struct PCI_DEVICE_ID _table[] __devinitco Nst/***************************************************************************************/static DEFINE_PCI_     Device_table (e100_id_table) = {Intel_8255x_ethernet_device (0x1029, 0), Intel_8255x_ethernet_device (0x1030, 0), Intel_8255x_ethernet_device (0x1031, 3), Intel_8255x_ethernet_device (0x1032, 3), Intel_8255x_ethernet_device (0x10 3), Intel_8255x_ethernet_device (0x1034, 3), Intel_8255x_ethernet_device (0x1038, 3), Intel_8255x_ethernet_d Evice (0x1039, 4), Intel_8255x_ethernet_device (0x103a, 4), Intel_8255x_ethernet_device (0x103b, 4), INTEL_8255X_ Ethernet_device (0x103c, 4), intel_8255x_ethernet_device (0x103d, 4), Intel_8255x_ethernet_device (0x103e, 4), Intel_8255x_ethernet_device (0x1050, 5), I  Ntel_8255x_ethernet_device (0x1051, 5), Intel_8255x_ethernet_device (0x1052, 5), Intel_8255x_ethernet_device (0x1053, 5), Intel_8255x_ethernet_device (0x1054, 5), Intel_8255x_ethernet_device (0x1055, 5), Intel_8255x_ethernet_devi CE (0x1056, 5), Intel_8255x_ethernet_device (0x1057, 5), Intel_8255x_ethernet_device (0x1059, 0), Intel_8255x_eth Ernet_device (0x1064, 6), Intel_8255x_ethernet_device (0x1065, 6), Intel_8255x_ethernet_device (0x1066, 6), INTEL      _8255x_ethernet_device (0x1067, 6), Intel_8255x_ethernet_device (0x1068, 6), Intel_8255x_ethernet_device (0x1069, 6), Intel_8255x_ethernet_device (0x106a, 6), Intel_8255x_ethernet_device (0x106b, 6), Intel_8255x_ethernet_device (0 x1091, 7), Intel_8255x_ethernet_device (0x1092, 7), Intel_8255x_ethernet_device (0x1093, 7), Intel_8255x_etherne    T_device (0x1094, 7), Intel_8255x_ethernet_device (0x1095, 7), Intel_8255x_ethernet_device (0X10FE, 7), Intel_8255x_ethernet_device (0x120 9, 0), Intel_8255x_ethernet_device (0x1229, 0), Intel_8255x_ethernet_device (0x2449, 2), Intel_8255x_ethernet_de VICE (0x2459, 2), Intel_8255x_ethernet_device (0x245d, 2), Intel_8255x_ethernet_device (0X27DC, 7), {0,}};


Complete the registration and logoff of the PCI device driver in the initialization and uninstallation interfaces of the module:

static struct Pci_driver E100_driver = {     . Name =         Drv_name,     . id_table =     e100_id_table,     . Probe =        e100_probe,     . Remove =       __devexit_p (e100_remove), #ifdef config_pm/     * Power Management hooks */     . Suspend =      E100_suspend,     . Resume =       E100_resume, #endif     . Shutdown =     E100_shutdown,     . Err_handler = &e100_err_handler,};static int __init e100_init_module (void) {     if (((1 << Debug)-1) & NETIF_MSG_DRV) {         pr_info ("%s,%s\n", Drv_description, drv_version);         Pr_info ("%s\n", drv_copyright);     }     Return Pci_register_driver (&e100_driver); }static void __exit e100_cleanup_module (void) {     pci_unregister_driver (&e100_driver);} Module_init (E100_init_module); Module_exit (E100_cleanup_module);


Some of these function pointer prototypes:

#define DRV_NAME        "e100" static int __devinit e100_probe (struct Pci_dev *pdev,  const struct pci_device_id *ent) { C2/>struct Net_device *netdev;     struct NIC *nic;     int err;    if (! ( Netdev = Alloc_etherdev (sizeof (struct NIC))) {         if (((1 << Debug)-1) & Netif_msg_probe)             pr_err ("ether Dev Alloc failed, aborting\n ");         Return-enomem;     }                         ... ......}


Overview of the PCI subsystem

(a) When the system boots, a database is created that associates each bus to a list of devices that have been detected and used on that bus. The PCI bus descriptor handles other parameters, including a list of detected PCI devices.

(b) When the driver is loaded and the call Pci_register_driver registers pci_driver to the PCI layer, PCI uses the PCI device ID parameter id_table in the Pci_driver structure to match the list of detected PCI devices. A list of devices that will establish the driver if it matches. For each device that matches, the PCI layer invokes the probe function in the pci_driver structure in the matching driver to establish and register the associated network device.




The/proc/pci file contains information about a registered PCI device. The LSPCI command in the Pciutils suite outputs information about the local PCI device, some of which are taken from/sys.


 










Deep understanding of Linux Network Technology Insider--PCI layer and network interface card

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.