/*++
Copyright (c) 2006, Intel Corporation                                                         
All rights reserved. This program and the accompanying materials                          
are licensed and made available under the terms and conditions of the BSD License         
which accompanies this distribution.  The full text of the license may be found at        
http://opensource.org/licenses/bsd-license.php                                            
                                                                                          
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             

Module name:
  
    transmit.c

Abstract:

Revision history:
  2000-Feb-03 M(f)J   Genesis.
--*/


#include "Snp.h"

EFI_STATUS
pxe_fillheader (
  SNP_DRIVER      *snp,
  VOID            *MacHeaderPtr,
  UINTN           MacHeaderSize,
  VOID            *BufferPtr,
  UINTN           BufferLength,
  EFI_MAC_ADDRESS *DestinationAddrPtr,
  EFI_MAC_ADDRESS *SourceAddrPtr,
  UINT16          *ProtocolPtr
  )
/*++

Routine Description:
 This routine calls undi to create the meadia header for the given data buffer.
 
Arguments:
 snp - pointer to SNP driver structure
 MacHeaderPtr - address where the media header will be filled in.
 MacHeaderSize - size of the memory at MacHeaderPtr
 BufferPtr - data buffer pointer
 BufferLength - Size of data in the BufferPtr
 DestinationAddrPtr - address of the destination mac address buffer
 SourceAddrPtr - address of the source mac address buffer
 ProtocolPtr - address of the protocol type
 
Returns:
 EFI_SUCCESS - if successfully completed the undi call
 Other - error return from undi call.
 
--*/
{
  PXE_CPB_FILL_HEADER_FRAGMENTED  *cpb;
  EFI_STATUS                      Status;
  struct s_v2p                    *pkt_v2p;
  UINT64                          TempData;

  cpb = snp->cpb;
  if (SourceAddrPtr) {
    CopyMem (
      (VOID *) cpb->SrcAddr,
      (VOID *) SourceAddrPtr,
      snp->mode.HwAddressSize
      );
  } else {
    CopyMem (
      (VOID *) cpb->SrcAddr,
      (VOID *) &(snp->mode.CurrentAddress),
      snp->mode.HwAddressSize
      );
  }

  CopyMem (
    (VOID *) cpb->DestAddr,
    (VOID *) DestinationAddrPtr,
    snp->mode.HwAddressSize
    );

  //
  // we need to do the byte swapping
  //
  cpb->Protocol             = (UINT16) PXE_SWAP_UINT16 (*ProtocolPtr);

  cpb->PacketLen            = (UINT32) (BufferLength);
  cpb->MediaHeaderLen       = (UINT16) MacHeaderSize;

  cpb->FragCnt              = 2;
  cpb->reserved             = 0;

  cpb->FragDesc[0].FragAddr = (UINT64) (UINTN) MacHeaderPtr;
  cpb->FragDesc[0].FragLen  = (UINT32) MacHeaderSize;
  cpb->FragDesc[1].FragAddr = (UINT64) (UINTN) BufferPtr;
  cpb->FragDesc[1].FragLen  = (UINT32) BufferLength;

  cpb->FragDesc[0].reserved = cpb->FragDesc[1].reserved = 0;

  if (snp->IsOldUndi) {
    TempData = (UINT64) (UINTN) MacHeaderPtr;
    if (TempData >= FOUR_GIGABYTES) {
      cpb->FragDesc[0].FragAddr = (UINT64) (UINTN) snp->fill_hdr_buf;
      cpb->FragDesc[0].FragLen  = (UINT32) snp->init_info.MediaHeaderLen;
    }

    TempData = (UINT64) (UINTN) (BufferPtr);
    if (TempData >= FOUR_GIGABYTES) {
      //
      // Let the device just read this buffer
      //
      Status = add_v2p (
                &pkt_v2p,
                EfiPciIoOperationBusMasterRead,
                BufferPtr,
                BufferLength
                );
      if (Status != EFI_SUCCESS) {
        return Status;
      }
      //
      // give the virtual address to UNDI and it will call back on Virt2Phys
      // to get the mapped address, if it needs it
      //
      cpb->FragDesc[1].FragLen = (UINT32) pkt_v2p->bsize;
    }
  }

  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    = 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->if_num;
  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

  //
  // Issue UNDI command and check result.
  //
  DEBUG ((EFI_D_NET, "\nsnp->undi.fill_header()  "));

  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

  if (snp->IsOldUndi) {
    TempData = (UINT64) (UINTN) (BufferPtr);
    if (TempData >= FOUR_GIGABYTES) {
      del_v2p (BufferPtr);
    }
    //
    // if we used the global buffer for header, copy the contents
    //
    TempData = (UINT64) (UINTN) MacHeaderPtr;
    if (TempData >= FOUR_GIGABYTES) {
      CopyMem (
        MacHeaderPtr,
        snp->fill_hdr_buf,
        snp->init_info.MediaHeaderLen
        );
    }
  }

  switch (snp->cdb.StatCode) {
  case PXE_STATCODE_SUCCESS:
    return EFI_SUCCESS;

  case PXE_STATCODE_INVALID_PARAMETER:
    DEBUG (
      (EFI_D_ERROR,
      "\nsnp->undi.fill_header()  %xh:%xh\n",
      snp->cdb.StatFlags,
      snp->cdb.StatCode)
      );

    return EFI_INVALID_PARAMETER;

  default:
    DEBUG (
      (EFI_D_ERROR,
      "\nsnp->undi.fill_header()  %xh:%xh\n",
      snp->cdb.StatFlags,
      snp->cdb.StatCode)
      );

    return EFI_DEVICE_ERROR;
  }
}

EFI_STATUS
pxe_transmit (
  SNP_DRIVER *snp,
  VOID       *BufferPtr,
  UINTN      BufferLength
  )
/*++

Routine Description:
 This routine calls undi to transmit the given data buffer
 
Arguments:
 snp - pointer to SNP driver structure
 BufferPtr - data buffer pointer
 BufferLength - Size of data in the BufferPtr
 
Returns:
 EFI_SUCCESS - if successfully completed the undi call
 Other - error return from undi call.
 
--*/
{
  PXE_CPB_TRANSMIT  *cpb;
  EFI_STATUS        Status;
  struct s_v2p      *v2p;
  UINT64            TempData;

  cpb             = snp->cpb;
  cpb->FrameAddr  = (UINT64) (UINTN) BufferPtr;
  cpb->DataLen    = (UINT32) BufferLength;
  
  TempData = (UINT64) (UINTN) BufferPtr;
  if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
    //
    // we need to create a mapping now and give it to the undi when it calls
    // the Virt2Phys on this address.
    // this is a transmit, just map it for the device to READ
    //
    Status = add_v2p (
              &v2p,
              EfiPciIoOperationBusMasterRead,
              BufferPtr,
              BufferLength
              );
    if (Status != EFI_SUCCESS) {
      return Status;
    }

    cpb->DataLen = (UINT32) v2p->bsize;
  }

  cpb->MediaheaderLen = 0;
  cpb->reserved       = 0;

  snp->cdb.OpFlags    = PXE_OPFLAGS_TRANSMIT_WHOLE;

  snp->cdb.CPBsize    = 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->if_num;
  snp->cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;

  //
  // Issue UNDI command and check result.
  //
  DEBUG ((EFI_D_NET, "\nsnp->undi.transmit()  "));
  DEBUG ((EFI_D_NET, "\nsnp->cdb.OpCode  == %x", snp->cdb.OpCode));
  DEBUG ((EFI_D_NET, "\nsnp->cdb.CPBaddr == %X", snp->cdb.CPBaddr));
  DEBUG ((EFI_D_NET, "\nsnp->cdb.DBaddr  == %X", snp->cdb.DBaddr));
  DEBUG ((EFI_D_NET, "\ncpb->FrameAddr   == %X\n", cpb->FrameAddr));

  (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);

  DEBUG ((EFI_D_NET, "\nexit snp->undi.transmit()  "));
  DEBUG ((EFI_D_NET, "\nsnp->cdb.StatCode == %r", snp->cdb.StatCode));

  //
  // 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_QUEUE_FULL:
  case PXE_STATCODE_BUSY:
    Status = EFI_NOT_READY;
    break;

  default:
    Status = EFI_DEVICE_ERROR;
  }

  DEBUG (
    (EFI_D_ERROR,
    "\nsnp->undi.transmit()  %xh:%xh\n",
    snp->cdb.StatFlags,
    snp->cdb.StatCode)
    );

  return Status;
}

EFI_STATUS
EFIAPI
snp_undi32_transmit (
  IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
  IN UINTN                       MacHeaderSize,
  IN UINTN                       BufferLength,
  IN VOID                        *BufferPtr,
  IN EFI_MAC_ADDRESS             * SourceAddrPtr OPTIONAL,
  IN EFI_MAC_ADDRESS             * DestinationAddrPtr OPTIONAL,
  IN UINT16                      *ProtocolPtr OPTIONAL
  )
/*++

Routine Description:
 This is the snp interface routine for transmitting a packet. this routine 
 basically retrieves the snp structure, checks the snp state and calls
 pxe_fill_header and pxe_transmit calls to complete the transmission.
 
Arguments:
 this - pointer to SNP driver context
 MacHeaderSize - size of the memory at MacHeaderPtr
 BufferLength - Size of data in the BufferPtr
 BufferPtr - data buffer pointer
 SourceAddrPtr - address of the source mac address buffer
 DestinationAddrPtr - address of the destination mac address buffer
 ProtocolPtr - address of the protocol type
 
Returns:
 EFI_SUCCESS - if successfully completed the undi call
 Other - error return from undi call.
 
--*/
{
  SNP_DRIVER  *snp;
  EFI_STATUS  Status;

  if (this == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);

  if (snp == NULL) {
    return EFI_DEVICE_ERROR;
  }

  switch (snp->mode.State) {
  case EfiSimpleNetworkInitialized:
    break;

  case EfiSimpleNetworkStopped:
    return EFI_NOT_STARTED;

  case EfiSimpleNetworkStarted:
    return EFI_DEVICE_ERROR;

  default:
    return EFI_DEVICE_ERROR;
  }

  if (BufferPtr == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  if (BufferLength < snp->mode.MediaHeaderSize) {
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // if the MacHeaderSize is non-zero, we need to fill up the header and for that
  // we need the destination address and the protocol
  //
  if (MacHeaderSize != 0) {
    if (MacHeaderSize != snp->mode.MediaHeaderSize || DestinationAddrPtr == 0 || ProtocolPtr == 0) {
      return EFI_INVALID_PARAMETER;
    }

    Status = pxe_fillheader (
              snp,
              BufferPtr,
              MacHeaderSize,
              (UINT8 *) BufferPtr + MacHeaderSize,
              BufferLength - MacHeaderSize,
              DestinationAddrPtr,
              SourceAddrPtr,
              ProtocolPtr
              );

    if (Status != EFI_SUCCESS) {
      return Status;
    }
  }

  return pxe_transmit (snp, BufferPtr, BufferLength);
}
