aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@etherboot.org>2009-06-23 21:54:50 +0100
committerMichael Brown <mcb30@etherboot.org>2009-06-23 21:54:50 +0100
commit4f881ae35262d4e788507a9e4712a5eae4f26310 (patch)
tree01dcfce8c0234db112d8e67e8cc6fa80b9b3dde1
parentded4d3a703e42a2d57eb72467fafe8e06f32e40d (diff)
downloadipxe-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.c17
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