// 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 <assert.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <threads.h>

#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-function.h>
#include <inet6/inet6.h>
#include <usb/usb-request.h>
#include <zircon/listnode.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/device/usb-peripheral.h>
#include <zircon/hw/usb-cdc.h>

#define BULK_REQ_SIZE   2048
#define BULK_TX_COUNT   16
#define BULK_RX_COUNT   16

#define BULK_MAX_PACKET     512 // FIXME(voydanoff) USB 3.0 support
#define INTR_MAX_PACKET     sizeof(usb_cdc_speed_change_notification_t)

#define CDC_BITRATE         1000000000  // say we are gigabit

typedef struct {
    zx_device_t* zxdev;
    usb_function_protocol_t function;

    list_node_t bulk_out_reqs;      // list of usb_request_t
    list_node_t bulk_in_reqs;       // list of usb_request_t
    list_node_t tx_pending_infos;   // list of ethmac_netbuf_t
    bool unbound;                   // set to true when device is going away. Guarded by tx_mutex

    // Device attributes
    uint8_t mac_addr[ETH_MAC_SIZE];

    mtx_t ethmac_mutex;
    ethmac_ifc_t* ethmac_ifc;
    void* ethmac_cookie;
    bool online;

    mtx_t tx_mutex;
    mtx_t rx_mutex;

    uint8_t bulk_out_addr;
    uint8_t bulk_in_addr;
    uint8_t intr_addr;
    uint16_t bulk_max_packet;
} usb_cdc_t;

 static struct {
    usb_interface_descriptor_t comm_intf;
    usb_cs_header_interface_descriptor_t cdc_header;
    usb_cs_union_interface_descriptor_1_t cdc_union;
    usb_cs_ethernet_interface_descriptor_t cdc_eth;
    usb_endpoint_descriptor_t intr_ep;
    usb_interface_descriptor_t cdc_intf_0;
    usb_interface_descriptor_t cdc_intf_1;
    usb_endpoint_descriptor_t bulk_out_ep;
    usb_endpoint_descriptor_t bulk_in_ep;
} descriptors = {
    .comm_intf = {
        .bLength = sizeof(usb_interface_descriptor_t),
        .bDescriptorType = USB_DT_INTERFACE,
//      .bInterfaceNumber set later
        .bAlternateSetting = 0,
        .bNumEndpoints = 1,
        .bInterfaceClass = USB_CLASS_COMM,
        .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET,
        .bInterfaceProtocol = 0,
        .iInterface = 0,
    },
    .cdc_header = {
        .bLength = sizeof(usb_cs_header_interface_descriptor_t),
        .bDescriptorType = USB_DT_CS_INTERFACE,
        .bDescriptorSubType = USB_CDC_DST_HEADER,
        .bcdCDC = 0x120,
    },
    .cdc_union = {
        .bLength = sizeof(usb_cs_union_interface_descriptor_1_t),
        .bDescriptorType = USB_DT_CS_INTERFACE,
        .bDescriptorSubType = USB_CDC_DST_UNION,
//        .bControlInterface set later
//        .bSubordinateInterface set later
    },
    .cdc_eth = {
        .bLength = sizeof(usb_cs_ethernet_interface_descriptor_t),
        .bDescriptorType = USB_DT_CS_INTERFACE,
        .bDescriptorSubType = USB_CDC_DST_ETHERNET,
//        .iMACAddress filled in later
        .bmEthernetStatistics = 0,
        .wMaxSegmentSize = ETH_MTU,
        .wNumberMCFilters = 0,
        .bNumberPowerFilters = 0,
    },
    .intr_ep = {
        .bLength = sizeof(usb_endpoint_descriptor_t),
        .bDescriptorType = USB_DT_ENDPOINT,
//      .bEndpointAddress set later
        .bmAttributes = USB_ENDPOINT_INTERRUPT,
        .wMaxPacketSize = htole16(INTR_MAX_PACKET),
        .bInterval = 8,
    },
    .cdc_intf_0 = {
        .bLength = sizeof(usb_interface_descriptor_t),
        .bDescriptorType = USB_DT_INTERFACE,
//      .bInterfaceNumber set later
        .bAlternateSetting = 0,
        .bNumEndpoints = 0,
        .bInterfaceClass = USB_CLASS_CDC,
        .bInterfaceSubClass = 0,
        .bInterfaceProtocol = 0,
        .iInterface = 0,
    },
    .cdc_intf_1 = {
        .bLength = sizeof(usb_interface_descriptor_t),
        .bDescriptorType = USB_DT_INTERFACE,
//      .bInterfaceNumber set later
        .bAlternateSetting = 1,
        .bNumEndpoints = 2,
        .bInterfaceClass = USB_CLASS_CDC,
        .bInterfaceSubClass = 0,
        .bInterfaceProtocol = 0,
        .iInterface = 0,
    },
    .bulk_out_ep = {
        .bLength = sizeof(usb_endpoint_descriptor_t),
        .bDescriptorType = USB_DT_ENDPOINT,
//      .bEndpointAddress set later
        .bmAttributes = USB_ENDPOINT_BULK,
        .wMaxPacketSize = htole16(BULK_MAX_PACKET),
        .bInterval = 0,
    },
    .bulk_in_ep = {
        .bLength = sizeof(usb_endpoint_descriptor_t),
        .bDescriptorType = USB_DT_ENDPOINT,
//      .bEndpointAddress set later
        .bmAttributes = USB_ENDPOINT_BULK,
        .wMaxPacketSize = htole16(BULK_MAX_PACKET),
        .bInterval = 0,
    },
};

static zx_status_t cdc_generate_mac_address(usb_cdc_t* cdc) {
    zx_cprng_draw(cdc->mac_addr, sizeof(cdc->mac_addr));

    // set most significant byte so we are using a locally managed address
    // TODO(voydanoff) add a way to configure a real MAC address here
    cdc->mac_addr[0] = 0x02;
    char buffer[sizeof(cdc->mac_addr) * 3];
    snprintf(buffer, sizeof(buffer), "%02X%02X%02X%02X%02X%02X",
             cdc->mac_addr[0], cdc->mac_addr[1], cdc->mac_addr[2],
             cdc->mac_addr[3], cdc->mac_addr[4], cdc->mac_addr[5]);

    return usb_function_alloc_string_desc(&cdc->function, buffer, &descriptors.cdc_eth.iMACAddress);
}

static zx_status_t cdc_ethmac_query(void* ctx, uint32_t options, ethmac_info_t* info) {
    zxlogf(TRACE, "%s:\n", __FUNCTION__);
    usb_cdc_t* cdc = ctx;

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

    memset(info, 0, sizeof(*info));
    info->mtu = ETH_MTU;
    memcpy(info->mac, cdc->mac_addr, sizeof(cdc->mac_addr));

    return ZX_OK;
}

static void cdc_ethmac_stop(void* cookie) {
    zxlogf(TRACE, "%s:\n", __FUNCTION__);
    usb_cdc_t* cdc = cookie;
    mtx_lock(&cdc->ethmac_mutex);
    cdc->ethmac_ifc = NULL;
    mtx_unlock(&cdc->ethmac_mutex);
}

static zx_status_t cdc_ethmac_start(void* ctx_cookie, ethmac_ifc_t* ifc, void* ethmac_cookie) {
    zxlogf(TRACE, "%s:\n", __FUNCTION__);
    usb_cdc_t* cdc = ctx_cookie;
    zx_status_t status = ZX_OK;

    mtx_lock(&cdc->ethmac_mutex);
    if (cdc->ethmac_ifc) {
        status = ZX_ERR_ALREADY_BOUND;
    } else {
        cdc->ethmac_ifc = ifc;
        cdc->ethmac_cookie = ethmac_cookie;
        cdc->ethmac_ifc->status(ethmac_cookie, cdc->online ? ETH_STATUS_ONLINE : 0);
    }
    mtx_unlock(&cdc->ethmac_mutex);

    return status;
}

static zx_status_t cdc_send_locked(usb_cdc_t* cdc, ethmac_netbuf_t* netbuf) {
    uint8_t* byte_data = netbuf->data;
    size_t length = netbuf->len;

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

    // Send data
    tx_req->header.length = length;
    ssize_t bytes_copied = usb_request_copy_to(tx_req, byte_data,
                                                    tx_req->header.length, 0);
    if (bytes_copied < 0) {
        zxlogf(LERROR, "%s: failed to copy data into send req (error %zd)\n", __FUNCTION__,
                bytes_copied);
        list_add_tail(&cdc->bulk_in_reqs, &tx_req->node);
        return ZX_ERR_INTERNAL;
    }

    usb_function_queue(&cdc->function, tx_req);

    return ZX_OK;
}

static zx_status_t cdc_ethmac_queue_tx(void* cookie, uint32_t options, ethmac_netbuf_t* netbuf) {
    usb_cdc_t* cdc = cookie;
    size_t length = netbuf->len;
    zx_status_t status;

    if (!cdc->online || length > ETH_MTU || length == 0) {
        return ZX_ERR_INVALID_ARGS;
    }

    zxlogf(LTRACE, "%s: sending %zu bytes\n", __FUNCTION__, length);

    mtx_lock(&cdc->tx_mutex);
    if (cdc->unbound) {
        status = ZX_ERR_IO_NOT_PRESENT;
    } else {
        status = cdc_send_locked(cdc, netbuf);
        if (status == ZX_ERR_SHOULD_WAIT) {
            // No buffers available, queue it up
            list_add_tail(&cdc->tx_pending_infos, &netbuf->node);
        }
    }

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

static zx_status_t ethmac_set_param(void *cookie, uint32_t param, int32_t value, void* data) {
    return ZX_ERR_NOT_SUPPORTED;
}

static ethmac_protocol_ops_t ethmac_ops = {
    .query = cdc_ethmac_query,
    .stop = cdc_ethmac_stop,
    .start = cdc_ethmac_start,
    .queue_tx = cdc_ethmac_queue_tx,
    .set_param = ethmac_set_param,
};

static void cdc_intr_complete(usb_request_t* req, void* cookie) {
    zxlogf(TRACE, "%s %d %ld\n", __FUNCTION__, req->response.status, req->response.actual);
    usb_request_release(req);
}

static zx_status_t cdc_alloc_interrupt_req(usb_cdc_t* cdc, usb_request_t** out_req) {
    usb_request_t* req;
    zx_status_t status = usb_request_alloc(&req, INTR_MAX_PACKET,
                                                cdc->intr_addr);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: usb_request_alloc failed %d\n", __FUNCTION__, status);
        return status;
    }
    req->complete_cb = cdc_intr_complete;
    req->cookie = cdc;
    *out_req = req;
    return ZX_OK;
}

// sends network connection and speed change notifications on the interrupt endpoint
// we only do this once per USB connect, so instead of pooling usb requests we just allocate
// them here and release them when they complete.
static zx_status_t cdc_send_notifications(usb_cdc_t* cdc) {
    usb_request_t* req;
    zx_status_t status;

    usb_cdc_notification_t network_notification = {
        .bmRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
        .bNotification = USB_CDC_NC_NETWORK_CONNECTION,
        .wValue = 1, // online
        .wIndex = descriptors.cdc_intf_0.bInterfaceNumber,
        .wLength = 0,
    };

    usb_cdc_speed_change_notification_t speed_notification = {
        .notification = {
            .bmRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
            .bNotification = USB_CDC_NC_CONNECTION_SPEED_CHANGE,
            .wValue = 0,
            .wIndex = descriptors.cdc_intf_0.bInterfaceNumber,
            .wLength = 0,
        },
        .downlink_br = CDC_BITRATE,
        .uplink_br = CDC_BITRATE,
    };

    status = cdc_alloc_interrupt_req(cdc, &req);
    if (status != ZX_OK) return status;
    usb_request_copy_to(req, &network_notification,
                             sizeof(network_notification), 0);
    req->header.length = sizeof(network_notification);
    usb_function_queue(&cdc->function, req);

    status = cdc_alloc_interrupt_req(cdc, &req);
    if (status != ZX_OK) return status;
    usb_request_copy_to(req, &speed_notification,
                             sizeof(speed_notification), 0);
    req->header.length = sizeof(speed_notification);
    usb_function_queue(&cdc->function, req);

    return ZX_OK;
}

static void cdc_rx_complete(usb_request_t* req, void* cookie) {
    usb_cdc_t* cdc = cookie;

    zxlogf(LTRACE, "%s %d %ld\n", __FUNCTION__, req->response.status, req->response.actual);

    if (req->response.status == ZX_ERR_IO_NOT_PRESENT) {
        mtx_lock(&cdc->rx_mutex);
        list_add_head(&cdc->bulk_out_reqs, &req->node);
        mtx_unlock(&cdc->rx_mutex);
        return;
    }
    if (req->response.status != ZX_OK) {
        zxlogf(ERROR, "%s: usb_read_complete called with status %d\n",
                __FUNCTION__, req->response.status);
    }

    if (req->response.status == ZX_OK) {
        mtx_lock(&cdc->ethmac_mutex);
        if (cdc->ethmac_ifc) {
            uint8_t* data = NULL;
            usb_request_mmap(req, (void*)&data);
            cdc->ethmac_ifc->recv(cdc->ethmac_cookie, data, req->response.actual, 0);
        }
        mtx_unlock(&cdc->ethmac_mutex);
    }

    usb_function_queue(&cdc->function, req);
}

static void cdc_tx_complete(usb_request_t* req, void* cookie) {
    usb_cdc_t* cdc = cookie;

    zxlogf(LTRACE, "%s %d %ld\n", __FUNCTION__, req->response.status, req->response.actual);

    mtx_lock(&cdc->tx_mutex);
    list_add_tail(&cdc->bulk_in_reqs, &req->node);

    bool additional_tx_queued = false;
    ethmac_netbuf_t* netbuf;
    zx_status_t send_status = ZX_OK;
    if ((netbuf = list_peek_head_type(&cdc->tx_pending_infos, ethmac_netbuf_t, node))) {
        if ((send_status = cdc_send_locked(cdc, netbuf)) != ZX_ERR_SHOULD_WAIT) {
            list_remove_head(&cdc->tx_pending_infos);
            additional_tx_queued = true;
        }
    }
    mtx_unlock(&cdc->tx_mutex);

    if (additional_tx_queued) {
        mtx_lock(&cdc->ethmac_mutex);
        if (cdc->ethmac_ifc) {
            cdc->ethmac_ifc->complete_tx(cdc->ethmac_cookie, netbuf, send_status);
        }
        mtx_unlock(&cdc->ethmac_mutex);
    }
}

static const usb_descriptor_header_t* cdc_get_descriptors(void* ctx, size_t* out_length) {
    *out_length = sizeof(descriptors);
    return (const usb_descriptor_header_t *)&descriptors;
}

static zx_status_t cdc_control(void* ctx, const usb_setup_t* setup, void* buffer,
                               size_t length, size_t* out_actual) {
    *out_actual = 0;

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

    // USB_CDC_SET_ETHERNET_PACKET_FILTER is the only control request required by the spec
    if (setup->bmRequestType == (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE) &&
        setup->bRequest == USB_CDC_SET_ETHERNET_PACKET_FILTER) {
        zxlogf(TRACE, "%s: USB_CDC_SET_ETHERNET_PACKET_FILTER\n", __FUNCTION__);
        // TODO(voydanoff) implement the requested packet filtering
        return ZX_OK;
    }

    return ZX_ERR_NOT_SUPPORTED;
}

static zx_status_t cdc_set_configured(void* ctx, bool configured, usb_speed_t speed) {
    zxlogf(TRACE, "%s: %d %d\n", __FUNCTION__, configured, speed);
    usb_cdc_t* cdc = ctx;
    zx_status_t status;

    mtx_lock(&cdc->ethmac_mutex);
    cdc->online = false;
    if (cdc->ethmac_ifc) {
        cdc->ethmac_ifc->status(cdc->ethmac_cookie, 0);
    }
    mtx_unlock(&cdc->ethmac_mutex);

    if (configured) {
        if ((status = usb_function_config_ep(&cdc->function, &descriptors.intr_ep, NULL)) != ZX_OK) {
            zxlogf(ERROR, "%s: usb_function_config_ep failed\n", __FUNCTION__);
            return status;
        }
    } else {
        usb_function_disable_ep(&cdc->function, cdc->bulk_out_addr);
        usb_function_disable_ep(&cdc->function, cdc->bulk_in_addr);
        usb_function_disable_ep(&cdc->function, cdc->intr_addr);
    }

    return ZX_OK;
}

static zx_status_t cdc_set_interface(void* ctx, unsigned interface, unsigned alt_setting) {
    zxlogf(TRACE, "%s: %d %d\n", __FUNCTION__, interface, alt_setting);
    usb_cdc_t* cdc = ctx;
    zx_status_t status;

    if (interface != descriptors.cdc_intf_0.bInterfaceNumber || alt_setting > 1) {
        return ZX_ERR_INVALID_ARGS;
    }

    // TODO(voydanoff) fullspeed and superspeed support
    if (alt_setting) {
        if ((status = usb_function_config_ep(&cdc->function, &descriptors.bulk_out_ep, NULL))
                != ZX_OK ||
            (status = usb_function_config_ep(&cdc->function, &descriptors.bulk_in_ep, NULL))
                != ZX_OK) {
            zxlogf(ERROR, "%s: usb_function_config_ep failed\n", __FUNCTION__);
        }
    } else {
        if ((status = usb_function_disable_ep(&cdc->function, cdc->bulk_out_addr)) != ZX_OK ||
            (status = usb_function_disable_ep(&cdc->function, cdc->bulk_in_addr)) != ZX_OK) {
            zxlogf(ERROR, "%s: usb_function_disable_ep failed\n", __FUNCTION__);
        }
    }

    bool online = false;
    if (alt_setting && status == ZX_OK) {
        online = true;

        // queue our OUT reqs
        mtx_lock(&cdc->rx_mutex);
        usb_request_t* req;
        while ((req = list_remove_head_type(&cdc->bulk_out_reqs, usb_request_t, node)) != NULL) {
            usb_function_queue(&cdc->function, req);
        }
        mtx_unlock(&cdc->rx_mutex);

        // send status notifications on interrupt endpoint
        status = cdc_send_notifications(cdc);
    }

    mtx_lock(&cdc->ethmac_mutex);
    cdc->online = online;
    if (cdc->ethmac_ifc) {
        cdc->ethmac_ifc->status(cdc->ethmac_cookie, online ? ETH_STATUS_ONLINE : 0);
    }
    mtx_unlock(&cdc->ethmac_mutex);

    return status;
}

usb_function_interface_ops_t device_ops = {
    .get_descriptors = cdc_get_descriptors,
    .control = cdc_control,
    .set_configured = cdc_set_configured,
    .set_interface = cdc_set_interface,
};

static void usb_cdc_unbind(void* ctx) {
    zxlogf(TRACE, "%s\n", __FUNCTION__);
    usb_cdc_t* cdc = ctx;

    mtx_lock(&cdc->tx_mutex);
    cdc->unbound = true;
    if (cdc->ethmac_ifc) {
        ethmac_netbuf_t* netbuf;
        while ((netbuf = list_remove_head_type(&cdc->tx_pending_infos, ethmac_netbuf_t, node)) !=
               NULL) {
            cdc->ethmac_ifc->complete_tx(cdc->ethmac_cookie, netbuf, ZX_ERR_PEER_CLOSED);
        }
    }
    mtx_unlock(&cdc->tx_mutex);

    device_remove(cdc->zxdev);
}

static void usb_cdc_release(void* ctx) {
    zxlogf(TRACE, "%s\n", __FUNCTION__);
    usb_cdc_t* cdc = ctx;
    usb_request_t* req;

    while ((req = list_remove_head_type(&cdc->bulk_out_reqs, usb_request_t, node)) != NULL) {
        usb_request_release(req);
    }
    while ((req = list_remove_head_type(&cdc->bulk_in_reqs, usb_request_t, node)) != NULL) {
        usb_request_release(req);
    }
    mtx_destroy(&cdc->ethmac_mutex);
    mtx_destroy(&cdc->tx_mutex);
    mtx_destroy(&cdc->rx_mutex);
    free(cdc);
}

static zx_protocol_device_t usb_cdc_proto = {
    .version = DEVICE_OPS_VERSION,
    .unbind = usb_cdc_unbind,
    .release = usb_cdc_release,
};

zx_status_t usb_cdc_bind(void* ctx, zx_device_t* parent) {
    zxlogf(INFO, "%s\n", __FUNCTION__);

    usb_cdc_t* cdc = calloc(1, sizeof(usb_cdc_t));
    if (!cdc) {
        return ZX_ERR_NO_MEMORY;
    }

    zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_USB_FUNCTION, &cdc->function);
    if (status != ZX_OK) {
        free(cdc);
        return status;
    }

    list_initialize(&cdc->bulk_out_reqs);
    list_initialize(&cdc->bulk_in_reqs);
    list_initialize(&cdc->tx_pending_infos);
    mtx_init(&cdc->ethmac_mutex, mtx_plain);
    mtx_init(&cdc->tx_mutex, mtx_plain);
    mtx_init(&cdc->rx_mutex, mtx_plain);

    cdc->bulk_max_packet = BULK_MAX_PACKET; // FIXME(voydanoff) USB 3.0 support

    status = usb_function_alloc_interface(&cdc->function, &descriptors.comm_intf.bInterfaceNumber);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: usb_function_alloc_interface failed\n", __FUNCTION__);
        goto fail;
    }
    status = usb_function_alloc_interface(&cdc->function, &descriptors.cdc_intf_0.bInterfaceNumber);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: usb_function_alloc_interface failed\n", __FUNCTION__);
        goto fail;
    }
    descriptors.cdc_intf_1.bInterfaceNumber = descriptors.cdc_intf_0.bInterfaceNumber;
    descriptors.cdc_union.bControlInterface = descriptors.comm_intf.bInterfaceNumber;
    descriptors.cdc_union.bSubordinateInterface = descriptors.cdc_intf_0.bInterfaceNumber;

    status = usb_function_alloc_ep(&cdc->function, USB_DIR_OUT, &cdc->bulk_out_addr);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: usb_function_alloc_ep failed\n", __FUNCTION__);
        goto fail;
    }
    status = usb_function_alloc_ep(&cdc->function, USB_DIR_IN, &cdc->bulk_in_addr);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: usb_function_alloc_ep failed\n", __FUNCTION__);
        goto fail;
    }
    status = usb_function_alloc_ep(&cdc->function, USB_DIR_IN, &cdc->intr_addr);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: usb_function_alloc_ep failed\n", __FUNCTION__);
        goto fail;
    }

    descriptors.bulk_out_ep.bEndpointAddress = cdc->bulk_out_addr;
    descriptors.bulk_in_ep.bEndpointAddress = cdc->bulk_in_addr;
    descriptors.intr_ep.bEndpointAddress = cdc->intr_addr;

    status = cdc_generate_mac_address(cdc);
    if (status != ZX_OK) {
        goto fail;
    }

    // allocate bulk out usb requests
    usb_request_t* req;
    for (int i = 0; i < BULK_TX_COUNT; i++) {
        status = usb_request_alloc(&req, BULK_REQ_SIZE, cdc->bulk_out_addr);
        if (status != ZX_OK) {
            goto fail;
        }
        req->complete_cb = cdc_rx_complete;
        req->cookie = cdc;
        list_add_head(&cdc->bulk_out_reqs, &req->node);
    }
    // allocate bulk in usb requests
    for (int i = 0; i < BULK_RX_COUNT; i++) {
        status = usb_request_alloc(&req, BULK_REQ_SIZE, cdc->bulk_in_addr);
        if (status != ZX_OK) {
            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
        req->header.send_zlp = true;

        req->complete_cb = cdc_tx_complete;
        req->cookie = cdc;
        list_add_head(&cdc->bulk_in_reqs, &req->node);
    }

    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "cdc-eth-function",
        .ctx = cdc,
        .ops = &usb_cdc_proto,
        .proto_id = ZX_PROTOCOL_ETHERNET_IMPL,
        .proto_ops = &ethmac_ops,
    };

    status = device_add(parent, &args, &cdc->zxdev);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: add_device failed %d\n", __FUNCTION__, status);
        goto fail;
    }

    usb_function_interface_t intf = {
        .ops = &device_ops,
        .ctx = cdc,
    };
    usb_function_register(&cdc->function, &intf);

    return ZX_OK;

fail:
    usb_cdc_release(cdc);
    return status;
}

static zx_driver_ops_t usb_cdc_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = usb_cdc_bind,
};

// clang-format off
ZIRCON_DRIVER_BEGIN(usb_cdc, usb_cdc_ops, "zircon", "0.1", 4)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_USB_FUNCTION),
    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(usb_cdc)
