cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ncm.c (5386B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * ncm.c -- NCM gadget driver
      4 *
      5 * Copyright (C) 2010 Nokia Corporation
      6 * Contact: Yauheni Kaliuta <yauheni.kaliuta@nokia.com>
      7 *
      8 * The driver borrows from ether.c which is:
      9 *
     10 * Copyright (C) 2003-2005,2008 David Brownell
     11 * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger
     12 * Copyright (C) 2008 Nokia Corporation
     13 */
     14
     15/* #define DEBUG */
     16/* #define VERBOSE_DEBUG */
     17
     18#include <linux/kernel.h>
     19#include <linux/module.h>
     20#include <linux/usb/composite.h>
     21
     22#include "u_ether.h"
     23#include "u_ncm.h"
     24
     25#define DRIVER_DESC		"NCM Gadget"
     26
     27/*-------------------------------------------------------------------------*/
     28
     29/* DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
     30 * Instead:  allocate your own, using normal USB-IF procedures.
     31 */
     32
     33/* Thanks to NetChip Technologies for donating this product ID.
     34 * It's for devices with only CDC Ethernet configurations.
     35 */
     36#define CDC_VENDOR_NUM		0x0525	/* NetChip */
     37#define CDC_PRODUCT_NUM		0xa4a1	/* Linux-USB Ethernet Gadget */
     38
     39/*-------------------------------------------------------------------------*/
     40USB_GADGET_COMPOSITE_OPTIONS();
     41
     42USB_ETHERNET_MODULE_PARAMETERS();
     43
     44static struct usb_device_descriptor device_desc = {
     45	.bLength =		sizeof device_desc,
     46	.bDescriptorType =	USB_DT_DEVICE,
     47
     48	/* .bcdUSB = DYNAMIC */
     49
     50	.bDeviceClass =		USB_CLASS_COMM,
     51	.bDeviceSubClass =	0,
     52	.bDeviceProtocol =	0,
     53	/* .bMaxPacketSize0 = f(hardware) */
     54
     55	/* Vendor and product id defaults change according to what configs
     56	 * we support.  (As does bNumConfigurations.)  These values can
     57	 * also be overridden by module parameters.
     58	 */
     59	.idVendor =		cpu_to_le16 (CDC_VENDOR_NUM),
     60	.idProduct =		cpu_to_le16 (CDC_PRODUCT_NUM),
     61	/* .bcdDevice = f(hardware) */
     62	/* .iManufacturer = DYNAMIC */
     63	/* .iProduct = DYNAMIC */
     64	/* NO SERIAL NUMBER */
     65	.bNumConfigurations =	1,
     66};
     67
     68static const struct usb_descriptor_header *otg_desc[2];
     69
     70/* string IDs are assigned dynamically */
     71static struct usb_string strings_dev[] = {
     72	[USB_GADGET_MANUFACTURER_IDX].s = "",
     73	[USB_GADGET_PRODUCT_IDX].s = DRIVER_DESC,
     74	[USB_GADGET_SERIAL_IDX].s = "",
     75	{  } /* end of list */
     76};
     77
     78static struct usb_gadget_strings stringtab_dev = {
     79	.language	= 0x0409,	/* en-us */
     80	.strings	= strings_dev,
     81};
     82
     83static struct usb_gadget_strings *dev_strings[] = {
     84	&stringtab_dev,
     85	NULL,
     86};
     87
     88static struct usb_function_instance *f_ncm_inst;
     89static struct usb_function *f_ncm;
     90
     91/*-------------------------------------------------------------------------*/
     92
     93static int ncm_do_config(struct usb_configuration *c)
     94{
     95	int status;
     96
     97	/* FIXME alloc iConfiguration string, set it in c->strings */
     98
     99	if (gadget_is_otg(c->cdev->gadget)) {
    100		c->descriptors = otg_desc;
    101		c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
    102	}
    103
    104	f_ncm = usb_get_function(f_ncm_inst);
    105	if (IS_ERR(f_ncm))
    106		return PTR_ERR(f_ncm);
    107
    108	status = usb_add_function(c, f_ncm);
    109	if (status < 0) {
    110		usb_put_function(f_ncm);
    111		return status;
    112	}
    113
    114	return 0;
    115}
    116
    117static struct usb_configuration ncm_config_driver = {
    118	/* .label = f(hardware) */
    119	.label			= "CDC Ethernet (NCM)",
    120	.bConfigurationValue	= 1,
    121	/* .iConfiguration = DYNAMIC */
    122	.bmAttributes		= USB_CONFIG_ATT_SELFPOWER,
    123};
    124
    125/*-------------------------------------------------------------------------*/
    126
    127static int gncm_bind(struct usb_composite_dev *cdev)
    128{
    129	struct usb_gadget	*gadget = cdev->gadget;
    130	struct f_ncm_opts	*ncm_opts;
    131	int			status;
    132
    133	f_ncm_inst = usb_get_function_instance("ncm");
    134	if (IS_ERR(f_ncm_inst))
    135		return PTR_ERR(f_ncm_inst);
    136
    137	ncm_opts = container_of(f_ncm_inst, struct f_ncm_opts, func_inst);
    138
    139	gether_set_qmult(ncm_opts->net, qmult);
    140	if (!gether_set_host_addr(ncm_opts->net, host_addr))
    141		pr_info("using host ethernet address: %s", host_addr);
    142	if (!gether_set_dev_addr(ncm_opts->net, dev_addr))
    143		pr_info("using self ethernet address: %s", dev_addr);
    144
    145	/* Allocate string descriptor numbers ... note that string
    146	 * contents can be overridden by the composite_dev glue.
    147	 */
    148
    149	status = usb_string_ids_tab(cdev, strings_dev);
    150	if (status < 0)
    151		goto fail;
    152	device_desc.iManufacturer = strings_dev[USB_GADGET_MANUFACTURER_IDX].id;
    153	device_desc.iProduct = strings_dev[USB_GADGET_PRODUCT_IDX].id;
    154
    155	if (gadget_is_otg(gadget) && !otg_desc[0]) {
    156		struct usb_descriptor_header *usb_desc;
    157
    158		usb_desc = usb_otg_descriptor_alloc(gadget);
    159		if (!usb_desc) {
    160			status = -ENOMEM;
    161			goto fail;
    162		}
    163		usb_otg_descriptor_init(gadget, usb_desc);
    164		otg_desc[0] = usb_desc;
    165		otg_desc[1] = NULL;
    166	}
    167
    168	status = usb_add_config(cdev, &ncm_config_driver,
    169				ncm_do_config);
    170	if (status < 0)
    171		goto fail1;
    172
    173	usb_composite_overwrite_options(cdev, &coverwrite);
    174	dev_info(&gadget->dev, "%s\n", DRIVER_DESC);
    175
    176	return 0;
    177
    178fail1:
    179	kfree(otg_desc[0]);
    180	otg_desc[0] = NULL;
    181fail:
    182	usb_put_function_instance(f_ncm_inst);
    183	return status;
    184}
    185
    186static int gncm_unbind(struct usb_composite_dev *cdev)
    187{
    188	if (!IS_ERR_OR_NULL(f_ncm))
    189		usb_put_function(f_ncm);
    190	if (!IS_ERR_OR_NULL(f_ncm_inst))
    191		usb_put_function_instance(f_ncm_inst);
    192	kfree(otg_desc[0]);
    193	otg_desc[0] = NULL;
    194
    195	return 0;
    196}
    197
    198static struct usb_composite_driver ncm_driver = {
    199	.name		= "g_ncm",
    200	.dev		= &device_desc,
    201	.strings	= dev_strings,
    202	.max_speed	= USB_SPEED_SUPER,
    203	.bind		= gncm_bind,
    204	.unbind		= gncm_unbind,
    205};
    206
    207module_usb_composite_driver(ncm_driver);
    208
    209MODULE_DESCRIPTION(DRIVER_DESC);
    210MODULE_AUTHOR("Yauheni Kaliuta");
    211MODULE_LICENSE("GPL");