david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

Add mechanism for providing TX completion events.

This commit is contained in:
Michael Brown 2007-07-02 23:49:00 +01:00
parent 0297a63877
commit 8f37a6a424
1 changed files with 43 additions and 9 deletions

View File

@ -38,6 +38,17 @@
#include <gpxe/shutdown.h>
#include "pxe.h"
/**
* Count of outstanding transmitted packets
*
* This is incremented each time PXENV_UNDI_TRANSMIT is called, and
* decremented each time that PXENV_UNDI_ISR is called with the TX
* queue empty, stopping when the count reaches zero. This allows us
* to provide a pessimistic approximation of TX completion events to
* the PXE NBP simply by monitoring the netdev's TX queue.
*/
static int undi_tx_count = 0;
/* PXENV_UNDI_STARTUP
*
* Status: working
@ -56,6 +67,8 @@ PXENV_EXIT_t pxenv_undi_startup ( struct s_PXENV_UNDI_STARTUP *undi_startup ) {
PXENV_EXIT_t pxenv_undi_cleanup ( struct s_PXENV_UNDI_CLEANUP *undi_cleanup ) {
DBG ( "PXENV_UNDI_CLEANUP" );
netdev_close ( pxe_netdev );
undi_cleanup->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
}
@ -78,8 +91,17 @@ PXENV_EXIT_t pxenv_undi_initialize ( struct s_PXENV_UNDI_INITIALIZE
*/
PXENV_EXIT_t pxenv_undi_reset_adapter ( struct s_PXENV_UNDI_RESET
*undi_reset_adapter ) {
int rc;
DBG ( "PXENV_UNDI_RESET_ADAPTER" );
netdev_close ( pxe_netdev );
undi_tx_count = 0;
if ( ( rc = netdev_open ( pxe_netdev ) ) != 0 ) {
undi_reset_adapter->Status = PXENV_STATUS ( rc );
return PXENV_EXIT_FAILURE;
}
undi_reset_adapter->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
}
@ -103,15 +125,14 @@ PXENV_EXIT_t pxenv_undi_shutdown ( struct s_PXENV_UNDI_SHUTDOWN
* Status: working
*/
PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
int rc;
DBG ( "PXENV_UNDI_OPEN" );
#if 0
/* PXESPEC: This is where we choose to enable interrupts.
* Can't actually find where we're meant to in the PXE spec,
* but this should work.
*/
eth_irq ( ENABLE );
#endif
if ( ( rc = netdev_open ( pxe_netdev ) ) != 0 ) {
undi_open->Status = PXENV_STATUS ( rc );
return PXENV_EXIT_FAILURE;
}
undi_open->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
@ -124,6 +145,9 @@ PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
PXENV_EXIT_t pxenv_undi_close ( struct s_PXENV_UNDI_CLOSE *undi_close ) {
DBG ( "PXENV_UNDI_CLOSE" );
netdev_close ( pxe_netdev );
undi_tx_count = 0;
undi_close->Status = PXENV_STATUS_SUCCESS;
return PXENV_EXIT_SUCCESS;
}
@ -200,7 +224,8 @@ PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
rc = net_tx ( iobuf, pxe_netdev, net_protocol, ll_dest );
}
#warning "TX completion?"
/* Flag transmission as in-progress */
undi_tx_count++;
undi_transmit->Status = PXENV_STATUS ( rc );
return ( ( rc == 0 ) ? PXENV_EXIT_SUCCESS : PXENV_EXIT_FAILURE );
@ -490,7 +515,16 @@ PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) {
case PXENV_UNDI_ISR_IN_PROCESS :
case PXENV_UNDI_ISR_IN_GET_NEXT :
DBG ( " PROCESS/GET_NEXT" );
/* If we have not yet marked a TX as complete, and the
* netdev TX queue is empty, report the TX completion.
*/
if ( undi_tx_count && list_empty ( &pxe_netdev->tx_queue ) ) {
undi_tx_count--;
undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_TRANSMIT;
break;
}
/* Remove first packet from netdev RX queue */
iobuf = netdev_rx_dequeue ( pxe_netdev );
if ( ! iobuf ) {