소스 검색

Add mechanism for providing TX completion events.

tags/v0.9.3
Michael Brown 17 년 전
부모
커밋
8f37a6a424
1개의 변경된 파일43개의 추가작업 그리고 9개의 파일을 삭제
  1. 43
    9
      src/interface/pxe/pxe_undi.c

+ 43
- 9
src/interface/pxe/pxe_undi.c 파일 보기

@@ -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 ) {

Loading…
취소
저장