|  | @@ -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 */
 |