summaryrefslogtreecommitdiffstats
path: root/src/arch
diff options
context:
space:
mode:
authorMichael Brown2009-06-27 17:36:21 +0200
committerMichael Brown2009-06-27 17:36:21 +0200
commitc26a38b313389af157880efa8557ef894906e317 (patch)
treef058da3f63671b12f2608dc8b2ff4f7bfac12f1a /src/arch
parent[pxe] Implement PXENV_UNDI_{GET,SET}_MCAST_ADDRESS (diff)
downloadipxe-c26a38b313389af157880efa8557ef894906e317.tar.gz
ipxe-c26a38b313389af157880efa8557ef894906e317.tar.xz
ipxe-c26a38b313389af157880efa8557ef894906e317.zip
[pxe] Update UNDI transmit count before transmitting packet
It is possible that the UNDI ISR may be triggered before netdev_tx() returns control to pxenv_undi_transmit(). This means that pxenv_undi_isr() may see a zero undi_tx_count, and so not check for TX completions. This is not a significant problem, since it will check for TX completions on the next call to pxenv_undi_isr() anyway; it just means that the NBP will see a spurious IRQ that was apparently caused by nothing. Fix by updating the undi_tx_count before calling netdev_tx(), so that pxenv_undi_isr() can decrement it and report the TX completion.
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/i386/interface/pxe/pxe_undi.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/src/arch/i386/interface/pxe/pxe_undi.c b/src/arch/i386/interface/pxe/pxe_undi.c
index e284c905..bd387ea5 100644
--- a/src/arch/i386/interface/pxe/pxe_undi.c
+++ b/src/arch/i386/interface/pxe/pxe_undi.c
@@ -316,18 +316,22 @@ PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
}
}
+ /* Flag transmission as in-progress. Do this before starting
+ * to transmit the packet, because the ISR may trigger before
+ * we return from netdev_tx().
+ */
+ undi_tx_count++;
+
/* Transmit packet */
- DBG2 ( "\n" ); /* ISR may trigger before we return from netdev_tx() */
+ DBG2 ( "\n" );
if ( ( rc = netdev_tx ( pxe_netdev, iobuf ) ) != 0 ) {
DBG2 ( "PXENV_UNDI_TRANSMIT could not transmit: %s\n",
strerror ( rc ) );
+ undi_tx_count--;
undi_transmit->Status = PXENV_STATUS ( rc );
return PXENV_EXIT_FAILURE;
}
- /* Flag transmission as in-progress */
- undi_tx_count++;
-
undi_transmit->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
}