/** @file
PEIM to produce gPeiUsb2HostControllerPpiGuid based on gPeiUsbControllerPpiGuid
which is used to enable recovery function from USB Drivers.

Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "EhcPeim.h"

/**
  Delete a single asynchronous interrupt transfer for
  the device and endpoint.

  @param  Ehc         The EHCI device.
  @param  Data        Current data not associated with a QTD.
  @param  DataLen     The length of the data.
  @param  PktId       Packet ID to use in the QTD.
  @param  Toggle      Data toggle to use in the QTD.
  @param  MaxPacket   Maximu packet length of the endpoint.

  @retval the pointer to the created QTD or NULL if failed to create one.

**/
PEI_EHC_QTD *
EhcCreateQtd (
  IN PEI_USB2_HC_DEV  *Ehc,
  IN UINT8            *Data,
  IN UINTN            DataLen,
  IN UINT8            PktId,
  IN UINT8            Toggle,
  IN UINTN            MaxPacket
  )
{
  PEI_EHC_QTD  *Qtd;
  QTD_HW       *QtdHw;
  UINTN        Index;
  UINTN        Len;
  UINTN        ThisBufLen;

  ASSERT (Ehc != NULL);

  Qtd = UsbHcAllocateMem (Ehc, Ehc->MemPool, sizeof (PEI_EHC_QTD));

  if (Qtd == NULL) {
    return NULL;
  }

  Qtd->Signature = EHC_QTD_SIG;
  Qtd->Data      = Data;
  Qtd->DataLen   = 0;

  InitializeListHead (&Qtd->QtdList);

  QtdHw             = &Qtd->QtdHw;
  QtdHw->NextQtd    = QTD_LINK (NULL, TRUE);
  QtdHw->AltNext    = QTD_LINK (NULL, TRUE);
  QtdHw->Status     = QTD_STAT_ACTIVE;
  QtdHw->Pid        = PktId;
  QtdHw->ErrCnt     = QTD_MAX_ERR;
  QtdHw->Ioc        = 0;
  QtdHw->TotalBytes = 0;
  QtdHw->DataToggle = Toggle;

  //
  // Fill in the buffer points
  //
  if (Data != NULL) {
    Len = 0;

    for (Index = 0; Index <= QTD_MAX_BUFFER; Index++) {
      //
      // Set the buffer point (Check page 41 EHCI Spec 1.0). No need to
      // compute the offset and clear Reserved fields. This is already
      // done in the data point.
      //
      QtdHw->Page[Index]     = EHC_LOW_32BIT (Data);
      QtdHw->PageHigh[Index] = EHC_HIGH_32BIT (Data);

      ThisBufLen = QTD_BUF_LEN - (EHC_LOW_32BIT (Data) & QTD_BUF_MASK);

      if (Len + ThisBufLen >= DataLen) {
        Len = DataLen;
        break;
      }

      Len  += ThisBufLen;
      Data += ThisBufLen;
    }

    //
    // Need to fix the last pointer if the Qtd can't hold all the
    // user's data to make sure that the length is in the unit of
    // max packets. If it can hold all the data, there is no such
    // need.
    //
    if (Len < DataLen) {
      Len = Len - Len % MaxPacket;
    }

    QtdHw->TotalBytes = (UINT32)Len;
    Qtd->DataLen      = Len;
  }

  return Qtd;
}

/**
  Initialize the queue head for interrupt transfer,
  that is, initialize the following three fields:
    1. SplitXState in the Status field.
    2. Microframe S-mask.
    3. Microframe C-mask.

  @param  Ep    The queue head's related endpoint.
  @param  QhHw  The queue head to initialize.

**/
VOID
EhcInitIntQh (
  IN USB_ENDPOINT  *Ep,
  IN QH_HW         *QhHw
  )
{
  //
  // Because UEFI interface can't utilitize an endpoint with
  // poll rate faster than 1ms, only need to set one bit in
  // the queue head. simple. But it may be changed later. If
  // sub-1ms interrupt is supported, need to update the S-Mask
  // here
  //
  if (Ep->DevSpeed == EFI_USB_SPEED_HIGH) {
    QhHw->SMask = QH_MICROFRAME_0;
    return;
  }

  //
  // For low/full speed device, the transfer must go through
  // the split transaction. Need to update three fields
  // 1. SplitXState in the status
  // 2. Microframe S-Mask
  // 3. Microframe C-Mask
  // UEFI USB doesn't exercise admission control. It simplely
  // schedule the high speed transactions in microframe 0, and
  // full/low speed transactions at microframe 1. This also
  // avoid the use of FSTN.
  //
  QhHw->SMask = QH_MICROFRAME_1;
  QhHw->CMask = QH_MICROFRAME_3 | QH_MICROFRAME_4 | QH_MICROFRAME_5;
}

/**
  Allocate and initialize a EHCI queue head.

  @param  Ehci      The EHCI device.
  @param  Ep        The endpoint to create queue head for.

  @retval the pointer to the created queue head or NULL if failed to create one.

**/
PEI_EHC_QH *
EhcCreateQh (
  IN PEI_USB2_HC_DEV  *Ehci,
  IN USB_ENDPOINT     *Ep
  )
{
  PEI_EHC_QH  *Qh;
  QH_HW       *QhHw;

  Qh = UsbHcAllocateMem (Ehci, Ehci->MemPool, sizeof (PEI_EHC_QH));

  if (Qh == NULL) {
    return NULL;
  }

  Qh->Signature = EHC_QH_SIG;
  Qh->NextQh    = NULL;
  Qh->Interval  = Ep->PollRate;

  InitializeListHead (&Qh->Qtds);

  QhHw               = &Qh->QhHw;
  QhHw->HorizonLink  = QH_LINK (NULL, 0, TRUE);
  QhHw->DeviceAddr   = Ep->DevAddr;
  QhHw->Inactive     = 0;
  QhHw->EpNum        = Ep->EpAddr;
  QhHw->EpSpeed      = Ep->DevSpeed;
  QhHw->DtCtrl       = 0;
  QhHw->ReclaimHead  = 0;
  QhHw->MaxPacketLen = (UINT32)Ep->MaxPacket;
  QhHw->CtrlEp       = 0;
  QhHw->NakReload    = QH_NAK_RELOAD;
  QhHw->HubAddr      = Ep->HubAddr;
  QhHw->PortNum      = Ep->HubPort;
  QhHw->Multiplier   = 1;
  QhHw->DataToggle   = Ep->Toggle;

  if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) {
    QhHw->Status |= QTD_STAT_DO_SS;
  }

  switch (Ep->Type) {
    case EHC_CTRL_TRANSFER:
      //
      // Special initialization for the control transfer:
      // 1. Control transfer initialize data toggle from each QTD
      // 2. Set the Control Endpoint Flag (C) for low/full speed endpoint.
      //
      QhHw->DtCtrl = 1;

      if (Ep->DevSpeed != EFI_USB_SPEED_HIGH) {
        QhHw->CtrlEp = 1;
      }

      break;

    case EHC_INT_TRANSFER_ASYNC:
    case EHC_INT_TRANSFER_SYNC:
      //
      // Special initialization for the interrupt transfer
      // to set the S-Mask and C-Mask
      //
      QhHw->NakReload = 0;
      EhcInitIntQh (Ep, QhHw);
      break;

    case EHC_BULK_TRANSFER:
      if ((Ep->DevSpeed == EFI_USB_SPEED_HIGH) && (Ep->Direction == EfiUsbDataOut)) {
        QhHw->Status |= QTD_STAT_DO_PING;
      }

      break;
  }

  return Qh;
}

/**
  Convert the poll interval from application to that
  be used by EHCI interface data structure. Only need
  to get the max 2^n that is less than interval. UEFI
  can't support high speed endpoint with a interval less
  than 8 microframe because interval is specified in
  the unit of ms (millisecond).

  @param Interval       The interval to convert.

  @retval The converted interval.

**/
UINTN
EhcConvertPollRate (
  IN  UINTN  Interval
  )
{
  UINTN  BitCount;

  if (Interval == 0) {
    return 1;
  }

  //
  // Find the index (1 based) of the highest non-zero bit
  //
  BitCount = 0;

  while (Interval != 0) {
    Interval >>= 1;
    BitCount++;
  }

  return (UINTN)1 << (BitCount - 1);
}

/**
  Free a list of QTDs.

  @param  Ehc         The EHCI device.
  @param  Qtds        The list head of the QTD.

**/
VOID
EhcFreeQtds (
  IN PEI_USB2_HC_DEV  *Ehc,
  IN EFI_LIST_ENTRY   *Qtds
  )
{
  EFI_LIST_ENTRY  *Entry;
  EFI_LIST_ENTRY  *Next;
  PEI_EHC_QTD     *Qtd;

  BASE_LIST_FOR_EACH_SAFE (Entry, Next, Qtds) {
    Qtd = EFI_LIST_CONTAINER (Entry, PEI_EHC_QTD, QtdList);

    RemoveEntryList (&Qtd->QtdList);
    UsbHcFreeMem (Ehc, Ehc->MemPool, Qtd, sizeof (PEI_EHC_QTD));
  }
}

/**
  Free an allocated URB. It is possible for it to be partially inited.

  @param  Ehc         The EHCI device.
  @param  Urb         The URB to free.

**/
VOID
EhcFreeUrb (
  IN PEI_USB2_HC_DEV  *Ehc,
  IN PEI_URB          *Urb
  )
{
  if (Urb->RequestPhy != NULL) {
    IoMmuUnmap (Ehc->IoMmu, Urb->RequestMap);
  }

  if (Urb->DataMap != NULL) {
    IoMmuUnmap (Ehc->IoMmu, Urb->DataMap);
  }

  if (Urb->Qh != NULL) {
    //
    // Ensure that this queue head has been unlinked from the
    // schedule data structures. Free all the associated QTDs
    //
    EhcFreeQtds (Ehc, &Urb->Qh->Qtds);
    UsbHcFreeMem (Ehc, Ehc->MemPool, Urb->Qh, sizeof (PEI_EHC_QH));
  }
}

/**
  Create a list of QTDs for the URB.

  @param  Ehc         The EHCI device.
  @param  Urb         The URB to create QTDs for.

  @retval EFI_OUT_OF_RESOURCES    Failed to allocate resource for QTD.
  @retval EFI_SUCCESS             The QTDs are allocated for the URB.

**/
EFI_STATUS
EhcCreateQtds (
  IN PEI_USB2_HC_DEV  *Ehc,
  IN PEI_URB          *Urb
  )
{
  USB_ENDPOINT    *Ep;
  PEI_EHC_QH      *Qh;
  PEI_EHC_QTD     *Qtd;
  PEI_EHC_QTD     *StatusQtd;
  PEI_EHC_QTD     *NextQtd;
  EFI_LIST_ENTRY  *Entry;
  UINT32          AlterNext;
  UINT8           Toggle;
  UINTN           Len;
  UINT8           Pid;

  ASSERT ((Urb != NULL) && (Urb->Qh != NULL));

  //
  // EHCI follows the alternet next QTD pointer if it meets
  // a short read and the AlterNext pointer is valid. UEFI
  // EHCI driver should terminate the transfer except the
  // control transfer.
  //
  Toggle    = 0;
  Qh        = Urb->Qh;
  Ep        = &Urb->Ep;
  StatusQtd = NULL;
  AlterNext = QTD_LINK (NULL, TRUE);

  if (Ep->Direction == EfiUsbDataIn) {
    AlterNext = QTD_LINK (Ehc->ShortReadStop, FALSE);
  }

  //
  // Build the Setup and status packets for control transfer
  //
  if (Urb->Ep.Type == EHC_CTRL_TRANSFER) {
    Len = sizeof (EFI_USB_DEVICE_REQUEST);
    Qtd = EhcCreateQtd (Ehc, Urb->RequestPhy, Len, QTD_PID_SETUP, 0, Ep->MaxPacket);

    if (Qtd == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    InsertTailList (&Qh->Qtds, &Qtd->QtdList);

    //
    // Create the status packet now. Set the AlterNext to it. So, when
    // EHCI meets a short control read, it can resume at the status stage.
    // Use the opposite direction of the data stage, or IN if there is
    // no data stage.
    //
    if (Ep->Direction == EfiUsbDataIn) {
      Pid = QTD_PID_OUTPUT;
    } else {
      Pid = QTD_PID_INPUT;
    }

    StatusQtd = EhcCreateQtd (Ehc, NULL, 0, Pid, 1, Ep->MaxPacket);

    if (StatusQtd == NULL) {
      goto ON_ERROR;
    }

    if (Ep->Direction == EfiUsbDataIn) {
      AlterNext = QTD_LINK (StatusQtd, FALSE);
    }

    Toggle = 1;
  }

  //
  // Build the data packets for all the transfers
  //
  if (Ep->Direction == EfiUsbDataIn) {
    Pid = QTD_PID_INPUT;
  } else {
    Pid = QTD_PID_OUTPUT;
  }

  Qtd = NULL;
  Len = 0;

  while (Len < Urb->DataLen) {
    Qtd = EhcCreateQtd (
            Ehc,
            (UINT8 *)Urb->DataPhy + Len,
            Urb->DataLen - Len,
            Pid,
            Toggle,
            Ep->MaxPacket
            );

    if (Qtd == NULL) {
      goto ON_ERROR;
    }

    Qtd->QtdHw.AltNext = AlterNext;
    InsertTailList (&Qh->Qtds, &Qtd->QtdList);

    //
    // Switch the Toggle bit if odd number of packets are included in the QTD.
    //
    if (((Qtd->DataLen + Ep->MaxPacket - 1) / Ep->MaxPacket) % 2) {
      Toggle = (UINT8)(1 - Toggle);
    }

    Len += Qtd->DataLen;
  }

  //
  // Insert the status packet for control transfer
  //
  if (Ep->Type == EHC_CTRL_TRANSFER) {
    InsertTailList (&Qh->Qtds, &StatusQtd->QtdList);
  }

  //
  // OK, all the QTDs needed are created. Now, fix the NextQtd point
  //
  BASE_LIST_FOR_EACH (Entry, &Qh->Qtds) {
    Qtd = EFI_LIST_CONTAINER (Entry, PEI_EHC_QTD, QtdList);

    //
    // break if it is the last entry on the list
    //
    if (Entry->ForwardLink == &Qh->Qtds) {
      break;
    }

    NextQtd            = EFI_LIST_CONTAINER (Entry->ForwardLink, PEI_EHC_QTD, QtdList);
    Qtd->QtdHw.NextQtd = QTD_LINK (NextQtd, FALSE);
  }

  //
  // Link the QTDs to the queue head
  //
  NextQtd          = EFI_LIST_CONTAINER (Qh->Qtds.ForwardLink, PEI_EHC_QTD, QtdList);
  Qh->QhHw.NextQtd = QTD_LINK (NextQtd, FALSE);
  return EFI_SUCCESS;

ON_ERROR:
  EhcFreeQtds (Ehc, &Qh->Qtds);
  return EFI_OUT_OF_RESOURCES;
}

/**
  Create a new URB and its associated QTD.

  @param  Ehc               The EHCI device.
  @param  DevAddr           The device address.
  @param  EpAddr            Endpoint addrress & its direction.
  @param  DevSpeed          The device speed.
  @param  Toggle            Initial data toggle to use.
  @param  MaxPacket         The max packet length of the endpoint.
  @param  Hub               The transaction translator to use.
  @param  Type              The transaction type.
  @param  Request           The standard USB request for control transfer.
  @param  Data              The user data to transfer.
  @param  DataLen           The length of data buffer.
  @param  Callback          The function to call when data is transferred.
  @param  Context           The context to the callback.
  @param  Interval          The interval for interrupt transfer.

  @retval the pointer to the created URB or NULL.

**/
PEI_URB *
EhcCreateUrb (
  IN PEI_USB2_HC_DEV                     *Ehc,
  IN UINT8                               DevAddr,
  IN UINT8                               EpAddr,
  IN UINT8                               DevSpeed,
  IN UINT8                               Toggle,
  IN UINTN                               MaxPacket,
  IN EFI_USB2_HC_TRANSACTION_TRANSLATOR  *Hub,
  IN UINTN                               Type,
  IN EFI_USB_DEVICE_REQUEST              *Request,
  IN VOID                                *Data,
  IN UINTN                               DataLen,
  IN EFI_ASYNC_USB_TRANSFER_CALLBACK     Callback,
  IN VOID                                *Context,
  IN UINTN                               Interval
  )
{
  USB_ENDPOINT           *Ep;
  EFI_PHYSICAL_ADDRESS   PhyAddr;
  EDKII_IOMMU_OPERATION  MapOp;
  EFI_STATUS             Status;
  UINTN                  Len;
  PEI_URB                *Urb;
  VOID                   *Map;

  Map = NULL;

  Urb            = Ehc->Urb;
  Urb->Signature = EHC_URB_SIG;
  InitializeListHead (&Urb->UrbList);

  Ep            = &Urb->Ep;
  Ep->DevAddr   = DevAddr;
  Ep->EpAddr    = (UINT8)(EpAddr & 0x0F);
  Ep->Direction = (((EpAddr & 0x80) != 0) ? EfiUsbDataIn : EfiUsbDataOut);
  Ep->DevSpeed  = DevSpeed;
  Ep->MaxPacket = MaxPacket;

  Ep->HubAddr = 0;
  Ep->HubPort = 0;

  if (DevSpeed != EFI_USB_SPEED_HIGH) {
    ASSERT (Hub != NULL);

    Ep->HubAddr = Hub->TranslatorHubAddress;
    Ep->HubPort = Hub->TranslatorPortNumber;
  }

  Ep->Toggle   = Toggle;
  Ep->Type     = Type;
  Ep->PollRate = EhcConvertPollRate (Interval);

  Urb->Request  = Request;
  Urb->Data     = Data;
  Urb->DataLen  = DataLen;
  Urb->Callback = Callback;
  Urb->Context  = Context;
  Urb->Qh       = EhcCreateQh (Ehc, &Urb->Ep);

  if (Urb->Qh == NULL) {
    goto ON_ERROR;
  }

  Urb->RequestPhy = NULL;
  Urb->RequestMap = NULL;
  Urb->DataPhy    = NULL;
  Urb->DataMap    = NULL;

  //
  // Map the request and user data
  //
  if (Request != NULL) {
    Len    = sizeof (EFI_USB_DEVICE_REQUEST);
    MapOp  = EdkiiIoMmuOperationBusMasterRead;
    Status = IoMmuMap (Ehc->IoMmu, MapOp, Request, &Len, &PhyAddr, &Map);

    if (EFI_ERROR (Status) || (Len != sizeof (EFI_USB_DEVICE_REQUEST))) {
      goto ON_ERROR;
    }

    Urb->RequestPhy = (VOID *)((UINTN)PhyAddr);
    Urb->RequestMap = Map;
  }

  if (Data != NULL) {
    Len = DataLen;

    if (Ep->Direction == EfiUsbDataIn) {
      MapOp = EdkiiIoMmuOperationBusMasterWrite;
    } else {
      MapOp = EdkiiIoMmuOperationBusMasterRead;
    }

    Status = IoMmuMap (Ehc->IoMmu, MapOp, Data, &Len, &PhyAddr, &Map);

    if (EFI_ERROR (Status) || (Len != DataLen)) {
      goto ON_ERROR;
    }

    Urb->DataPhy = (VOID *)((UINTN)PhyAddr);
    Urb->DataMap = Map;
  }

  Status = EhcCreateQtds (Ehc, Urb);

  if (EFI_ERROR (Status)) {
    goto ON_ERROR;
  }

  return Urb;

ON_ERROR:
  EhcFreeUrb (Ehc, Urb);
  return NULL;
}
