This is an old revision of the document!


A PCRE internal error occured. This might be caused by a faulty plugin

====== gPXE Driver API Documentation ====== A gPXE network driver may incorporate elements of the following: * [[#gpxe_pci_device_driver_api|gPXE PCI Device Driver API]] * [[#gpxe_network_driver_api|gPXE Network Driver API]] * [[#non-volatile_storage_api|Non-Volatile Storage API]] Note the [[:dev:netdriverapi|previous driver model]] of Etherboot is deprecated. Existing Etherboot PCI drivers are temporarily supported via the compatibility layer in src/drivers/net/legacy.c Drivers conforming to the gPXE Network Driver API are: * e1000 * natsemi * rtl8139 ===== gPXE PCI Device Driver API ===== A PCI driver provides its API routines to gPXE via a ''struct pci_driver'': <code c> struct pci_driver natsemi_driver __pci_driver = { .ids = natsemi_nics, .id_count = (sizeof (natsemi_nics) / sizeof (natsemi_nics[0])), .probe = natsemi_probe, .remove = natsemi_remove, }; </code> The ''.ids'' and ''.id_count'' members list the vendor & device IDs of supported devices. The functions natsemi_probe & natsemi_remove are driver implementations of the required PCI device driver API functions: * ''[[#probe|static int probe ( struct pci_device* , const struct pci_device_id* )]]'' * ''[[#remove|static void remove ( struct pci_device* )]]'' ==== probe ==== ''static int probe ( struct pci_device* , const struct pci_device_id* )''\\ This function is called [[:soc:2008:mdeck:notes:initialization|first]] to initialize the card. Here a typical network driver will: - Allocate a ''struct net_device'' with associated private data using ''alloc_etherdev()''. - Associate the driver functions with the ''net_device'' via ''netdev_init()''. - Associate the ''net_device'' with the ''pci_device'' via ''pci_set_drvdata()''. - Initialize private data. - Ensure busmastering is enabled and check pci latency with ''adjust_pci_device()''. - Reset the device. - Initialize [[#EEPROM|EEPROM]]. - Read the MAC address from EEPROM. - Mark the ''net_device'' as having a link up with ''netdev_link_up()'', as we don't yet handle the link state. - Name the device and add it to the list of network devices via ''register_netdev()''. - Possibly setup a non-volatile stored options block with ''nvo_init()'' & ''register_nvo()''. ==== remove ==== ''static void remove ( struct pci_device* )''\\ This function is called last to remove the device. A typical driver will: - Call ''unregister_nvo()'' for any registered non-volatile stored options. - Call ''iounmap()'' for any addresses previously mapped with ''ioremap()''. - Call ''unregister_netdev()'' for the device previously registered with ''register_netdev()'' - Reset the device. - Dissociate driver functions from ''net_device'' via ''netdev_nullify()''. - Decrement reference count of ''net_device'' with ''netdev_put()''. ===== gPXE Network Driver API ===== A network driver in gPXE provides its API routines to the system via a ''struct net_device_operations'' during the initial ''probe()'' call (see [[:soc:2008:mdeck:notes:initialization|initialization of a network driver]]). For example, in natsemi.c: <code c> static struct net_device_operations natsemi_operations = { .open = natsemi_open, .close = natsemi_close, .transmit = natsemi_transmit, .poll = natsemi_poll, .irq = natsemi_irq, }; </code> Here, natsemi_open/close/etc are driver implementations of the required network driver API functions: * ''[[#open|static int open ( struct net_device* )]]'' * ''[[#close|static void close ( struct net_device* )]]'' * ''[[#transmit|static int transmit ( struct net_device*, struct io_buffer* )]]'' * ''[[#poll|static void poll ( struct net_device* )]]'' * ''[[#irq|static void irq ( struct net_device*, int enable )]]'' ==== open ==== ''static int open ( struct net_device* )''\\ This function is called after ''probe()'' during [[:soc:2008:mdeck:notes:initialization|initialization]]. A driver would: - Program MAC address to device. - Setup TX & RX rings. - Perform other configuration (e.g. filters, bursts, interrupts). - Enable RX and TX. ==== close ==== ''static void close ( struct net_device* )''\\ In this function, a typical driver might: - Acknowledge interrupts. - Disable irq, receives. - Reset the device. - Free any used resources (e.g. rx/tx rings, dma buffers, etc). ==== transmit ==== ''static int transmit ( struct net_device*, struct io_buffer* )''\\ A data transmission is actuated with this routine. A typical driver might: - Check for tx overflow. - Save buffer pointer for later tx completion reference. - Pad & align packet if necessary. - Add packet to transmit ring. - Possibly ensure transmit is on. ==== poll ==== ''static void poll ( struct net_device* )''\\ This function is called periodically to process tx completions and rx packets. A typical driver would: - Acknowledge interrupts. - Feed tx completions to ''netdev_tx_complete()'' or ''netdev_tx_complete_err()''. - Add good received packets to receive queue with ''netdev_rx()'', or feed corrupted packets to ''netdev_rx_err()'' ==== irq ==== ''static void irq ( struct net_device*, int enable )''\\ In this function, a typical driver will: - Enable interrupts if the int parameter is non-zero ===== Non-Volatile Storage API ===== The nvs API may be used to access non-volatile storage that conforms to a number of supported SPI variants. * To initialize nvs support: - The read_bit() and write_bit() function pointers are stored in a ''struct spi_bit_basher''. - The mode & endianness are also initialized. - ''init_spi_bit_basher()'' is called. - A ''struct spi_device'' is initialized (EEPROM-model dependent). - Bus is copied: ''spidev.bus = &spibb.bus'' - EITHER - Initialize a ''struct nvo_block'' with ''nvob.nvs = &spidev.nvs'' - Assign usable regions via ''nvob.fragments = nvof'' where ''nvof'' is an array of ''struct nvo_fragment''s that specify the usable regions. - OR - Call ''nvo_init(&nvob, &spidev.nvs, nvof, ..)'' where ''nvof'' is an array of ''struct nvo_fragment''s that specify the usable regions. * Use ''nvs_read()'' to perform a serial read @ a specific address. * Use ''nvs_write()'' to perform a serial write @ a specific address.


Navigation

* [[:start|Home]] * [[:about|About our Project]] * [[:download|Download]] * [[:screenshots|Screenshots]] * Documentation * [[:howtos|HowTo Guides]] * [[:appnotes|Application Notes]] * [[:faq:|FAQs]] * [[:doc|General Doc]] * [[:talks|Videos, Talks, and Papers]] * [[:hardwareissues|Hardware Issues]] * [[:mailinglists|Mailing lists]] * [[http://support.etherboot.org/|Bugtracker]] * [[:contributing|Contributing]] * [[:editing_permission|Wiki Edit Permission]] * [[:wiki:syntax|Wiki Syntax]] * [[:contact|Contact]] * [[:relatedlinks|Related Links]] * [[:commerciallinks|Commercial Links]] * [[:acknowledgements|Acknowledgements]] * [[:logos|Logo Art]]

QR Code
QR Code soc:2008:mdeck:notes:gpxe_driver_api (generated for current page)