// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVICES_USB_DRIVERS_DWC3_DWC3_H_
#define SRC_DEVICES_USB_DRIVERS_DWC3_DWC3_H_

#include <lib/ddk/io-buffer.h>
#include <lib/device-protocol/pdev-fidl.h>
#include <lib/mmio/mmio.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <lib/zx/result.h>

#include <array>

#include <ddktl/device.h>
#include <fbl/auto_lock.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/mutex.h>
#include <usb/request-cpp.h>
#include <usb/usb.h>

#include "fuchsia/hardware/usb/dci/cpp/banjo.h"
#include "fuchsia/hardware/usb/descriptor/cpp/banjo.h"
#include "src/devices/usb/drivers/dwc3/dwc3-types.h"

namespace dwc3 {

class Dwc3;
using Dwc3Type = ddk::Device<Dwc3, ddk::Initializable, ddk::Unbindable>;

class Dwc3 : public Dwc3Type, public ddk::UsbDciProtocol<Dwc3, ddk::base_protocol> {
 public:
  explicit Dwc3(zx_device_t* parent) : Dwc3Type(parent) {}
  static zx_status_t Create(void* ctx, zx_device_t* parent);

  // Device protocol implementation.
  void DdkInit(ddk::InitTxn txn);
  void DdkUnbind(ddk::UnbindTxn txn);
  void DdkRelease();

  // USB DCI protocol implementation.
  void UsbDciRequestQueue(usb_request_t* req, const usb_request_complete_callback_t* cb);
  zx_status_t UsbDciSetInterface(const usb_dci_interface_protocol_t* interface);
  zx_status_t UsbDciConfigEp(const usb_endpoint_descriptor_t* ep_desc,
                             const usb_ss_ep_comp_descriptor_t* ss_comp_desc);
  zx_status_t UsbDciDisableEp(uint8_t ep_address);
  zx_status_t UsbDciEpSetStall(uint8_t ep_address);
  zx_status_t UsbDciEpClearStall(uint8_t ep_address);
  size_t UsbDciGetRequestSize();
  zx_status_t UsbDciCancelAll(uint8_t ep_address);

 private:
  static inline const uint32_t kEventBufferSize = zx_system_get_page_size();

  // physical endpoint numbers.  We use 0 and 1 for EP0, and let the device-mode
  // driver use the rest.
  static inline constexpr uint8_t kEp0Out = 0;
  static inline constexpr uint8_t kEp0In = 1;
  static inline constexpr uint8_t kUserEndpointStartNum = 2;
  static inline constexpr size_t kEp0MaxPacketSize = 512;

  static inline constexpr zx::duration kHwResetTimeout{zx::msec(50)};

  using Request = usb::BorrowedRequest<void>;
  using RequestQueue = usb::BorrowedRequestQueue<void>;

  enum class IrqSignal : uint32_t {
    Invalid = 0,
    Exit = 1,
    Wakeup = 2,
  };

  struct Fifo {
    static inline const uint32_t kFifoSize = zx_system_get_page_size();

    zx_status_t Init(zx::bti& bti);
    void Release();

    zx_paddr_t GetTrbPhys(dwc3_trb_t* trb) const {
      ZX_DEBUG_ASSERT((trb >= first) && (trb <= last));
      return buffer.phys() + ((trb - first) * sizeof(*trb));
    }

    ddk::IoBuffer buffer;
    dwc3_trb_t* first{nullptr};    // first TRB in the fifo
    dwc3_trb_t* next{nullptr};     // next free TRB in the fifo
    dwc3_trb_t* current{nullptr};  // TRB for currently pending transaction
    dwc3_trb_t* last{nullptr};     // last TRB in the fifo (link TRB)
  };

  struct Endpoint {
    Endpoint() = default;
    explicit Endpoint(uint8_t ep_num) : ep_num(ep_num) {}

    Endpoint(const Endpoint&) = delete;
    Endpoint& operator=(const Endpoint&) = delete;
    Endpoint(Endpoint&&) = delete;
    Endpoint& operator=(Endpoint&&) = delete;

    static inline constexpr bool IsOutput(uint8_t ep_num) { return (ep_num & 0x1) == 0; }
    static inline constexpr bool IsInput(uint8_t ep_num) { return (ep_num & 0x1) == 1; }

    bool IsOutput() const { return IsOutput(ep_num); }
    bool IsInput() const { return IsInput(ep_num); }

    RequestQueue queued_reqs;             // requests waiting to be processed
    usb_request_t* current_req{nullptr};  // request currently being processed
    uint32_t rsrc_id{0};                  // resource ID for current_req

    const uint8_t ep_num{0};
    uint8_t type{0};  // control, bulk, interrupt or isochronous
    uint8_t interval{0};
    uint16_t max_packet_size{0};
    bool enabled{false};
    // TODO(voydanoff) USB 3 specific stuff here

    bool got_not_ready{false};
    bool stalled{false};
  };

  struct UserEndpoint {
    UserEndpoint() = default;
    UserEndpoint(const UserEndpoint&) = delete;
    UserEndpoint& operator=(const UserEndpoint&) = delete;
    UserEndpoint(UserEndpoint&&) = delete;
    UserEndpoint& operator=(UserEndpoint&&) = delete;

    // Used for synchronizing endpoint state and ep specific hardware registers
    // This should be acquired before Dwc3::lock_ if acquiring both locks.
    fbl::Mutex lock;

    TA_GUARDED(lock) Fifo fifo;
    TA_GUARDED(lock) Endpoint ep;
  };

  // A small helper class which basically allows us to have a collection of user
  // endpoints which is dynamically allocated at startup, but which will never
  // change in size.  std::array is not an option here, as it is sized at
  // compile time, while std::vector would force us to make user endpoints
  // movable objects (which we really don't want to do).  Basically, this is a
  // lot of typing to get a C-style array which knows its size and supports
  // range based iteration.
  class UserEndpointCollection {
   public:
    void Init(size_t count) {
      ZX_DEBUG_ASSERT(count <= (std::numeric_limits<uint8_t>::max() - kUserEndpointStartNum));
      ZX_DEBUG_ASSERT(count_ == 0);
      ZX_DEBUG_ASSERT(endpoints_.get() == nullptr);

      count_ = count;
      endpoints_.reset(new UserEndpoint[count_]);
      for (size_t i = 0; i < count_; ++i) {
        UserEndpoint& uep = endpoints_[i];
        fbl::AutoLock lock(&uep.lock);
        const_cast<uint8_t&>(uep.ep.ep_num) = static_cast<uint8_t>(i) + kUserEndpointStartNum;
      }
    }

    // Standard size and index-operator
    size_t size() const { return count_; }
    UserEndpoint& operator[](size_t ndx) {
      ZX_DEBUG_ASSERT(ndx < count_);
      return endpoints_[ndx];
    }

    // Support for range-based for loops.
    UserEndpoint* begin() { return endpoints_.get() + 0; }
    UserEndpoint* end() { return endpoints_.get() + count_; }
    const UserEndpoint* begin() const { return endpoints_.get() + 0; }
    const UserEndpoint* end() const { return endpoints_.get() + count_; }

   private:
    size_t count_{0};
    std::unique_ptr<UserEndpoint[]> endpoints_;
  };

  struct Ep0 {
    Ep0() : out(kEp0Out), in(kEp0In) {}

    Ep0(const Ep0&) = delete;
    Ep0& operator=(const Ep0&) = delete;
    Ep0(Ep0&&) = delete;
    Ep0& operator=(Ep0&&) = delete;

    enum class State {
      None,
      Setup,        // Queued setup phase
      DataOut,      // Queued data on EP0_OUT
      DataIn,       // Queued data on EP0_IN
      WaitNrdyOut,  // Waiting for not-ready on EP0_OUT
      WaitNrdyIn,   // Waiting for not-ready on EP0_IN
      Status,       // Waiting for status to complete
    };

    fbl::Mutex lock;

    TA_GUARDED(lock) Fifo shared_fifo;
    TA_GUARDED(lock) ddk::IoBuffer buffer;
    TA_GUARDED(lock) State state{Ep0::State::None};
    TA_GUARDED(lock) Endpoint out;
    TA_GUARDED(lock) Endpoint in;
    TA_GUARDED(lock) usb_setup_t cur_setup;  // current setup request
    TA_GUARDED(lock) usb_speed_t cur_speed = USB_SPEED_UNDEFINED;
  };

  constexpr bool is_ep0_num(uint8_t ep_num) { return ((ep_num == kEp0Out) || (ep_num == kEp0In)); }

  UserEndpoint* get_user_endpoint(uint8_t ep_num) {
    if (ep_num >= kUserEndpointStartNum) {
      const uint8_t ndx = ep_num - kUserEndpointStartNum;
      return (ndx < user_endpoints_.size()) ? &user_endpoints_[ndx] : nullptr;
    }
    return nullptr;
  }

  fdf::MmioBuffer* get_mmio() { return &*mmio_; }
  static uint8_t UsbAddressToEpNum(uint8_t addr) {
    return static_cast<uint8_t>(((addr & 0xF) << 1) | !!(addr & USB_DIR_IN));
  }

  zx_status_t AcquirePDevResources();
  zx_status_t Init();
  void ReleaseResources();

  // The IRQ thread and its two top level event decoders.
  int IrqThread();
  void HandleEvent(uint32_t event);
  void HandleEpEvent(uint32_t event);

  [[nodiscard]] zx_status_t SignalIrqThread(IrqSignal signal) {
    if (!irq_bound_to_port_) {
      return ZX_ERR_BAD_STATE;
    }

    zx_port_packet_t pkt{
        .key = 0,
        .type = ZX_PKT_TYPE_USER,
        .status = ZX_OK,
    };
    pkt.user.u32[0] = static_cast<std::underlying_type_t<decltype(signal)>>(signal);

    return irq_port_.queue(&pkt);
  }

  IrqSignal GetIrqSignal(const zx_port_packet_t& pkt) {
    if (pkt.type != ZX_PKT_TYPE_USER) {
      return IrqSignal::Invalid;
    }
    return static_cast<IrqSignal>(pkt.user.u32[0]);
  }

  // Handlers for global events posted to the event buffer by the controller HW.
  void HandleResetEvent() TA_EXCL(lock_);
  void HandleConnectionDoneEvent() TA_EXCL(lock_);
  void HandleDisconnectedEvent() TA_EXCL(lock_);

  // Handlers for end-point specific events posted to the event buffer by the controller HW.
  void HandleEpTransferCompleteEvent(uint8_t ep_num) TA_EXCL(lock_);
  void HandleEpTransferNotReadyEvent(uint8_t ep_num, uint32_t stage) TA_EXCL(lock_);
  void HandleEpTransferStartedEvent(uint8_t ep_num, uint32_t rsrc_id) TA_EXCL(lock_);

  [[nodiscard]] zx_status_t CheckHwVersion() TA_REQ(lock_);
  [[nodiscard]] zx_status_t ResetHw() TA_REQ(lock_);
  void StartEvents() TA_REQ(lock_);
  void SetDeviceAddress(uint32_t address) TA_REQ(lock_);

  // EP0 stuff
  zx_status_t Ep0Init() TA_EXCL(lock_);
  void Ep0Reset() TA_EXCL(lock_);
  void Ep0Start() TA_EXCL(lock_);
  void Ep0QueueSetupLocked() TA_REQ(ep0_.lock) TA_EXCL(lock_);
  void Ep0StartEndpoints() TA_REQ(ep0_.lock) TA_EXCL(lock_);
  zx::result<size_t> HandleEp0Setup(const usb_setup_t& setup, void* buffer, size_t length)
      TA_REQ(ep0_.lock) TA_EXCL(lock_);
  void HandleEp0TransferCompleteEvent(uint8_t ep_num) TA_EXCL(lock_, ep0_.lock);
  void HandleEp0TransferNotReadyEvent(uint8_t ep_num, uint32_t stage) TA_EXCL(lock_, ep0_.lock);

  // General EP stuff
  void EpEnable(const Endpoint& ep, bool enable) TA_EXCL(lock_);
  void EpSetConfig(Endpoint& ep, bool enable) TA_EXCL(lock_);
  zx_status_t EpSetStall(Endpoint& ep, bool stall) TA_EXCL(lock_);
  void EpStartTransfer(Endpoint& ep, Fifo& fifo, uint32_t type, zx_paddr_t buffer, size_t length,
                       bool send_zlp) TA_EXCL(lock_);
  void EpEndTransfers(Endpoint& ep, zx_status_t reason) TA_EXCL(lock_);
  void EpReadTrb(Endpoint& ep, Fifo& fifo, const dwc3_trb_t* src, dwc3_trb_t* dst) TA_EXCL(lock_);

  // Methods specific to user endpoints
  void UserEpQueueNext(UserEndpoint& uep) TA_REQ(uep.lock) TA_EXCL(lock_);
  zx_status_t UserEpCancelAll(UserEndpoint& uep) TA_EXCL(lock_, uep.lock);

  // Cancel all currently in flight requests, and return a list of requests
  // which were in-flight.  Note that these requests have not been completed
  // yet.  It is the responsibility of the caller to (eventually) take care of
  // this once the lock has been dropped.
  [[nodiscard]] RequestQueue UserEpCancelAllLocked(UserEndpoint& uep) TA_REQ(uep.lock)
      TA_EXCL(lock_);

  // Commands
  void CmdStartNewConfig(const Endpoint& ep, uint32_t rsrc_id) TA_EXCL(lock_);
  void CmdEpSetConfig(const Endpoint& ep, bool modify) TA_EXCL(lock_);
  void CmdEpTransferConfig(const Endpoint& ep) TA_EXCL(lock_);
  void CmdEpStartTransfer(const Endpoint& ep, zx_paddr_t trb_phys) TA_EXCL(lock_);
  void CmdEpEndTransfer(const Endpoint& ep) TA_EXCL(lock_);
  void CmdEpSetStall(const Endpoint& ep) TA_EXCL(lock_);
  void CmdEpClearStall(const Endpoint& ep) TA_EXCL(lock_);

  // Start to operate in peripheral mode.
  void StartPeripheralMode() TA_EXCL(lock_);
  void ResetConfiguration() TA_EXCL(lock_);

  fbl::Mutex lock_;
  fbl::Mutex dci_lock_;

  ddk::PDevFidl pdev_;

  TA_GUARDED(dci_lock_) std::optional<ddk::UsbDciInterfaceProtocolClient> dci_intf_;

  std::optional<ddk::MmioBuffer> mmio_;

  zx::bti bti_;
  bool has_pinned_memory_{false};

  zx::interrupt irq_;
  zx::port irq_port_;
  bool irq_bound_to_port_{false};

  thrd_t irq_thread_;
  std::atomic<bool> irq_thread_started_{false};

  ddk::IoBuffer event_buffer_;
  Ep0 ep0_;
  UserEndpointCollection user_endpoints_;

  RequestQueue pending_completions_;

  // TODO(johngro): What lock protects this?  Right now, it is effectively
  // endpoints_[0].lock(), but how do we express this?
  bool configured_ = false;
};

}  // namespace dwc3

#endif  // SRC_DEVICES_USB_DRIVERS_DWC3_DWC3_H_
