// Copyright 2018 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.

#include "qmi-usb-transport.h"
#include <ddk/binding.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/ethernet.h>
#include <ddk/protocol/usb.h>
#include <ddk/usb/usb.h>
#include <lib/sync/completion.h>
#include <zircon/device/qmi-transport.h>
#include <zircon/hw/usb-cdc.h>
#include <zircon/status.h>
#include <zircon/syscalls/port.h>
#include <zircon/types.h>

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define _ALL_SOURCE
#include <threads.h>
#include <usb/usb-request.h>

// The maximum amount of memory we are willing to allocate to transaction
// buffers
#define MAX_TX_BUF_SZ 32768
#define MAX_RX_BUF_SZ 32768

#define ETHMAC_MAX_TRANSMIT_DELAY 100
#define ETHMAC_MAX_RECV_DELAY 100
#define ETHMAC_TRANSMIT_DELAY 10
#define ETHMAC_RECV_DELAY 10
#define ETHMAC_INITIAL_TRANSMIT_DELAY 0
#define ETHMAC_INITIAL_RECV_DELAY 0

#define ETHERNET_FRAME_OFFSET 14

typedef struct txn_info {
    ethmac_netbuf_t netbuf;
    list_node_t node;
} txn_info_t;

// qmi usb transport device
typedef struct qmi_ctx {
  // Interrupt handling
  usb_request_t* int_txn_buf;
  sync_completion_t completion;
  thrd_t int_thread;

  uint16_t max_packet_size;

  // Port to watch for QMI messages on
  zx_handle_t channel_port;
  zx_handle_t channel;

  usb_protocol_t usb;
  zx_device_t* usb_device;
  zx_device_t* zxdev;
  size_t parent_req_size;

  // Ethernet
  zx_device_t* eth_zxdev;

  mtx_t ethmac_mutex;
  ethmac_ifc_t ethmac_ifc;

  // Device attributes
  uint8_t mac_addr[ETH_MAC_SIZE];
  uint16_t mtu;

  // Connection attributes
  bool online;
  uint32_t ds_bps;
  uint32_t us_bps;

  // Send context
  mtx_t tx_mutex;
  uint8_t tx_endpoint_addr;
  uint16_t endpoint_size;
  list_node_t tx_txn_bufs;       // list of usb_request_t
  list_node_t tx_pending_infos;  // list of txn_info_t
  bool unbound;  // set to true when device is going away. Guarded by tx_mutex
  uint64_t tx_endpoint_delay;  // wait time between 2 transmit requests

  // Receive context
  uint8_t rx_endpoint_addr;
  uint64_t rx_endpoint_delay;  // wait time between 2 recv requests
} qmi_ctx_t;

static void usb_write_complete(usb_request_t* request, void* cookie);

static zx_status_t get_channel(void* ctx, zx_handle_t* out_channel) {
  ZX_DEBUG_ASSERT(ctx);
  zxlogf(INFO, "qmi-usb-transport: getting channel from transport\n");
  qmi_ctx_t* qmi_ctx = ctx;
  zx_status_t result = ZX_OK;

  zx_handle_t* in_channel = &qmi_ctx->channel;

  if (*in_channel != ZX_HANDLE_INVALID) {
    zxlogf(ERROR, "qmi-usb-transport: already bound, failing\n");
    result = ZX_ERR_ALREADY_BOUND;
    goto done;
  }

  result = zx_channel_create(0, in_channel, out_channel);
  if (result < 0) {
    zxlogf(ERROR, "qmi-usb-transport: Failed to create channel: %s\n",
           zx_status_get_string(result));
    goto done;
  }

done:
  return result;
}

static zx_status_t queue_request(qmi_ctx_t* ctx, const uint8_t* data, size_t length,
                                 usb_request_t* req) {
  req->header.length = length;
  if (length < 41) {
    zxlogf(ERROR, "qmi-usb-transport: length is too short (length: %zx) \n", length);
    return ZX_ERR_IO;
  }

  if (length > 1024) {
    zxlogf(ERROR,
        "qmi-usb-transport: length is greater than buffer size. (length: %zx) \n", length);
    return ZX_ERR_IO;
  }

  // Check if this in an arp frame, short-circuit return a synthetic one if so
  const uint8_t* eth = &data[ETHERNET_FRAME_OFFSET];
  if ((eth[0] == 0x00) &&     // hardware type
      (eth[1] == 0x01) && (eth[2] == 0x08) &&  // protocol
      (eth[3] == 0x00) && (eth[4] == 0x06) &&  // hardware len
      (eth[5] == 0x04) &&                        // protocol len
      (eth[6] == 0x00) &&                        // arp request op
      (eth[7] == 0x01)) {
    uint8_t read_data[] = {
        // ethernet frame
        0x62, 0x77, 0x62, 0x62, 0x77, 0x62,  // destination mac addr (bwb)
        0x79, 0x61, 0x6B, 0x79, 0x61, 0x6B,  // source mac addr (yak)
        0x08, 0x06,  // arp ethertype
        // data payload
        0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x02, // ARP header
        0x79, 0x61, 0x6B, 0x79, 0x61, 0x6B,             // yak mac addr
        eth[24], eth[25], eth[26], eth[27],             // swapped IP addr
        0x62, 0x77, 0x62, 0x62, 0x77, 0x62,             // bwb mac addr
        eth[14], eth[15], eth[16], eth[17],             // swapped IP addr
    };

    zx_nanosleep(zx_deadline_after(ZX_USEC(ctx->tx_endpoint_delay)));
    mtx_lock(&ctx->ethmac_mutex);
    if (ctx->ethmac_ifc.ops) {
        ethmac_ifc_recv(&ctx->ethmac_ifc, read_data, sizeof(read_data), 0);
    }
    mtx_unlock(&ctx->ethmac_mutex);
    return ZX_OK;
  }

  ssize_t ip_length = ((eth[2] << 8) + eth[3]);
  if (ip_length > (ssize_t)length) {
    zxlogf(ERROR,
        "qmi-usb-transport: length of IP packet is more than the ethernet frame! %zx/%zd \n",
        ip_length, length);
    return ZX_ERR_IO;
  }

  ssize_t bytes_copied = usb_request_copy_to(req, eth, ip_length, 0);
  if (bytes_copied < 0) {
    zxlogf(ERROR,
           "qmi-usb-transport: failed to copy data into send txn (error %zd)\n",
           bytes_copied);
    return ZX_ERR_IO;
  }

  usb_request_queue(&ctx->usb, req, usb_write_complete, ctx);
  return ZX_OK;
}

static zx_status_t send_locked(qmi_ctx_t* ctx, ethmac_netbuf_t* netbuf) {
  const uint8_t* byte_data = netbuf->data_buffer;
  size_t length = netbuf->data_size;

  // Make sure that we can get all of the tx buffers we need to use
  usb_request_t* tx_req =
      usb_req_list_remove_head(&ctx->tx_txn_bufs, ctx->parent_req_size);
  if (tx_req == NULL) {
    return ZX_ERR_SHOULD_WAIT;
  }

  zx_nanosleep(zx_deadline_after(ZX_USEC(ctx->tx_endpoint_delay)));
  zx_status_t status;
  if ((status = queue_request(ctx, byte_data, length, tx_req)) != ZX_OK) {
    zx_status_t add_status = usb_req_list_add_tail(&ctx->tx_txn_bufs, tx_req, ctx->parent_req_size);
    ZX_DEBUG_ASSERT(add_status == ZX_OK);
    return status;
  }

  return ZX_OK;
}

static void qmi_update_online_status(qmi_ctx_t* ctx, bool is_online) {
  mtx_lock(&ctx->ethmac_mutex);
  if ((is_online && ctx->online) || (!is_online && !ctx->online)) {
    goto done;
  }

  if (is_online) {
    zxlogf(INFO, "qmi-usb-transport: connected to network\n");
    ctx->online = true;
    if (ctx->ethmac_ifc.ops) {
      ethmac_ifc_status(&ctx->ethmac_ifc, ctx->online ? ETHMAC_STATUS_ONLINE : 0);
    } else {
      zxlogf(ERROR, "qmi-usb-transport: not connected to ethermac interface\n");
    }
  } else {
    zxlogf(INFO, "qmi-usb-transport: no connection to network\n");
    ctx->online = false;
    if (ctx->ethmac_ifc.ops) {
      ethmac_ifc_status(&ctx->ethmac_ifc, 0);
    }
  }

done:
  mtx_unlock(&ctx->ethmac_mutex);
}

static inline zx_status_t set_async_wait(qmi_ctx_t* ctx) {
  zx_status_t status = zx_object_wait_async(
      ctx->channel, ctx->channel_port, CHANNEL_MSG,
      ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED, ZX_WAIT_ASYNC_ONCE);
  return status;
}

static zx_status_t qmi_ioctl(void* ctx, uint32_t op, const void* in_buf,
                             size_t in_len, void* out_buf, size_t out_len,
                             size_t* out_actual) {
  qmi_ctx_t* qmi_ctx = ctx;
  zx_status_t status = ZX_OK;
  if ((op != IOCTL_QMI_GET_CHANNEL) && (op != IOCTL_QMI_SET_NETWORK)) {
    status = ZX_ERR_NOT_SUPPORTED;
    goto done;
  }

  if (op == IOCTL_QMI_SET_NETWORK) {
    bool state = (bool)in_buf;
    qmi_update_online_status(qmi_ctx, state);
    return status;
  }

  if (out_buf == NULL || out_len != sizeof(zx_handle_t)) {
    status = ZX_ERR_INVALID_ARGS;
    goto done;
  }

  zx_handle_t* out_channel = (zx_handle_t*)out_buf;
  status = get_channel(ctx, out_channel);
  if (status != ZX_OK) {
    goto done;
  }
  *out_actual = sizeof(zx_handle_t);

  status = set_async_wait(qmi_ctx);
  if (status != ZX_OK) {
    zx_handle_close(*out_channel);
    zx_handle_close(qmi_ctx->channel);
  }

done:
  return status;
}

static void qmi_release(void* ctx) {
  zxlogf(INFO, "qmi-usb-transport: releasing device\n");
  qmi_ctx_t* qmi_ctx = ctx;
  free(qmi_ctx);
}

static void qmi_unbind(void* ctx) {
  qmi_ctx_t* qmi_ctx = ctx;
  zx_status_t result = ZX_OK;
  result = device_remove(qmi_ctx->zxdev);
  if (result != ZX_OK) {
    zxlogf(
        ERROR,
        "Failed to unbind qmi-usb-transport driver. Cannot remove device: %u\n",
        result);
  }
}

static zx_status_t qmi_ethmac_query(void* ctx, uint32_t options, ethmac_info_t* info) {
  qmi_ctx_t* eth = ctx;

  zxlogf(INFO, "qmi-usb-transport: %s called\n", __FUNCTION__);

  // No options are supported
  if (options) {
    zxlogf(ERROR, "qmi-usb-transport: unexpected options to ethmac_query\n");
    return ZX_ERR_INVALID_ARGS;
  }

  memset(info, 0, sizeof(*info));
  info->mtu = 1024;
  memcpy(info->mac, eth->mac_addr, sizeof(eth->mac_addr));
  info->netbuf_size = sizeof(txn_info_t);

  return ZX_OK;
}

static zx_status_t qmi_ethmac_start(void* ctx_cookie, const ethmac_ifc_t* ifc) {
  zxlogf(INFO, "qmi-usb-transport: %s called\n", __FUNCTION__);
  qmi_ctx_t* ctx = ctx_cookie;
  zx_status_t status = ZX_OK;

  mtx_lock(&ctx->ethmac_mutex);
  if (ctx->ethmac_ifc.ops) {
    status = ZX_ERR_ALREADY_BOUND;
  } else {
    ctx->ethmac_ifc = *ifc;
    ethmac_ifc_status(&ctx->ethmac_ifc, ctx->online ? ETHMAC_STATUS_ONLINE : 0);
  }

  mtx_unlock(&ctx->ethmac_mutex);
  return status;
}

static zx_status_t qmi_ethmac_set_param(void *cookie, uint32_t param, int32_t value,
                                        const void* data, size_t data_size) {
  return ZX_ERR_NOT_SUPPORTED;
}

static void qmi_ethmac_stop(void* cookie) {
  zxlogf(INFO, "qmi-usb-transport: %s called\n", __FUNCTION__);
  qmi_ctx_t* ctx = cookie;
  mtx_lock(&ctx->ethmac_mutex);
  ctx->ethmac_ifc.ops = NULL;
  mtx_unlock(&ctx->ethmac_mutex);
}

static zx_status_t qmi_ethmac_queue_tx(void* cookie, uint32_t options,
                                   ethmac_netbuf_t* netbuf) {
  qmi_ctx_t* ctx = cookie;
  size_t length = netbuf->data_size;
  zx_status_t status;

  // TODO mtu better
  if (length > 1024 || length == 0) {
    return ZX_ERR_INVALID_ARGS;
  }

  mtx_lock(&ctx->tx_mutex);
  if (ctx->unbound) {
    status = ZX_ERR_IO_NOT_PRESENT;
  } else {
    status = send_locked(ctx, netbuf);
    if (status == ZX_ERR_SHOULD_WAIT) {
      // No buffers available, queue it up
      txn_info_t* txn = containerof(netbuf, txn_info_t, netbuf);
      list_add_tail(&ctx->tx_pending_infos, &txn->node);
    }
  }

  mtx_unlock(&ctx->tx_mutex);
  return status;
}

static ethmac_protocol_ops_t ethmac_ops = {
    .query = qmi_ethmac_query,
    .stop = qmi_ethmac_stop,
    .start = qmi_ethmac_start,
    .queue_tx = qmi_ethmac_queue_tx,
    .set_param = qmi_ethmac_set_param,
};

static zx_protocol_device_t qmi_ops = {
    .version = DEVICE_OPS_VERSION,
    .ioctl = qmi_ioctl,
    .release = qmi_release,
    .unbind = qmi_unbind,
};

static zx_protocol_device_t eth_qmi_ops = {
    .version = DEVICE_OPS_VERSION,
};

static void qmi_handle_interrupt(qmi_ctx_t* qmi_ctx, usb_request_t* request) {
  if (request->response.actual < sizeof(usb_cdc_notification_t)) {
    zxlogf(ERROR, "qmi-usb-transport: ignored interrupt (size = %ld)\n",
           (long)request->response.actual);
    return;
  }

  usb_cdc_notification_t usb_req;
  usb_request_copy_from(request, &usb_req, sizeof(usb_cdc_notification_t), 0);

  uint16_t packet_size = qmi_ctx->max_packet_size;
  if (packet_size > 2048) {
    zxlogf(ERROR, "qmi-usb-transport: packet too big: %d\n", packet_size);
    return;
  }
  uint8_t buffer[packet_size];
  zx_status_t status;

  switch (usb_req.bNotification) {
    case USB_CDC_NC_RESPONSE_AVAILABLE:
      status = usb_control(
          &qmi_ctx->usb, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
          USB_CDC_GET_ENCAPSULATED_RESPONSE, 0, QMI_INTERFACE_NUM, buffer,
          packet_size, ZX_TIME_INFINITE, NULL);
      if (!qmi_ctx->channel) {
        zxlogf(
            WARN,
            "qmi-usb-transport: recieving USB CDC frames without a channel\n");
        return;
      }
      status = zx_channel_write(qmi_ctx->channel, 0, buffer, sizeof(buffer),
                                NULL, 0);
      if (status < 0) {
        zxlogf(ERROR,
               "qmi-usb-transport: failed to write message to channel: %s\n",
               zx_status_get_string(status));
      }
      return;
    default:
      zxlogf(ERROR, "qmi-usb-transport: Unknown Notification Type for QMI: %d\n",
             usb_req.bNotification);
  }
}

static void qmi_interrupt_cb(usb_request_t* req, void* cookie) {
  qmi_ctx_t* qmi_ctx = (qmi_ctx_t*)cookie;

  zx_port_packet_t packet = {};
  packet.key = INTERRUPT_MSG;
  zx_port_queue(qmi_ctx->channel_port, &packet);
}

static int qmi_transport_thread(void* cookie) {
  qmi_ctx_t* ctx = cookie;
  usb_request_t* txn = ctx->int_txn_buf;

  usb_request_queue(&ctx->usb, txn, qmi_interrupt_cb, ctx);
  if (ctx->max_packet_size > 2048) {
    zxlogf(ERROR, "qmi-usb-transport: packet too big: %d\n",
           ctx->max_packet_size);
    return ZX_ERR_IO_REFUSED;
  }
  uint8_t buffer[ctx->max_packet_size];
  uint32_t length = sizeof(buffer);
  zx_port_packet_t packet;
  while (true) {
    zx_status_t status =
        zx_port_wait(ctx->channel_port, ZX_TIME_INFINITE, &packet);
    if (status == ZX_ERR_TIMED_OUT) {
      zxlogf(ERROR, "qmi-usb-transport: timed out: %s\n",
             zx_status_get_string(status));
    } else {
      if (packet.key == CHANNEL_MSG) {
        status = zx_channel_read(ctx->channel, 0, buffer, NULL, sizeof(buffer),
                                 0, &length, NULL);
        if (status != ZX_OK) {
          zxlogf(ERROR, "qmi-usb-transport: failed to read channel: %s\n",
                 zx_status_get_string(status));
          return status;
        }
        status = usb_control(&ctx->usb,
                             USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                             USB_CDC_SEND_ENCAPSULATED_COMMAND, 0, 8, buffer,
                             length, ZX_TIME_INFINITE, NULL);
        if (status != ZX_OK) {
          zxlogf(ERROR,
                 "qmi-usb-transport: got an bad status from usb_control: %s\n",
                 zx_status_get_string(status));
          return status;
        }
        status = set_async_wait(ctx);
        if (status != ZX_OK) {
          return status;
        }
      } else if (packet.key == INTERRUPT_MSG) {
        if (txn->response.status == ZX_OK) {
          qmi_handle_interrupt(ctx, txn);
          usb_request_queue(&ctx->usb, txn, qmi_interrupt_cb, ctx);
        } else if (txn->response.status == ZX_ERR_PEER_CLOSED ||
                   txn->response.status == ZX_ERR_IO_NOT_PRESENT) {
          zxlogf(INFO,
                 "qmi-usb-transport: terminating interrupt handling thread\n");
          return txn->response.status;
        }
      }
    }
  }
}

// Note: the assumption made here is that no rx transmissions will be processed
// in parallel, so we do not maintain an rx mutex.
static void usb_recv(qmi_ctx_t* ctx, usb_request_t* request) {
  size_t len = request->response.actual;

  uint8_t* read_data;
  zx_status_t status = usb_request_mmap(request, (void*)&read_data);
  if (status != ZX_OK) {
    zxlogf(ERROR, "qmi-usb-transport: usb_request_mmap failed with status %d\n",
           status);
    return;
  }

  if (len > 2048) {
    zxlogf(ERROR, "qmi-usb-transport: recieved usb packet is too large: %zd\n", len);
    return;
  }

  uint8_t send_data[len + ETHERNET_FRAME_OFFSET];  // woo! VLA!
  send_data[0] = 0x62;                             // destination mac addr
  send_data[1] = 0x77;
  send_data[2] = 0x62;
  send_data[3] = 0x62;
  send_data[4] = 0x77;
  send_data[5] = 0x62;

  send_data[6] = 0x79;  // source mac addr
  send_data[7] = 0x61;
  send_data[8] = 0x6B;
  send_data[9] = 0x79;
  send_data[10] = 0x61;
  send_data[11] = 0x6B;

  send_data[12] = 0x08;
  send_data[13] = 0x00;

  memcpy(&send_data[ETHERNET_FRAME_OFFSET], read_data, len);
  mtx_lock(&ctx->ethmac_mutex);
  if (ctx->ethmac_ifc.ops) {
    ethmac_ifc_recv(&ctx->ethmac_ifc, send_data, len + ETHERNET_FRAME_OFFSET, 0);
  }
  mtx_unlock(&ctx->ethmac_mutex);
}

static void usb_read_complete(usb_request_t* request, void* cookie) {
  qmi_ctx_t* ctx = cookie;

  if (request->response.status != ZX_OK) {
    zxlogf(ERROR,
           "qmi-usb-transport: usb_read_complete called with status %d\n",
           (int)request->response.status);
  }

  if (request->response.status == ZX_ERR_IO_NOT_PRESENT) {
    usb_request_release(request);
    return;
  }

  if (request->response.status == ZX_ERR_IO_REFUSED) {
    zxlogf(ERROR, "qmi-usb-transport: resetting receive endpoint\n");
    usb_reset_endpoint(&ctx->usb, ctx->rx_endpoint_addr);
  } else if (request->response.status == ZX_ERR_IO_INVALID) {
    if (ctx->rx_endpoint_delay < ETHMAC_MAX_RECV_DELAY) {
      ctx->rx_endpoint_delay += ETHMAC_RECV_DELAY;
    }
    zxlogf(ERROR,
           "qmi-usb-transport: slowing down the requests by %d usec."
           "Resetting the recv endpoint\n",
           ETHMAC_RECV_DELAY);
    usb_reset_endpoint(&ctx->usb, ctx->rx_endpoint_addr);
  } else if (request->response.status == ZX_OK) {
    usb_recv(ctx, request);
  }

  zx_nanosleep(zx_deadline_after(ZX_USEC(ctx->rx_endpoint_delay)));
  usb_request_queue(&ctx->usb, request, usb_read_complete, ctx);
}

static void usb_write_complete(usb_request_t* request, void* cookie) {
  qmi_ctx_t* ctx = cookie;

  if (request->response.status == ZX_ERR_IO_NOT_PRESENT) {
    usb_request_release(request);
    return;
  }

  mtx_lock(&ctx->tx_mutex);

  // Return transmission buffer to pool
  zx_status_t status = usb_req_list_add_tail(&ctx->tx_txn_bufs, request, ctx->parent_req_size);
  ZX_DEBUG_ASSERT(status == ZX_OK);

  if (request->response.status == ZX_ERR_IO_REFUSED) {
    zxlogf(ERROR, "qmi-usb-transport: resetting transmit endpoint\n");
    usb_reset_endpoint(&ctx->usb, ctx->tx_endpoint_addr);
  }

  if (request->response.status == ZX_ERR_IO_INVALID) {
    zxlogf(ERROR,
           "qmi-usb-transport: slowing down the requests by %d usec."
           "Resetting the transmit endpoint\n",
           ETHMAC_TRANSMIT_DELAY);
    if (ctx->tx_endpoint_delay < ETHMAC_MAX_TRANSMIT_DELAY) {
      ctx->tx_endpoint_delay += ETHMAC_TRANSMIT_DELAY;
    }
    usb_reset_endpoint(&ctx->usb, ctx->tx_endpoint_addr);
  }

  bool additional_tx_queued = false;
  txn_info_t* txn;
  zx_status_t send_status = ZX_OK;
  if (!list_is_empty(&ctx->tx_pending_infos)) {
    txn = list_peek_head_type(&ctx->tx_pending_infos, txn_info_t, node);
    if ((send_status = send_locked(ctx, &txn->netbuf)) != ZX_ERR_SHOULD_WAIT) {
      list_remove_head(&ctx->tx_pending_infos);
      additional_tx_queued = true;
    }
  }

  mtx_unlock(&ctx->tx_mutex);

  mtx_lock(&ctx->ethmac_mutex);
  if (additional_tx_queued && ctx->ethmac_ifc.ops) {
    ethmac_ifc_complete_tx(&ctx->ethmac_ifc, &txn->netbuf, send_status);
  }
  mtx_unlock(&ctx->ethmac_mutex);

  // When the interface is offline, the transaction will complete with status
  // set to ZX_ERR_IO_NOT_PRESENT. There's not much we can do except ignore it.
}

static zx_status_t qmi_bind(void* ctx, zx_device_t* device) {
  zx_status_t status;
  qmi_ctx_t* qmi_ctx;
  usb_request_t* int_buf = NULL;
  if ((qmi_ctx = calloc(1, sizeof(qmi_ctx_t))) == NULL) {
    return ZX_ERR_NO_MEMORY;
  }

  // Set up USB stuff
  usb_protocol_t usb;
  status = device_get_protocol(device, ZX_PROTOCOL_USB, &usb);
  if (status != ZX_OK) {
    zxlogf(ERROR, "qmi-usb-transport: get protocol failed: %s\n",
           zx_status_get_string(status));
    goto fail;
  }

  // Initialize context
  qmi_ctx->usb_device = device;
  memcpy(&qmi_ctx->usb, &usb, sizeof(qmi_ctx->usb));
  list_initialize(&qmi_ctx->tx_txn_bufs);
  list_initialize(&qmi_ctx->tx_pending_infos);
  mtx_init(&qmi_ctx->ethmac_mutex, mtx_plain);
  mtx_init(&qmi_ctx->tx_mutex, mtx_plain);

  qmi_ctx->parent_req_size = usb_get_request_size(&qmi_ctx->usb);
  uint64_t req_size = qmi_ctx->parent_req_size + sizeof(usb_req_internal_t);
  ZX_DEBUG_ASSERT(qmi_ctx->parent_req_size != 0);

  // find our endpoints
  usb_desc_iter_t iter;
  zx_status_t result = usb_desc_iter_init(&usb, &iter);
  if (result < 0) {
    goto fail;
  }

  // QMI needs to bind to interface QMI_INTERFACE_NUM on current hardware.
  // Ignore the others for now.
  // TODO generic way of describing usb interfaces
  usb_interface_descriptor_t* intf = usb_desc_iter_next_interface(&iter, true);
  if (!intf || intf->bInterfaceNumber != QMI_INTERFACE_NUM) {
    usb_desc_iter_release(&iter);
    status = ZX_ERR_NOT_SUPPORTED;
    goto failnoerr;  // this is not a big deal, just don't bind
  }

  if (intf->bNumEndpoints != 3) {
    zxlogf(ERROR,
           "qmi-usb-transport: interface does not have the required 3 "
           "endpoints\n");
    usb_desc_iter_release(&iter);
    status = ZX_ERR_NOT_SUPPORTED;
    goto fail;
  }

  uint8_t bulk_in_addr = 0;
  uint8_t bulk_out_addr = 0;
  uint8_t intr_addr = 0;
  uint16_t intr_max_packet = 0;
  uint16_t bulk_max_packet = 0;

  usb_descriptor_header_t* desc = usb_desc_iter_next(&iter);
  while (desc) {
    if (desc->bDescriptorType == USB_DT_ENDPOINT) {
      usb_endpoint_descriptor_t* endp = (void*)desc;
      if (usb_ep_direction(endp) == USB_ENDPOINT_OUT) {
        if (usb_ep_type(endp) == USB_ENDPOINT_BULK) {
          bulk_out_addr = endp->bEndpointAddress;
          bulk_max_packet = usb_ep_max_packet(endp);
        }
      } else {
        if (usb_ep_type(endp) == USB_ENDPOINT_BULK) {
          bulk_in_addr = endp->bEndpointAddress;
        } else if (usb_ep_type(endp) == USB_ENDPOINT_INTERRUPT) {
          intr_addr = endp->bEndpointAddress;
          intr_max_packet = usb_ep_max_packet(endp);
        }
      }
    }
    desc = usb_desc_iter_next(&iter);
  }
  usb_desc_iter_release(&iter);

  if (bulk_in_addr == 0 || bulk_out_addr == 0 || intr_addr == 0) {
    zxlogf(ERROR, "qmi-usb-transport: failed to find one of the usb endpoints");
    goto fail;
  }

  if (intr_max_packet < 1 || bulk_max_packet < 1) {
    zxlogf(ERROR,
           "qmi-usb-transport: failed to find reasonable max packet sizes");
    goto fail;
  }

  qmi_ctx->rx_endpoint_delay = ETHMAC_INITIAL_RECV_DELAY;
  qmi_ctx->tx_endpoint_delay = ETHMAC_INITIAL_TRANSMIT_DELAY;
  // Reset by selecting default interface followed by data interface. We can't
  // start queueing transactions until this is complete.
  usb_set_interface(&usb, 8, 0);

  // set up interrupt
  status = usb_request_alloc(&int_buf, intr_max_packet, intr_addr, req_size);
  qmi_ctx->max_packet_size = bulk_max_packet;
  if (status != ZX_OK) {
    zxlogf(ERROR, "qmi-usb-transport: failed to allocate for usb request: %s\n",
           zx_status_get_string(status));
    goto fail;
  }
  qmi_ctx->int_txn_buf = int_buf;

  // create port to watch for interrupts and channel messages
  status = zx_port_create(0, &qmi_ctx->channel_port);
  if (status != ZX_OK) {
    zxlogf(ERROR, "qmi-usb-transport: failed to create a port: %s\n",
           zx_status_get_string(status));
    goto fail;
  }
  qmi_ctx->tx_endpoint_addr = bulk_out_addr;
  qmi_ctx->rx_endpoint_addr = bulk_in_addr;
  qmi_ctx->endpoint_size = bulk_max_packet;

  // Allocate tx transaction buffers
  // TODO uint16_t tx_buf_sz = qmi_ctx->mtu;
  uint16_t tx_buf_sz = 1024;
  size_t tx_buf_remain = MAX_TX_BUF_SZ;
  while (tx_buf_remain >= tx_buf_sz) {
    usb_request_t* tx_buf;
    zx_status_t alloc_result = usb_request_alloc(
        &tx_buf, tx_buf_sz, qmi_ctx->tx_endpoint_addr, qmi_ctx->parent_req_size);
    if (alloc_result != ZX_OK) {
      result = alloc_result;
      goto fail;
    }

    // As per the CDC-ECM spec, we need to send a zero-length packet to signify
    // the end of transmission when the endpoint max packet size is a factor of
    // the total transmission size
    tx_buf->header.send_zlp = true;

    zx_status_t status = usb_req_list_add_head(&qmi_ctx->tx_txn_bufs, tx_buf,
                                               qmi_ctx->parent_req_size);
    ZX_DEBUG_ASSERT(status == ZX_OK);
    tx_buf_remain -= tx_buf_sz;
  }

  // Allocate rx transaction buffers
  // TODO(bwb) get correct buffer sizes from usb
  uint16_t rx_buf_sz = 1024;
  size_t rx_buf_remain = MAX_RX_BUF_SZ;
  while (rx_buf_remain >= rx_buf_sz) {
    usb_request_t* rx_buf;
    zx_status_t alloc_result = usb_request_alloc(
        &rx_buf, rx_buf_sz, qmi_ctx->rx_endpoint_addr, req_size);
    if (alloc_result != ZX_OK) {
      result = alloc_result;
      goto fail;
    }

    usb_request_queue(&qmi_ctx->usb, rx_buf, usb_read_complete, qmi_ctx);
    rx_buf_remain -= rx_buf_sz;
  }

  // Set MAC addr
  qmi_ctx->mac_addr[0] = 0x62;
  qmi_ctx->mac_addr[1] = 0x77;
  qmi_ctx->mac_addr[2] = 0x62;
  qmi_ctx->mac_addr[3] = 0x62;
  qmi_ctx->mac_addr[4] = 0x77;
  qmi_ctx->mac_addr[5] = 0x62;

  // Kick off the handler thread
  int thread_result =
      thrd_create_with_name(&qmi_ctx->int_thread, qmi_transport_thread, qmi_ctx,
                            "qmi_transport_thread");
  if (thread_result != thrd_success) {
    zxlogf(ERROR, "qmi-usb-transport: failed to create transport thread (%d)\n",
           thread_result);
    goto fail;
  }

  device_add_args_t eth_args = {
      .version = DEVICE_ADD_ARGS_VERSION,
      .name = "qmi-cdc-ethernet",
      .ctx = qmi_ctx,
      // sibling of qmi transport. Cleanup happens when qmi device unbinds
      .ops = &eth_qmi_ops,
      .proto_id = ZX_PROTOCOL_ETHMAC,
      .proto_ops = &ethmac_ops,
  };
  result = device_add(device, &eth_args, &qmi_ctx->eth_zxdev);
  if (result < 0) {
    zxlogf(ERROR, "qmi-usb-transport: failed to add ethernet device: %d\n",
           (int)result);
    goto fail;
  }

  // Add the devices
  device_add_args_t args = {
      .version = DEVICE_ADD_ARGS_VERSION,
      .name = "qmi-usb-transport",
      .ctx = qmi_ctx,
      .ops = &qmi_ops,
      .proto_id = ZX_PROTOCOL_QMI_TRANSPORT,
  };

  if ((status = device_add(device, &args, &qmi_ctx->zxdev)) < 0) {
    goto fail;
  }

  return ZX_OK;

fail:
  zxlogf(ERROR, "qmi-usb-transport: bind failed: %s\n",
         zx_status_get_string(status));
failnoerr:
  if (int_buf) {
    usb_request_release(int_buf);
  }
  free(qmi_ctx);
  return status;
}

static zx_driver_ops_t qmi_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = qmi_bind,
};

// clang-format off
ZIRCON_DRIVER_BEGIN(qmi_usb, qmi_driver_ops, "zircon", "0.1", 3)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_USB),
    BI_ABORT_IF(NE, BIND_USB_VID, SIERRA_VID),
    BI_MATCH_IF(EQ, BIND_USB_PID, EM7565_PID),
ZIRCON_DRIVER_END(qmi_usb)
