i40evf Analysize

The function interface

i40evf_init_module
    |-->create_singlethread_workqueue(i40evf_driver_name);
    |-->pci_register_driver(&i40evf_driver);

static struct pci_driver i40evf_driver = {
.name = i40evf_driver_name,
.id_table = i40evf_pci_tbl,
.probe = i40evf_probe,
.remove = i40evf_remove,

#ifdef CONFIG_PM
.suspend = i40evf_suspend,
.resume = i40evf_resume,

#endif
.shutdown = i40evf_shutdown,
};

i40evf_probe
1) enable pcie device;

pci_enable_device(pdev);

2) set dma mask to 64bits or 32bits

dma_set_mask_and_coherent();

3) request regions, indicate this pdev belonged to this driver

pci_request_regions(pdev, i40evf_driver_name);

4) enable error report, pcie device have its own error report machisum

pci_enable_pcie_error_reporting(pdev);

5) set pci master, then the device can access the DDR

pci_set_master(pdev);

6) alloc net device, mac support 16 queues

alloc_etherdev_mq(sizeof(struct i40evf_adapter), MAX_QUEUES);

7) set netdev dev

SET_NETDEV_DEV(netdev, &pdev->dev);
pci_set_drvdata(pdev, netdev);

8) adapter initialize

hw = &adapter->hw;
hw->back = adapter;

9) get mem base address

hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
              pci_resource_len(pdev, 0));

10) get the vendor_id, device_id, revision_id, susystem_vendor_id,
subsystem_device_id, bus_id, bus_func;

11) initialize two lock(ASQ and ARQ) for admin queue

12) initialize two list(mac, vlan) for filter

13) 4 work queue

i40evf_reset_task
i40evf_adminq_task
i40evf_watchdog_task
i40evf_init_task(delayed work queue)

14) call i40evf_init_task

schedule_delayed_work(&adapter->init_task,
              secs_to_jiffies(5 * (pdev->devfn & 0x07)));