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

#include <ddk/binding.h>
#include <ddk/debug.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/ethernet.h>
#include <ddk/protocol/usb-old.h>
#include <ddk/protocol/usb/composite.h>
#include <ddk/usb/usb.h>
#include <usb/usb-request.h>
#include <zircon/hw/usb/cdc.h>
#include <lib/sync/completion.h>

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>

#define CDC_SUPPORTED_VERSION 0x0110 /* 1.10 */

// 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

const char* module_name = "usb-cdc-ecm";

typedef struct {
    uint8_t addr;
    uint16_t max_packet_size;
} ecm_endpoint_t;

typedef struct {
    zx_device_t* zxdev;
    zx_device_t* usb_device;
    usb_protocol_t usb;

    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;

    // Interrupt handling
    ecm_endpoint_t int_endpoint;
    usb_request_t* int_txn_buf;
    sync_completion_t completion;
    thrd_t int_thread;

    // Send context
    mtx_t tx_mutex;
    ecm_endpoint_t tx_endpoint;
    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

    size_t parent_req_size;

    // Receive context
    ecm_endpoint_t rx_endpoint;
    uint64_t rx_endpoint_delay;    // wait time between 2 recv requests
} ecm_ctx_t;

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

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

static void ecm_unbind(void* cookie) {
    zxlogf(TRACE, "%s: unbinding\n", module_name);
    ecm_ctx_t* ctx = cookie;

    mtx_lock(&ctx->tx_mutex);
    ctx->unbound = true;
    if (ctx->ethmac_ifc.ops) {
        txn_info_t* txn;
        while ((txn = list_remove_head_type(&ctx->tx_pending_infos, txn_info_t, node)) !=
               NULL) {
            ethmac_ifc_complete_tx(&ctx->ethmac_ifc, &txn->netbuf, ZX_ERR_PEER_CLOSED);
        }
    }
    mtx_unlock(&ctx->tx_mutex);

    device_remove(ctx->zxdev);
}

static void ecm_free(ecm_ctx_t* ctx) {
    zxlogf(TRACE, "%s: deallocating memory\n", module_name);
    if (ctx->int_thread) {
        thrd_join(ctx->int_thread, NULL);
    }
    usb_request_t* txn;
    while ((txn = usb_req_list_remove_head(&ctx->tx_txn_bufs, ctx->parent_req_size)) != NULL) {
        usb_request_release(txn);
    }
    if (ctx->int_txn_buf) {
        usb_request_release(ctx->int_txn_buf);
    }
    mtx_destroy(&ctx->ethmac_mutex);
    mtx_destroy(&ctx->tx_mutex);
    free(ctx);
}

static void ecm_release(void* ctx) {
    ecm_ctx_t* eth = ctx;
    ecm_free(eth);
}

static zx_protocol_device_t ecm_device_proto = {
    .version = DEVICE_OPS_VERSION,
    .unbind = ecm_unbind,
    .release = ecm_release,
};

static void ecm_update_online_status(ecm_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, "%s: connected to network\n", module_name);
        ctx->online = true;
        if (ctx->ethmac_ifc.ops) {
            ethmac_ifc_status(&ctx->ethmac_ifc, ETHMAC_STATUS_ONLINE);
        } else {
            zxlogf(ERROR, "%s: not connected to ethermac interface\n", module_name);
        }
    } else {
        zxlogf(INFO, "%s: no connection to network\n", module_name);
        ctx->online = false;
        if (ctx->ethmac_ifc.ops) {
            ethmac_ifc_status(&ctx->ethmac_ifc, 0);
        }
    }

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

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

    zxlogf(TRACE, "%s: %s called\n", module_name, __FUNCTION__);

    // No options are supported
    if (options) {
        zxlogf(ERROR, "%s: unexpected options (0x%"PRIx32") to ecm_ethmac_query\n", module_name,
               options);
        return ZX_ERR_INVALID_ARGS;
    }

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

    return ZX_OK;
}

static void ecm_ethmac_stop(void* cookie) {
    zxlogf(TRACE, "%s: %s called\n", module_name, __FUNCTION__);
    ecm_ctx_t* ctx = cookie;
    mtx_lock(&ctx->ethmac_mutex);
    ctx->ethmac_ifc.ops = NULL;
    mtx_unlock(&ctx->ethmac_mutex);
}

static zx_status_t ecm_ethmac_start(void* ctx_cookie, const ethmac_ifc_t* ifc) {
    zxlogf(TRACE, "%s: %s called\n", module_name, __FUNCTION__);
    ecm_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 queue_request(ecm_ctx_t* ctx, const uint8_t* data, size_t length,
                                 usb_request_t* req) {
    req->header.length = length;
    ssize_t bytes_copied = usb_request_copy_to(req, data, length, 0);
    if (bytes_copied < 0) {
        zxlogf(ERROR, "%s: failed to copy data into send txn (error %zd)\n", module_name, 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(ecm_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 usb_write_complete(usb_request_t* request, void* cookie) {
    ecm_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(TRACE, "%s: resetting transmit endpoint\n", module_name);
        usb_reset_endpoint(&ctx->usb, ctx->tx_endpoint.addr);
    }

    if (request->response.status == ZX_ERR_IO_INVALID) {
        zxlogf(TRACE, "%s: slowing down the requests by %d usec."
                     "Resetting the transmit endpoint\n",
               module_name, 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.
}

// 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(ecm_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, "%s: usb_request_mmap failed with status %d\n",
                module_name, status);
        return;
    }

    mtx_lock(&ctx->ethmac_mutex);
    if (ctx->ethmac_ifc.ops) {
        ethmac_ifc_recv(&ctx->ethmac_ifc, read_data, len, 0);
    }
    mtx_unlock(&ctx->ethmac_mutex);
}

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

    if (request->response.status != ZX_OK) {
        zxlogf(TRACE, "%s: usb_read_complete called with status %d\n",
                module_name, (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(TRACE, "%s: resetting receive endpoint\n", module_name);
        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(TRACE, "%s: slowing down the requests by %d usec."
                     "Resetting the recv endpoint\n",
               module_name, 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 zx_status_t ecm_ethmac_queue_tx(void* cookie, uint32_t options, ethmac_netbuf_t* netbuf) {
    ecm_ctx_t* ctx = cookie;
    size_t length = netbuf->data_size;
    zx_status_t status;

    if (length > ctx->mtu || length == 0) {
        return ZX_ERR_INVALID_ARGS;
    }

    zxlogf(SPEW, "%s: sending %zu bytes to endpoint 0x%"PRIx8"\n",
            module_name, length, ctx->tx_endpoint.addr);

    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 zx_status_t ecm_ethmac_set_param(void *cookie, uint32_t param, int32_t value,
                                        const void* data, size_t data_size) {
    return ZX_ERR_NOT_SUPPORTED;
}

static ethmac_protocol_ops_t ethmac_ops = {
    .query = ecm_ethmac_query,
    .stop = ecm_ethmac_stop,
    .start = ecm_ethmac_start,
    .queue_tx = ecm_ethmac_queue_tx,
    .set_param = ecm_ethmac_set_param,
};

static void ecm_interrupt_complete(usb_request_t* request, void* cookie) {
    ecm_ctx_t* ctx = cookie;
    sync_completion_signal(&ctx->completion);
}

static void ecm_handle_interrupt(ecm_ctx_t* ctx, usb_request_t* request) {
    if (request->response.actual < sizeof(usb_cdc_notification_t)) {
        zxlogf(ERROR, "%s: ignored interrupt (size = %ld)\n", module_name, (long)request->response.actual);
        return;
    }

    usb_cdc_notification_t usb_req;
    usb_request_copy_from(request, &usb_req, sizeof(usb_cdc_notification_t), 0);
    if (usb_req.bmRequestType == (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) &&
        usb_req.bNotification == USB_CDC_NC_NETWORK_CONNECTION) {
        ecm_update_online_status(ctx, usb_req.wValue != 0);
    } else if (usb_req.bmRequestType == (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) &&
               usb_req.bNotification == USB_CDC_NC_CONNECTION_SPEED_CHANGE) {
        // The ethermac driver doesn't care about speed changes, so even though we track this
        // information, it's currently unused.
        if (usb_req.wLength != 8) {
            zxlogf(ERROR, "%s: invalid size (%"PRIu16") for CONNECTION_SPEED_CHANGE notification\n",
                   module_name, usb_req.wLength);
            return;
        }
        // Data immediately follows notification in packet
        uint32_t new_us_bps, new_ds_bps;
        usb_request_copy_from(request, &new_us_bps, 4, sizeof(usb_cdc_notification_t));
        usb_request_copy_from(request, &new_ds_bps, 4, sizeof(usb_cdc_notification_t) + 4);
        if (new_us_bps != ctx->us_bps) {
            zxlogf(ERROR, "%s: connection speed change... upstream bits/s: %"PRIu32"\n",
                    module_name, new_us_bps);
            ctx->us_bps = new_us_bps;
        }
        if (new_ds_bps != ctx->ds_bps) {
            zxlogf(ERROR, "%s: connection speed change... downstream bits/s: %"PRIu32"\n",
                    module_name, new_ds_bps);
            ctx->ds_bps = new_ds_bps;
        }
    }  else {
        zxlogf(ERROR, "%s: ignored interrupt (type = %"PRIu8", request = %"PRIu8")\n",
               module_name, usb_req.bmRequestType, usb_req.bNotification);
        return;
    }
}

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

    while (true) {
        sync_completion_reset(&ctx->completion);
        usb_request_queue(&ctx->usb, txn, ecm_interrupt_complete, ctx);
        sync_completion_wait(&ctx->completion, ZX_TIME_INFINITE);
        if (txn->response.status == ZX_OK) {
            ecm_handle_interrupt(ctx, txn);
        } else if (txn->response.status == ZX_ERR_PEER_CLOSED ||
                   txn->response.status == ZX_ERR_IO_NOT_PRESENT) {
            zxlogf(TRACE, "%s: terminating interrupt handling thread\n", module_name);
            return txn->response.status;
        } else if (txn->response.status == ZX_ERR_IO_REFUSED ||
                   txn->response.status == ZX_ERR_IO_INVALID) {
            zxlogf(TRACE, "%s: resetting interrupt endpoint\n", module_name);
            usb_reset_endpoint(&ctx->usb, ctx->int_endpoint.addr);
        } else {
            zxlogf(ERROR, "%s: error (%ld) waiting for interrupt - ignoring\n",
                   module_name, (long)txn->response.status);
        }
    }
}

static bool parse_cdc_header(usb_cs_header_interface_descriptor_t* header_desc) {
    // Check for supported CDC version
    zxlogf(TRACE, "%s: device reports CDC version as 0x%x\n", module_name, header_desc->bcdCDC);
    return header_desc->bcdCDC >= CDC_SUPPORTED_VERSION;
}

static bool parse_cdc_ethernet_descriptor(ecm_ctx_t* ctx,
                                          usb_cs_ethernet_interface_descriptor_t* desc) {
    ctx->mtu = desc->wMaxSegmentSize;

    // MAC address is stored in a string descriptor in UTF-16 format, so we get one byte of
    // address for each 32 bits of text.
    const size_t expected_str_size = sizeof(usb_string_descriptor_t) + ETH_MAC_SIZE * 4;
    char str_desc_buf[expected_str_size];

    // Read string descriptor for MAC address (string index is in iMACAddress field)
    size_t out_length;
    zx_status_t result = usb_get_descriptor(&ctx->usb, 0, USB_DT_STRING, desc->iMACAddress,
                                            str_desc_buf, sizeof(str_desc_buf), ZX_TIME_INFINITE,
                                            &out_length);
    if (result < 0) {
        zxlogf(ERROR, "%s: error reading MAC address\n", module_name);
        return false;
    }
    if (out_length != expected_str_size) {
        zxlogf(ERROR, "%s: MAC address string incorrect length (saw %zd, expected %zd)\n",
               module_name, out_length, expected_str_size);
        return false;
    }

    // Convert MAC address to something more machine-friendly
    usb_string_descriptor_t* str_desc = (usb_string_descriptor_t*)str_desc_buf;
    uint8_t* str = str_desc->bString;
    size_t ndx;
    for (ndx = 0; ndx < ETH_MAC_SIZE * 4; ndx++) {
        if (ndx % 2 == 1) {
            if (str[ndx] != 0) {
                zxlogf(ERROR, "%s: MAC address contains invalid characters\n", module_name);
                return false;
            }
            continue;
        }
        uint8_t value;
        if (str[ndx] >= '0' && str[ndx] <= '9') {
            value = str[ndx] - '0';
        } else if (str[ndx] >= 'A' && str[ndx] <= 'F') {
            value = (str[ndx] - 'A') + 0xa;
        } else {
            zxlogf(ERROR, "%s: MAC address contains invalid characters\n", module_name);
            return false;
        }
        if (ndx % 4 == 0) {
            ctx->mac_addr[ndx/4] = value << 4;
        } else {
            ctx->mac_addr[ndx/4] |= value;
        }
    }

    zxlogf(ERROR, "%s: MAC address is %02X:%02X:%02X:%02X:%02X:%02X\n", module_name,
           ctx->mac_addr[0], ctx->mac_addr[1], ctx->mac_addr[2],
            ctx->mac_addr[3], ctx->mac_addr[4], ctx->mac_addr[5]);
    return true;
}

static void copy_endpoint_info(ecm_endpoint_t* ep_info, usb_endpoint_descriptor_t* desc) {
    ep_info->addr = desc->bEndpointAddress;
    ep_info->max_packet_size = desc->wMaxPacketSize;
}

static bool want_interface(usb_interface_descriptor_t* intf, void* arg) {
    return intf->bInterfaceClass == USB_CLASS_CDC;
}

static zx_status_t ecm_bind(void* ctx, zx_device_t* device) {
    zxlogf(TRACE, "%s: starting %s\n", module_name, __FUNCTION__);

    usb_protocol_t usb;
    zx_status_t result = device_get_protocol(device, ZX_PROTOCOL_USB_OLD, &usb);
    if (result != ZX_OK) {
        return result;
    }
    usb_composite_protocol_t usb_composite;
    result = device_get_protocol(device, ZX_PROTOCOL_USB_COMPOSITE, &usb_composite);
    if (result != ZX_OK) {
        return result;
    }

    // Allocate context
    ecm_ctx_t* ecm_ctx = calloc(1, sizeof(ecm_ctx_t));
    if (!ecm_ctx) {
        zxlogf(ERROR, "%s: failed to allocate memory for USB CDC ECM driver\n", module_name);
        return ZX_ERR_NO_MEMORY;
    }

    result = usb_claim_additional_interfaces(&usb_composite, want_interface, NULL);
    if (result != ZX_OK) {
        goto fail;
    }
    // Initialize context
    ecm_ctx->usb_device = device;
    memcpy(&ecm_ctx->usb, &usb, sizeof(ecm_ctx->usb));
    list_initialize(&ecm_ctx->tx_txn_bufs);
    list_initialize(&ecm_ctx->tx_pending_infos);
    mtx_init(&ecm_ctx->ethmac_mutex, mtx_plain);
    mtx_init(&ecm_ctx->tx_mutex, mtx_plain);

    ecm_ctx->parent_req_size = usb_get_request_size(&ecm_ctx->usb);

    usb_desc_iter_t iter;
    result = usb_desc_iter_init(&usb, &iter);
    if (result != ZX_OK) {
        goto fail;
    }
    result = ZX_ERR_NOT_SUPPORTED;

    // Find the CDC descriptors and endpoints
    usb_descriptor_header_t* desc = usb_desc_iter_next(&iter);
    usb_cs_header_interface_descriptor_t* cdc_header_desc = NULL;
    usb_cs_ethernet_interface_descriptor_t* cdc_eth_desc = NULL;
    usb_endpoint_descriptor_t* int_ep = NULL;
    usb_endpoint_descriptor_t* tx_ep = NULL;
    usb_endpoint_descriptor_t* rx_ep = NULL;
    usb_interface_descriptor_t* default_ifc = NULL;
    usb_interface_descriptor_t* data_ifc = NULL;
    while (desc) {
        if (desc->bDescriptorType == USB_DT_INTERFACE) {
            usb_interface_descriptor_t* ifc_desc = (void*)desc;
            if (ifc_desc->bInterfaceClass == USB_CLASS_CDC) {
                if (ifc_desc->bNumEndpoints == 0) {
                    if (default_ifc) {
                        zxlogf(ERROR, "%s: multiple default interfaces found\n", module_name);
                        goto fail;
                    }
                    default_ifc = ifc_desc;
                } else if (ifc_desc->bNumEndpoints == 2) {
                    if (data_ifc) {
                        zxlogf(ERROR, "%s: multiple data interfaces found\n", module_name);
                        goto fail;
                    }
                    data_ifc = ifc_desc;
                }
            }
        } else if (desc->bDescriptorType == USB_DT_CS_INTERFACE) {
            usb_cs_interface_descriptor_t* cs_ifc_desc = (void*)desc;
            if (cs_ifc_desc->bDescriptorSubType == USB_CDC_DST_HEADER) {
                if (cdc_header_desc != NULL) {
                    zxlogf(ERROR, "%s: multiple CDC headers\n", module_name);
                    goto fail;
                }
                cdc_header_desc = (void*)cs_ifc_desc;
            } else if (cs_ifc_desc->bDescriptorSubType == USB_CDC_DST_ETHERNET) {
                if (cdc_eth_desc != NULL) {
                    zxlogf(ERROR, "%s: multiple CDC ethernet descriptors\n", module_name);
                    goto fail;
                }
                cdc_eth_desc = (void*)cs_ifc_desc;
            }
        } else if (desc->bDescriptorType == USB_DT_ENDPOINT) {
            usb_endpoint_descriptor_t* endpoint_desc = (void*)desc;
            if (usb_ep_direction(endpoint_desc) == USB_ENDPOINT_IN &&
                usb_ep_type(endpoint_desc) == USB_ENDPOINT_INTERRUPT) {
                if (int_ep != NULL) {
                    zxlogf(ERROR, "%s: multiple interrupt endpoint descriptors\n", module_name);
                    goto fail;
                }
                int_ep = endpoint_desc;
            } else if (usb_ep_direction(endpoint_desc) == USB_ENDPOINT_OUT &&
                       usb_ep_type(endpoint_desc) == USB_ENDPOINT_BULK) {
                if (tx_ep != NULL) {
                    zxlogf(ERROR, "%s: multiple tx endpoint descriptors\n", module_name);
                    goto fail;
                }
                tx_ep = endpoint_desc;
            } else if (usb_ep_direction(endpoint_desc) == USB_ENDPOINT_IN &&
                       usb_ep_type(endpoint_desc) == USB_ENDPOINT_BULK) {
                if (rx_ep != NULL) {
                    zxlogf(ERROR, "%s: multiple rx endpoint descriptors\n", module_name);
                    goto fail;
                }
                rx_ep = endpoint_desc;
            } else {
                zxlogf(ERROR, "%s: unrecognized endpoint\n", module_name);
                goto fail;
            }
        }
        desc = usb_desc_iter_next(&iter);
    }
    if (cdc_header_desc == NULL || cdc_eth_desc == NULL) {
        zxlogf(ERROR, "%s: CDC %s descriptor(s) not found", module_name,
               cdc_header_desc ? "ethernet" : cdc_eth_desc ? "header" : "ethernet and header");
        goto fail;
    }
    if (int_ep == NULL || tx_ep == NULL || rx_ep == NULL) {
        zxlogf(ERROR, "%s: missing one or more required endpoints\n", module_name);
        goto fail;
    }
    if (default_ifc == NULL) {
        zxlogf(ERROR, "%s: unable to find CDC default interface\n", module_name);
        goto fail;
    }
    if (data_ifc == NULL) {
        zxlogf(ERROR, "%s: unable to find CDC data interface\n", module_name);
        goto fail;
    }

    // Parse the information in the CDC descriptors
    if (!parse_cdc_header(cdc_header_desc)) {
        goto fail;
    }
    if (!parse_cdc_ethernet_descriptor(ecm_ctx, cdc_eth_desc)) {
        goto fail;
    }

    // Parse endpoint information
    copy_endpoint_info(&ecm_ctx->int_endpoint, int_ep);
    copy_endpoint_info(&ecm_ctx->tx_endpoint, tx_ep);
    copy_endpoint_info(&ecm_ctx->rx_endpoint, rx_ep);

    ecm_ctx->rx_endpoint_delay = ETHMAC_INITIAL_RECV_DELAY;
    ecm_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, default_ifc->bInterfaceNumber, default_ifc->bAlternateSetting);
    usb_set_interface(&usb, data_ifc->bInterfaceNumber, data_ifc->bAlternateSetting);

    // Allocate interrupt transaction buffer
    usb_request_t* int_buf;
    uint64_t req_size = ecm_ctx->parent_req_size + sizeof(usb_req_internal_t);
    zx_status_t alloc_result = usb_request_alloc(&int_buf,
                                             ecm_ctx->int_endpoint.max_packet_size,
                                             ecm_ctx->int_endpoint.addr, req_size);
    if (alloc_result != ZX_OK) {
        result = alloc_result;
        goto fail;
    }

    ecm_ctx->int_txn_buf = int_buf;

    // Allocate tx transaction buffers
    uint16_t tx_buf_sz = ecm_ctx->mtu;
#if MAX_TX_BUF_SZ < UINT16_MAX
    if (tx_buf_sz > MAX_TX_BUF_SZ) {
        zxlogf(ERROR, "%s: insufficient space for even a single tx buffer\n", module_name);
        goto fail;
    }
#endif
    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,
                                                     ecm_ctx->tx_endpoint.addr, 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 add_result = usb_req_list_add_head(&ecm_ctx->tx_txn_bufs, tx_buf,
                                                       ecm_ctx->parent_req_size);
        ZX_DEBUG_ASSERT(add_result == ZX_OK);

        tx_buf_remain -= tx_buf_sz;
    }

    // Allocate rx transaction buffers
    uint16_t rx_buf_sz = ecm_ctx->mtu;
#if MAX_TX_BUF_SZ < UINT16_MAX
    if (rx_buf_sz > MAX_RX_BUF_SZ) {
        zxlogf(ERROR, "%s: insufficient space for even a single rx buffer\n", module_name);
        goto fail;
    }
#endif
    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,
                                                 ecm_ctx->rx_endpoint.addr,
                                                 req_size);
        if (alloc_result != ZX_OK) {
            result = alloc_result;
            goto fail;
        }

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

    // Kick off the handler thread
    int thread_result = thrd_create_with_name(&ecm_ctx->int_thread, ecm_int_handler_thread,
                                              ecm_ctx, "ecm_int_handler_thread");
    if (thread_result != thrd_success) {
        zxlogf(ERROR, "%s: failed to create interrupt handler thread (%d)\n", module_name, thread_result);
        goto fail;
    }

    // Add the device
    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "usb-cdc-ecm",
        .ctx = ecm_ctx,
        .ops = &ecm_device_proto,
        .proto_id = ZX_PROTOCOL_ETHMAC,
        .proto_ops = &ethmac_ops,
    };
    result = device_add(ecm_ctx->usb_device, &args, &ecm_ctx->zxdev);
    if (result < 0) {
        zxlogf(ERROR, "%s: failed to add device: %d\n", module_name, (int)result);
        goto fail;
    }

    usb_desc_iter_release(&iter);
    return ZX_OK;

fail:
    usb_desc_iter_release(&iter);
    ecm_free(ecm_ctx);
    zxlogf(ERROR, "%s: failed to bind\n", module_name);
    return result;
}

static zx_driver_ops_t ecm_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = ecm_bind,
};

ZIRCON_DRIVER_BEGIN(ethernet_usb_cdc_ecm, ecm_driver_ops, "zircon", "0.1", 4)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_USB_OLD),
    BI_ABORT_IF(NE, BIND_USB_CLASS, USB_CLASS_COMM),
    BI_ABORT_IF(NE, BIND_USB_SUBCLASS, USB_CDC_SUBCLASS_ETHERNET),
    BI_MATCH_IF(EQ, BIND_USB_PROTOCOL, 0),
ZIRCON_DRIVER_END(ethernet_usb_cdc_ecm)
