Start.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /** @file
  2. Implementation of starting a network adapter.
  3. Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "Snp.h"
  7. /**
  8. Call UNDI to start the interface and changes the snp state.
  9. @param Snp pointer to snp driver structure.
  10. @retval EFI_SUCCESS UNDI is started successfully.
  11. @retval EFI_DEVICE_ERROR UNDI could not be started.
  12. **/
  13. EFI_STATUS
  14. PxeStart (
  15. IN SNP_DRIVER *Snp
  16. )
  17. {
  18. PXE_CPB_START_31 *Cpb31;
  19. Cpb31 = Snp->Cpb;
  20. //
  21. // Initialize UNDI Start CDB for H/W UNDI
  22. //
  23. Snp->Cdb.OpCode = PXE_OPCODE_START;
  24. Snp->Cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
  25. Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
  26. Snp->Cdb.DBsize = PXE_DBSIZE_NOT_USED;
  27. Snp->Cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
  28. Snp->Cdb.DBaddr = PXE_DBADDR_NOT_USED;
  29. Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
  30. Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
  31. Snp->Cdb.IFnum = Snp->IfNum;
  32. Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
  33. //
  34. // Make changes to H/W UNDI Start CDB if this is
  35. // a S/W UNDI.
  36. //
  37. if (Snp->IsSwUndi) {
  38. Snp->Cdb.CPBsize = (UINT16)sizeof (PXE_CPB_START_31);
  39. Snp->Cdb.CPBaddr = (UINT64)(UINTN)Cpb31;
  40. Cpb31->Delay = (UINT64)(UINTN)&SnpUndi32CallbackDelay;
  41. Cpb31->Block = (UINT64)(UINTN)&SnpUndi32CallbackBlock;
  42. //
  43. // Virtual == Physical. This can be set to zero.
  44. //
  45. Cpb31->Virt2Phys = (UINT64)(UINTN)0;
  46. Cpb31->Mem_IO = (UINT64)(UINTN)&SnpUndi32CallbackMemio;
  47. Cpb31->Map_Mem = (UINT64)(UINTN)&SnpUndi32CallbackMap;
  48. Cpb31->UnMap_Mem = (UINT64)(UINTN)&SnpUndi32CallbackUnmap;
  49. Cpb31->Sync_Mem = (UINT64)(UINTN)&SnpUndi32CallbackSync;
  50. Cpb31->Unique_ID = (UINT64)(UINTN)Snp;
  51. }
  52. //
  53. // Issue UNDI command and check result.
  54. //
  55. DEBUG ((DEBUG_NET, "\nsnp->undi.start() "));
  56. (*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb);
  57. if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {
  58. //
  59. // UNDI could not be started. Return UNDI error.
  60. //
  61. DEBUG (
  62. (DEBUG_ERROR,
  63. "\nsnp->undi.start() %xh:%xh\n",
  64. Snp->Cdb.StatCode,
  65. Snp->Cdb.StatFlags)
  66. );
  67. return EFI_DEVICE_ERROR;
  68. }
  69. //
  70. // Set simple network state to Started and return success.
  71. //
  72. Snp->Mode.State = EfiSimpleNetworkStarted;
  73. return EFI_SUCCESS;
  74. }
  75. /**
  76. Change the state of a network interface from "stopped" to "started."
  77. This function starts a network interface. If the network interface successfully
  78. starts, then EFI_SUCCESS will be returned.
  79. @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
  80. @retval EFI_SUCCESS The network interface was started.
  81. @retval EFI_ALREADY_STARTED The network interface is already in the started state.
  82. @retval EFI_INVALID_PARAMETER This parameter was NULL or did not point to a valid
  83. EFI_SIMPLE_NETWORK_PROTOCOL structure.
  84. @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
  85. @retval EFI_UNSUPPORTED This function is not supported by the network interface.
  86. **/
  87. EFI_STATUS
  88. EFIAPI
  89. SnpUndi32Start (
  90. IN EFI_SIMPLE_NETWORK_PROTOCOL *This
  91. )
  92. {
  93. SNP_DRIVER *Snp;
  94. EFI_STATUS Status;
  95. UINTN Index;
  96. EFI_TPL OldTpl;
  97. if (This == NULL) {
  98. return EFI_INVALID_PARAMETER;
  99. }
  100. Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
  101. OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
  102. switch (Snp->Mode.State) {
  103. case EfiSimpleNetworkStopped:
  104. break;
  105. case EfiSimpleNetworkStarted:
  106. case EfiSimpleNetworkInitialized:
  107. Status = EFI_ALREADY_STARTED;
  108. goto ON_EXIT;
  109. default:
  110. Status = EFI_DEVICE_ERROR;
  111. goto ON_EXIT;
  112. }
  113. Status = PxeStart (Snp);
  114. if (EFI_ERROR (Status)) {
  115. goto ON_EXIT;
  116. }
  117. //
  118. // clear the map_list in SNP structure
  119. //
  120. for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
  121. Snp->MapList[Index].VirtualAddress = 0;
  122. Snp->MapList[Index].MapCookie = 0;
  123. }
  124. Snp->Mode.MCastFilterCount = 0;
  125. ON_EXIT:
  126. gBS->RestoreTPL (OldTpl);
  127. return Status;
  128. }