linux/drivers/usb/gadget/function/f_ecm.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * f_ecm.c -- USB CDC Ethernet (ECM) link function driver
 *
 * Copyright (C) 2003-2005,2008 David Brownell
 * Copyright (C) 2008 Nokia Corporation
 */

/* #define VERBOSE_DEBUG */

#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/etherdevice.h>

#include "u_ether.h"
#include "u_ether_configfs.h"
#include "u_ecm.h"


/*
 * This function is a "CDC Ethernet Networking Control Model" (CDC ECM)
 * Ethernet link.  The data transfer model is simple (packets sent and
 * received over bulk endpoints using normal short packet termination),
 * and the control model exposes various data and optional notifications.
 *
 * ECM is well standardized and (except for Microsoft) supported by most
 * operating systems with USB host support.  It's the preferred interop
 * solution for Ethernet over USB, at least for firmware based solutions.
 * (Hardware solutions tend to be more minimalist.)  A newer and simpler
 * "Ethernet Emulation Model" (CDC EEM) hasn't yet caught on.
 *
 * Note that ECM requires the use of "alternate settings" for its data
 * interface.  This means that the set_alt() method has real work to do,
 * and also means that a get_alt() method is required.
 */


enum ecm_notify_state {};

struct f_ecm {};

static inline struct f_ecm *func_to_ecm(struct usb_function *f)
{}

/*-------------------------------------------------------------------------*/

/*
 * Include the status endpoint if we can, even though it's optional.
 *
 * Use wMaxPacketSize big enough to fit CDC_NOTIFY_SPEED_CHANGE in one
 * packet, to simplify cancellation; and a big transfer interval, to
 * waste less bandwidth.
 *
 * Some drivers (like Linux 2.4 cdc-ether!) "need" it to exist even
 * if they ignore the connect/disconnect notifications that real aether
 * can provide.  More advanced cdc configurations might want to support
 * encapsulated commands (vendor-specific, using control-OUT).
 */

#define ECM_STATUS_INTERVAL_MS
#define ECM_STATUS_BYTECOUNT


/* interface descriptor: */

static struct usb_interface_assoc_descriptor
ecm_iad_descriptor =;


static struct usb_interface_descriptor ecm_control_intf =;

static struct usb_cdc_header_desc ecm_header_desc =;

static struct usb_cdc_union_desc ecm_union_desc =;

static struct usb_cdc_ether_desc ecm_desc =;

/* the default data interface has no endpoints ... */

static struct usb_interface_descriptor ecm_data_nop_intf =;

/* ... but the "real" data interface has two bulk endpoints */

static struct usb_interface_descriptor ecm_data_intf =;

/* full speed support: */

static struct usb_endpoint_descriptor fs_ecm_notify_desc =;

static struct usb_endpoint_descriptor fs_ecm_in_desc =;

static struct usb_endpoint_descriptor fs_ecm_out_desc =;

static struct usb_descriptor_header *ecm_fs_function[] =;

/* high speed support: */

static struct usb_endpoint_descriptor hs_ecm_notify_desc =;

static struct usb_endpoint_descriptor hs_ecm_in_desc =;

static struct usb_endpoint_descriptor hs_ecm_out_desc =;

static struct usb_descriptor_header *ecm_hs_function[] =;

/* super speed support: */

static struct usb_endpoint_descriptor ss_ecm_notify_desc =;

static struct usb_ss_ep_comp_descriptor ss_ecm_intr_comp_desc =;

static struct usb_endpoint_descriptor ss_ecm_in_desc =;

static struct usb_endpoint_descriptor ss_ecm_out_desc =;

static struct usb_ss_ep_comp_descriptor ss_ecm_bulk_comp_desc =;

static struct usb_descriptor_header *ecm_ss_function[] =;

/* string descriptors: */

static struct usb_string ecm_string_defs[] =;

static struct usb_gadget_strings ecm_string_table =;

static struct usb_gadget_strings *ecm_strings[] =;

/*-------------------------------------------------------------------------*/

static void ecm_do_notify(struct f_ecm *ecm)
{}

static void ecm_notify(struct f_ecm *ecm)
{}

static void ecm_notify_complete(struct usb_ep *ep, struct usb_request *req)
{}

static int ecm_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
{}


static int ecm_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
{}

/* Because the data interface supports multiple altsettings,
 * this ECM function *MUST* implement a get_alt() method.
 */
static int ecm_get_alt(struct usb_function *f, unsigned intf)
{}

static void ecm_disable(struct usb_function *f)
{}

/*-------------------------------------------------------------------------*/

/*
 * Callbacks let us notify the host about connect/disconnect when the
 * net device is opened or closed.
 *
 * For testing, note that link states on this side include both opened
 * and closed variants of:
 *
 *   - disconnected/unconfigured
 *   - configured but inactive (data alt 0)
 *   - configured and active (data alt 1)
 *
 * Each needs to be tested with unplug, rmmod, SET_CONFIGURATION, and
 * SET_INTERFACE (altsetting).  Remember also that "configured" doesn't
 * imply the host is actually polling the notification endpoint, and
 * likewise that "active" doesn't imply it's actually using the data
 * endpoints for traffic.
 */

static void ecm_open(struct gether *geth)
{}

static void ecm_close(struct gether *geth)
{}

/*-------------------------------------------------------------------------*/

/* ethernet function driver setup/binding */

static int
ecm_bind(struct usb_configuration *c, struct usb_function *f)
{}

static inline struct f_ecm_opts *to_f_ecm_opts(struct config_item *item)
{}

/* f_ecm_item_ops */
USB_ETHERNET_CONFIGFS_ITEM();

/* f_ecm_opts_dev_addr */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR();

/* f_ecm_opts_host_addr */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR();

/* f_ecm_opts_qmult */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT();

/* f_ecm_opts_ifname */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME();

static struct configfs_attribute *ecm_attrs[] =;

static const struct config_item_type ecm_func_type =;

static void ecm_free_inst(struct usb_function_instance *f)
{}

static struct usb_function_instance *ecm_alloc_inst(void)
{}

static void ecm_suspend(struct usb_function *f)
{}

static void ecm_resume(struct usb_function *f)
{}

static void ecm_free(struct usb_function *f)
{}

static void ecm_unbind(struct usb_configuration *c, struct usb_function *f)
{}

static struct usb_function *ecm_alloc(struct usb_function_instance *fi)
{}

DECLARE_USB_FUNCTION_INIT(ecm, ecm_alloc_inst, ecm_alloc);
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_AUTHOR();