/** @file
  IPMI Command - NetFnApp.

  Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved.<BR>
  Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <PiPei.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/IpmiLib.h>

#include <IndustryStandard/Ipmi.h>

/**
  This function is used to retrieve device ID.

  @param [out]  DeviceId  The pointer to receive IPMI_GET_DEVICE_ID_RESPONSE.

  @retval EFI_STATUS   See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiGetDeviceId (
  OUT IPMI_GET_DEVICE_ID_RESPONSE  *DeviceId
  )
{
  EFI_STATUS  Status;
  UINT32      DataSize;

  DataSize = sizeof (*DeviceId);
  Status   = IpmiSubmitCommand (
               IPMI_NETFN_APP,
               IPMI_APP_GET_DEVICE_ID,
               NULL,
               0,
               (VOID *)DeviceId,
               &DataSize
               );
  return Status;
}

/**
  This function returns device self test results

  @param [out]  SelfTestResult  The pointer to receive IPMI_SELF_TEST_RESULT_RESPONSE.

  @retval EFI_STATUS   See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiGetSelfTestResult (
  OUT IPMI_SELF_TEST_RESULT_RESPONSE  *SelfTestResult
  )
{
  EFI_STATUS  Status;
  UINT32      DataSize;

  DataSize = sizeof (*SelfTestResult);
  Status   = IpmiSubmitCommand (
               IPMI_NETFN_APP,
               IPMI_APP_GET_SELFTEST_RESULTS,
               NULL,
               0,
               (VOID *)SelfTestResult,
               &DataSize
               );
  return Status;
}

/**
  This function is used for starting and restarting the Watchdog
  Timer from the initial countdown value that was specified in
  the Set Watchdog Timer command the watchdog timer

  @param [out]  CompletionCode  IPMI completetion code, refer to Ipmi.h.

  @retval EFI_STATUS   See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiResetWatchdogTimer (
  OUT UINT8  *CompletionCode
  )
{
  EFI_STATUS  Status;
  UINT32      DataSize;

  DataSize = sizeof (*CompletionCode);
  Status   = IpmiSubmitCommand (
               IPMI_NETFN_APP,
               IPMI_APP_RESET_WATCHDOG_TIMER,
               NULL,
               0,
               (VOID *)CompletionCode,
               &DataSize
               );
  return Status;
}

/**
  This function  is used for initializing and configuring
  the watchdog timer.

  @param [in]   SetWatchdogTimer  Pointer to receive IPMI_SET_WATCHDOG_TIMER_REQUEST.
  @param [out]  CompletionCode    IPMI completetion code, refer to Ipmi.h.

  @retval EFI_STATUS   See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiSetWatchdogTimer (
  IN  IPMI_SET_WATCHDOG_TIMER_REQUEST  *SetWatchdogTimer,
  OUT UINT8                            *CompletionCode
  )
{
  EFI_STATUS  Status;
  UINT32      DataSize;

  DataSize = sizeof (*CompletionCode);
  Status   = IpmiSubmitCommand (
               IPMI_NETFN_APP,
               IPMI_APP_SET_WATCHDOG_TIMER,
               (VOID *)SetWatchdogTimer,
               sizeof (*SetWatchdogTimer),
               (VOID *)CompletionCode,
               &DataSize
               );
  return Status;
}

/**
  This function retrieves the current settings and present
  countdown of the watchdog timer.

  @param [out]  GetWatchdogTimer  Pointer to receive IPMI_GET_WATCHDOG_TIMER_RESPONSE.

  @retval EFI_STATUS   See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiGetWatchdogTimer (
  OUT IPMI_GET_WATCHDOG_TIMER_RESPONSE  *GetWatchdogTimer
  )
{
  EFI_STATUS  Status;
  UINT32      DataSize;

  DataSize = sizeof (*GetWatchdogTimer);
  Status   = IpmiSubmitCommand (
               IPMI_NETFN_APP,
               IPMI_APP_GET_WATCHDOG_TIMER,
               NULL,
               0,
               (VOID *)GetWatchdogTimer,
               &DataSize
               );
  return Status;
}

/**
  This function enables message reception into Message Buffers,
  and any interrupt associated with that buffer getting full.

  @param [in]   SetBmcGlobalEnables  Pointer receive to IPMI_SET_BMC_GLOBAL_ENABLES_REQUEST.
  @param [out]  CompletionCode      IPMI completetion code refer to Ipmi.h.

  @retval EFI_STATUS   See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiSetBmcGlobalEnables (
  IN  IPMI_SET_BMC_GLOBAL_ENABLES_REQUEST  *SetBmcGlobalEnables,
  OUT UINT8                                *CompletionCode
  )
{
  EFI_STATUS  Status;
  UINT32      DataSize;

  DataSize = sizeof (*CompletionCode);
  Status   = IpmiSubmitCommand (
               IPMI_NETFN_APP,
               IPMI_APP_SET_BMC_GLOBAL_ENABLES,
               (VOID *)SetBmcGlobalEnables,
               sizeof (*SetBmcGlobalEnables),
               (VOID *)CompletionCode,
               &DataSize
               );
  return Status;
}

/**
  This function retrieves the present setting of the Global Enables

  @param [out]  GetBmcGlobalEnables  Pointer to receive IPMI_GET_BMC_GLOBAL_ENABLES_RESPONSE.

  @retval EFI_STATUS   See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiGetBmcGlobalEnables (
  OUT IPMI_GET_BMC_GLOBAL_ENABLES_RESPONSE  *GetBmcGlobalEnables
  )
{
  EFI_STATUS  Status;
  UINT32      DataSize;

  DataSize = sizeof (*GetBmcGlobalEnables);
  Status   = IpmiSubmitCommand (
               IPMI_NETFN_APP,
               IPMI_APP_GET_BMC_GLOBAL_ENABLES,
               NULL,
               0,
               (VOID *)GetBmcGlobalEnables,
               &DataSize
               );
  return Status;
}

/**
  This function is used to flush unread data from the Receive
  Message Queue or Event Message Buffer

  @param [in]   ClearMessageFlagsRequest IPMI_CLEAR_MESSAGE_FLAGS_REQUEST
  @param [out]  CompletionCode           IPMI completetion code, refer to Ipmi.h.

  @retval EFI_STATUS   See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiClearMessageFlags (
  IN  IPMI_CLEAR_MESSAGE_FLAGS_REQUEST  *ClearMessageFlagsRequest,
  OUT UINT8                             *CompletionCode
  )
{
  EFI_STATUS  Status;
  UINT32      DataSize;

  DataSize = sizeof (*CompletionCode);
  Status   = IpmiSubmitCommand (
               IPMI_NETFN_APP,
               IPMI_APP_CLEAR_MESSAGE_FLAGS,
               (VOID *)ClearMessageFlagsRequest,
               sizeof (*ClearMessageFlagsRequest),
               (VOID *)CompletionCode,
               &DataSize
               );
  return Status;
}

/**
  This function is used to retrieve the present message available states.

  @param  [out]  GetMessageFlagsResponse  Pointer to receive IPMI_GET_MESSAGE_FLAGS_RESPONSE

  @retval EFI_STATUS   See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiGetMessageFlags (
  OUT IPMI_GET_MESSAGE_FLAGS_RESPONSE  *GetMessageFlagsResponse
  )
{
  EFI_STATUS  Status;
  UINT32      DataSize;

  DataSize = sizeof (*GetMessageFlagsResponse);
  Status   = IpmiSubmitCommand (
               IPMI_NETFN_APP,
               IPMI_APP_GET_MESSAGE_FLAGS,
               NULL,
               0,
               (VOID *)GetMessageFlagsResponse,
               &DataSize
               );
  return Status;
}

/**
  This function is used to get data from the Receive Message Queue.

  @param [out]      GetMessageResponse      Pointer to receive IPMI_GET_MESSAGE_RESPONSE.
  @param [in, out]  GetMessageResponseSize  When in, which is the expected size of
                                            response. When out, which is the actual
                                            size returned.

  @retval EFI_STATUS   See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiGetMessage (
  OUT IPMI_GET_MESSAGE_RESPONSE  *GetMessageResponse,
  IN OUT UINT32                  *GetMessageResponseSize
  )
{
  EFI_STATUS  Status;

  Status = IpmiSubmitCommand (
             IPMI_NETFN_APP,
             IPMI_APP_GET_MESSAGE,
             NULL,
             0,
             (VOID *)GetMessageResponse,
             GetMessageResponseSize
             );
  return Status;
}

/**
  This function is used for bridging IPMI messages between channels,
  and between the system management software (SMS) and a given channel

  @param [in]   SendMessageRequest       Pointer to IPMI_SEND_MESSAGE_REQUEST.
  @param [in]   SendMessageRequestSize   Size of entire SendMessageRequestSize.
  @param [out]  SendMessageResponse      Pointer to receive IPMI_SEND_MESSAGE_RESPONSE.
  @param [in, out]  SendMessageResponseSize  When in, which is the expected size of
                                         response. When out, which is the actual
                                         size returned.

  @retval EFI_STATUS   See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiSendMessage (
  IN  IPMI_SEND_MESSAGE_REQUEST   *SendMessageRequest,
  IN  UINT32                      SendMessageRequestSize,
  OUT IPMI_SEND_MESSAGE_RESPONSE  *SendMessageResponse,
  IN OUT UINT32                   *SendMessageResponseSize
  )
{
  EFI_STATUS  Status;

  Status = IpmiSubmitCommand (
             IPMI_NETFN_APP,
             IPMI_APP_SEND_MESSAGE,
             (VOID *)SendMessageRequest,
             SendMessageRequestSize,
             (VOID *)SendMessageResponse,
             SendMessageResponseSize
             );
  return Status;
}

/**
  This function gets the system UUID.

  @param[out] SystemGuid   The pointer to retrieve system UUID.

  @retval EFI_SUCCESS               UUID is returned.
  @retval EFI_INVALID_PARAMETER     SystemGuid is a NULL pointer.
  @retval Others                    See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiGetSystemUuid (
  OUT EFI_GUID  *SystemGuid
  )
{
  EFI_STATUS                     Status;
  UINT32                         RequestSize;
  UINT32                         ResponseSize;
  IPMI_GET_SYSTEM_UUID_RESPONSE  GetSystemUuidResponse;

  if (SystemGuid == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  RequestSize  = 0;
  ResponseSize = sizeof (IPMI_GET_SYSTEM_UUID_RESPONSE);
  Status       = IpmiSubmitCommand (
                   IPMI_NETFN_APP,
                   IPMI_APP_GET_SYSTEM_GUID,
                   (VOID *)NULL,
                   RequestSize,
                   (VOID *)&GetSystemUuidResponse,
                   &ResponseSize
                   );
  if (!EFI_ERROR (Status) && (GetSystemUuidResponse.CompletionCode == IPMI_COMP_CODE_NORMAL)) {
    CopyMem (
      (VOID *)SystemGuid,
      (VOID *)&GetSystemUuidResponse.SystemUuid,
      sizeof (EFI_GUID)
      );
  } else {
    return EFI_DEVICE_ERROR;
  }

  return Status;
}

/**
  This function gets the channel information.

  @param[in]   GetChannelInfoRequest          The get channel information request.
  @param[out]  GetChannelInfoResponse         The get channel information response.
  @param[out]  GetChannelInfoResponseSize     When input, the expected size of response.
                                              When output, the exact size of the returned
                                              response.

  @retval EFI_SUCCESS            Get channel information successfully.
  @retval EFI_INVALID_PARAMETER  One of the given input parameters is invalid.
  @retval Others                 See the return values of IpmiSubmitCommand () function.

**/
EFI_STATUS
EFIAPI
IpmiGetChannelInfo (
  IN  IPMI_GET_CHANNEL_INFO_REQUEST   *GetChannelInfoRequest,
  OUT IPMI_GET_CHANNEL_INFO_RESPONSE  *GetChannelInfoResponse,
  OUT UINT32                          *GetChannelInfoResponseSize
  )
{
  EFI_STATUS  Status;

  if ((GetChannelInfoRequest == NULL) ||
      (GetChannelInfoResponse == NULL) ||
      (GetChannelInfoResponseSize == NULL))
  {
    return EFI_INVALID_PARAMETER;
  }

  *GetChannelInfoResponseSize = sizeof (IPMI_GET_CHANNEL_INFO_RESPONSE);
  Status                      = IpmiSubmitCommand (
                                  IPMI_NETFN_APP,
                                  IPMI_APP_GET_CHANNEL_INFO,
                                  (UINT8 *)GetChannelInfoRequest,
                                  sizeof (IPMI_GET_CHANNEL_INFO_REQUEST),
                                  (UINT8 *)GetChannelInfoResponse,
                                  GetChannelInfoResponseSize
                                  );
  return Status;
}

/**
  This function gets system interface capability

  @param[in]  InterfaceCapabilityRequest    Get system interface capability request.
  @param[out] InterfaceCapabilityResponse   The response of system interface capability.
                                            That is caller's responsibility to allocate
                                            memory for the response data.

  @retval EFI_SUCCESS            Command is sent successfully.
  @retval Other                  Failure.

**/
EFI_STATUS
EFIAPI
IpmiGetSystemInterfaceCapability (
  IN  IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_REQUEST   *InterfaceCapabilityRequest,
  OUT IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_RESPONSE  *InterfaceCapabilityResponse
  )
{
  UINT8       InterfaceType;
  UINT32      ResponseSize;
  UINT32      ActualResponseSize;
  UINT8       *ResponsePtr;
  EFI_STATUS  Status;

  if (InterfaceCapabilityRequest == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  InterfaceType = InterfaceCapabilityRequest->Bits.InterfaceType;
  if ((InterfaceType != IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_INTERFACE_TYPE_SSIF) &&
      (InterfaceType != IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_INTERFACE_TYPE_KCS) &&
      (InterfaceType != IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_INTERFACE_TYPE_SMIC))
  {
    DEBUG ((DEBUG_ERROR, "%a: Unsupported given system interface type = 0x%x.\n", __func__, InterfaceType));
    return EFI_INVALID_PARAMETER;
  }

  if (InterfaceType == IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_INTERFACE_TYPE_SSIF) {
    ResponseSize = sizeof (IPMI_GET_SYSTEM_INTERFACE_SSIF_CAPABILITIES_RESPONSE);
    ResponsePtr  = (UINT8 *)InterfaceCapabilityResponse->InterfaceSsifCapability;
  } else {
    ResponseSize = sizeof (IPMI_GET_SYSTEM_INTERFACE_KCS_SMIC_CAPABILITIES_RESPONSE);
    ResponsePtr  = (UINT8 *)InterfaceCapabilityResponse->InterfaceKcsSmicCapability;
  }

  ActualResponseSize = ResponseSize;
  Status             = IpmiSubmitCommand (
                         IPMI_NETFN_APP,
                         IPMI_APP_GET_SYSTEM_INTERFACE_CAPABILITIES,
                         (UINT8 *)InterfaceCapabilityRequest,
                         sizeof (IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_REQUEST),
                         ResponsePtr,
                         &ActualResponseSize
                         );
  if (ActualResponseSize != ResponseSize) {
    DEBUG ((
      DEBUG_ERROR,
      "%a: The expected response size 0x%x is not equal to the returned size 0x%x.\n",
      __func__,
      ResponseSize,
      ActualResponseSize
      ));
  }

  return Status;
}
