1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * f_subset.c -- "CDC Subset" Ethernet link function driver 4 * 5 * Copyright (C) 2003-2005,2008 David Brownell 6 * Copyright (C) 2008 Nokia Corporation 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 */ 13 14 #include <linux/slab.h> 15 #include <linux/kernel.h> 16 #include <linux/module.h> 17 #include <linux/device.h> 18 #include <linux/etherdevice.h> 19 20 #include "u_ether.h" 21 #include "u_ether_configfs.h" 22 #include "u_gether.h" 23 24 /* 25 * This function packages a simple "CDC Subset" Ethernet port with no real 26 * control mechanisms; just raw data transfer over two bulk endpoints. 27 * The data transfer model is exactly that of CDC Ethernet, which is 28 * why we call it the "CDC Subset". 29 * 30 * Because it's not standardized, this has some interoperability issues. 31 * They mostly relate to driver binding, since the data transfer model is 32 * so simple (CDC Ethernet). The original versions of this protocol used 33 * specific product/vendor IDs: byteswapped IDs for Digital Equipment's 34 * SA-1100 "Itsy" board, which could run Linux 2.4 kernels and supported 35 * daughtercards with USB peripheral connectors. (It was used more often 36 * with other boards, using the Itsy identifiers.) Linux hosts recognized 37 * this with CONFIG_USB_ARMLINUX; these devices have only one configuration 38 * and one interface. 39 * 40 * At some point, MCCI defined a (nonconformant) CDC MDLM variant called 41 * "SAFE", which happens to have a mode which is identical to the "CDC 42 * Subset" in terms of data transfer and lack of control model. This was 43 * adopted by later Sharp Zaurus models, and by some other software which 44 * Linux hosts recognize with CONFIG_USB_NET_ZAURUS. 45 * 46 * Because Microsoft's RNDIS drivers are far from robust, we added a few 47 * descriptors to the CDC Subset code, making this code look like a SAFE 48 * implementation. This lets you use MCCI's host side MS-Windows drivers 49 * if you get fed up with RNDIS. It also makes it easier for composite 50 * drivers to work, since they can use class based binding instead of 51 * caring about specific product and vendor IDs. 52 */ 53 54 struct f_gether { 55 struct gether port; 56 57 char ethaddr[14]; 58 }; 59 60 static inline struct f_gether *func_to_geth(struct usb_function *f) 61 { 62 return container_of(f, struct f_gether, port.func); 63 } 64 65 /*-------------------------------------------------------------------------*/ 66 67 /* 68 * "Simple" CDC-subset option is a simple vendor-neutral model that most 69 * full speed controllers can handle: one interface, two bulk endpoints. 70 * To assist host side drivers, we fancy it up a bit, and add descriptors so 71 * some host side drivers will understand it as a "SAFE" variant. 72 * 73 * "SAFE" loosely follows CDC WMC MDLM, violating the spec in various ways. 74 * Data endpoints live in the control interface, there's no data interface. 75 * And it's not used to talk to a cell phone radio. 76 */ 77 78 /* interface descriptor: */ 79 80 static struct usb_interface_descriptor subset_data_intf = { 81 .bLength = sizeof subset_data_intf, 82 .bDescriptorType = USB_DT_INTERFACE, 83 84 /* .bInterfaceNumber = DYNAMIC */ 85 .bAlternateSetting = 0, 86 .bNumEndpoints = 2, 87 .bInterfaceClass = USB_CLASS_COMM, 88 .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, 89 .bInterfaceProtocol = 0, 90 /* .iInterface = DYNAMIC */ 91 }; 92 93 static struct usb_cdc_header_desc mdlm_header_desc = { 94 .bLength = sizeof mdlm_header_desc, 95 .bDescriptorType = USB_DT_CS_INTERFACE, 96 .bDescriptorSubType = USB_CDC_HEADER_TYPE, 97 98 .bcdCDC = cpu_to_le16(0x0110), 99 }; 100 101 static struct usb_cdc_mdlm_desc mdlm_desc = { 102 .bLength = sizeof mdlm_desc, 103 .bDescriptorType = USB_DT_CS_INTERFACE, 104 .bDescriptorSubType = USB_CDC_MDLM_TYPE, 105 106 .bcdVersion = cpu_to_le16(0x0100), 107 .bGUID = { 108 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6, 109 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f, 110 }, 111 }; 112 113 /* since "usb_cdc_mdlm_detail_desc" is a variable length structure, we 114 * can't really use its struct. All we do here is say that we're using 115 * the submode of "SAFE" which directly matches the CDC Subset. 116 */ 117 static u8 mdlm_detail_desc[] = { 118 6, 119 USB_DT_CS_INTERFACE, 120 USB_CDC_MDLM_DETAIL_TYPE, 121 122 0, /* "SAFE" */ 123 0, /* network control capabilities (none) */ 124 0, /* network data capabilities ("raw" encapsulation) */ 125 }; 126 127 static struct usb_cdc_ether_desc ether_desc = { 128 .bLength = sizeof ether_desc, 129 .bDescriptorType = USB_DT_CS_INTERFACE, 130 .bDescriptorSubType = USB_CDC_ETHERNET_TYPE, 131 132 /* this descriptor actually adds value, surprise! */ 133 /* .iMACAddress = DYNAMIC */ 134 .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */ 135 .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN), 136 .wNumberMCFilters = cpu_to_le16(0), 137 .bNumberPowerFilters = 0, 138 }; 139 140 /* full speed support: */ 141 142 static struct usb_endpoint_descriptor fs_subset_in_desc = { 143 .bLength = USB_DT_ENDPOINT_SIZE, 144 .bDescriptorType = USB_DT_ENDPOINT, 145 146 .bEndpointAddress = USB_DIR_IN, 147 .bmAttributes = USB_ENDPOINT_XFER_BULK, 148 }; 149 150 static struct usb_endpoint_descriptor fs_subset_out_desc = { 151 .bLength = USB_DT_ENDPOINT_SIZE, 152 .bDescriptorType = USB_DT_ENDPOINT, 153 154 .bEndpointAddress = USB_DIR_OUT, 155 .bmAttributes = USB_ENDPOINT_XFER_BULK, 156 }; 157 158 static struct usb_descriptor_header *fs_eth_function[] = { 159 (struct usb_descriptor_header *) &subset_data_intf, 160 (struct usb_descriptor_header *) &mdlm_header_desc, 161 (struct usb_descriptor_header *) &mdlm_desc, 162 (struct usb_descriptor_header *) &mdlm_detail_desc, 163 (struct usb_descriptor_header *) ðer_desc, 164 (struct usb_descriptor_header *) &fs_subset_in_desc, 165 (struct usb_descriptor_header *) &fs_subset_out_desc, 166 NULL, 167 }; 168 169 /* high speed support: */ 170 171 static struct usb_endpoint_descriptor hs_subset_in_desc = { 172 .bLength = USB_DT_ENDPOINT_SIZE, 173 .bDescriptorType = USB_DT_ENDPOINT, 174 175 .bmAttributes = USB_ENDPOINT_XFER_BULK, 176 .wMaxPacketSize = cpu_to_le16(512), 177 }; 178 179 static struct usb_endpoint_descriptor hs_subset_out_desc = { 180 .bLength = USB_DT_ENDPOINT_SIZE, 181 .bDescriptorType = USB_DT_ENDPOINT, 182 183 .bmAttributes = USB_ENDPOINT_XFER_BULK, 184 .wMaxPacketSize = cpu_to_le16(512), 185 }; 186 187 static struct usb_descriptor_header *hs_eth_function[] = { 188 (struct usb_descriptor_header *) &subset_data_intf, 189 (struct usb_descriptor_header *) &mdlm_header_desc, 190 (struct usb_descriptor_header *) &mdlm_desc, 191 (struct usb_descriptor_header *) &mdlm_detail_desc, 192 (struct usb_descriptor_header *) ðer_desc, 193 (struct usb_descriptor_header *) &hs_subset_in_desc, 194 (struct usb_descriptor_header *) &hs_subset_out_desc, 195 NULL, 196 }; 197 198 /* super speed support: */ 199 200 static struct usb_endpoint_descriptor ss_subset_in_desc = { 201 .bLength = USB_DT_ENDPOINT_SIZE, 202 .bDescriptorType = USB_DT_ENDPOINT, 203 204 .bmAttributes = USB_ENDPOINT_XFER_BULK, 205 .wMaxPacketSize = cpu_to_le16(1024), 206 }; 207 208 static struct usb_endpoint_descriptor ss_subset_out_desc = { 209 .bLength = USB_DT_ENDPOINT_SIZE, 210 .bDescriptorType = USB_DT_ENDPOINT, 211 212 .bmAttributes = USB_ENDPOINT_XFER_BULK, 213 .wMaxPacketSize = cpu_to_le16(1024), 214 }; 215 216 static struct usb_ss_ep_comp_descriptor ss_subset_bulk_comp_desc = { 217 .bLength = sizeof ss_subset_bulk_comp_desc, 218 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, 219 220 /* the following 2 values can be tweaked if necessary */ 221 /* .bMaxBurst = 0, */ 222 /* .bmAttributes = 0, */ 223 }; 224 225 static struct usb_descriptor_header *ss_eth_function[] = { 226 (struct usb_descriptor_header *) &subset_data_intf, 227 (struct usb_descriptor_header *) &mdlm_header_desc, 228 (struct usb_descriptor_header *) &mdlm_desc, 229 (struct usb_descriptor_header *) &mdlm_detail_desc, 230 (struct usb_descriptor_header *) ðer_desc, 231 (struct usb_descriptor_header *) &ss_subset_in_desc, 232 (struct usb_descriptor_header *) &ss_subset_bulk_comp_desc, 233 (struct usb_descriptor_header *) &ss_subset_out_desc, 234 (struct usb_descriptor_header *) &ss_subset_bulk_comp_desc, 235 NULL, 236 }; 237 238 /* string descriptors: */ 239 240 static struct usb_string geth_string_defs[] = { 241 [0].s = "CDC Ethernet Subset/SAFE", 242 [1].s = "", 243 { } /* end of list */ 244 }; 245 246 static struct usb_gadget_strings geth_string_table = { 247 .language = 0x0409, /* en-us */ 248 .strings = geth_string_defs, 249 }; 250 251 static struct usb_gadget_strings *geth_strings[] = { 252 &geth_string_table, 253 NULL, 254 }; 255 256 /*-------------------------------------------------------------------------*/ 257 258 static int geth_set_alt(struct usb_function *f, unsigned intf, unsigned alt) 259 { 260 struct f_gether *geth = func_to_geth(f); 261 struct usb_composite_dev *cdev = f->config->cdev; 262 struct net_device *net; 263 264 /* we know alt == 0, so this is an activation or a reset */ 265 266 if (geth->port.in_ep->enabled) { 267 DBG(cdev, "reset cdc subset\n"); 268 gether_disconnect(&geth->port); 269 } 270 271 DBG(cdev, "init + activate cdc subset\n"); 272 if (config_ep_by_speed(cdev->gadget, f, geth->port.in_ep) || 273 config_ep_by_speed(cdev->gadget, f, geth->port.out_ep)) { 274 geth->port.in_ep->desc = NULL; 275 geth->port.out_ep->desc = NULL; 276 return -EINVAL; 277 } 278 279 net = gether_connect(&geth->port); 280 return PTR_ERR_OR_ZERO(net); 281 } 282 283 static void geth_disable(struct usb_function *f) 284 { 285 struct f_gether *geth = func_to_geth(f); 286 struct usb_composite_dev *cdev = f->config->cdev; 287 288 DBG(cdev, "net deactivated\n"); 289 gether_disconnect(&geth->port); 290 } 291 292 /*-------------------------------------------------------------------------*/ 293 294 /* serial function driver setup/binding */ 295 296 static int 297 geth_bind(struct usb_configuration *c, struct usb_function *f) 298 { 299 struct usb_composite_dev *cdev = c->cdev; 300 struct f_gether *geth = func_to_geth(f); 301 struct usb_string *us; 302 int status; 303 struct usb_ep *ep; 304 305 struct f_gether_opts *gether_opts; 306 307 gether_opts = container_of(f->fi, struct f_gether_opts, func_inst); 308 309 /* 310 * in drivers/usb/gadget/configfs.c:configfs_composite_bind() 311 * configurations are bound in sequence with list_for_each_entry, 312 * in each configuration its functions are bound in sequence 313 * with list_for_each_entry, so we assume no race condition 314 * with regard to gether_opts->bound access 315 */ 316 if (!gether_opts->bound) { 317 mutex_lock(&gether_opts->lock); 318 gether_set_gadget(gether_opts->net, cdev->gadget); 319 status = gether_register_netdev(gether_opts->net); 320 mutex_unlock(&gether_opts->lock); 321 if (status) 322 return status; 323 gether_opts->bound = true; 324 } 325 326 us = usb_gstrings_attach(cdev, geth_strings, 327 ARRAY_SIZE(geth_string_defs)); 328 if (IS_ERR(us)) 329 return PTR_ERR(us); 330 331 subset_data_intf.iInterface = us[0].id; 332 ether_desc.iMACAddress = us[1].id; 333 334 /* allocate instance-specific interface IDs */ 335 status = usb_interface_id(c, f); 336 if (status < 0) 337 goto fail; 338 subset_data_intf.bInterfaceNumber = status; 339 340 status = -ENODEV; 341 342 /* allocate instance-specific endpoints */ 343 ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_in_desc); 344 if (!ep) 345 goto fail; 346 geth->port.in_ep = ep; 347 348 ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc); 349 if (!ep) 350 goto fail; 351 geth->port.out_ep = ep; 352 353 /* support all relevant hardware speeds... we expect that when 354 * hardware is dual speed, all bulk-capable endpoints work at 355 * both speeds 356 */ 357 hs_subset_in_desc.bEndpointAddress = fs_subset_in_desc.bEndpointAddress; 358 hs_subset_out_desc.bEndpointAddress = 359 fs_subset_out_desc.bEndpointAddress; 360 361 ss_subset_in_desc.bEndpointAddress = fs_subset_in_desc.bEndpointAddress; 362 ss_subset_out_desc.bEndpointAddress = 363 fs_subset_out_desc.bEndpointAddress; 364 365 status = usb_assign_descriptors(f, fs_eth_function, hs_eth_function, 366 ss_eth_function, NULL); 367 if (status) 368 goto fail; 369 370 /* NOTE: all that is done without knowing or caring about 371 * the network link ... which is unavailable to this code 372 * until we're activated via set_alt(). 373 */ 374 375 DBG(cdev, "CDC Subset: %s speed IN/%s OUT/%s\n", 376 gadget_is_superspeed(c->cdev->gadget) ? "super" : 377 gadget_is_dualspeed(c->cdev->gadget) ? "dual" : "full", 378 geth->port.in_ep->name, geth->port.out_ep->name); 379 return 0; 380 381 fail: 382 ERROR(cdev, "%s: can't bind, err %d\n", f->name, status); 383 384 return status; 385 } 386 387 static inline struct f_gether_opts *to_f_gether_opts(struct config_item *item) 388 { 389 return container_of(to_config_group(item), struct f_gether_opts, 390 func_inst.group); 391 } 392 393 /* f_gether_item_ops */ 394 USB_ETHERNET_CONFIGFS_ITEM(gether); 395 396 /* f_gether_opts_dev_addr */ 397 USB_ETHERNET_CONFIGFS_ITEM_ATTR_DEV_ADDR(gether); 398 399 /* f_gether_opts_host_addr */ 400 USB_ETHERNET_CONFIGFS_ITEM_ATTR_HOST_ADDR(gether); 401 402 /* f_gether_opts_qmult */ 403 USB_ETHERNET_CONFIGFS_ITEM_ATTR_QMULT(gether); 404 405 /* f_gether_opts_ifname */ 406 USB_ETHERNET_CONFIGFS_ITEM_ATTR_IFNAME(gether); 407 408 static struct configfs_attribute *gether_attrs[] = { 409 &gether_opts_attr_dev_addr, 410 &gether_opts_attr_host_addr, 411 &gether_opts_attr_qmult, 412 &gether_opts_attr_ifname, 413 NULL, 414 }; 415 416 static struct config_item_type gether_func_type = { 417 .ct_item_ops = &gether_item_ops, 418 .ct_attrs = gether_attrs, 419 .ct_owner = THIS_MODULE, 420 }; 421 422 static void geth_free_inst(struct usb_function_instance *f) 423 { 424 struct f_gether_opts *opts; 425 426 opts = container_of(f, struct f_gether_opts, func_inst); 427 if (opts->bound) 428 gether_cleanup(netdev_priv(opts->net)); 429 else 430 free_netdev(opts->net); 431 kfree(opts); 432 } 433 434 static struct usb_function_instance *geth_alloc_inst(void) 435 { 436 struct f_gether_opts *opts; 437 438 opts = kzalloc(sizeof(*opts), GFP_KERNEL); 439 if (!opts) 440 return ERR_PTR(-ENOMEM); 441 mutex_init(&opts->lock); 442 opts->func_inst.free_func_inst = geth_free_inst; 443 opts->net = gether_setup_default(); 444 if (IS_ERR(opts->net)) { 445 struct net_device *net = opts->net; 446 kfree(opts); 447 return ERR_CAST(net); 448 } 449 450 config_group_init_type_name(&opts->func_inst.group, "", 451 &gether_func_type); 452 453 return &opts->func_inst; 454 } 455 456 static void geth_free(struct usb_function *f) 457 { 458 struct f_gether *eth; 459 460 eth = func_to_geth(f); 461 kfree(eth); 462 } 463 464 static void geth_unbind(struct usb_configuration *c, struct usb_function *f) 465 { 466 geth_string_defs[0].id = 0; 467 usb_free_all_descriptors(f); 468 } 469 470 static struct usb_function *geth_alloc(struct usb_function_instance *fi) 471 { 472 struct f_gether *geth; 473 struct f_gether_opts *opts; 474 int status; 475 476 /* allocate and initialize one new instance */ 477 geth = kzalloc(sizeof(*geth), GFP_KERNEL); 478 if (!geth) 479 return ERR_PTR(-ENOMEM); 480 481 opts = container_of(fi, struct f_gether_opts, func_inst); 482 483 mutex_lock(&opts->lock); 484 opts->refcnt++; 485 /* export host's Ethernet address in CDC format */ 486 status = gether_get_host_addr_cdc(opts->net, geth->ethaddr, 487 sizeof(geth->ethaddr)); 488 if (status < 12) { 489 kfree(geth); 490 mutex_unlock(&opts->lock); 491 return ERR_PTR(-EINVAL); 492 } 493 geth_string_defs[1].s = geth->ethaddr; 494 495 geth->port.ioport = netdev_priv(opts->net); 496 mutex_unlock(&opts->lock); 497 geth->port.cdc_filter = DEFAULT_FILTER; 498 499 geth->port.func.name = "cdc_subset"; 500 geth->port.func.bind = geth_bind; 501 geth->port.func.unbind = geth_unbind; 502 geth->port.func.set_alt = geth_set_alt; 503 geth->port.func.disable = geth_disable; 504 geth->port.func.free_func = geth_free; 505 506 return &geth->port.func; 507 } 508 509 DECLARE_USB_FUNCTION_INIT(geth, geth_alloc_inst, geth_alloc); 510 MODULE_LICENSE("GPL"); 511 MODULE_AUTHOR("David Brownell"); 512