/** @file
    Implementation of transmitting a packet.

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Snp.h"

/**
  Call UNDI to create the meadia header for the given data buffer.

  @param  Snp              Pointer to SNP driver structure.
  @param  MacHeaderPtr     Address where the media header will be filled in.
  @param  HeaderSize       Size of the memory at MacHeaderPtr.
  @param  Buffer           Data buffer pointer.
  @param  BufferSize       Size of data in the Buffer
  @param  DestAddr         Address of the destination mac address buffer.
  @param  SrcAddr          Address of the source mac address buffer.
  @param  ProtocolPtr      Address of the protocol type.

  @retval EFI_SUCCESS      Successfully completed the undi call.
  @retval Other            Error return from undi call.

**/
EFI_STATUS
PxeFillHeader (
  SNP_DRIVER       *Snp,
  VOID             *MacHeaderPtr,
  UINTN            HeaderSize,
  VOID             *Buffer,
  UINTN            BufferSize,
  EFI_MAC_ADDRESS  *DestAddr,
  EFI_MAC_ADDRESS  *SrcAddr,
  UINT16           *ProtocolPtr
  )
{
  PXE_CPB_FILL_HEADER_FRAGMENTED  *Cpb;

  if (Snp->Cdb == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: Snp->Cdb is NULL\n", __func__));
    return EFI_DEVICE_ERROR;
  }

  Cpb = Snp->Cpb;
  if (SrcAddr != NULL) {
    CopyMem (
      (VOID *)Cpb->SrcAddr,
      (VOID *)SrcAddr,
      Snp->Mode.HwAddressSize
      );
  } else {
    CopyMem (
      (VOID *)Cpb->SrcAddr,
      (VOID *)&(Snp->Mode.CurrentAddress),
      Snp->Mode.HwAddressSize
      );
  }

  CopyMem (
    (VOID *)Cpb->DestAddr,
    (VOID *)DestAddr,
    Snp->Mode.HwAddressSize
    );

  //
  // we need to do the byte swapping
  //
  Cpb->Protocol = (UINT16)PXE_SWAP_UINT16 (*ProtocolPtr);

  Cpb->PacketLen      = (UINT32)(BufferSize);
  Cpb->MediaHeaderLen = (UINT16)HeaderSize;

  Cpb->FragCnt  = 2;
  Cpb->reserved = 0;

  Cpb->FragDesc[0].FragAddr = (UINT64)(UINTN)MacHeaderPtr;
  Cpb->FragDesc[0].FragLen  = (UINT32)HeaderSize;
  Cpb->FragDesc[1].FragAddr = (UINT64)(UINTN)Buffer;
  Cpb->FragDesc[1].FragLen  = (UINT32)BufferSize;

  Cpb->FragDesc[0].reserved = Cpb->FragDesc[1].reserved = 0;

  Snp->Cdb->OpCode  = PXE_OPCODE_FILL_HEADER;
  Snp->Cdb->OpFlags = PXE_OPFLAGS_FILL_HEADER_FRAGMENTED;

  Snp->Cdb->DBsize = PXE_DBSIZE_NOT_USED;
  Snp->Cdb->DBaddr = PXE_DBADDR_NOT_USED;

  Snp->Cdb->CPBsize = (UINT16)sizeof (PXE_CPB_FILL_HEADER_FRAGMENTED);
  Snp->Cdb->CPBaddr = (UINT64)(UINTN)Cpb;

  Snp->Cdb->StatCode  = PXE_STATCODE_INITIALIZE;
  Snp->Cdb->StatFlags = PXE_STATFLAGS_INITIALIZE;
  Snp->Cdb->IFnum     = Snp->IfNum;
  Snp->Cdb->Control   = PXE_CONTROL_LAST_CDB_IN_LIST;

  //
  // Issue UNDI command and check result.
  //
  DEBUG ((DEBUG_NET, "\nSnp->undi.fill_header()  "));

  (*Snp->IssueUndi32Command)((UINT64)(UINTN)Snp->Cdb);

  switch (Snp->Cdb->StatCode) {
    case PXE_STATCODE_SUCCESS:
      return EFI_SUCCESS;

    case PXE_STATCODE_INVALID_PARAMETER:
      DEBUG (
        (DEBUG_ERROR,
         "\nSnp->undi.fill_header()  %xh:%xh\n",
         Snp->Cdb->StatFlags,
         Snp->Cdb->StatCode)
        );

      return EFI_INVALID_PARAMETER;

    default:
      DEBUG (
        (DEBUG_ERROR,
         "\nSnp->undi.fill_header()  %xh:%xh\n",
         Snp->Cdb->StatFlags,
         Snp->Cdb->StatCode)
        );

      return EFI_DEVICE_ERROR;
  }
}

/**
  This routine calls undi to transmit the given data buffer

  @param  Snp                 pointer to SNP driver structure
  @param  Buffer           data buffer pointer
  @param  BufferSize        Size of data in the Buffer

  @retval EFI_SUCCESS         if successfully completed the undi call
  @retval Other               error return from undi call.

**/
EFI_STATUS
PxeTransmit (
  SNP_DRIVER  *Snp,
  VOID        *Buffer,
  UINTN       BufferSize
  )
{
  PXE_CPB_TRANSMIT  *Cpb;
  EFI_STATUS        Status;

  if (Snp->Cdb == NULL) {
    DEBUG ((DEBUG_ERROR, "%a: Snp->Cdb is NULL\n", __func__));
    return EFI_DEVICE_ERROR;
  }

  Cpb            = Snp->Cpb;
  Cpb->FrameAddr = (UINT64)(UINTN)Buffer;
  Cpb->DataLen   = (UINT32)BufferSize;

  Cpb->MediaheaderLen = 0;
  Cpb->reserved       = 0;

  Snp->Cdb->OpFlags = PXE_OPFLAGS_TRANSMIT_WHOLE;

  Snp->Cdb->CPBsize = (UINT16)sizeof (PXE_CPB_TRANSMIT);
  Snp->Cdb->CPBaddr = (UINT64)(UINTN)Cpb;

  Snp->Cdb->OpCode = PXE_OPCODE_TRANSMIT;
  Snp->Cdb->DBsize = PXE_DBSIZE_NOT_USED;
  Snp->Cdb->DBaddr = PXE_DBADDR_NOT_USED;

  Snp->Cdb->StatCode  = PXE_STATCODE_INITIALIZE;
  Snp->Cdb->StatFlags = PXE_STATFLAGS_INITIALIZE;
  Snp->Cdb->IFnum     = Snp->IfNum;
  Snp->Cdb->Control   = PXE_CONTROL_LAST_CDB_IN_LIST;

  //
  // Issue UNDI command and check result.
  //
  DEBUG ((DEBUG_NET, "\nSnp->undi.transmit()  "));
  DEBUG ((DEBUG_NET, "\nSnp->Cdb->OpCode  == %x", Snp->Cdb->OpCode));
  DEBUG ((DEBUG_NET, "\nSnp->Cdb->CPBaddr == %LX", Snp->Cdb->CPBaddr));
  DEBUG ((DEBUG_NET, "\nSnp->Cdb->DBaddr  == %LX", Snp->Cdb->DBaddr));
  DEBUG ((DEBUG_NET, "\nCpb->FrameAddr   == %LX\n", Cpb->FrameAddr));

  (*Snp->IssueUndi32Command)((UINT64)(UINTN)Snp->Cdb);

  DEBUG ((DEBUG_NET, "\nexit Snp->undi.transmit()  "));

  //
  // we will unmap the buffers in get_status call, not here
  //
  switch (Snp->Cdb->StatCode) {
    case PXE_STATCODE_SUCCESS:
      return EFI_SUCCESS;

    case PXE_STATCODE_BUFFER_FULL:
    case PXE_STATCODE_QUEUE_FULL:
    case PXE_STATCODE_BUSY:
      Status = EFI_NOT_READY;
      DEBUG (
        (DEBUG_NET,
         "\nSnp->undi.transmit()  %xh:%xh\n",
         Snp->Cdb->StatFlags,
         Snp->Cdb->StatCode)
        );
      break;

    default:
      DEBUG (
        (DEBUG_ERROR,
         "\nSnp->undi.transmit()  %xh:%xh\n",
         Snp->Cdb->StatFlags,
         Snp->Cdb->StatCode)
        );
      Status = EFI_DEVICE_ERROR;
  }

  return Status;
}

/**
  Places a packet in the transmit queue of a network interface.

  This function places the packet specified by Header and Buffer on the transmit
  queue. If HeaderSize is nonzero and HeaderSize is not equal to
  This->Mode->MediaHeaderSize, then EFI_INVALID_PARAMETER will be returned. If
  BufferSize is less than This->Mode->MediaHeaderSize, then EFI_BUFFER_TOO_SMALL
  will be returned. If Buffer is NULL, then EFI_INVALID_PARAMETER will be
  returned. If HeaderSize is nonzero and DestAddr or Protocol is NULL, then
  EFI_INVALID_PARAMETER will be returned. If the transmit engine of the network
  interface is busy, then EFI_NOT_READY will be returned. If this packet can be
  accepted by the transmit engine of the network interface, the packet contents
  specified by Buffer will be placed on the transmit queue of the network
  interface, and EFI_SUCCESS will be returned. GetStatus() can be used to
  determine when the packet has actually been transmitted. The contents of the
  Buffer must not be modified until the packet has actually been transmitted.
  The Transmit() function performs nonblocking I/O. A caller who wants to perform
  blocking I/O, should call Transmit(), and then GetStatus() until the
  transmitted buffer shows up in the recycled transmit buffer.
  If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.

  @param This       A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
  @param HeaderSize The size, in bytes, of the media header to be filled in by the
                    Transmit() function. If HeaderSize is nonzero, then it must
                    be equal to This->Mode->MediaHeaderSize and the DestAddr and
                    Protocol parameters must not be NULL.
  @param BufferSize The size, in bytes, of the entire packet (media header and
                    data) to be transmitted through the network interface.
  @param Buffer     A pointer to the packet (media header followed by data) to be
                    transmitted. This parameter cannot be NULL. If HeaderSize is
                    zero, then the media header in Buffer must already be filled
                    in by the caller. If HeaderSize is nonzero, then the media
                    header will be filled in by the Transmit() function.
  @param SrcAddr    The source HW MAC address. If HeaderSize is zero, then this
                    parameter is ignored. If HeaderSize is nonzero and SrcAddr
                    is NULL, then This->Mode->CurrentAddress is used for the
                    source HW MAC address.
  @param DestAddr   The destination HW MAC address. If HeaderSize is zero, then
                    this parameter is ignored.
  @param Protocol   The type of header to build. If HeaderSize is zero, then this
                    parameter is ignored. See RFC 1700, section "Ether Types,"
                    for examples.

  @retval EFI_SUCCESS           The packet was placed on the transmit queue.
  @retval EFI_NOT_STARTED       The network interface has not been started.
  @retval EFI_NOT_READY         The network interface is too busy to accept this
                                transmit request.
  @retval EFI_BUFFER_TOO_SMALL  The BufferSize parameter is too small.
  @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported
                                value.
  @retval EFI_DEVICE_ERROR      The command could not be sent to the network interface.
  @retval EFI_UNSUPPORTED       This function is not supported by the network interface.

**/
EFI_STATUS
EFIAPI
SnpUndi32Transmit (
  IN EFI_SIMPLE_NETWORK_PROTOCOL  *This,
  IN UINTN                        HeaderSize,
  IN UINTN                        BufferSize,
  IN VOID                         *Buffer,
  IN EFI_MAC_ADDRESS              *SrcAddr   OPTIONAL,
  IN EFI_MAC_ADDRESS              *DestAddr  OPTIONAL,
  IN UINT16                       *Protocol  OPTIONAL
  )
{
  SNP_DRIVER  *Snp;
  EFI_STATUS  Status;
  EFI_TPL     OldTpl;

  if (This == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);

  if (Snp == NULL) {
    return EFI_DEVICE_ERROR;
  }

  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);

  switch (Snp->Mode.State) {
    case EfiSimpleNetworkInitialized:
      break;

    case EfiSimpleNetworkStopped:
      Status = EFI_NOT_STARTED;
      goto ON_EXIT;

    default:
      Status = EFI_DEVICE_ERROR;
      goto ON_EXIT;
  }

  if (Buffer == NULL) {
    Status = EFI_INVALID_PARAMETER;
    goto ON_EXIT;
  }

  if (BufferSize < Snp->Mode.MediaHeaderSize) {
    Status = EFI_BUFFER_TOO_SMALL;
    goto ON_EXIT;
  }

  //
  // if the HeaderSize is non-zero, we need to fill up the header and for that
  // we need the destination address and the protocol
  //
  if (HeaderSize != 0) {
    if ((HeaderSize != Snp->Mode.MediaHeaderSize) || (DestAddr == 0) || (Protocol == 0)) {
      Status = EFI_INVALID_PARAMETER;
      goto ON_EXIT;
    }

    Status = PxeFillHeader (
               Snp,
               Buffer,
               HeaderSize,
               (UINT8 *)Buffer + HeaderSize,
               BufferSize - HeaderSize,
               DestAddr,
               SrcAddr,
               Protocol
               );

    if (EFI_ERROR (Status)) {
      goto ON_EXIT;
    }
  }

  Status = PxeTransmit (Snp, Buffer, BufferSize);

ON_EXIT:
  gBS->RestoreTPL (OldTpl);

  return Status;
}
