|
iPXE
|
UNDI network device driver. More...
#include <string.h>#include <unistd.h>#include <byteswap.h>#include <pxe.h>#include <realmode.h>#include <pic8259.h>#include <biosint.h>#include <pnpbios.h>#include <basemem_packet.h>#include <ipxe/io.h>#include <ipxe/iobuf.h>#include <ipxe/netdevice.h>#include <ipxe/if_ether.h>#include <ipxe/ethernet.h>#include <ipxe/pci.h>#include <ipxe/profile.h>#include <undi.h>#include <undinet.h>Go to the source code of this file.
Data Structures | |
| struct | undi_nic |
| An UNDI NIC. More... | |
| struct | undinet_profiler |
| A PXE API call breakdown profiler. More... | |
| struct | undinet_irq_broken |
| A device with broken support for generating interrupts. More... | |
Macros | |
| #define | EINFO_EPXECALL |
| #define | EPXECALL(status) |
| #define | UNDI_HACK_EB54 0x0001 |
| Work around Etherboot 5.4 bugs. | |
| #define | UNDI_INITIALIZE_RETRY_MAX 10 |
| Maximum number of times to retry PXENV_UNDI_INITIALIZE. | |
| #define | UNDI_INITIALIZE_RETRY_DELAY_MS 200 |
| Delay between retries of PXENV_UNDI_INITIALIZE. | |
| #define | UNDI_RX_QUOTA 4 |
| Maximum number of received packets per poll. | |
| #define | UNDI_RX_ALIGN 16 |
| Alignment of received frame payload. | |
| #define | undinet_params __use_data16 ( undinet_params ) |
| #define | undinet_entry_point __use_data16 ( undinet_entry_point ) |
| #define | RDTSC_IF_PROFILING "" |
| #define | undiisr_irq __use_data16 ( undiisr_irq ) |
| #define | undiisr_imr __use_data16 ( undiisr_imr ) |
| #define | undiisr_bit __use_data16 ( undiisr_bit ) |
| #define | undiisr_rearm __use_data16 ( undiisr_rearm ) |
| #define | undiisr_next_handler __use_data16 ( undiisr_next_handler ) |
| #define | undiisr_trigger_count __use_data16 ( undiisr_trigger_count ) |
| #define | undinet_tbd __use_data16 ( undinet_tbd ) |
| #define | undinet_destaddr __use_data16 ( undinet_destaddr ) |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static void | undinet_close (struct net_device *netdev) |
| Close NIC. | |
| static union u_PXENV_ANY | __bss16 (undinet_params) |
| UNDI parameter block. | |
| SEGOFF16_t | __bss16 (undinet_entry_point) |
| UNDI entry point. | |
| static const char * | undinet_function_name (unsigned int function) |
| Name PXE API call. | |
| static struct undinet_profiler * | undinet_profiler (unsigned int function) |
| Determine applicable profiler pair (for debugging) | |
| static int | undinet_call (struct undi_nic *undinic, unsigned int function, void *params, size_t params_len) |
| Issue UNDI API call. | |
| void | undiisr (void) |
| UNDI interrupt service routine. | |
| uint8_t | __data16 (undiisr_irq) |
| IRQ number. | |
| uint16_t | __data16 (undiisr_imr) |
| IRQ mask register. | |
| uint8_t | __data16 (undiisr_bit) |
| IRQ mask bit. | |
| uint8_t | __data16 (undiisr_rearm) |
| IRQ rearm flag. | |
| struct segoff | __data16 (undiisr_next_handler) |
| IRQ chain vector. | |
| volatile uint8_t | __data16 (undiisr_trigger_count)=0 |
| IRQ trigger count. | |
| static void | undinet_hook_isr (unsigned int irq) |
| Hook UNDI interrupt service routine. | |
| static void | undinet_unhook_isr (unsigned int irq) |
| Unhook UNDI interrupt service routine. | |
| static int | undinet_isr_triggered (void) |
| Test to see if UNDI ISR has been triggered. | |
| static struct s_PXENV_UNDI_TBD | __data16 (undinet_tbd) |
| UNDI transmit buffer descriptor. | |
| static uint8_t | __data16_array (undinet_destaddr, [ETH_ALEN]) |
| UNDI transmit destination address. | |
| static int | undinet_transmit (struct net_device *netdev, struct io_buffer *iobuf) |
| Transmit packet. | |
| static void | undinet_poll (struct net_device *netdev) |
| Poll for received packets. | |
| static int | undinet_open (struct net_device *netdev) |
| Open NIC. | |
| static void | undinet_irq (struct net_device *netdev, int enable) |
| Enable/disable interrupts. | |
| static int | undinet_irq_is_broken (struct net_device *netdev) |
| Check for devices with broken support for generating interrupts. | |
| int | undinet_probe (struct undi_device *undi, struct device *dev) |
| Probe UNDI device. | |
| void | undinet_remove (struct undi_device *undi) |
| Remove UNDI device. | |
Variables | |
| static struct profiler undinet_irq_profiler | __profiler |
| IRQ profiler. | |
| static unsigned int | last_trigger_count = 0 |
| Last observed trigger count. | |
| static struct net_device_operations | undinet_operations |
| UNDI network device operations. | |
| static const struct undinet_irq_broken | undinet_irq_broken_list [] |
| List of devices with broken support for generating interrupts. | |
UNDI network device driver.
Definition in file undinet.c.
| #define EINFO_EPXECALL |
Definition at line 60 of file undinet.c.
| #define EPXECALL | ( | status | ) |
Definition at line 63 of file undinet.c.
Referenced by undinet_call().
| #define UNDI_INITIALIZE_RETRY_MAX 10 |
Maximum number of times to retry PXENV_UNDI_INITIALIZE.
Definition at line 76 of file undinet.c.
Referenced by undinet_probe().
| #define UNDI_INITIALIZE_RETRY_DELAY_MS 200 |
Delay between retries of PXENV_UNDI_INITIALIZE.
Definition at line 79 of file undinet.c.
Referenced by undinet_probe().
| #define UNDI_RX_QUOTA 4 |
Maximum number of received packets per poll.
Definition at line 82 of file undinet.c.
Referenced by undinet_poll().
| #define UNDI_RX_ALIGN 16 |
Alignment of received frame payload.
Definition at line 85 of file undinet.c.
Referenced by undinet_poll().
| #define undinet_params __use_data16 ( undinet_params ) |
Definition at line 96 of file undinet.c.
Referenced by __bss16(), and undinet_call().
| #define undinet_entry_point __use_data16 ( undinet_entry_point ) |
Definition at line 105 of file undinet.c.
Referenced by __bss16(), undinet_call(), undinet_probe(), and undinet_remove().
| #define RDTSC_IF_PROFILING "" |
Definition at line 111 of file undinet.c.
Referenced by undinet_call().
| #define undiisr_irq __use_data16 ( undiisr_irq ) |
Definition at line 374 of file undinet.c.
Referenced by __data16(), undinet_hook_isr(), and undinet_unhook_isr().
| #define undiisr_imr __use_data16 ( undiisr_imr ) |
Definition at line 378 of file undinet.c.
Referenced by __data16(), and undinet_hook_isr().
| #define undiisr_bit __use_data16 ( undiisr_bit ) |
Definition at line 382 of file undinet.c.
Referenced by __data16(), and undinet_hook_isr().
| #define undiisr_rearm __use_data16 ( undiisr_rearm ) |
Definition at line 386 of file undinet.c.
Referenced by __data16(), undinet_hook_isr(), and undinet_poll().
| #define undiisr_next_handler __use_data16 ( undiisr_next_handler ) |
Definition at line 390 of file undinet.c.
Referenced by __data16(), undinet_hook_isr(), and undinet_unhook_isr().
| #define undiisr_trigger_count __use_data16 ( undiisr_trigger_count ) |
Definition at line 394 of file undinet.c.
Referenced by __data16(), and undinet_isr_triggered().
| #define undinet_tbd __use_data16 ( undinet_tbd ) |
Definition at line 461 of file undinet.c.
Referenced by __data16(), and undinet_transmit().
| #define undinet_destaddr __use_data16 ( undinet_destaddr ) |
Definition at line 465 of file undinet.c.
Referenced by __data16_array(), and undinet_transmit().
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
|
static |
Close NIC.
| netdev | Net device |
Definition at line 775 of file undinet.c.
References DBGC, s_PXENV_UNDI_ISR::FuncFlag, undi_nic::irq, undi_nic::isr_processing, netdev, PXENV_UNDI_CLOSE, PXENV_UNDI_ISR, PXENV_UNDI_ISR_IN_GET_NEXT, PXENV_UNDI_ISR_OUT_RECEIVE, PXENV_UNDI_ISR_OUT_TRANSMIT, rc, undinet_call(), and undinet_unhook_isr().
Referenced by undinet_open().
|
static |
UNDI parameter block.
Used as the parameter block for all UNDI API calls. Resides in base memory.
References __bss16, and undinet_params.
| SEGOFF16_t __bss16 | ( | undinet_entry_point | ) |
UNDI entry point.
Used as the indirection vector for all UNDI API calls. Resides in base memory.
References undinet_entry_point.
|
inlinestatic |
Name PXE API call.
| function | API call number |
| name | API call name |
Definition at line 189 of file undinet.c.
References function, PXENV_GET_CACHED_INFO, PXENV_START_UNDI, PXENV_STOP_UNDI, PXENV_UNDI_CLEANUP, PXENV_UNDI_CLEAR_STATISTICS, PXENV_UNDI_CLOSE, PXENV_UNDI_FORCE_INTERRUPT, PXENV_UNDI_GET_IFACE_INFO, PXENV_UNDI_GET_INFORMATION, PXENV_UNDI_GET_MCAST_ADDRESS, PXENV_UNDI_GET_NIC_TYPE, PXENV_UNDI_GET_STATISTICS, PXENV_UNDI_INITIALIZE, PXENV_UNDI_INITIATE_DIAGS, PXENV_UNDI_ISR, PXENV_UNDI_OPEN, PXENV_UNDI_RESET_ADAPTER, PXENV_UNDI_SET_MCAST_ADDRESS, PXENV_UNDI_SET_PACKET_FILTER, PXENV_UNDI_SET_STATION_ADDRESS, PXENV_UNDI_SHUTDOWN, PXENV_UNDI_STARTUP, and PXENV_UNDI_TRANSMIT.
Referenced by undinet_call().
|
static |
Determine applicable profiler pair (for debugging)
| function | API call number |
| profiler | Profiler |
Definition at line 254 of file undinet.c.
References function, PXENV_UNDI_ISR, PXENV_UNDI_TRANSMIT, and PXENV_UNKNOWN.
Referenced by undinet_call().
|
static |
Issue UNDI API call.
| undinic | UNDI NIC |
| function | API call number |
| params | PXE parameter block |
| params_len | Length of PXE parameter block |
| rc | Return status code |
Definition at line 278 of file undinet.c.
References __asm__(), __from_data16, __volatile__(), after, assert, before, DBGC, DBGC_HDA, discard_D, EPXECALL, function, memcpy(), profile_start(), profile_start_at(), profile_started(), profile_stop(), profile_stop_at(), profile_stopped(), PXENV_EXIT_SUCCESS, rc, RDTSC_IF_PROFILING, REAL_CODE, rm_ds, started, strerror(), undinet_entry_point, undinet_function_name(), undinet_params, and undinet_profiler().
Referenced by undinet_close(), undinet_open(), undinet_poll(), undinet_probe(), undinet_remove(), and undinet_transmit().
|
extern |
UNDI interrupt service routine.
The UNDI ISR increments a counter (trigger_count) and exits.
Referenced by undinet_hook_isr(), and undinet_unhook_isr().
| uint8_t __data16 | ( | undiisr_irq | ) |
IRQ number.
References undiisr_irq.
| uint16_t __data16 | ( | undiisr_imr | ) |
IRQ mask register.
References undiisr_imr.
| uint8_t __data16 | ( | undiisr_bit | ) |
IRQ mask bit.
References undiisr_bit.
| uint8_t __data16 | ( | undiisr_rearm | ) |
IRQ rearm flag.
References undiisr_rearm.
| struct segoff __data16 | ( | undiisr_next_handler | ) |
IRQ chain vector.
References __data16, and undiisr_next_handler.
|
pure virtual |
IRQ trigger count.
References undiisr_trigger_count.
|
static |
Hook UNDI interrupt service routine.
| irq | IRQ number |
Definition at line 404 of file undinet.c.
References assert, hook_bios_interrupt(), IMR_BIT, IMR_REG, IRQ_INT, IRQ_MAX, undiisr(), undiisr_bit, undiisr_imr, undiisr_irq, undiisr_next_handler, and undiisr_rearm.
Referenced by undinet_open().
|
static |
Unhook UNDI interrupt service routine.
| irq | IRQ number |
Definition at line 422 of file undinet.c.
References assert, IRQ_INT, IRQ_MAX, undiisr(), undiisr_irq, undiisr_next_handler, and unhook_bios_interrupt().
Referenced by undinet_close().
|
static |
Test to see if UNDI ISR has been triggered.
| triggered | ISR has been triggered since last check |
Definition at line 436 of file undinet.c.
References last_trigger_count, and undiisr_trigger_count.
Referenced by undinet_poll().
|
static |
UNDI transmit buffer descriptor.
References __data16, and undinet_tbd.
|
static |
UNDI transmit destination address.
References ETH_ALEN, and undinet_destaddr.
|
static |
Transmit packet.
| netdev | Network device |
| iobuf | I/O buffer |
| rc | Return status code |
Definition at line 474 of file undinet.c.
References __from_data16, basemem_packet, io_buffer::data, DBGC, s_PXENV_UNDI_TRANSMIT::DestAddr, done, ETH_P_ARP, ETH_P_IP, ETH_P_RARP, eth_pull(), flags, htons, iob_len(), iob_push, len, LL_BROADCAST, memcpy(), memset(), netdev, netdev_tx_complete(), P_ARP, P_IP, P_RARP, P_UNKNOWN, s_PXENV_UNDI_TRANSMIT::Protocol, protocol, PXENV_UNDI_TRANSMIT, rc, rm_ds, strerror(), s_PXENV_UNDI_TRANSMIT::TBD, undinet_call(), undinet_destaddr, undinet_tbd, s_PXENV_UNDI_TRANSMIT::XmitFlag, XMT_BROADCAST, and XMT_DESTADDR.
|
static |
Poll for received packets.
| netdev | Network device |
Fun, fun, fun. UNDI drivers don't use polling; they use interrupts. We therefore cheat and pretend that an interrupt has occurred every time undinet_poll() is called. This isn't too much of a hack; PCI devices share IRQs and so the first thing that a proper ISR should do is call PXENV_UNDI_ISR to determine whether or not the UNDI NIC generated the interrupt; there is no harm done by spurious calls to PXENV_UNDI_ISR. Similarly, we wouldn't be handling them any more rapidly than the usual rate of undinet_poll() being called even if we did implement a full ISR. So it should work. Ha!
Addendum (21/10/03). Some cards don't play nicely with this trick, so instead of doing it the easy way we have to go to all the hassle of installing a genuine interrupt service routine and dealing with the wonderful 8259 Programmable Interrupt Controller. Joy.
Addendum (10/07/07). When doing things such as iSCSI boot, in which we have to co-operate with a running OS, we can't get away with the "ISR-just-increments-a-counter-and-returns" trick at all, because it involves tying up the PIC for far too long, and other interrupt-dependent components (e.g. local disks) start breaking. We therefore implement a "proper" ISR which calls PXENV_UNDI_ISR from within interrupt context in order to deassert the device interrupt, and sends EOI if applicable.
Definition at line 588 of file undinet.c.
References __asm__(), __volatile__(), alloc_iob(), assert, s_PXENV_UNDI_ISR::BufferLength, copy_from_real, DBGC, done, EINVAL, ENOMEM, s_PXENV_UNDI_ISR::Frame, s_PXENV_UNDI_ISR::FrameHeaderLength, s_PXENV_UNDI_ISR::FrameLength, s_PXENV_UNDI_ISR::FuncFlag, undi_nic::hacks, iob_disown, iob_len(), iob_put, iob_reserve, iob_tailroom(), undi_nic::irq, undi_nic::irq_supported, undi_nic::isr_processing, last_trigger_count, len, netdev, netdev_rx(), netdev_rx_err(), NULL, profile_start(), profile_stop(), PXENV_UNDI_ISR, PXENV_UNDI_ISR_IN_GET_NEXT, PXENV_UNDI_ISR_IN_PROCESS, PXENV_UNDI_ISR_OUT_DONE, PXENV_UNDI_ISR_OUT_RECEIVE, PXENV_UNDI_ISR_OUT_TRANSMIT, rc, UNDI_HACK_EB54, UNDI_RX_ALIGN, UNDI_RX_QUOTA, undiisr_rearm, undinet_call(), and undinet_isr_triggered().
|
static |
Open NIC.
| netdev | Net device |
| rc | Return status code |
Definition at line 728 of file undinet.c.
References DBGC, FLTR_BRDCST, FLTR_DIRECTED, FLTR_PRMSCS, undi_nic::irq, memcpy(), memset(), netdev, s_PXENV_UNDI_OPEN::PktFilter, PXENV_UNDI_OPEN, PXENV_UNDI_SET_STATION_ADDRESS, rc, send_eoi(), s_PXENV_UNDI_SET_STATION_ADDRESS::StationAddress, undinet_call(), undinet_close(), and undinet_hook_isr().
|
static |
|
static |
Check for devices with broken support for generating interrupts.
| netdev | Net device |
| irq_is_broken | Interrupt support is broken; no interrupts are generated |
Definition at line 874 of file undinet.c.
References BUS_TYPE_PCI, DBGC, desc, netdev, PCI_ANY_ID, PCI_CAP_ID_EXP, undinet_irq_broken::pci_device, pci_find_capability(), pci_init(), pci_read_config_word(), undinet_irq_broken::pci_subsys, undinet_irq_broken::pci_subsys_vendor, PCI_SUBSYSTEM_ID, PCI_SUBSYSTEM_VENDOR_ID, undinet_irq_broken::pci_vendor, and undinet_irq_broken_list.
Referenced by undinet_probe().
| int undinet_probe | ( | struct undi_device * | undi, |
| struct device * | dev ) |
Probe UNDI device.
| undi | UNDI device |
| dev | Underlying generic device |
| rc | Return status code |
Definition at line 931 of file undinet.c.
References alloc_etherdev(), assert, s_PXENV_START_UNDI::AX, BIOS_SEG, s_PXENV_START_UNDI::BX, s_PXENV_UNDI_GET_INFORMATION::CurrentNodeAddress, DBGC, s_PXENV_START_UNDI::DI, s_PXENV_START_UNDI::DX, ENOMEM, undi_device::entry, s_PXENV_START_UNDI::ES, ETH_ALEN, eth_ntoa(), find_pnp_bios(), undi_device::flags, undi_nic::hacks, s_PXENV_UNDI_GET_IFACE_INFO::IfaceType, s_PXENV_UNDI_GET_INFORMATION::IntNumber, undi_nic::irq, IRQ_MAX, undi_nic::irq_supported, undi_device::isapnp_csn, undi_device::isapnp_read_port, s_PXENV_UNDI_GET_IFACE_INFO::LinkSpeed, mdelay(), memcpy(), memset(), netdev, netdev_init(), netdev_link_up(), netdev_nullify(), netdev_put(), NULL, undi_device::pci_busdevfn, s_PXENV_UNDI_GET_INFORMATION::PermNodeAddress, PXENV_START_UNDI, PXENV_STOP_UNDI, PXENV_UNDI_CLEANUP, PXENV_UNDI_GET_IFACE_INFO, PXENV_UNDI_GET_INFORMATION, PXENV_UNDI_INITIALIZE, PXENV_UNDI_SHUTDOWN, PXENV_UNDI_STARTUP, rc, register_netdev(), s_PXENV_UNDI_GET_IFACE_INFO::ServiceFlags, strncmp(), SUPPORTED_IRQ, UNDI_FL_INITIALIZED, UNDI_FL_STARTED, UNDI_HACK_EB54, UNDI_INITIALIZE_RETRY_DELAY_MS, UNDI_INITIALIZE_RETRY_MAX, undi_set_drvdata(), undinet_call(), undinet_entry_point, undinet_irq_is_broken(), and undinet_operations.
Referenced by undibus_probe(), and undipci_probe().
| void undinet_remove | ( | struct undi_device * | undi | ) |
Remove UNDI device.
| undi | UNDI device |
Definition at line 1089 of file undinet.c.
References DBGC, undi_device::flags, memset(), netdev, netdev_nullify(), netdev_put(), PXENV_STOP_UNDI, PXENV_UNDI_CLEANUP, PXENV_UNDI_SHUTDOWN, UNDI_FL_INITIALIZED, UNDI_FL_KEEP_ALL, UNDI_FL_STARTED, undi_get_drvdata(), undinet_call(), undinet_entry_point, and unregister_netdev().
Referenced by undibus_remove(), and undipci_remove().
|
static |
IRQ profiler.
Miscellaneous PXE API call profiler.
PXE unknown API call profiler.
PXENV_UNDI_ISR profiler.
PXENV_UNDI_TRANSMIT profiler.
Receive profiler.
Note that this profiler will not see calls to PXENV_UNDI_ISR_IN_START, which are handled by the UNDI ISR and do not go via undinet_call().
This profiler can be used to measure the overhead of a dummy PXE API call.
Definition at line 115 of file undinet.c.
|
static |
Last observed trigger count.
Definition at line 397 of file undinet.c.
Referenced by undinet_isr_triggered(), and undinet_poll().
|
static |
UNDI network device operations.
Definition at line 827 of file undinet.c.
Referenced by undinet_probe().
|
static |
List of devices with broken support for generating interrupts.
Some PXE stacks are known to claim that IRQs are supported, but then never generate interrupts. No satisfactory solution has been found to this problem; the workaround is to add the PCI vendor and device IDs to this list. This is something of a hack, since it will generate false positives for identical devices with a working PXE stack (e.g. those that have been reflashed with iPXE), but it's an improvement on the current situation.
Definition at line 858 of file undinet.c.
Referenced by undinet_irq_is_broken().