|
@@ -38,6 +38,17 @@
|
38
|
38
|
#include <gpxe/shutdown.h>
|
39
|
39
|
#include "pxe.h"
|
40
|
40
|
|
|
41
|
+/**
|
|
42
|
+ * Count of outstanding transmitted packets
|
|
43
|
+ *
|
|
44
|
+ * This is incremented each time PXENV_UNDI_TRANSMIT is called, and
|
|
45
|
+ * decremented each time that PXENV_UNDI_ISR is called with the TX
|
|
46
|
+ * queue empty, stopping when the count reaches zero. This allows us
|
|
47
|
+ * to provide a pessimistic approximation of TX completion events to
|
|
48
|
+ * the PXE NBP simply by monitoring the netdev's TX queue.
|
|
49
|
+ */
|
|
50
|
+static int undi_tx_count = 0;
|
|
51
|
+
|
41
|
52
|
/* PXENV_UNDI_STARTUP
|
42
|
53
|
*
|
43
|
54
|
* Status: working
|
|
@@ -56,6 +67,8 @@ PXENV_EXIT_t pxenv_undi_startup ( struct s_PXENV_UNDI_STARTUP *undi_startup ) {
|
56
|
67
|
PXENV_EXIT_t pxenv_undi_cleanup ( struct s_PXENV_UNDI_CLEANUP *undi_cleanup ) {
|
57
|
68
|
DBG ( "PXENV_UNDI_CLEANUP" );
|
58
|
69
|
|
|
70
|
+ netdev_close ( pxe_netdev );
|
|
71
|
+
|
59
|
72
|
undi_cleanup->Status = PXENV_STATUS_SUCCESS;
|
60
|
73
|
return PXENV_EXIT_SUCCESS;
|
61
|
74
|
}
|
|
@@ -78,8 +91,17 @@ PXENV_EXIT_t pxenv_undi_initialize ( struct s_PXENV_UNDI_INITIALIZE
|
78
|
91
|
*/
|
79
|
92
|
PXENV_EXIT_t pxenv_undi_reset_adapter ( struct s_PXENV_UNDI_RESET
|
80
|
93
|
*undi_reset_adapter ) {
|
|
94
|
+ int rc;
|
|
95
|
+
|
81
|
96
|
DBG ( "PXENV_UNDI_RESET_ADAPTER" );
|
82
|
97
|
|
|
98
|
+ netdev_close ( pxe_netdev );
|
|
99
|
+ undi_tx_count = 0;
|
|
100
|
+ if ( ( rc = netdev_open ( pxe_netdev ) ) != 0 ) {
|
|
101
|
+ undi_reset_adapter->Status = PXENV_STATUS ( rc );
|
|
102
|
+ return PXENV_EXIT_FAILURE;
|
|
103
|
+ }
|
|
104
|
+
|
83
|
105
|
undi_reset_adapter->Status = PXENV_STATUS_SUCCESS;
|
84
|
106
|
return PXENV_EXIT_SUCCESS;
|
85
|
107
|
}
|
|
@@ -103,15 +125,14 @@ PXENV_EXIT_t pxenv_undi_shutdown ( struct s_PXENV_UNDI_SHUTDOWN
|
103
|
125
|
* Status: working
|
104
|
126
|
*/
|
105
|
127
|
PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
|
|
128
|
+ int rc;
|
|
129
|
+
|
106
|
130
|
DBG ( "PXENV_UNDI_OPEN" );
|
107
|
131
|
|
108
|
|
-#if 0
|
109
|
|
- /* PXESPEC: This is where we choose to enable interrupts.
|
110
|
|
- * Can't actually find where we're meant to in the PXE spec,
|
111
|
|
- * but this should work.
|
112
|
|
- */
|
113
|
|
- eth_irq ( ENABLE );
|
114
|
|
-#endif
|
|
132
|
+ if ( ( rc = netdev_open ( pxe_netdev ) ) != 0 ) {
|
|
133
|
+ undi_open->Status = PXENV_STATUS ( rc );
|
|
134
|
+ return PXENV_EXIT_FAILURE;
|
|
135
|
+ }
|
115
|
136
|
|
116
|
137
|
undi_open->Status = PXENV_STATUS_SUCCESS;
|
117
|
138
|
return PXENV_EXIT_SUCCESS;
|
|
@@ -124,6 +145,9 @@ PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
|
124
|
145
|
PXENV_EXIT_t pxenv_undi_close ( struct s_PXENV_UNDI_CLOSE *undi_close ) {
|
125
|
146
|
DBG ( "PXENV_UNDI_CLOSE" );
|
126
|
147
|
|
|
148
|
+ netdev_close ( pxe_netdev );
|
|
149
|
+ undi_tx_count = 0;
|
|
150
|
+
|
127
|
151
|
undi_close->Status = PXENV_STATUS_SUCCESS;
|
128
|
152
|
return PXENV_EXIT_SUCCESS;
|
129
|
153
|
}
|
|
@@ -200,7 +224,8 @@ PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
|
200
|
224
|
rc = net_tx ( iobuf, pxe_netdev, net_protocol, ll_dest );
|
201
|
225
|
}
|
202
|
226
|
|
203
|
|
-#warning "TX completion?"
|
|
227
|
+ /* Flag transmission as in-progress */
|
|
228
|
+ undi_tx_count++;
|
204
|
229
|
|
205
|
230
|
undi_transmit->Status = PXENV_STATUS ( rc );
|
206
|
231
|
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 ) {
|
490
|
515
|
case PXENV_UNDI_ISR_IN_PROCESS :
|
491
|
516
|
case PXENV_UNDI_ISR_IN_GET_NEXT :
|
492
|
517
|
DBG ( " PROCESS/GET_NEXT" );
|
493
|
|
-
|
|
518
|
+
|
|
519
|
+ /* If we have not yet marked a TX as complete, and the
|
|
520
|
+ * netdev TX queue is empty, report the TX completion.
|
|
521
|
+ */
|
|
522
|
+ if ( undi_tx_count && list_empty ( &pxe_netdev->tx_queue ) ) {
|
|
523
|
+ undi_tx_count--;
|
|
524
|
+ undi_isr->FuncFlag = PXENV_UNDI_ISR_OUT_TRANSMIT;
|
|
525
|
+ break;
|
|
526
|
+ }
|
|
527
|
+
|
494
|
528
|
/* Remove first packet from netdev RX queue */
|
495
|
529
|
iobuf = netdev_rx_dequeue ( pxe_netdev );
|
496
|
530
|
if ( ! iobuf ) {
|