mirror of https://github.com/ipxe/ipxe.git
Add mechanism for providing TX completion events.
parent
0297a63877
commit
8f37a6a424
|
@ -38,6 +38,17 @@
|
||||||
#include <gpxe/shutdown.h>
|
#include <gpxe/shutdown.h>
|
||||||
#include "pxe.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
|
/* PXENV_UNDI_STARTUP
|
||||||
*
|
*
|
||||||
* Status: working
|
* 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 ) {
|
PXENV_EXIT_t pxenv_undi_cleanup ( struct s_PXENV_UNDI_CLEANUP *undi_cleanup ) {
|
||||||
DBG ( "PXENV_UNDI_CLEANUP" );
|
DBG ( "PXENV_UNDI_CLEANUP" );
|
||||||
|
|
||||||
|
netdev_close ( pxe_netdev );
|
||||||
|
|
||||||
undi_cleanup->Status = PXENV_STATUS_SUCCESS;
|
undi_cleanup->Status = PXENV_STATUS_SUCCESS;
|
||||||
return PXENV_EXIT_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
|
PXENV_EXIT_t pxenv_undi_reset_adapter ( struct s_PXENV_UNDI_RESET
|
||||||
*undi_reset_adapter ) {
|
*undi_reset_adapter ) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
DBG ( "PXENV_UNDI_RESET_ADAPTER" );
|
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;
|
undi_reset_adapter->Status = PXENV_STATUS_SUCCESS;
|
||||||
return PXENV_EXIT_SUCCESS;
|
return PXENV_EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -103,15 +125,14 @@ PXENV_EXIT_t pxenv_undi_shutdown ( struct s_PXENV_UNDI_SHUTDOWN
|
||||||
* Status: working
|
* Status: working
|
||||||
*/
|
*/
|
||||||
PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
|
PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
|
||||||
|
int rc;
|
||||||
|
|
||||||
DBG ( "PXENV_UNDI_OPEN" );
|
DBG ( "PXENV_UNDI_OPEN" );
|
||||||
|
|
||||||
#if 0
|
if ( ( rc = netdev_open ( pxe_netdev ) ) != 0 ) {
|
||||||
/* PXESPEC: This is where we choose to enable interrupts.
|
undi_open->Status = PXENV_STATUS ( rc );
|
||||||
* Can't actually find where we're meant to in the PXE spec,
|
return PXENV_EXIT_FAILURE;
|
||||||
* but this should work.
|
}
|
||||||
*/
|
|
||||||
eth_irq ( ENABLE );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
undi_open->Status = PXENV_STATUS_SUCCESS;
|
undi_open->Status = PXENV_STATUS_SUCCESS;
|
||||||
return PXENV_EXIT_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 ) {
|
PXENV_EXIT_t pxenv_undi_close ( struct s_PXENV_UNDI_CLOSE *undi_close ) {
|
||||||
DBG ( "PXENV_UNDI_CLOSE" );
|
DBG ( "PXENV_UNDI_CLOSE" );
|
||||||
|
|
||||||
|
netdev_close ( pxe_netdev );
|
||||||
|
undi_tx_count = 0;
|
||||||
|
|
||||||
undi_close->Status = PXENV_STATUS_SUCCESS;
|
undi_close->Status = PXENV_STATUS_SUCCESS;
|
||||||
return PXENV_EXIT_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 );
|
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 );
|
undi_transmit->Status = PXENV_STATUS ( rc );
|
||||||
return ( ( rc == 0 ) ? PXENV_EXIT_SUCCESS : PXENV_EXIT_FAILURE );
|
return ( ( rc == 0 ) ? PXENV_EXIT_SUCCESS : PXENV_EXIT_FAILURE );
|
||||||
|
@ -491,6 +516,15 @@ PXENV_EXIT_t pxenv_undi_isr ( struct s_PXENV_UNDI_ISR *undi_isr ) {
|
||||||
case PXENV_UNDI_ISR_IN_GET_NEXT :
|
case PXENV_UNDI_ISR_IN_GET_NEXT :
|
||||||
DBG ( " PROCESS/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 */
|
/* Remove first packet from netdev RX queue */
|
||||||
iobuf = netdev_rx_dequeue ( pxe_netdev );
|
iobuf = netdev_rx_dequeue ( pxe_netdev );
|
||||||
if ( ! iobuf ) {
|
if ( ! iobuf ) {
|
||||||
|
|
Loading…
Reference in New Issue