// 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 <zircon/listnode.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/device/usb-device.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_function_req_copy_to(&cdc->function, 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) {
    usb_cdc_t* cdc = cookie;
    zxlogf(TRACE, "%s %d %ld\n", __FUNCTION__, req->response.status, req->response.actual);
    usb_function_req_release(&cdc->function, 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_function_req_alloc(&cdc->function, &req, INTR_MAX_PACKET,
                                                cdc->intr_addr);
    if (status != ZX_OK) {
        zxlogf(ERROR, "%s: usb_function_req_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_function_req_copy_to(&cdc->function, 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_function_req_copy_to(&cdc->function, 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_function_req_mmap(&cdc->function, 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_function_req_release(&cdc->function, req);
    }
    while ((req = list_remove_head_type(&cdc->bulk_in_reqs, usb_request_t, node)) != NULL) {
        usb_function_req_release(&cdc->function, 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_function_req_alloc(&cdc->function, &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_function_req_alloc(&cdc->function, &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)
