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

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

#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_gether.h"

/*
 * This function packages a simple "CDC Subset" Ethernet port with no real
 * control mechanisms; just raw data transfer over two bulk endpoints.
 * The data transfer model is exactly that of CDC Ethernet, which is
 * why we call it the "CDC Subset".
 *
 * Because it's not standardized, this has some interoperability issues.
 * They mostly relate to driver binding, since the data transfer model is
 * so simple (CDC Ethernet).  The original versions of this protocol used
 * specific product/vendor IDs:  byteswapped IDs for Digital Equipment's
 * SA-1100 "Itsy" board, which could run Linux 2.4 kernels and supported
 * daughtercards with USB peripheral connectors.  (It was used more often
 * with other boards, using the Itsy identifiers.)  Linux hosts recognized
 * this with CONFIG_USB_ARMLINUX; these devices have only one configuration
 * and one interface.
 *
 * At some point, MCCI defined a (nonconformant) CDC MDLM variant called
 * "SAFE", which happens to have a mode which is identical to the "CDC
 * Subset" in terms of data transfer and lack of control model.  This was
 * adopted by later Sharp Zaurus models, and by some other software which
 * Linux hosts recognize with CONFIG_USB_NET_ZAURUS.
 *
 * Because Microsoft's RNDIS drivers are far from robust, we added a few
 * descriptors to the CDC Subset code, making this code look like a SAFE
 * implementation.  This lets you use MCCI's host side MS-Windows drivers
 * if you get fed up with RNDIS.  It also makes it easier for composite
 * drivers to work, since they can use class based binding instead of
 * caring about specific product and vendor IDs.
 */

struct f_gether {};

static inline struct f_gether *func_to_geth(struct usb_function *f)
{}

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

/*
 * "Simple" CDC-subset option is a simple vendor-neutral model that most
 * full speed controllers can handle:  one interface, two bulk endpoints.
 * To assist host side drivers, we fancy it up a bit, and add descriptors so
 * some host side drivers will understand it as a "SAFE" variant.
 *
 * "SAFE" loosely follows CDC WMC MDLM, violating the spec in various ways.
 * Data endpoints live in the control interface, there's no data interface.
 * And it's not used to talk to a cell phone radio.
 */

/* interface descriptor: */

static struct usb_interface_descriptor subset_data_intf =;

static struct usb_cdc_header_desc mdlm_header_desc =;

static struct usb_cdc_mdlm_desc mdlm_desc =;

/* since "usb_cdc_mdlm_detail_desc" is a variable length structure, we
 * can't really use its struct.  All we do here is say that we're using
 * the submode of "SAFE" which directly matches the CDC Subset.
 */
static u8 mdlm_detail_desc[] =;

static struct usb_cdc_ether_desc ether_desc =;

/* full speed support: */

static struct usb_endpoint_descriptor fs_subset_in_desc =;

static struct usb_endpoint_descriptor fs_subset_out_desc =;

static struct usb_descriptor_header *fs_eth_function[] =;

/* high speed support: */

static struct usb_endpoint_descriptor hs_subset_in_desc =;

static struct usb_endpoint_descriptor hs_subset_out_desc =;

static struct usb_descriptor_header *hs_eth_function[] =;

/* super speed support: */

static struct usb_endpoint_descriptor ss_subset_in_desc =;

static struct usb_endpoint_descriptor ss_subset_out_desc =;

static struct usb_ss_ep_comp_descriptor ss_subset_bulk_comp_desc =;

static struct usb_descriptor_header *ss_eth_function[] =;

/* string descriptors: */

static struct usb_string geth_string_defs[] =;

static struct usb_gadget_strings geth_string_table =;

static struct usb_gadget_strings *geth_strings[] =;

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

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

static void geth_disable(struct usb_function *f)
{}

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

/* serial function driver setup/binding */

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

static inline struct f_gether_opts *to_f_gether_opts(struct config_item *item)
{}

/* f_gether_item_ops */
USB_ETHERNET_CONFIGFS_ITEM();

/* f_gether_opts_dev_addr */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR();

/* f_gether_opts_host_addr */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR();

/* f_gether_opts_qmult */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT();

/* f_gether_opts_ifname */
USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME();

static struct configfs_attribute *gether_attrs[] =;

static const struct config_item_type gether_func_type =;

static void geth_free_inst(struct usb_function_instance *f)
{}

static struct usb_function_instance *geth_alloc_inst(void)
{}

static void geth_free(struct usb_function *f)
{}

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

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

DECLARE_USB_FUNCTION_INIT(geth, geth_alloc_inst, geth_alloc);
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_AUTHOR();