1 /** @file 2 Provides the Simple Network functions. 3 4 Copyright (c) 2011, Intel Corporation. All rights reserved.<BR> 5 This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include "Ax88772.h" 16 17 /** 18 This function updates the filtering on the receiver. 19 20 This support routine calls ::Ax88772MacAddressSet to update 21 the MAC address. This routine then rebuilds the multicast 22 hash by calling ::Ax88772MulticastClear and ::Ax88772MulticastSet. 23 Finally this routine enables the receiver by calling 24 ::Ax88772RxControl. 25 26 @param [in] pSimpleNetwork Simple network mode pointer 27 28 @retval EFI_SUCCESS This operation was successful. 29 @retval EFI_NOT_STARTED The network interface was not started. 30 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 31 EFI_SIMPLE_NETWORK_PROTOCOL structure. 32 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 33 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported. 34 35 **/ 36 EFI_STATUS 37 ReceiveFilterUpdate ( 38 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork 39 ) 40 { 41 EFI_SIMPLE_NETWORK_MODE * pMode; 42 NIC_DEVICE * pNicDevice; 43 EFI_STATUS Status; 44 UINT32 Index; 45 46 DBG_ENTER ( ); 47 48 // 49 // Set the MAC address 50 // 51 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork ); 52 pMode = pSimpleNetwork->Mode; 53 Status = Ax88772MacAddressSet ( pNicDevice, 54 &pMode->CurrentAddress.Addr[0]); 55 if ( !EFI_ERROR ( Status )) { 56 // 57 // Clear the multicast hash table 58 // 59 Ax88772MulticastClear ( pNicDevice ); 60 61 // 62 // Load the multicast hash table 63 // 64 if ( 0 != ( pMode->ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST )) { 65 for ( Index = 0; 66 ( !EFI_ERROR ( Status )) && ( Index < pMode->MCastFilterCount ); 67 Index++ ) { 68 // 69 // Enable the next multicast address 70 // 71 Ax88772MulticastSet ( pNicDevice, 72 &pMode->MCastFilter[ Index ].Addr[0]); 73 } 74 } 75 76 // 77 // Enable the receiver 78 // 79 if ( !EFI_ERROR ( Status )) { 80 Status = Ax88772RxControl ( pNicDevice, pMode->ReceiveFilterSetting ); 81 } 82 } 83 84 // 85 // Return the operation status 86 // 87 DBG_EXIT_STATUS ( Status ); 88 return Status; 89 } 90 91 92 /** 93 This function updates the SNP driver status. 94 95 This function gets the current interrupt and recycled transmit 96 buffer status from the network interface. The interrupt status 97 and the media status are returned as a bit mask in InterruptStatus. 98 If InterruptStatus is NULL, the interrupt status will not be read. 99 Upon successful return of the media status, the MediaPresent field 100 of EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change 101 of media status. If TxBuf is not NULL, a recycled transmit buffer 102 address will be retrived. If a recycled transmit buffer address 103 is returned in TxBuf, then the buffer has been successfully 104 transmitted, and the status for that buffer is cleared. 105 106 This function calls ::Ax88772Rx to update the media status and 107 queue any receive packets. 108 109 @param [in] pSimpleNetwork Protocol instance pointer 110 @param [in] pInterruptStatus A pointer to the bit mask of the current active interrupts. 111 If this is NULL, the interrupt status will not be read from 112 the device. If this is not NULL, the interrupt status will 113 be read from teh device. When the interrupt status is read, 114 it will also be cleared. Clearing the transmit interrupt 115 does not empty the recycled transmit buffer array. 116 @param [out] ppTxBuf Recycled transmit buffer address. The network interface will 117 not transmit if its internal recycled transmit buffer array is 118 full. Reading the transmit buffer does not clear the transmit 119 interrupt. If this is NULL, then the transmit buffer status 120 will not be read. If there are not transmit buffers to recycle 121 and TxBuf is not NULL, *TxBuf will be set to NULL. 122 123 @retval EFI_SUCCESS This operation was successful. 124 @retval EFI_NOT_STARTED The network interface was not started. 125 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 126 EFI_SIMPLE_NETWORK_PROTOCOL structure. 127 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 128 129 **/ 130 EFI_STATUS 131 EFIAPI 132 SN_GetStatus ( 133 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork, 134 OUT UINT32 * pInterruptStatus, 135 OUT VOID ** ppTxBuf 136 ) 137 { 138 BOOLEAN bLinkIdle; 139 EFI_SIMPLE_NETWORK_MODE * pMode; 140 NIC_DEVICE * pNicDevice; 141 EFI_STATUS Status; 142 EFI_TPL TplPrevious; 143 144 DBG_ENTER ( ); 145 146 // 147 // Verify the parameters 148 // 149 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) { 150 // 151 // Return the transmit buffer 152 // 153 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork ); 154 if (( NULL != ppTxBuf ) && ( NULL != pNicDevice->pTxBuffer )) { 155 *ppTxBuf = pNicDevice->pTxBuffer; 156 pNicDevice->pTxBuffer = NULL; 157 } 158 159 // 160 // Determine if interface is running 161 // 162 pMode = pSimpleNetwork->Mode; 163 if ( EfiSimpleNetworkStopped != pMode->State ) { 164 // 165 // Synchronize with Ax88772Timer 166 // 167 VERIFY_TPL ( TPL_AX88772 ); 168 TplPrevious = gBS->RaiseTPL ( TPL_AX88772 ); 169 170 // 171 // Update the link status 172 // 173 bLinkIdle = pNicDevice->bLinkIdle; 174 pNicDevice->bLinkIdle = TRUE; 175 Ax88772Rx ( pNicDevice, bLinkIdle ); 176 pMode->MediaPresent = pNicDevice->bLinkUp; 177 178 // 179 // Release the synchronization with Ax88772Timer 180 // 181 gBS->RestoreTPL ( TplPrevious ); 182 183 // 184 // Return the interrupt status 185 // 186 if ( NULL != pInterruptStatus ) { 187 *pInterruptStatus = 0; 188 } 189 Status = EFI_SUCCESS; 190 } 191 else { 192 Status = EFI_NOT_STARTED; 193 } 194 } 195 else { 196 Status = EFI_INVALID_PARAMETER; 197 } 198 199 // 200 // Return the operation status 201 // 202 DBG_EXIT_STATUS ( Status ); 203 return Status; 204 } 205 206 207 /** 208 Resets the network adapter and allocates the transmit and receive buffers 209 required by the network interface; optionally, also requests allocation of 210 additional transmit and receive buffers. This routine must be called before 211 any other routine in the Simple Network protocol is called. 212 213 @param [in] pSimpleNetwork Protocol instance pointer 214 @param [in] ExtraRxBufferSize Size in bytes to add to the receive buffer allocation 215 @param [in] ExtraTxBufferSize Size in bytes to add to the transmit buffer allocation 216 217 @retval EFI_SUCCESS This operation was successful. 218 @retval EFI_NOT_STARTED The network interface was not started. 219 @retval EFI_OUT_OF_RESORUCES There was not enough memory for the transmit and receive buffers 220 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 221 EFI_SIMPLE_NETWORK_PROTOCOL structure. 222 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 223 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported. 224 225 **/ 226 EFI_STATUS 227 EFIAPI 228 SN_Initialize ( 229 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork, 230 IN UINTN ExtraRxBufferSize, 231 IN UINTN ExtraTxBufferSize 232 ) 233 { 234 EFI_SIMPLE_NETWORK_MODE * pMode; 235 EFI_STATUS Status; 236 237 DBG_ENTER ( ); 238 239 // 240 // Verify the parameters 241 // 242 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) { 243 // 244 // Determine if the interface is already started 245 // 246 pMode = pSimpleNetwork->Mode; 247 if ( EfiSimpleNetworkStarted == pMode->State ) { 248 if (( 0 == ExtraRxBufferSize ) && ( 0 == ExtraTxBufferSize )) { 249 // 250 // Start the adapter 251 // 252 Status = SN_Reset ( pSimpleNetwork, FALSE ); 253 if ( !EFI_ERROR ( Status )) { 254 // 255 // Update the network state 256 // 257 pMode->State = EfiSimpleNetworkInitialized; 258 } 259 } 260 else { 261 Status = EFI_UNSUPPORTED; 262 } 263 } 264 else { 265 Status = EFI_NOT_STARTED; 266 } 267 } 268 else { 269 Status = EFI_INVALID_PARAMETER; 270 } 271 272 // 273 // Return the operation status 274 // 275 DBG_EXIT_STATUS ( Status ); 276 return Status; 277 } 278 279 280 /** 281 This function converts a multicast IP address to a multicast HW MAC address 282 for all packet transactions. 283 284 @param [in] pSimpleNetwork Protocol instance pointer 285 @param [in] bIPv6 Set to TRUE if the multicast IP address is IPv6 [RFC2460]. 286 Set to FALSE if the multicast IP address is IPv4 [RFC 791]. 287 @param [in] pIP The multicast IP address that is to be converted to a 288 multicast HW MAC address. 289 @param [in] pMAC The multicast HW MAC address that is to be generated from IP. 290 291 @retval EFI_SUCCESS This operation was successful. 292 @retval EFI_NOT_STARTED The network interface was not started. 293 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 294 EFI_SIMPLE_NETWORK_PROTOCOL structure. 295 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 296 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported. 297 298 **/ 299 EFI_STATUS 300 EFIAPI 301 SN_MCastIPtoMAC ( 302 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork, 303 IN BOOLEAN bIPv6, 304 IN EFI_IP_ADDRESS * pIP, 305 IN EFI_MAC_ADDRESS * pMAC 306 ) 307 { 308 EFI_STATUS Status; 309 310 DBG_ENTER ( ); 311 312 // 313 // This is not currently supported 314 // 315 Status = EFI_UNSUPPORTED; 316 317 // 318 // Return the operation status 319 // 320 DBG_EXIT_STATUS ( Status ); 321 return Status; 322 } 323 324 325 /** 326 This function performs read and write operations on the NVRAM device 327 attached to a network interface. 328 329 @param [in] pSimpleNetwork Protocol instance pointer 330 @param [in] ReadWrite TRUE for read operations, FALSE for write operations. 331 @param [in] Offset Byte offset in the NVRAM device at which to start the 332 read or write operation. This must be a multiple of 333 NvRamAccessSize and less than NvRamSize. 334 @param [in] BufferSize The number of bytes to read or write from the NVRAM device. 335 This must also be a multiple of NvramAccessSize. 336 @param [in, out] pBuffer A pointer to the data buffer. 337 338 @retval EFI_SUCCESS This operation was successful. 339 @retval EFI_NOT_STARTED The network interface was not started. 340 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 341 EFI_SIMPLE_NETWORK_PROTOCOL structure. 342 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 343 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported. 344 345 **/ 346 EFI_STATUS 347 EFIAPI 348 SN_NvData ( 349 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork, 350 IN BOOLEAN ReadWrite, 351 IN UINTN Offset, 352 IN UINTN BufferSize, 353 IN OUT VOID * pBuffer 354 ) 355 { 356 EFI_STATUS Status; 357 358 DBG_ENTER ( ); 359 360 // 361 // This is not currently supported 362 // 363 Status = EFI_UNSUPPORTED; 364 365 // 366 // Return the operation status 367 // 368 DBG_EXIT_STATUS ( Status ); 369 return Status; 370 } 371 372 373 /** 374 Attempt to receive a packet from the network adapter. 375 376 This function retrieves one packet from the receive queue of the network 377 interface. If there are no packets on the receive queue, then EFI_NOT_READY 378 will be returned. If there is a packet on the receive queue, and the size 379 of the packet is smaller than BufferSize, then the contents of the packet 380 will be placed in Buffer, and BufferSize will be udpated with the actual 381 size of the packet. In addition, if SrcAddr, DestAddr, and Protocol are 382 not NULL, then these values will be extracted from the media header and 383 returned. If BufferSize is smaller than the received packet, then the 384 size of the receive packet will be placed in BufferSize and 385 EFI_BUFFER_TOO_SMALL will be returned. 386 387 This routine calls ::Ax88772Rx to update the media status and 388 empty the network adapter of receive packets. 389 390 @param [in] pSimpleNetwork Protocol instance pointer 391 @param [out] pHeaderSize The size, in bytes, of the media header to be filled in by 392 the Transmit() function. If HeaderSize is non-zero, then 393 it must be equal to SimpleNetwork->Mode->MediaHeaderSize 394 and DestAddr and Protocol parameters must not be NULL. 395 @param [out] pBufferSize The size, in bytes, of the entire packet (media header and 396 data) to be transmitted through the network interface. 397 @param [out] pBuffer A pointer to the packet (media header followed by data) to 398 to be transmitted. This parameter can not be NULL. If 399 HeaderSize is zero, then the media header is Buffer must 400 already be filled in by the caller. If HeaderSize is nonzero, 401 then the media header will be filled in by the Transmit() 402 function. 403 @param [out] pSrcAddr The source HW MAC address. If HeaderSize is zero, then 404 this parameter is ignored. If HeaderSize is nonzero and 405 SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress 406 is used for the source HW MAC address. 407 @param [out] pDestAddr The destination HW MAC address. If HeaderSize is zero, then 408 this parameter is ignored. 409 @param [out] pProtocol The type of header to build. If HeaderSize is zero, then 410 this parameter is ignored. 411 412 @retval EFI_SUCCESS This operation was successful. 413 @retval EFI_NOT_STARTED The network interface was not started. 414 @retval EFI_NOT_READY No packets have been received on the network interface. 415 @retval EFI_BUFFER_TOO_SMALL The packet is larger than BufferSize bytes. 416 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 417 EFI_SIMPLE_NETWORK_PROTOCOL structure. 418 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 419 420 **/ 421 EFI_STATUS 422 EFIAPI 423 SN_Receive ( 424 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork, 425 OUT UINTN * pHeaderSize, 426 OUT UINTN * pBufferSize, 427 OUT VOID * pBuffer, 428 OUT EFI_MAC_ADDRESS * pSrcAddr, 429 OUT EFI_MAC_ADDRESS * pDestAddr, 430 OUT UINT16 * pProtocol 431 ) 432 { 433 ETHERNET_HEADER * pHeader; 434 EFI_SIMPLE_NETWORK_MODE * pMode; 435 NIC_DEVICE * pNicDevice; 436 RX_TX_PACKET * pRxPacket; 437 EFI_STATUS Status; 438 EFI_TPL TplPrevious; 439 UINT16 Type; 440 441 DBG_ENTER ( ); 442 443 // 444 // Verify the parameters 445 // 446 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) { 447 // 448 // The interface must be running 449 // 450 pMode = pSimpleNetwork->Mode; 451 if ( EfiSimpleNetworkInitialized == pMode->State ) { 452 // 453 // Synchronize with Ax88772Timer 454 // 455 VERIFY_TPL ( TPL_AX88772 ); 456 TplPrevious = gBS->RaiseTPL ( TPL_AX88772 ); 457 458 // 459 // Update the link status 460 // 461 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork ); 462 Ax88772Rx ( pNicDevice, FALSE ); 463 pMode->MediaPresent = pNicDevice->bLinkUp; 464 if ( pMode->MediaPresent ) { 465 // 466 // Attempt to receive a packet 467 // 468 pRxPacket = pNicDevice->pRxHead; 469 if ( NULL != pRxPacket ) { 470 pNicDevice->pRxHead = pRxPacket->pNext; 471 if ( NULL == pNicDevice->pRxHead ) { 472 pNicDevice->pRxTail = NULL; 473 } 474 475 // 476 // Copy the received packet into the receive buffer 477 // 478 *pBufferSize = pRxPacket->Length; 479 CopyMem ( pBuffer, &pRxPacket->Data[0], pRxPacket->Length ); 480 pHeader = (ETHERNET_HEADER *) &pRxPacket->Data[0]; 481 if ( NULL != pHeaderSize ) { 482 *pHeaderSize = sizeof ( *pHeader ); 483 } 484 if ( NULL != pDestAddr ) { 485 CopyMem ( pDestAddr, &pHeader->dest_addr, PXE_HWADDR_LEN_ETHER ); 486 } 487 if ( NULL != pSrcAddr ) { 488 CopyMem ( pSrcAddr, &pHeader->src_addr, PXE_HWADDR_LEN_ETHER ); 489 } 490 if ( NULL != pProtocol ) { 491 Type = pHeader->type; 492 Type = (UINT16)(( Type >> 8 ) | ( Type << 8 )); 493 *pProtocol = Type; 494 } 495 Status = EFI_SUCCESS; 496 } 497 else { 498 // 499 // No receive packets available 500 // 501 Status = EFI_NOT_READY; 502 } 503 } 504 else { 505 // 506 // Link no up 507 // 508 Status = EFI_NOT_READY; 509 } 510 511 // 512 // Release the synchronization with Ax88772Timer 513 // 514 gBS->RestoreTPL ( TplPrevious ); 515 } 516 else { 517 Status = EFI_NOT_STARTED; 518 } 519 } 520 else { 521 Status = EFI_INVALID_PARAMETER; 522 } 523 524 // 525 // Return the operation status 526 // 527 DBG_EXIT_STATUS ( Status ); 528 return Status; 529 } 530 531 532 /** 533 This function is used to enable and disable the hardware and software receive 534 filters for the underlying network device. 535 536 The receive filter change is broken down into three steps: 537 538 1. The filter mask bits that are set (ON) in the Enable parameter 539 are added to the current receive filter settings. 540 541 2. The filter mask bits that are set (ON) in the Disable parameter 542 are subtracted from the updated receive filter settins. 543 544 3. If the resulting filter settigns is not supported by the hardware 545 a more liberal setting is selected. 546 547 If the same bits are set in the Enable and Disable parameters, then the bits 548 in the Disable parameter takes precedence. 549 550 If the ResetMCastFilter parameter is TRUE, then the multicast address list 551 filter is disabled (irregardless of what other multicast bits are set in 552 the enable and Disable parameters). The SNP->Mode->MCastFilterCount field 553 is set to zero. The SNP->Mode->MCastFilter contents are undefined. 554 555 After enableing or disabling receive filter settings, software should 556 verify the new settings by checking the SNP->Mode->ReceeiveFilterSettings, 557 SNP->Mode->MCastFilterCount and SNP->Mode->MCastFilter fields. 558 559 Note: Some network drivers and/or devices will automatically promote 560 receive filter settings if the requested setting can not be honored. 561 For example, if a request for four multicast addresses is made and 562 the underlying hardware only supports two multicast addresses the 563 driver might set the promiscuous or promiscuous multicast receive filters 564 instead. The receiving software is responsible for discarding any extra 565 packets that get through the hardware receive filters. 566 567 If ResetMCastFilter is TRUE, then the multicast receive filter list 568 on the network interface will be reset to the default multicast receive 569 filter list. If ResetMCastFilter is FALSE, and this network interface 570 allows the multicast receive filter list to be modified, then the 571 MCastFilterCnt and MCastFilter are used to update the current multicast 572 receive filter list. The modified receive filter list settings can be 573 found in the MCastFilter field of EFI_SIMPLE_NETWORK_MODE. 574 575 This routine calls ::ReceiveFilterUpdate to update the receive 576 state in the network adapter. 577 578 @param [in] pSimpleNetwork Protocol instance pointer 579 @param [in] Enable A bit mask of receive filters to enable on the network interface. 580 @param [in] Disable A bit mask of receive filters to disable on the network interface. 581 For backward compatibility with EFI 1.1 platforms, the 582 EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST bit must be set 583 when the ResetMCastFilter parameter is TRUE. 584 @param [in] bResetMCastFilter Set to TRUE to reset the contents of the multicast receive 585 filters on the network interface to their default values. 586 @param [in] MCastFilterCnt Number of multicast HW MAC address in the new MCastFilter list. 587 This value must be less than or equal to the MaxMCastFilterCnt 588 field of EFI_SIMPLE_NETWORK_MODE. This field is optional if 589 ResetMCastFilter is TRUE. 590 @param [in] pMCastFilter A pointer to a list of new multicast receive filter HW MAC 591 addresses. This list will replace any existing multicast 592 HW MAC address list. This field is optional if ResetMCastFilter 593 is TRUE. 594 595 @retval EFI_SUCCESS This operation was successful. 596 @retval EFI_NOT_STARTED The network interface was not started. 597 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 598 EFI_SIMPLE_NETWORK_PROTOCOL structure. 599 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 600 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported. 601 602 **/ 603 EFI_STATUS 604 EFIAPI 605 SN_ReceiveFilters ( 606 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork, 607 IN UINT32 Enable, 608 IN UINT32 Disable, 609 IN BOOLEAN bResetMCastFilter, 610 IN UINTN MCastFilterCnt, 611 IN EFI_MAC_ADDRESS * pMCastFilter 612 ) 613 { 614 EFI_SIMPLE_NETWORK_MODE * pMode; 615 EFI_MAC_ADDRESS * pMulticastAddress; 616 EFI_MAC_ADDRESS * pTableEnd; 617 EFI_STATUS Status; 618 619 DBG_ENTER ( ); 620 621 // 622 // Verify the parameters 623 // 624 Status = EFI_INVALID_PARAMETER; 625 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) { 626 pMode = pSimpleNetwork->Mode; 627 628 // 629 // Update the multicast list if necessary 630 // 631 if ( !bResetMCastFilter ) { 632 if ( 0 != MCastFilterCnt ) { 633 if (( MAX_MCAST_FILTER_CNT >= MCastFilterCnt ) 634 && ( NULL != pMCastFilter )) { 635 // 636 // Verify the multicast addresses 637 // 638 pMulticastAddress = pMCastFilter; 639 pTableEnd = pMulticastAddress + MCastFilterCnt; 640 while ( pTableEnd > pMulticastAddress ) { 641 // 642 // The first digit of the multicast address must have the LSB set 643 // 644 if ( 0 == ( pMulticastAddress->Addr[0] & 1 )) { 645 // 646 // Invalid multicast address 647 // 648 break; 649 } 650 pMulticastAddress += 1; 651 } 652 if ( pTableEnd == pMulticastAddress ) { 653 // 654 // Update the multicast filter list. 655 // 656 CopyMem (&pMode->MCastFilter[0], 657 pMCastFilter, 658 MCastFilterCnt * sizeof ( *pMCastFilter )); 659 Status = EFI_SUCCESS; 660 } 661 } 662 } 663 else { 664 Status = EFI_SUCCESS; 665 } 666 } 667 else { 668 // 669 // No multicast address list is specified 670 // 671 MCastFilterCnt = 0; 672 Status = EFI_SUCCESS; 673 } 674 if ( !EFI_ERROR ( Status )) { 675 // 676 // The parameters are valid! 677 // 678 pMode->ReceiveFilterSetting |= Enable; 679 pMode->ReceiveFilterSetting &= ~Disable; 680 pMode->MCastFilterCount = (UINT32)MCastFilterCnt; 681 682 // 683 // Update the receive filters in the adapter 684 // 685 Status = ReceiveFilterUpdate ( pSimpleNetwork ); 686 } 687 } 688 689 // 690 // Return the operation status 691 // 692 DBG_EXIT_STATUS ( Status ); 693 return Status; 694 } 695 696 697 /** 698 Reset the network adapter. 699 700 Resets a network adapter and reinitializes it with the parameters that 701 were provided in the previous call to Initialize (). The transmit and 702 receive queues are cleared. Receive filters, the station address, the 703 statistics, and the multicast-IP-to-HW MAC addresses are not reset by 704 this call. 705 706 This routine calls ::Ax88772Reset to perform the adapter specific 707 reset operation. This routine also starts the link negotiation 708 by calling ::Ax88772NegotiateLinkStart. 709 710 @param [in] pSimpleNetwork Protocol instance pointer 711 @param [in] bExtendedVerification Indicates that the driver may perform a more 712 exhaustive verification operation of the device 713 during reset. 714 715 @retval EFI_SUCCESS This operation was successful. 716 @retval EFI_NOT_STARTED The network interface was not started. 717 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 718 EFI_SIMPLE_NETWORK_PROTOCOL structure. 719 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 720 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported. 721 722 **/ 723 EFI_STATUS 724 EFIAPI 725 SN_Reset ( 726 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork, 727 IN BOOLEAN bExtendedVerification 728 ) 729 { 730 EFI_SIMPLE_NETWORK_MODE * pMode; 731 NIC_DEVICE * pNicDevice; 732 RX_TX_PACKET * pRxPacket; 733 EFI_STATUS Status; 734 EFI_TPL TplPrevious; 735 736 DBG_ENTER ( ); 737 738 // 739 // Verify the parameters 740 // 741 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) { 742 // 743 // Synchronize with Ax88772Timer 744 // 745 VERIFY_TPL ( TPL_AX88772 ); 746 TplPrevious = gBS->RaiseTPL ( TPL_AX88772 ); 747 748 // 749 // Update the device state 750 // 751 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork ); 752 pNicDevice->bComplete = FALSE; 753 pNicDevice->bLinkUp = FALSE; 754 755 pMode = pSimpleNetwork->Mode; 756 pMode->MediaPresent = FALSE; 757 758 // 759 // Discard any received packets 760 // 761 while ( NULL != pNicDevice->pRxHead ) { 762 // 763 // Remove the packet from the received packet list 764 // 765 pRxPacket = pNicDevice->pRxHead; 766 pNicDevice->pRxHead = pRxPacket->pNext; 767 768 // 769 // Queue the packet to the free list 770 // 771 pRxPacket->pNext = pNicDevice->pRxFree; 772 pNicDevice->pRxFree = pRxPacket; 773 } 774 pNicDevice->pRxTail = NULL; 775 776 // 777 // Reset the device 778 // 779 Status = Ax88772Reset ( pNicDevice ); 780 if ( !EFI_ERROR ( Status )) { 781 // 782 // Update the receive filters in the adapter 783 // 784 Status = ReceiveFilterUpdate ( pSimpleNetwork ); 785 786 // 787 // Try to get a connection to the network 788 // 789 if ( !EFI_ERROR ( Status )) { 790 // 791 // Start the autonegotiation 792 // 793 Status = Ax88772NegotiateLinkStart ( pNicDevice ); 794 } 795 } 796 797 // 798 // Release the synchronization with Ax88772Timer 799 // 800 gBS->RestoreTPL ( TplPrevious ); 801 } 802 else { 803 Status = EFI_INVALID_PARAMETER; 804 } 805 806 // 807 // Return the operation status 808 // 809 DBG_EXIT_STATUS ( Status ); 810 return Status; 811 } 812 813 814 /** 815 Initialize the simple network protocol. 816 817 This routine calls ::Ax88772MacAddressGet to obtain the 818 MAC address. 819 820 @param [in] pNicDevice NIC_DEVICE_INSTANCE pointer 821 822 @retval EFI_SUCCESS Setup was successful 823 824 **/ 825 EFI_STATUS 826 SN_Setup ( 827 IN NIC_DEVICE * pNicDevice 828 ) 829 { 830 EFI_SIMPLE_NETWORK_MODE * pMode; 831 EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork; 832 EFI_STATUS Status; 833 834 DBG_ENTER ( ); 835 836 // 837 // Initialize the simple network protocol 838 // 839 pSimpleNetwork = &pNicDevice->SimpleNetwork; 840 pSimpleNetwork->Revision = EFI_SIMPLE_NETWORK_PROTOCOL_REVISION; 841 pSimpleNetwork->Start = (EFI_SIMPLE_NETWORK_START)SN_Start; 842 pSimpleNetwork->Stop = (EFI_SIMPLE_NETWORK_STOP)SN_Stop; 843 pSimpleNetwork->Initialize = (EFI_SIMPLE_NETWORK_INITIALIZE)SN_Initialize; 844 pSimpleNetwork->Reset = (EFI_SIMPLE_NETWORK_RESET)SN_Reset; 845 pSimpleNetwork->Shutdown = (EFI_SIMPLE_NETWORK_SHUTDOWN)SN_Shutdown; 846 pSimpleNetwork->ReceiveFilters = (EFI_SIMPLE_NETWORK_RECEIVE_FILTERS)SN_ReceiveFilters; 847 pSimpleNetwork->StationAddress = (EFI_SIMPLE_NETWORK_STATION_ADDRESS)SN_StationAddress; 848 pSimpleNetwork->Statistics = (EFI_SIMPLE_NETWORK_STATISTICS)SN_Statistics; 849 pSimpleNetwork->MCastIpToMac = (EFI_SIMPLE_NETWORK_MCAST_IP_TO_MAC)SN_MCastIPtoMAC; 850 pSimpleNetwork->NvData = (EFI_SIMPLE_NETWORK_NVDATA)SN_NvData; 851 pSimpleNetwork->GetStatus = (EFI_SIMPLE_NETWORK_GET_STATUS)SN_GetStatus; 852 pSimpleNetwork->Transmit = (EFI_SIMPLE_NETWORK_TRANSMIT)SN_Transmit; 853 pSimpleNetwork->Receive = (EFI_SIMPLE_NETWORK_RECEIVE)SN_Receive; 854 pSimpleNetwork->WaitForPacket = NULL; 855 pMode = &pNicDevice->SimpleNetworkData; 856 pSimpleNetwork->Mode = pMode; 857 858 pMode->State = EfiSimpleNetworkStopped; 859 pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER; 860 pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER ); 861 pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE; 862 pMode->NvRamSize = 0; 863 pMode->NvRamAccessSize = 0; 864 pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 865 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 866 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 867 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 868 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST; 869 pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 870 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST; 871 pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT; 872 pMode->MCastFilterCount = 0; 873 SetMem ( &pMode->BroadcastAddress, 874 PXE_HWADDR_LEN_ETHER, 875 0xff ); 876 pMode->IfType = EfiNetworkInterfaceUndi; 877 pMode->MacAddressChangeable = TRUE; 878 pMode->MultipleTxSupported = TRUE; 879 pMode->MediaPresentSupported = TRUE; 880 pMode->MediaPresent = FALSE; 881 882 // 883 // Read the MAC address 884 // 885 pNicDevice->PhyId = PHY_ID_INTERNAL; 886 pNicDevice->b100Mbps = TRUE; 887 pNicDevice->bFullDuplex = TRUE; 888 889 Status = gBS->AllocatePool ( EfiRuntimeServicesData, 890 MAX_BULKIN_SIZE, 891 (VOID **) &pNicDevice->pBulkInBuff); 892 if ( EFI_ERROR(Status)) { 893 DEBUG (( EFI_D_ERROR, "Memory are not enough\n")); 894 return Status; 895 } 896 897 Status = Ax88772MacAddressGet ( 898 pNicDevice, 899 &pMode->PermanentAddress.Addr[0]); 900 if ( !EFI_ERROR ( Status )) { 901 // 902 // Display the MAC address 903 // 904 DEBUG (( DEBUG_MAC_ADDRESS | DEBUG_INFO, 905 "MAC: %02x-%02x-%02x-%02x-%02x-%02x\n", 906 pMode->PermanentAddress.Addr[0], 907 pMode->PermanentAddress.Addr[1], 908 pMode->PermanentAddress.Addr[2], 909 pMode->PermanentAddress.Addr[3], 910 pMode->PermanentAddress.Addr[4], 911 pMode->PermanentAddress.Addr[5])); 912 913 // 914 // Use the hardware address as the current address 915 // 916 CopyMem ( &pMode->CurrentAddress, 917 &pMode->PermanentAddress, 918 PXE_HWADDR_LEN_ETHER ); 919 } 920 921 // 922 // Return the setup status 923 // 924 DBG_EXIT_STATUS ( Status ); 925 return Status; 926 } 927 928 929 /** 930 This routine starts the network interface. 931 932 @param [in] pSimpleNetwork Protocol instance pointer 933 934 @retval EFI_SUCCESS This operation was successful. 935 @retval EFI_ALREADY_STARTED The network interface was already started. 936 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 937 EFI_SIMPLE_NETWORK_PROTOCOL structure. 938 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 939 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported. 940 941 **/ 942 EFI_STATUS 943 EFIAPI 944 SN_Start ( 945 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork 946 ) 947 { 948 NIC_DEVICE * pNicDevice; 949 EFI_SIMPLE_NETWORK_MODE * pMode; 950 EFI_STATUS Status; 951 952 DBG_ENTER ( ); 953 954 // 955 // Verify the parameters 956 // 957 Status = EFI_INVALID_PARAMETER; 958 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) { 959 pMode = pSimpleNetwork->Mode; 960 if ( EfiSimpleNetworkStopped == pMode->State ) { 961 // 962 // Initialize the mode structure 963 // NVRAM access is not supported 964 // 965 ZeroMem ( pMode, sizeof ( *pMode )); 966 967 pMode->State = EfiSimpleNetworkStarted; 968 pMode->HwAddressSize = PXE_HWADDR_LEN_ETHER; 969 pMode->MediaHeaderSize = sizeof ( ETHERNET_HEADER ); 970 pMode->MaxPacketSize = MAX_ETHERNET_PKT_SIZE; 971 pMode->ReceiveFilterMask = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST 972 | EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST 973 | EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST 974 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS 975 | EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST; 976 pMode->ReceiveFilterSetting = EFI_SIMPLE_NETWORK_RECEIVE_UNICAST; 977 pMode->MaxMCastFilterCount = MAX_MCAST_FILTER_CNT; 978 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork ); 979 Status = Ax88772MacAddressGet ( pNicDevice, &pMode->PermanentAddress.Addr[0]); 980 CopyMem ( &pMode->CurrentAddress, 981 &pMode->PermanentAddress, 982 sizeof ( pMode->CurrentAddress )); 983 pMode->BroadcastAddress.Addr[0] = 0xff; 984 pMode->BroadcastAddress.Addr[1] = 0xff; 985 pMode->BroadcastAddress.Addr[2] = 0xff; 986 pMode->BroadcastAddress.Addr[3] = 0xff; 987 pMode->BroadcastAddress.Addr[4] = 0xff; 988 pMode->BroadcastAddress.Addr[5] = 0xff; 989 pMode->IfType = 1; 990 pMode->MacAddressChangeable = TRUE; 991 pMode->MultipleTxSupported = TRUE; 992 pMode->MediaPresentSupported = TRUE; 993 pMode->MediaPresent = FALSE; 994 } 995 else { 996 Status = EFI_ALREADY_STARTED; 997 } 998 } 999 1000 // 1001 // Return the operation status 1002 // 1003 DBG_EXIT_STATUS ( Status ); 1004 return Status; 1005 } 1006 1007 1008 /** 1009 Set the MAC address. 1010 1011 This function modifies or resets the current station address of a 1012 network interface. If Reset is TRUE, then the current station address 1013 is set ot the network interface's permanent address. If Reset if FALSE 1014 then the current station address is changed to the address specified by 1015 pNew. 1016 1017 This routine calls ::Ax88772MacAddressSet to update the MAC address 1018 in the network adapter. 1019 1020 @param [in] pSimpleNetwork Protocol instance pointer 1021 @param [in] bReset Flag used to reset the station address to the 1022 network interface's permanent address. 1023 @param [in] pNew New station address to be used for the network 1024 interface. 1025 1026 @retval EFI_SUCCESS This operation was successful. 1027 @retval EFI_NOT_STARTED The network interface was not started. 1028 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 1029 EFI_SIMPLE_NETWORK_PROTOCOL structure. 1030 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 1031 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported. 1032 1033 **/ 1034 EFI_STATUS 1035 EFIAPI 1036 SN_StationAddress ( 1037 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork, 1038 IN BOOLEAN bReset, 1039 IN EFI_MAC_ADDRESS * pNew 1040 ) 1041 { 1042 NIC_DEVICE * pNicDevice; 1043 EFI_SIMPLE_NETWORK_MODE * pMode; 1044 EFI_STATUS Status; 1045 1046 DBG_ENTER ( ); 1047 1048 // 1049 // Verify the parameters 1050 // 1051 if (( NULL != pSimpleNetwork ) 1052 && ( NULL != pSimpleNetwork->Mode ) 1053 && (( !bReset ) || ( bReset && ( NULL != pNew )))) { 1054 // 1055 // Verify that the adapter is already started 1056 // 1057 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork ); 1058 pMode = pSimpleNetwork->Mode; 1059 if ( EfiSimpleNetworkStarted == pMode->State ) { 1060 // 1061 // Determine the adapter MAC address 1062 // 1063 if ( bReset ) { 1064 // 1065 // Use the permanent address 1066 // 1067 CopyMem ( &pMode->CurrentAddress, 1068 &pMode->PermanentAddress, 1069 sizeof ( pMode->CurrentAddress )); 1070 } 1071 else { 1072 // 1073 // Use the specified address 1074 // 1075 CopyMem ( &pMode->CurrentAddress, 1076 pNew, 1077 sizeof ( pMode->CurrentAddress )); 1078 } 1079 1080 // 1081 // Update the address on the adapter 1082 // 1083 Status = Ax88772MacAddressSet ( pNicDevice, &pMode->CurrentAddress.Addr[0]); 1084 } 1085 else { 1086 Status = EFI_NOT_STARTED; 1087 } 1088 } 1089 else { 1090 Status = EFI_INVALID_PARAMETER; 1091 } 1092 1093 // 1094 // Return the operation status 1095 // 1096 DBG_EXIT_STATUS ( Status ); 1097 return Status; 1098 } 1099 1100 1101 /** 1102 This function resets or collects the statistics on a network interface. 1103 If the size of the statistics table specified by StatisticsSize is not 1104 big enough for all of the statistics that are collected by the network 1105 interface, then a partial buffer of statistics is returned in 1106 StatisticsTable. 1107 1108 @param [in] pSimpleNetwork Protocol instance pointer 1109 @param [in] bReset Set to TRUE to reset the statistics for the network interface. 1110 @param [in, out] pStatisticsSize On input the size, in bytes, of StatisticsTable. On output 1111 the size, in bytes, of the resulting table of statistics. 1112 @param [out] pStatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that 1113 conains the statistics. 1114 1115 @retval EFI_SUCCESS This operation was successful. 1116 @retval EFI_NOT_STARTED The network interface was not started. 1117 @retval EFI_BUFFER_TOO_SMALL The pStatisticsTable is NULL or the buffer is too small. 1118 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 1119 EFI_SIMPLE_NETWORK_PROTOCOL structure. 1120 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 1121 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported. 1122 1123 **/ 1124 EFI_STATUS 1125 EFIAPI 1126 SN_Statistics ( 1127 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork, 1128 IN BOOLEAN bReset, 1129 IN OUT UINTN * pStatisticsSize, 1130 OUT EFI_NETWORK_STATISTICS * pStatisticsTable 1131 ) 1132 { 1133 EFI_STATUS Status; 1134 1135 DBG_ENTER ( ); 1136 1137 // 1138 // This is not currently supported 1139 // 1140 Status = EFI_UNSUPPORTED; 1141 1142 // 1143 // Return the operation status 1144 // 1145 DBG_EXIT_STATUS ( Status ); 1146 return Status; 1147 } 1148 1149 1150 /** 1151 This function stops a network interface. This call is only valid 1152 if the network interface is in the started state. 1153 1154 @param [in] pSimpleNetwork Protocol instance pointer 1155 1156 @retval EFI_SUCCESS This operation was successful. 1157 @retval EFI_NOT_STARTED The network interface was not started. 1158 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 1159 EFI_SIMPLE_NETWORK_PROTOCOL structure. 1160 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 1161 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported. 1162 1163 **/ 1164 EFI_STATUS 1165 EFIAPI 1166 SN_Stop ( 1167 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork 1168 ) 1169 { 1170 EFI_SIMPLE_NETWORK_MODE * pMode; 1171 EFI_STATUS Status; 1172 1173 DBG_ENTER ( ); 1174 1175 // 1176 // Verify the parameters 1177 // 1178 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) { 1179 // 1180 // Determine if the interface is started 1181 // 1182 pMode = pSimpleNetwork->Mode; 1183 if ( EfiSimpleNetworkStopped != pMode->State ) { 1184 if ( EfiSimpleNetworkStarted == pMode->State ) { 1185 // 1186 // Release the resources acquired in SN_Start 1187 // 1188 1189 // 1190 // Mark the adapter as stopped 1191 // 1192 pMode->State = EfiSimpleNetworkStopped; 1193 Status = EFI_SUCCESS; 1194 } 1195 else { 1196 Status = EFI_UNSUPPORTED; 1197 } 1198 } 1199 else { 1200 Status = EFI_NOT_STARTED; 1201 } 1202 } 1203 else { 1204 Status = EFI_INVALID_PARAMETER; 1205 } 1206 1207 // 1208 // Return the operation status 1209 // 1210 DBG_EXIT_STATUS ( Status ); 1211 return Status; 1212 } 1213 1214 1215 /** 1216 This function releases the memory buffers assigned in the Initialize() call. 1217 Pending transmits and receives are lost, and interrupts are cleared and disabled. 1218 After this call, only Initialize() and Stop() calls may be used. 1219 1220 @param [in] pSimpleNetwork Protocol instance pointer 1221 1222 @retval EFI_SUCCESS This operation was successful. 1223 @retval EFI_NOT_STARTED The network interface was not started. 1224 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 1225 EFI_SIMPLE_NETWORK_PROTOCOL structure. 1226 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 1227 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported. 1228 1229 **/ 1230 EFI_STATUS 1231 EFIAPI 1232 SN_Shutdown ( 1233 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork 1234 ) 1235 { 1236 EFI_SIMPLE_NETWORK_MODE * pMode; 1237 UINT32 RxFilter; 1238 EFI_STATUS Status; 1239 1240 DBG_ENTER ( ); 1241 1242 // 1243 // Verify the parameters 1244 // 1245 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) { 1246 // 1247 // Determine if the interface is already started 1248 // 1249 pMode = pSimpleNetwork->Mode; 1250 if ( EfiSimpleNetworkInitialized == pMode->State ) { 1251 // 1252 // Stop the adapter 1253 // 1254 RxFilter = pMode->ReceiveFilterSetting; 1255 pMode->ReceiveFilterSetting = 0; 1256 Status = SN_Reset ( pSimpleNetwork, FALSE ); 1257 pMode->ReceiveFilterSetting = RxFilter; 1258 if ( !EFI_ERROR ( Status )) { 1259 // 1260 // Release the resources acquired by SN_Initialize 1261 // 1262 1263 // 1264 // Update the network state 1265 // 1266 pMode->State = EfiSimpleNetworkStarted; 1267 } 1268 } 1269 else { 1270 Status = EFI_NOT_STARTED; 1271 } 1272 } 1273 else { 1274 Status = EFI_INVALID_PARAMETER; 1275 } 1276 1277 // 1278 // Return the operation status 1279 // 1280 DBG_EXIT_STATUS ( Status ); 1281 return Status; 1282 } 1283 1284 1285 /** 1286 Send a packet over the network. 1287 1288 This function places the packet specified by Header and Buffer on 1289 the transmit queue. This function performs a non-blocking transmit 1290 operation. When the transmit is complete, the buffer is returned 1291 via the GetStatus() call. 1292 1293 This routine calls ::Ax88772Rx to empty the network adapter of 1294 receive packets. The routine then passes the transmit packet 1295 to the network adapter. 1296 1297 @param [in] pSimpleNetwork Protocol instance pointer 1298 @param [in] HeaderSize The size, in bytes, of the media header to be filled in by 1299 the Transmit() function. If HeaderSize is non-zero, then 1300 it must be equal to SimpleNetwork->Mode->MediaHeaderSize 1301 and DestAddr and Protocol parameters must not be NULL. 1302 @param [in] BufferSize The size, in bytes, of the entire packet (media header and 1303 data) to be transmitted through the network interface. 1304 @param [in] pBuffer A pointer to the packet (media header followed by data) to 1305 to be transmitted. This parameter can not be NULL. If 1306 HeaderSize is zero, then the media header is Buffer must 1307 already be filled in by the caller. If HeaderSize is nonzero, 1308 then the media header will be filled in by the Transmit() 1309 function. 1310 @param [in] pSrcAddr The source HW MAC address. If HeaderSize is zero, then 1311 this parameter is ignored. If HeaderSize is nonzero and 1312 SrcAddr is NULL, then SimpleNetwork->Mode->CurrentAddress 1313 is used for the source HW MAC address. 1314 @param [in] pDestAddr The destination HW MAC address. If HeaderSize is zero, then 1315 this parameter is ignored. 1316 @param [in] pProtocol The type of header to build. If HeaderSize is zero, then 1317 this parameter is ignored. 1318 1319 @retval EFI_SUCCESS This operation was successful. 1320 @retval EFI_NOT_STARTED The network interface was not started. 1321 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request. 1322 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small. 1323 @retval EFI_INVALID_PARAMETER pSimpleNetwork parameter was NULL or did not point to a valid 1324 EFI_SIMPLE_NETWORK_PROTOCOL structure. 1325 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface. 1326 1327 **/ 1328 EFI_STATUS 1329 EFIAPI 1330 SN_Transmit ( 1331 IN EFI_SIMPLE_NETWORK_PROTOCOL * pSimpleNetwork, 1332 IN UINTN HeaderSize, 1333 IN UINTN BufferSize, 1334 IN VOID * pBuffer, 1335 IN EFI_MAC_ADDRESS * pSrcAddr, 1336 IN EFI_MAC_ADDRESS * pDestAddr, 1337 IN UINT16 * pProtocol 1338 ) 1339 { 1340 RX_TX_PACKET Packet; 1341 ETHERNET_HEADER * pHeader; 1342 EFI_SIMPLE_NETWORK_MODE * pMode; 1343 NIC_DEVICE * pNicDevice; 1344 EFI_USB_IO_PROTOCOL * pUsbIo; 1345 EFI_STATUS Status; 1346 EFI_TPL TplPrevious; 1347 UINTN TransferLength; 1348 UINT32 TransferStatus; 1349 UINT16 Type; 1350 1351 DBG_ENTER ( ); 1352 1353 // 1354 // Verify the parameters 1355 // 1356 if (( NULL != pSimpleNetwork ) && ( NULL != pSimpleNetwork->Mode )) { 1357 // 1358 // The interface must be running 1359 // 1360 pMode = pSimpleNetwork->Mode; 1361 if ( EfiSimpleNetworkInitialized == pMode->State ) { 1362 // 1363 // Synchronize with Ax88772Timer 1364 // 1365 VERIFY_TPL ( TPL_AX88772 ); 1366 TplPrevious = gBS->RaiseTPL ( TPL_AX88772 ); 1367 1368 // 1369 // Update the link status 1370 // 1371 pNicDevice = DEV_FROM_SIMPLE_NETWORK ( pSimpleNetwork ); 1372 1373 // 1374 //No need to call receive to receive packet 1375 // 1376 //Ax88772Rx ( pNicDevice, FALSE ); 1377 pMode->MediaPresent = pNicDevice->bLinkUp; 1378 1379 // 1380 // Release the synchronization with Ax88772Timer 1381 // 1382 gBS->RestoreTPL ( TplPrevious ); 1383 if ( pMode->MediaPresent ) { 1384 // 1385 // Copy the packet into the USB buffer 1386 // 1387 CopyMem ( &Packet.Data[0], pBuffer, BufferSize ); 1388 Packet.Length = (UINT16) BufferSize; 1389 1390 // 1391 // Transmit the packet 1392 // 1393 pHeader = (ETHERNET_HEADER *) &Packet.Data[0]; 1394 if ( 0 != HeaderSize ) { 1395 if ( NULL != pDestAddr ) { 1396 CopyMem ( &pHeader->dest_addr, pDestAddr, PXE_HWADDR_LEN_ETHER ); 1397 } 1398 if ( NULL != pSrcAddr ) { 1399 CopyMem ( &pHeader->src_addr, pSrcAddr, PXE_HWADDR_LEN_ETHER ); 1400 } 1401 else { 1402 CopyMem ( &pHeader->src_addr, &pMode->CurrentAddress.Addr[0], PXE_HWADDR_LEN_ETHER ); 1403 } 1404 if ( NULL != pProtocol ) { 1405 Type = *pProtocol; 1406 } 1407 else { 1408 Type = Packet.Length; 1409 } 1410 Type = (UINT16)(( Type >> 8 ) | ( Type << 8 )); 1411 pHeader->type = Type; 1412 } 1413 if ( Packet.Length < MIN_ETHERNET_PKT_SIZE ) { 1414 Packet.Length = MIN_ETHERNET_PKT_SIZE; 1415 ZeroMem ( &Packet.Data[ BufferSize ], 1416 Packet.Length - BufferSize ); 1417 } 1418 DEBUG (( DEBUG_TX | DEBUG_INFO, 1419 "TX: %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x-%02x-%02x-%02x-%02x %02x-%02x %d bytes\r\n", 1420 Packet.Data[0], 1421 Packet.Data[1], 1422 Packet.Data[2], 1423 Packet.Data[3], 1424 Packet.Data[4], 1425 Packet.Data[5], 1426 Packet.Data[6], 1427 Packet.Data[7], 1428 Packet.Data[8], 1429 Packet.Data[9], 1430 Packet.Data[10], 1431 Packet.Data[11], 1432 Packet.Data[12], 1433 Packet.Data[13], 1434 Packet.Length )); 1435 Packet.LengthBar = ~Packet.Length; 1436 TransferLength = sizeof ( Packet.Length ) 1437 + sizeof ( Packet.LengthBar ) 1438 + Packet.Length; 1439 1440 // 1441 // Work around USB bus driver bug where a timeout set by receive 1442 // succeeds but the timeout expires immediately after, causing the 1443 // transmit operation to timeout. 1444 // 1445 pUsbIo = pNicDevice->pUsbIo; 1446 Status = pUsbIo->UsbBulkTransfer ( pUsbIo, 1447 BULK_OUT_ENDPOINT, 1448 &Packet.Length, 1449 &TransferLength, 1450 0xfffffffe, 1451 &TransferStatus ); 1452 if ( !EFI_ERROR ( Status )) { 1453 Status = TransferStatus; 1454 } 1455 if (( !EFI_ERROR ( Status )) 1456 && ( TransferLength != (UINTN)( Packet.Length + 4 ))) { 1457 Status = EFI_WARN_WRITE_FAILURE; 1458 } 1459 if ( EFI_SUCCESS == Status ) { 1460 pNicDevice->pTxBuffer = pBuffer; 1461 } 1462 else { 1463 DEBUG (( DEBUG_ERROR | DEBUG_INFO, 1464 "Ax88772 USB transmit error, TransferLength: %d, Status: %r\r\n", 1465 sizeof ( Packet.Length ) + Packet.Length, 1466 Status )); 1467 // 1468 // Reset the controller to fix the error 1469 // 1470 if ( EFI_DEVICE_ERROR == Status ) { 1471 SN_Reset ( pSimpleNetwork, FALSE ); 1472 } 1473 } 1474 } 1475 else { 1476 // 1477 // No packets available. 1478 // 1479 Status = EFI_NOT_READY; 1480 } 1481 } 1482 else { 1483 Status = EFI_NOT_STARTED; 1484 } 1485 } 1486 else { 1487 DEBUG (( DEBUG_ERROR | DEBUG_INFO, 1488 "Ax88772 invalid transmit parameter\r\n" 1489 " 0x%08x: HeaderSize\r\n" 1490 " 0x%08x: BufferSize\r\n" 1491 " 0x%08x: Buffer\r\n" 1492 " 0x%08x: SrcAddr\r\n" 1493 " 0x%08x: DestAddr\r\n" 1494 " 0x%04x: Protocol\r\n", 1495 HeaderSize, 1496 BufferSize, 1497 pBuffer, 1498 pSrcAddr, 1499 pDestAddr, 1500 pProtocol )); 1501 Status = EFI_INVALID_PARAMETER; 1502 } 1503 1504 // 1505 // Return the operation status 1506 // 1507 DBG_EXIT_STATUS ( Status ); 1508 return Status; 1509 } 1510