|  | @@ -90,6 +90,20 @@ static void pxe_netdev_close ( void ) {
 | 
		
	
		
			
			| 90 | 90 |  	undi_tx_count = 0;
 | 
		
	
		
			
			| 91 | 91 |  }
 | 
		
	
		
			
			| 92 | 92 |  
 | 
		
	
		
			
			|  | 93 | +/**
 | 
		
	
		
			
			|  | 94 | + * Dump multicast address list
 | 
		
	
		
			
			|  | 95 | + *
 | 
		
	
		
			
			|  | 96 | + * @v mcast		PXE multicast address list
 | 
		
	
		
			
			|  | 97 | + */
 | 
		
	
		
			
			|  | 98 | +static void pxe_dump_mcast_list ( struct s_PXENV_UNDI_MCAST_ADDRESS *mcast ) {
 | 
		
	
		
			
			|  | 99 | +	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
 | 
		
	
		
			
			|  | 100 | +	unsigned int i;
 | 
		
	
		
			
			|  | 101 | +
 | 
		
	
		
			
			|  | 102 | +	for ( i = 0 ; i < mcast->MCastAddrCount ; i++ ) {
 | 
		
	
		
			
			|  | 103 | +		DBG ( " %s", ll_protocol->ntoa ( mcast->McastAddr[i] ) );
 | 
		
	
		
			
			|  | 104 | +	}
 | 
		
	
		
			
			|  | 105 | +}
 | 
		
	
		
			
			|  | 106 | +
 | 
		
	
		
			
			| 93 | 107 |  /* PXENV_UNDI_STARTUP
 | 
		
	
		
			
			| 94 | 108 |   *
 | 
		
	
		
			
			| 95 | 109 |   * Status: working
 | 
		
	
	
		
			
			|  | @@ -135,8 +149,9 @@ PXENV_EXIT_t pxenv_undi_reset_adapter ( struct s_PXENV_UNDI_RESET
 | 
		
	
		
			
			| 135 | 149 |  					*undi_reset_adapter ) {
 | 
		
	
		
			
			| 136 | 150 |  	int rc;
 | 
		
	
		
			
			| 137 | 151 |  
 | 
		
	
		
			
			| 138 |  | -	DBG ( "PXENV_UNDI_RESET_ADAPTER %04x\n",
 | 
		
	
		
			
			| 139 |  | -	      undi_reset_adapter->R_Mcast_Buf.MCastAddrCount );
 | 
		
	
		
			
			|  | 152 | +	DBG ( "PXENV_UNDI_RESET_ADAPTER" );
 | 
		
	
		
			
			|  | 153 | +	pxe_dump_mcast_list ( &undi_reset_adapter->R_Mcast_Buf );
 | 
		
	
		
			
			|  | 154 | +	DBG ( "\n" );
 | 
		
	
		
			
			| 140 | 155 |  
 | 
		
	
		
			
			| 141 | 156 |  	pxe_netdev_close();
 | 
		
	
		
			
			| 142 | 157 |  	if ( ( rc = pxe_netdev_open() ) != 0 ) {
 | 
		
	
	
		
			
			|  | @@ -171,9 +186,10 @@ PXENV_EXIT_t pxenv_undi_shutdown ( struct s_PXENV_UNDI_SHUTDOWN
 | 
		
	
		
			
			| 171 | 186 |  PXENV_EXIT_t pxenv_undi_open ( struct s_PXENV_UNDI_OPEN *undi_open ) {
 | 
		
	
		
			
			| 172 | 187 |  	int rc;
 | 
		
	
		
			
			| 173 | 188 |  
 | 
		
	
		
			
			| 174 |  | -	DBG ( "PXENV_UNDI_OPEN flag %04x filter %04x mcast %04x\n",
 | 
		
	
		
			
			| 175 |  | -	      undi_open->OpenFlag, undi_open->PktFilter,
 | 
		
	
		
			
			| 176 |  | -	      undi_open->R_Mcast_Buf.MCastAddrCount );
 | 
		
	
		
			
			|  | 189 | +	DBG ( "PXENV_UNDI_OPEN flag %04x filter %04x",
 | 
		
	
		
			
			|  | 190 | +	      undi_open->OpenFlag, undi_open->PktFilter );
 | 
		
	
		
			
			|  | 191 | +	pxe_dump_mcast_list ( &undi_open->R_Mcast_Buf );
 | 
		
	
		
			
			|  | 192 | +	DBG ( "\n" );
 | 
		
	
		
			
			| 177 | 193 |  
 | 
		
	
		
			
			| 178 | 194 |  	if ( ( rc = pxe_netdev_open() ) != 0 ) {
 | 
		
	
		
			
			| 179 | 195 |  		DBG ( "PXENV_UNDI_OPEN could not open %s: %s\n",
 | 
		
	
	
		
			
			|  | @@ -318,16 +334,17 @@ PXENV_EXIT_t pxenv_undi_transmit ( struct s_PXENV_UNDI_TRANSMIT
 | 
		
	
		
			
			| 318 | 334 |  
 | 
		
	
		
			
			| 319 | 335 |  /* PXENV_UNDI_SET_MCAST_ADDRESS
 | 
		
	
		
			
			| 320 | 336 |   *
 | 
		
	
		
			
			| 321 |  | - * Status: stub (no PXE multicast support)
 | 
		
	
		
			
			|  | 337 | + * Status: working (for NICs that support receive-all-multicast)
 | 
		
	
		
			
			| 322 | 338 |   */
 | 
		
	
		
			
			| 323 | 339 |  PXENV_EXIT_t
 | 
		
	
		
			
			| 324 | 340 |  pxenv_undi_set_mcast_address ( struct s_PXENV_UNDI_SET_MCAST_ADDRESS
 | 
		
	
		
			
			| 325 | 341 |  			       *undi_set_mcast_address ) {
 | 
		
	
		
			
			| 326 |  | -	DBG ( "PXENV_UNDI_SET_MCAST_ADDRESS %04x failed: unsupported\n",
 | 
		
	
		
			
			| 327 |  | -	      undi_set_mcast_address->R_Mcast_Buf.MCastAddrCount );
 | 
		
	
		
			
			|  | 342 | +	DBG ( "PXENV_UNDI_SET_MCAST_ADDRESS" );
 | 
		
	
		
			
			|  | 343 | +	pxe_dump_mcast_list ( &undi_set_mcast_address->R_Mcast_Buf );
 | 
		
	
		
			
			|  | 344 | +	DBG ( "\n" );
 | 
		
	
		
			
			| 328 | 345 |  
 | 
		
	
		
			
			| 329 |  | -	undi_set_mcast_address->Status = PXENV_STATUS_UNSUPPORTED;
 | 
		
	
		
			
			| 330 |  | -	return PXENV_EXIT_FAILURE;
 | 
		
	
		
			
			|  | 346 | +	undi_set_mcast_address->Status = PXENV_STATUS_SUCCESS;
 | 
		
	
		
			
			|  | 347 | +	return PXENV_EXIT_SUCCESS;
 | 
		
	
		
			
			| 331 | 348 |  }
 | 
		
	
		
			
			| 332 | 349 |  
 | 
		
	
		
			
			| 333 | 350 |  /* PXENV_UNDI_SET_STATION_ADDRESS
 | 
		
	
	
		
			
			|  | @@ -491,18 +508,28 @@ PXENV_EXIT_t pxenv_undi_force_interrupt ( struct s_PXENV_UNDI_FORCE_INTERRUPT
 | 
		
	
		
			
			| 491 | 508 |  
 | 
		
	
		
			
			| 492 | 509 |  /* PXENV_UNDI_GET_MCAST_ADDRESS
 | 
		
	
		
			
			| 493 | 510 |   *
 | 
		
	
		
			
			| 494 |  | - * Status: stub (no PXE multicast support)
 | 
		
	
		
			
			|  | 511 | + * Status: working
 | 
		
	
		
			
			| 495 | 512 |   */
 | 
		
	
		
			
			| 496 | 513 |  PXENV_EXIT_t
 | 
		
	
		
			
			| 497 | 514 |  pxenv_undi_get_mcast_address ( struct s_PXENV_UNDI_GET_MCAST_ADDRESS
 | 
		
	
		
			
			| 498 | 515 |  			       *undi_get_mcast_address ) {
 | 
		
	
		
			
			|  | 516 | +	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
 | 
		
	
		
			
			| 499 | 517 |  	struct in_addr ip = { .s_addr = undi_get_mcast_address->InetAddr };
 | 
		
	
		
			
			|  | 518 | +	int rc;
 | 
		
	
		
			
			| 500 | 519 |  
 | 
		
	
		
			
			| 501 |  | -	DBG ( "PXENV_UNDI_GET_MCAST_ADDRESS %s failed: unsupported\n",
 | 
		
	
		
			
			| 502 |  | -	      inet_ntoa ( ip ) );
 | 
		
	
		
			
			|  | 520 | +	DBG ( "PXENV_UNDI_GET_MCAST_ADDRESS %s", inet_ntoa ( ip ) );
 | 
		
	
		
			
			| 503 | 521 |  
 | 
		
	
		
			
			| 504 |  | -	undi_get_mcast_address->Status = PXENV_STATUS_UNSUPPORTED;
 | 
		
	
		
			
			| 505 |  | -	return PXENV_EXIT_FAILURE;
 | 
		
	
		
			
			|  | 522 | +	if ( ( rc = ll_protocol->mc_hash ( AF_INET, &ip,
 | 
		
	
		
			
			|  | 523 | +				      undi_get_mcast_address->MediaAddr ))!=0){
 | 
		
	
		
			
			|  | 524 | +		DBG ( " failed: %s\n", strerror ( rc ) );
 | 
		
	
		
			
			|  | 525 | +		undi_get_mcast_address->Status = PXENV_STATUS ( rc );
 | 
		
	
		
			
			|  | 526 | +		return PXENV_EXIT_FAILURE;
 | 
		
	
		
			
			|  | 527 | +	}
 | 
		
	
		
			
			|  | 528 | +	DBG ( "=>%s\n",
 | 
		
	
		
			
			|  | 529 | +	      ll_protocol->ntoa ( undi_get_mcast_address->MediaAddr ) );
 | 
		
	
		
			
			|  | 530 | +
 | 
		
	
		
			
			|  | 531 | +	undi_get_mcast_address->Status = PXENV_STATUS_SUCCESS;
 | 
		
	
		
			
			|  | 532 | +	return PXENV_EXIT_SUCCESS;
 | 
		
	
		
			
			| 506 | 533 |  }
 | 
		
	
		
			
			| 507 | 534 |  
 | 
		
	
		
			
			| 508 | 535 |  /* PXENV_UNDI_GET_NIC_TYPE
 |