Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
soc:2008:mdeck:notes:gpxe_driver_api [2008/05/29 07:38]
mdeck
soc:2008:mdeck:notes:gpxe_driver_api [2009/11/03 08:58] (current)
meteger
Line 7: Line 7:
 Note the [[:​dev:​netdriverapi|previous driver model]] of Etherboot is deprecated. 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 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:+Drivers ​currently ​conforming to the gPXE Network Driver API are: 
 +  * 3c90x 
 +  * ath5k 
 +  * atl1e 
 +  * b44
   * e1000   * e1000
 +  * etherfabric
 +  * mtnic
   * natsemi   * natsemi
 +  * phantom
 +  * pnic
 +  * r8169
   * rtl8139   * rtl8139
 +  * rtl818x 
 +  * sis190 
 +  * sky2
  
  
 ===== gPXE PCI Device Driver API ===== ===== gPXE PCI Device Driver API =====
-A PCI driver provides its API routines to gPXE via a ''​struct pci_driver'':​+A PCI driver provides its API routines to gPXE via a ''​struct pci_driver''​.  For example, in natsemi.c:
 <code c> <code c>
 struct pci_driver natsemi_driver __pci_driver = { struct pci_driver natsemi_driver __pci_driver = {
Line 40: Line 51:
   - Initialize [[#​EEPROM|EEPROM]].   - Initialize [[#​EEPROM|EEPROM]].
   - Read the MAC address from 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.+  - Check the link state and report ​''​netdev_link_up()'' ​if connected. ​ Many drivers ​don't yet handle the link state and simply assume the link is up.
   - Name the device and add it to the list of network devices via ''​register_netdev()''​.   - 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()''​.   - Possibly setup a non-volatile stored options block with ''​nvo_init()''​ & ''​register_nvo()''​.
Line 69: Line 80:
 </​code>​ </​code>​
 Here, natsemi_open/​close/​etc are driver implementations of the required network driver API functions: ​ 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* )]]''​   * ''​[[#​close|static void close ( struct net_device* )]]''​
 +  * ''​[[#​open|static int open ( struct net_device* )]]''​
   * ''​[[#​transmit|static int transmit ( struct net_device*,​ struct io_buffer* )]]''​   * ''​[[#​transmit|static int transmit ( struct net_device*,​ struct io_buffer* )]]''​
   * ''​[[#​poll|static void poll ( struct net_device* )]]''​   * ''​[[#​poll|static void poll ( struct net_device* )]]''​
   * ''​[[#​irq|static void irq ( struct net_device*,​ int enable )]]''​   * ''​[[#​irq|static void irq ( struct net_device*,​ int enable )]]''​
 +
 +==== close ====
 +''​static void close ( struct net_device* )''​\\
 +This function is called if the device is open in ''​autoboot()''​ during [[:​soc:​2008:​mdeck:​notes:​initialization|initialization]],​ after a failed or successful attempt to boot the network device. ​ In this routine, a typical driver might:
 +  - Acknowledge interrupts.
 +  - Disable irq, receives.
 +  - Reset the device.
 +  - Free any used resources (e.g. rx/tx rings, dma buffers, etc).
  
 ==== open ==== ==== open ====
 ''​static int open ( struct net_device* )''​\\ ''​static int open ( struct net_device* )''​\\
-This function is called ​after ''​probe()''​ during [[:​soc:​2008:​mdeck:​notes:​initialization|initialization]]. ​ A driver would:+This function is first called ​in ''​netboot()'' ​when attempting a device boot during [[:​soc:​2008:​mdeck:​notes:​initialization|initialization]], after ''​close()''​ of any previous device attempt is called.  A driver would:
   - Program MAC address to device.   - Program MAC address to device.
   - Setup TX & RX rings.   - Setup TX & RX rings.
   - Perform other configuration (e.g. filters, bursts, interrupts).   - Perform other configuration (e.g. filters, bursts, interrupts).
   - Enable RX and TX.   - 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 ==== ==== transmit ====
Line 102: Line 113:
 ==== poll ==== ==== poll ====
 ''​static void poll ( struct net_device* )''​\\ ''​static void poll ( struct net_device* )''​\\
-This function is called periodically to process tx completions and rx packets. ​ A typical driver would:+This function is called periodically ​by the network stack to process tx completions and rx packets. ​ A typical driver would:
   - Acknowledge interrupts.   - Acknowledge interrupts.
-  - Feed tx completions to ''​netdev_tx_complete()''​ or ''​netdev_tx_complete_err()''​. +  - Check hardware and 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()''​+  - Add good received packets to receive queue with ''​netdev_rx()'',​ or report ​corrupted packets to ''​netdev_rx_err()''​ 
 +  - Check link state occasionally,​ and report changes with ''​netdev_link_up()''​ or ''​netdev_link_down()''​
  
 ==== irq ==== ==== irq ====
Line 111: Line 123:
 In this function, a typical driver will: In this function, a typical driver will:
   - Enable interrupts if the int parameter is non-zero   - Enable interrupts if the int parameter is non-zero
 +Note the //force interrupt// behavior from Etherboot is deprecated.
  
  
Line 123: Line 135:
     - A ''​struct spi_device''​ is initialized (EEPROM-model dependent).     - A ''​struct spi_device''​ is initialized (EEPROM-model dependent).
     - Bus is copied: ''​spidev.bus = &​spibb.bus''​     - Bus is copied: ''​spidev.bus = &​spibb.bus''​
-    - EITHER+    - If non-volatile options will be utilized: 
 +      - Call ''​nvo_init(&​nvob,​ &​spidev.nvs,​ nvof, ..)''​ where ''​nvof''​ is an array of ''​struct nvo_fragment''​s that specify the usable regions. ​ This will also initialize a settings block.  
 +    - Else, if non-volatile options will //not// be used:
       - Initialize a ''​struct nvo_block''​ with ''​nvob.nvs = &​spidev.nvs''​       - 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.       - 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_read()''​ to perform a serial read @ a specific address.
   * Use ''​nvs_write()''​ to perform a serial write @ a specific address.   * Use ''​nvs_write()''​ to perform a serial write @ a specific address.

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