|
@@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
33
|
33
|
#include <ipxe/netdevice.h>
|
34
|
34
|
#include <ipxe/if_ether.h>
|
35
|
35
|
#include <ipxe/ethernet.h>
|
|
36
|
+#include <ipxe/profile.h>
|
36
|
37
|
#include <undi.h>
|
37
|
38
|
#include <undinet.h>
|
38
|
39
|
#include <pxeparent.h>
|
|
@@ -79,6 +80,26 @@ static void undinet_close ( struct net_device *netdev );
|
79
|
80
|
/** Address of UNDI entry point */
|
80
|
81
|
static SEGOFF16_t undinet_entry;
|
81
|
82
|
|
|
83
|
+/** Transmit profiler */
|
|
84
|
+static struct profiler undinet_tx_profiler __profiler =
|
|
85
|
+ { .name = "undinet.tx" };
|
|
86
|
+
|
|
87
|
+/** Transmit call profiler */
|
|
88
|
+static struct profiler undinet_tx_call_profiler __profiler =
|
|
89
|
+ { .name = "undinet.tx_call" };
|
|
90
|
+
|
|
91
|
+/** IRQ profiler */
|
|
92
|
+static struct profiler undinet_irq_profiler __profiler =
|
|
93
|
+ { .name = "undinet.irq" };
|
|
94
|
+
|
|
95
|
+/** ISR call profiler */
|
|
96
|
+static struct profiler undinet_isr_call_profiler __profiler =
|
|
97
|
+ { .name = "undinet.isr_call" };
|
|
98
|
+
|
|
99
|
+/** Receive profiler */
|
|
100
|
+static struct profiler undinet_rx_profiler __profiler =
|
|
101
|
+ { .name = "undinet.rx" };
|
|
102
|
+
|
82
|
103
|
/*****************************************************************************
|
83
|
104
|
*
|
84
|
105
|
* UNDI interrupt service routine
|
|
@@ -194,6 +215,9 @@ static int undinet_transmit ( struct net_device *netdev,
|
194
|
215
|
size_t len;
|
195
|
216
|
int rc;
|
196
|
217
|
|
|
218
|
+ /* Start profiling */
|
|
219
|
+ profile_start ( &undinet_tx_profiler );
|
|
220
|
+
|
197
|
221
|
/* Technically, we ought to make sure that the previous
|
198
|
222
|
* transmission has completed before we re-use the buffer.
|
199
|
223
|
* However, many PXE stacks (including at least some Intel PXE
|
|
@@ -256,14 +280,16 @@ static int undinet_transmit ( struct net_device *netdev,
|
256
|
280
|
undinet_tbd.Xmit.offset = __from_data16 ( basemem_packet );
|
257
|
281
|
|
258
|
282
|
/* Issue PXE API call */
|
|
283
|
+ profile_start ( &undinet_tx_call_profiler );
|
259
|
284
|
if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_TRANSMIT,
|
260
|
285
|
&undi_transmit,
|
261
|
286
|
sizeof ( undi_transmit ) ) ) != 0 )
|
262
|
287
|
goto done;
|
|
288
|
+ profile_stop ( &undinet_tx_call_profiler );
|
263
|
289
|
|
264
|
290
|
/* Free I/O buffer */
|
265
|
291
|
netdev_tx_complete ( netdev, iobuf );
|
266
|
|
-
|
|
292
|
+ profile_stop ( &undinet_tx_profiler );
|
267
|
293
|
done:
|
268
|
294
|
return rc;
|
269
|
295
|
}
|
|
@@ -316,10 +342,12 @@ static void undinet_poll ( struct net_device *netdev ) {
|
316
|
342
|
*/
|
317
|
343
|
if ( ! undinet_isr_triggered() ) {
|
318
|
344
|
/* Allow interrupt to occur */
|
|
345
|
+ profile_start ( &undinet_irq_profiler );
|
319
|
346
|
__asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
|
320
|
347
|
"nop\n\t"
|
321
|
348
|
"nop\n\t"
|
322
|
349
|
"cli\n\t" ) : : );
|
|
350
|
+ profile_stop ( &undinet_irq_profiler );
|
323
|
351
|
|
324
|
352
|
/* If interrupts are known to be supported,
|
325
|
353
|
* then do nothing on this poll; wait for the
|
|
@@ -339,16 +367,19 @@ static void undinet_poll ( struct net_device *netdev ) {
|
339
|
367
|
|
340
|
368
|
/* Run through the ISR loop */
|
341
|
369
|
while ( 1 ) {
|
|
370
|
+ profile_start ( &undinet_isr_call_profiler );
|
342
|
371
|
if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_ISR,
|
343
|
372
|
&undi_isr,
|
344
|
373
|
sizeof ( undi_isr ) ) ) != 0 )
|
345
|
374
|
break;
|
|
375
|
+ profile_stop ( &undinet_isr_call_profiler );
|
346
|
376
|
switch ( undi_isr.FuncFlag ) {
|
347
|
377
|
case PXENV_UNDI_ISR_OUT_TRANSMIT:
|
348
|
378
|
/* We don't care about transmit completions */
|
349
|
379
|
break;
|
350
|
380
|
case PXENV_UNDI_ISR_OUT_RECEIVE:
|
351
|
381
|
/* Packet fragment received */
|
|
382
|
+ profile_start ( &undinet_rx_profiler );
|
352
|
383
|
len = undi_isr.FrameLength;
|
353
|
384
|
frag_len = undi_isr.BufferLength;
|
354
|
385
|
reserve_len = ( -undi_isr.FrameHeaderLength &
|
|
@@ -393,6 +424,7 @@ static void undinet_poll ( struct net_device *netdev ) {
|
393
|
424
|
if ( undinic->hacks & UNDI_HACK_EB54 )
|
394
|
425
|
--last_trigger_count;
|
395
|
426
|
}
|
|
427
|
+ profile_stop ( &undinet_rx_profiler );
|
396
|
428
|
break;
|
397
|
429
|
case PXENV_UNDI_ISR_OUT_DONE:
|
398
|
430
|
/* Processing complete */
|