mnpconfig.c

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,577 行 · 第 1/3 页

C
1,577
字号

  Initialize the mnp instance context data.

Arguments:

  MnpServiceData - Pointer to the mnp service context data.
  Instance       - Pointer to the mnp instance context data to initialize.

Returns:

  None.

--*/
{
  NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
  ASSERT (Instance != NULL);

  //
  // Set the signature.
  //
  Instance->Signature = MNP_INSTANCE_DATA_SIGNATURE;

  //
  // Copy the MNP Protocol interfaces from the template.
  //
  Instance->ManagedNetwork = mMnpProtocolTemplate;

  //
  // Copy the default config data.
  //
  Instance->ConfigData = mMnpDefaultConfigData;

  //
  // Initialize the locks.
  //
  NET_GLOBAL_LOCK_INIT (&Instance->RxLock);

  //
  // Initialize the lists.
  //
  NetListInit (&Instance->GroupCtrlBlkList);
  NetListInit (&Instance->RcvdPacketQueue);
  NetListInit (&Instance->RxDeliveredPacketQueue);

  //
  // Initialize the RxToken Map.
  //
  NetMapInit (&Instance->RxTokenMap);

  //
  // Save the MnpServiceData info.
  //
  Instance->MnpServiceData = MnpServiceData;
}

EFI_STATUS
MnpTokenExist (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Arg
  )
/*++

Routine Description:

  Check whether the token specified by Arg maches the token in Item.

Arguments:

  Map   - Pointer to the NET_MAP.
  Item  - Pointer to the NET_MAP_ITEM
  Arg   - Pointer to the Arg, it's a pointer to the token to check.

Returns:

  EFI_SUCCESS       - The token specified by Arg is different from the token in Item.
  EFI_ACCESS_DENIED - The token specified by Arg is the same as that in Item.

--*/
{
  EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *Token;
  EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *TokenInItem;

  Token       = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *) Arg;
  TokenInItem = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *) Item->Key;

  if ((Token == TokenInItem) || (Token->Event == TokenInItem->Event)) {
    //
    // The token is the same either the two tokens equals or the Events in
    // the two tokens are the same.
    //
    return EFI_ACCESS_DENIED;
  }

  return EFI_SUCCESS;
}

EFI_STATUS
MnpCancelTokens (
  IN NET_MAP       *Map,
  IN NET_MAP_ITEM  *Item,
  IN VOID          *Arg
  )
/*++

Routine Description:

  Cancel the token specified by Arg if it matches the token in Item.

Arguments:

  Map   - Pointer to the NET_MAP.
  Item  - Pointer to the NET_MAP_ITEM
  Arg   - Pointer to the Arg, it's a pointer to the token to cancel.

Returns:

  EFI_SUCCESS - The Arg is NULL, and the token in Item is cancelled, or
                the Arg isn't NULL, and the token in Item is different from
                the Arg.
  EFI_ABORTED - The Arg isn't NULL, the token in Item mathces the Arg, and the
                token is cancelled.

--*/
{
  EFI_MANAGED_NETWORK_COMPLETION_TOKEN  *TokenToCancel;

  if ((Arg != NULL) && (Item->Key != Arg)) {
    //
    // The token in Item is not the token specified by Arg.
    //
    return EFI_SUCCESS;
  }

  TokenToCancel         = (EFI_MANAGED_NETWORK_COMPLETION_TOKEN *) Item->Key;

  //
  // Cancel this token with status set to EFI_ABORTED.
  //
  TokenToCancel->Status = EFI_ABORTED;
  gBS->SignalEvent (TokenToCancel->Event);

  //
  // Remove the item from the map.
  //
  NetMapRemoveItem (Map, Item, NULL);

  if (Arg != NULL) {
    //
    // Only abort the token specified by Arg if Arg isn't NULL.
    //
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

STATIC
EFI_STATUS
MnpStartSnp (
  IN EFI_SIMPLE_NETWORK_PROTOCOL  *Snp
  )
/*++

Routine Description:

  Start and initialize the simple network.

Arguments:

  Snp - Pointer to the simple network protocol.

Returns:

  EFI_SUCCESS - The simple network protocol is started.
  Other       - Some error occurs.

--*/
{
  EFI_STATUS  Status;

  ASSERT (Snp != NULL);

  //
  // Start the simple network.
  //
  Status = Snp->Start (Snp);

  if (!EFI_ERROR (Status)) {
    //
    // Initialize the simple network.
    //
    Status  = Snp->Initialize (Snp, 0, 0);
  }

  return Status;
}

STATIC
EFI_STATUS
MnpStopSnp (
  IN EFI_SIMPLE_NETWORK_PROTOCOL  *Snp
  )
/*++

Routine Description:

  Stop the simple network.

Arguments:

  Snp - Pointer to the simple network protocol.

Returns:

  EFI_SUCCESS - The simple network is stopped.
  Other       - Some error occurs.
  
--*/
{
  EFI_STATUS  Status;

  ASSERT (Snp != NULL);

  //
  // Shut down the simple network.
  //
  Status = Snp->Shutdown (Snp);

  if (!EFI_ERROR (Status)) {
    //
    // Stop the simple network.
    //
    Status = Snp->Stop (Snp);
  }

  return Status;
}

STATIC
EFI_STATUS
MnpStart (
  IN MNP_SERVICE_DATA  *MnpServiceData,
  IN BOOLEAN           IsConfigUpdate,
  IN BOOLEAN           EnableSystemPoll
  )
/*++

Routine Description:

  Start the managed network, this function is called when one instance is configured
  or reconfigured.

Arguments:

  MnpServiceData   - Pointer to the mnp service context data.
  IsConfigUpdate   - The instance is reconfigured or it's the first time 
                     the instanced is configured.
  EnableSystemPoll - Enable the system polling or not.

Returns:

  EFI_SUCCESS - The managed network is started and some configuration is updated.
  Other       - Some error occurs.

--*/
{
  EFI_STATUS      Status;
  EFI_TIMER_DELAY TimerOpType;

  NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);

  Status = EFI_SUCCESS;

  if (!IsConfigUpdate) {
    //
    // If it's not a configuration update, increase the configured children number.
    //
    MnpServiceData->ConfiguredChildrenNumber++;

    if (MnpServiceData->ConfiguredChildrenNumber == 1) {
      //
      // It's the first configured child, start the simple network.
      //
      Status = MnpStartSnp (MnpServiceData->Snp);
      if (EFI_ERROR (Status)) {

        MNP_DEBUG_ERROR (("MnpStart: MnpStartSnp failed, %r.\n", Status));
        goto ErrorExit;
      }

      //
      // Start the timeout timer.
      //
      Status = gBS->SetTimer (
                      MnpServiceData->TimeoutCheckTimer,
                      TimerPeriodic,
                      MNP_TIMEOUT_CHECK_INTERVAL
                      );
      if (EFI_ERROR (Status)) {

        MNP_DEBUG_ERROR (
          ("MnpStart, gBS->SetTimer for TimeoutCheckTimer ""%r.\n",
          Status)
          );
        goto ErrorExit;
      }
    }
  }

  if (MnpServiceData->EnableSystemPoll ^ EnableSystemPoll) {
    //
    // The EnableSystemPoll differs with the current state, disable or enable
    // the system poll.
    //
    TimerOpType = EnableSystemPoll ? TimerPeriodic : TimerCancel;

    Status      = gBS->SetTimer (MnpServiceData->PollTimer, TimerOpType, MNP_SYS_POLL_INTERVAL);
    if (EFI_ERROR (Status)) {

      MNP_DEBUG_ERROR (("MnpStart: gBS->SetTimer for PollTimer failed, %r.\n", Status));
      goto ErrorExit;
    }

    MnpServiceData->EnableSystemPoll = EnableSystemPoll;
  }

  //
  // Change the receive filters if need.
  //
  Status = MnpConfigReceiveFilters (MnpServiceData);

ErrorExit:

  return Status;
}

STATIC
EFI_STATUS
MnpStop (
  IN MNP_SERVICE_DATA  *MnpServiceData
  )
/*++

Routine Description:

  Stop the managed network.

Arguments:

  MnpServiceData - Pointer to the mnp service context data.

Returns:

  EFI_SUCCESS - The managed network is stopped.
  Other       - Some error occurs.

--*/
{
  EFI_STATUS  Status;

  NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
  ASSERT (MnpServiceData->ConfiguredChildrenNumber > 0);

  //
  // Configure the receive filters.
  //
  MnpConfigReceiveFilters (MnpServiceData);

  //
  // Decrease the children number.
  //
  MnpServiceData->ConfiguredChildrenNumber--;

  if (MnpServiceData->ConfiguredChildrenNumber > 0) {
    //
    // If there are other configured chilren, return and keep the timers and
    // simple network unchanged.
    //
    return EFI_SUCCESS;
  }

  //
  // No configured children now.  
  //

  if (MnpServiceData->EnableSystemPoll) {
    //
    //  The system poll in on, cancel the poll timer.
    //
    Status  = gBS->SetTimer (MnpServiceData->PollTimer, TimerCancel, 0);
    MnpServiceData->EnableSystemPoll = FALSE;
  }

  //
  // Cancel the timeout timer.
  //
  Status  = gBS->SetTimer (MnpServiceData->TimeoutCheckTimer, TimerCancel, 0);

  //
  // Stop the simple network.
  //
  Status  = MnpStopSnp (MnpServiceData->Snp);

  return Status;
}

VOID
MnpFlushRcvdDataQueue (
  IN MNP_INSTANCE_DATA  *Instance
  )
/*++

Routine Description:

  Flush the instance's received data.

Arguments:

  Instance - Pointer to the mnp instance context data.

Returns:

  None.

--*/
{
  MNP_RXDATA_WRAP *RxDataWrap;

  NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);

  if (EFI_ERROR (NET_TRYLOCK (&Instance->RxLock))) {
    return ;
  }

  while (!NetListIsEmpty (&Instance->RcvdPacketQueue)) {
    //
    // Remove all the Wraps.
    //
    RxDataWrap = NET_LIST_HEAD (&Instance->RcvdPacketQueue, MNP_RXDATA_WRAP, WrapEntry);

    //
    // Recycle the RxDataWrap.
    //
    MnpRecycleRxData (NULL, (VOID *) RxDataWrap);
    Instance->RcvdPacketQueueSize--;
  }

  ASSERT (Instance->RcvdPacketQueueSize == 0);

  NET_UNLOCK (&Instance->RxLock);
}

EFI_STATUS
MnpConfigureInstance (
  IN MNP_INSTANCE_DATA                *Instance,
  IN EFI_MANAGED_NETWORK_CONFIG_DATA  *ConfigData OPTIONAL
  )
/*++

Routine Description:

  Configure the Instance using ConfigData.

Arguments:

  Instance   - Pointer to the mnp instance context data.
  ConfigData - Pointer to the configuration data used to configure the isntance.

Returns:

  EFI_SUCCESS     - The Instance is configured.
  EFI_UNSUPPORTED - EnableReceiveTimestamps is on and the implementation doesn't
                      support it.
  Other           - Some error occurs.

--*/
{
  EFI_STATUS                      Status;
  MNP_SERVICE_DATA                *MnpServiceData;
  EFI_MANAGED_NETWORK_CONFIG_DATA *OldConfigData;
  EFI_MANAGED_NETWORK_CONFIG_DATA *NewConfigData;
  BOOLEAN                         IsConfigUpdate;

  NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);

  if ((ConfigData != NULL) && ConfigData->EnableReceiveTimestamps) {
    //
    // Don't support timestamp.
    //
    return EFI_UNSUPPORTED;
  }

  Status          = EFI_SUCCESS;

  MnpServiceData  = Instance->MnpServiceData;
  NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);

  IsConfigUpdate  = (BOOLEAN) ((Instance->Configured) && (ConfigData != NULL));

  OldConfigData   = &Instance->ConfigData;
  NewConfigData   = ConfigData;
  if (NewConfigData == NULL) {
    //
    // Restore back the default config data if a reset of this instance
    // is required.
    //
    NewConfigData = &mMnpDefaultConfigData;
  }

  //
  // Reset the instance's receive filter.
  //
  Instance->ReceiveFilter = 0;

  //
  // Clear the receive counters according to the old ConfigData.
  //
  if (OldConfigData->EnableUnicastReceive) {
    MnpServiceData->UnicastCount--;
  }

  if (OldConfigData->EnableMulticastReceive) {
    MnpServiceData->MulticastCount--;
  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?