diff options
author | Michael Brown <mcb30@etherboot.org> | 2009-06-23 21:54:50 +0100 |
---|---|---|
committer | Michael Brown <mcb30@etherboot.org> | 2009-06-23 21:54:50 +0100 |
commit | 4f881ae35262d4e788507a9e4712a5eae4f26310 (patch) | |
tree | 01dcfce8c0234db112d8e67e8cc6fa80b9b3dde1 | |
parent | ded4d3a703e42a2d57eb72467fafe8e06f32e40d (diff) | |
download | ipxe-4f881ae35262d4e788507a9e4712a5eae4f26310.zip ipxe-4f881ae35262d4e788507a9e4712a5eae4f26310.tar.gz ipxe-4f881ae35262d4e788507a9e4712a5eae4f26310.tar.bz2 |
[pxe] Fix interoperability with the 3Com DOS UNDI driver
The 3Com DOS UNDI driver fails when run on top of gPXE for two
reasons: firstly because PXENV_UNDI_SET_PACKET_FILTER is unsupported,
and secondly because gPXE enters the NBP without enabling interrupts
on the NIC, and the 3Com driver never calls PXENV_UNDI_OPEN.
Fix by always returning success from PXENV_UNDI_SET_PACKET_FILTER
(which is no worse than the current situation, since we already ignore
the receive packet filter in PXENV_UNDI_OPEN), and by forcibly
enabling interrupts on the NIC within PXENV_UNDI_TRANSMIT. The latter
is something of a hack, but avoids the need to implement a complete
base-code ISR that we would otherwise need if we were to enter the NBP
with interrupts enabled.
-rw-r--r-- | src/arch/i386/interface/pxe/pxe_undi.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/src/arch/i386/interface/pxe/pxe_undi.c b/src/arch/i386/interface/pxe/pxe_undi.c index fd2d688..90e837c 100644 --- a/src/arch/i386/interface/pxe/pxe_undi.c +++ b/src/arch/i386/interface/pxe/pxe_undi.c @@ -211,6 +211,12 @@ PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT DBG ( "PXENV_UNDI_TRANSMIT" ); + /* Forcibly enable interrupts at this point, to work around + * callers that never call PXENV_UNDI_OPEN before attempting + * to use the UNDI API. + */ + netdev_irq ( pxe_netdev, 1 ); + /* Identify network-layer protocol */ switch ( undi_transmit->Protocol ) { case P_IP: net_protocol = &ipv4_protocol; break; @@ -341,10 +347,17 @@ pxenv_undi_set_station_address ( struct s_PXENV_UNDI_SET_STATION_ADDRESS PXENV_EXIT_t pxenv_undi_set_packet_filter ( struct s_PXENV_UNDI_SET_PACKET_FILTER *undi_set_packet_filter ) { + DBG ( "PXENV_UNDI_SET_PACKET_FILTER" ); - undi_set_packet_filter->Status = PXENV_STATUS_UNSUPPORTED; - return PXENV_EXIT_FAILURE; + /* Pretend that we succeeded, otherwise the 3Com DOS UNDI + * driver refuses to load. (We ignore the filter value in the + * PXENV_UNDI_OPEN call anyway.) + */ + DBG ( " %02x", undi_set_packet_filter->filter ); + undi_set_packet_filter->Status = PXENV_STATUS_SUCCESS; + + return PXENV_EXIT_SUCCESS; } /* PXENV_UNDI_GET_INFORMATION |