1/* ---------------------------------------------------------------------------- 2 * Copyright (c) Huawei Technologies Co., Ltd. 2016-2019. All rights reserved. 3 * Description: LiteOS USB Driver RNDIS Protocol 4 * Author: huangjieliang 5 * Create: 2016-07-13 6 * Redistribution and use in source and binary forms, with or without modification, 7 * are permitted provided that the following conditions are met: 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 * of conditions and the following disclaimer in the documentation and/or other materials 12 * provided with the distribution. 13 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 14 * to endorse or promote products derived from this software without specific prior written 15 * permission. 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * --------------------------------------------------------------------------- */ 28/* ---------------------------------------------------------------------------- 29 * Notice of Export Control Law 30 * =============================================== 31 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might 32 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located. 33 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such 34 * applicable export control laws and regulations. 35 * --------------------------------------------------------------------------- */ 36 37#include <lwip/netifapi.h> 38#include "gadget/f_ether.h" 39#include "gadget/rndis.h" 40#include "gadget/composite.h" 41#include "implementation/global_implementation.h" 42#include "controller/usb_device/dwc_otg_pcd.h" 43#include "controller/usb_device/dwc_otg_pcd_intr.h" 44#include "net/usb_eth_drv.h" 45 46#ifdef __cplusplus 47#if __cplusplus 48extern "C" { 49#endif /* __cplusplus */ 50#endif /* __cplusplus */ 51 52const struct netif *g_ether_usb0; 53 54/* device driver structure definition */ 55 56static const driver_t g_fethernet_driver_t = 57{ 58 .name = "fethernet", 59 .methods = NULL, 60 .size = 0 61}; 62 63/* private device class information */ 64 65static devclass_t g_fethernet_devclass; 66DRIVER_MODULE(fethernet, simple, g_fethernet_driver_t, g_fethernet_devclass, usbdev_rndis_initialize, 0); 67 68#define DEIVICE_VENDOR_ID 0x0525 69#define DEIVICE_PRODUCT_ID 0xa4a2 70 71#define ETHER_NCONFIGS 1 72#define ETHER_CONFIGID 0 73#define ETHER_NINTERFACES 2 74#define ETHER_NSTRIDS 5 75#define ETHER_NUM_EPS 3 76 77#define RNDIS_STRING_ID_LEN 4 78#define RNDIS_STRING_PID_LEN 44 79#define RNDIS_VERSION_STRING_LEN 62 80#define RNDIS_STRING_LEN 58 81#define RNDIS_TYPE_LEN 40 82 83static const char g_rndis_string_id[RNDIS_STRING_ID_LEN] = 84{ 85 RNDIS_STRING_ID_LEN, UDESC_STRING, 0x09, 0x04 86}; 87 88static const char g_rndis_string_pid[RNDIS_STRING_PID_LEN] = 89{ 90 RNDIS_STRING_PID_LEN, UDESC_STRING, 'R', 0, 'N', 0, 'D', 0, 'I', 91 0, 'S', 0, '/', 0, 'E', 0, 't', 0, 'h', 0, 'e', 0, 'r', 0, 'n', 92 0, 'e', 0, 't', 0, ' ', 0, 'G', 0, 'a', 0, 'd', 0, 'g', 0, 'e', 93 0, 't', 0 94}; 95 96static const char g_version_string[RNDIS_VERSION_STRING_LEN] = 97{ 98 RNDIS_VERSION_STRING_LEN, UDESC_STRING, 0x4c, 0x00, 0x69, 0x00, 99 0x6e, 0x00, 0x75, 0x00, 0x78, 0x00, 0x20, 0x00, 0x33, 0x00, 0x2e, 100 0x00, 0x31, 0x00, 0x38, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x30, 0x00, 101 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x74, 0x00, 0x68, 0x00, 0x20, 102 0x00, 0x64, 0x00, 0x77, 0x00, 0x63, 0x00, 0x5f, 0x00, 0x6f, 0x00, 103 0x74, 0x00, 0x67, 0x00, 0x5f, 0x00, 0x70, 0x00, 0x63, 0x00, 0x64, 104 0x00 105}; 106 107static const char g_rndis_string[RNDIS_STRING_LEN] = 108{ 109 RNDIS_STRING_LEN, UDESC_STRING, 0x52, 0x00, 0x4e, 0x00, 0x44, 0x00, 110 0x49, 0x00, 0x53, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x6d, 111 0x00, 0x6d, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x63, 0x00, 112 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x73, 113 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 114 0x72, 0x00, 0x6f, 0x00, 0x6c, 0x00 115}; 116 117static const char g_rndis_type_string[RNDIS_TYPE_LEN] = 118{ 119 RNDIS_TYPE_LEN, UDESC_STRING, 0x52, 0x00, 0x4e, 0x00, 0x44, 0x00, 120 0x49, 0x00, 0x53, 0x00, 0x20, 0x00, 0x45, 0x00, 0x74, 0x00, 0x68, 121 0x00, 0x65, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x74, 0x00, 122 0x20, 0x00, 0x44, 0x00, 0x61, 0x00, 0x74, 0x00, 0x61, 0x00 123}; 124 125static const struct usb_device_descriptor g_fether_device_desc = 126{ 127 .bLength = sizeof(struct usb_device_descriptor), 128 .bDescriptorType = UDESC_DEVICE, 129 HSETW(.bcdUSB, UD_BCD_USB), /* USB version */ 130 .bDeviceClass = UDCLASS_COMM, 131 .bDeviceSubClass = 0, 132 .bDeviceProtocol = 0, 133 .bMaxPacketSize = UD_USB_MPS, 134 HSETW(.idVendor, DEIVICE_VENDOR_ID), /* vendor */ 135 HSETW(.idProduct, DEIVICE_PRODUCT_ID), /* product */ 136 HSETW(.bcdDevice, 0x0318), /* device version */ 137 .iManufacturer = 1, 138 .iProduct = 2, 139 .iSerialNumber = 0, 140 .bNumConfigurations = 1, 141}; 142 143static struct usbd_string g_fether_device_strings[] = 144{ 145 {0, g_rndis_string_id}, 146 {1, g_version_string}, 147 {2, g_rndis_string_pid}, 148 {4, g_rndis_string}, 149 {5, g_rndis_type_string}, 150 USBD_DEVICE_STRINGS_END 151}; 152 153 154static inline int is_multicast_eth_addr(const uint8_t *addr) 155{ 156 return (0x01 & addr[0]); 157} 158 159uint8_t eth_set_hwaddr(struct netif *usb_netif, uint8_t *addr, uint8_t len) 160{ 161 errno_t err; 162 163 if (is_multicast_eth_addr(addr)) 164 { 165 usb_err("config a multicast mac address, please check!\n"); 166 return 1; 167 } 168 169 if (len != NETIF_MAX_HWADDR_LEN) 170 { 171 usb_err("config wrong mac address len=%u\n", len); 172 return 1; 173 } 174 175 err = memcpy_s(usb_netif->hwaddr, NETIF_MAX_HWADDR_LEN, addr, len); 176 if (err != EOK) 177 { 178 usb_err("memcpy_s fail, err:%d\n", err); 179 return 1; 180 } 181 182 return 0; 183} 184 185void eth_random_addr(uint8_t *addr) 186{ 187 uint32_t rand_val; 188 uint32_t nowclocks; 189 190 msleep(200); 191 nowclocks = hi_sched_clock() & 0xffffffff; /* Get low 32-bit value */ 192 srand(nowclocks); 193 rand_val = (uint32_t)rand(); 194 addr[0] = rand_val & 0xff; 195 addr[1] = (rand_val >> 8) & 0xff; 196 addr[2] = (rand_val >> 16) & 0xff; 197 addr[3] = (rand_val >> 24) & 0xff; 198 199 msleep(200); 200 nowclocks = hi_sched_clock() & 0xffffffff; /* Get low 32-bit value */ 201 srand(nowclocks); 202 rand_val = (uint32_t)rand(); 203 addr[4] = rand_val & 0xff; 204 addr[5] = (rand_val >> 8) & 0xff; 205 addr[0] &= 0xfe; /* clear multicast bit */ 206 addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ 207} 208 209static void eth_tx(struct netif *usb_netif, struct pbuf *p) 210{ 211 struct los_eth_driver *sc = (struct los_eth_driver *)usb_netif->state; 212 struct eth_drv_sg sg_list[MAX_ETH_DRV_SG]; 213 struct pbuf *q; 214 int sg_len = 0; 215 216 for (q = p; q != NULL; q = q->next) 217 { 218 sg_list[sg_len].buf = (UINTPTR)q->payload; 219 sg_list[sg_len++].len = q->len; 220 } 221 222 rndis_tx(sc, sg_list, sg_len, p->tot_len, (UINTPTR)p); 223} 224 225void eth_rx(struct los_eth_driver *sc, const struct usbdev_req_s *req) 226{ 227 struct netif *usb_netif = &sc->ac_if; 228 uint32_t total_len = req->xfrd - RNDIS_PACKET_HDR_SIZE; 229 struct pbuf *p; 230 231 if (total_len > MAX_ETH_MSG) 232 { 233 total_len = MAX_ETH_MSG; 234 } 235 236 p = pbuf_alloc(PBUF_RAW, (uint16_t)(total_len + ETH_PAD_SIZE), PBUF_RAM); 237 if (p == NULL) 238 { 239 usb_err("eth_drv_recv : pbuf_alloc failed\n"); 240 return; 241 } 242 243#if ETH_PAD_SIZE 244 (void)pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ 245#endif 246 247 (void)memcpy_s(p->payload, total_len, &req->buf[RNDIS_PACKET_HDR_SIZE], total_len); 248 249#if ETH_PAD_SIZE 250 (void)pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ 251#endif 252 253 driverif_input(usb_netif, p); 254} 255 256#if PF_PKT_SUPPORT 257static void eth_drv_config(struct netif *usb_netif, uint32_t cflags, uint8_t set_bit) 258{ 259 LWIP_UNUSED_ARG(usb_netif); 260 LWIP_UNUSED_ARG(cflags); 261 LWIP_UNUSED_ARG(set_bit); 262 263 /* Nothing to be done for now */ 264 265} 266#endif 267 268void netdev_register(struct los_eth_driver *sc) 269{ 270 struct netif *usb_netif = &sc->ac_if; 271 ip4_addr_t ipaddr, netmask, gw; 272 uint8_t dev_addr[NETIF_MAX_HWADDR_LEN]; 273 err_t ret; 274 275 IP4_ADDR(&gw, 10, 67, 233, 1); 276 IP4_ADDR(&ipaddr, 10, 67, 233, 3); 277 IP4_ADDR(&netmask, 255, 255, 255, 0); 278 279 usb_netif->state = sc; 280 usb_netif->drv_send = eth_tx; 281 usb_netif->drv_set_hwaddr = eth_set_hwaddr; 282 usb_netif->link_layer_type = ETHERNET_DRIVER_IF; 283 usb_netif->hwaddr_len = NETIF_MAX_HWADDR_LEN; 284 285#if PF_PKT_SUPPORT 286 usb_netif->drv_config = eth_drv_config; 287#endif 288 289#if LWIP_NETIF_ETHTOOL 290 usb_netif->ethtool_ops = NULL; 291#endif 292 293 eth_random_addr(dev_addr); 294 (void)memcpy_s(usb_netif->hwaddr, NETIF_MAX_HWADDR_LEN, dev_addr, NETIF_MAX_HWADDR_LEN); 295 296 ret = netifapi_netif_add(usb_netif, &ipaddr, &netmask, &gw); 297 if (ret) 298 { 299 usb_err("%s %d, add netif failed, ret:%d\n", __FUNCTION__, __LINE__, ret); 300 return; 301 } 302 303 (void)netifapi_netif_set_link_down(usb_netif); 304 305 g_ether_usb0 = usb_netif; 306} 307 308void netdev_unregister(struct los_eth_driver *sc) 309{ 310 struct netif *usb_netif = &sc->ac_if; 311 312 if (netifapi_netif_remove(usb_netif) != ERR_OK) 313 { 314 usb_err("%s %d, remove netif failed!\n", __FUNCTION__, __LINE__); 315 } 316} 317 318void rndis_mkdevdesc(uint8_t *buf) 319{ 320 errno_t ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, &g_fether_device_desc, sizeof(g_fether_device_desc)); 321 if (ret != EOK) 322 { 323 usb_err("memcpy_s fail!, ret:%d\n", ret); 324 return; 325 } 326} 327 328int16_t rndis_mkcfgdesc(uint8_t *buf, struct usbdev_devinfo_s *devinfo) 329{ 330 int16_t total_len = 0; 331 int16_t len = USB_CONFIG_DESC_SIZE; 332 errno_t ret; 333 334 (void)devinfo; 335 336 /* Copy RNDIS device configure descriptor. */ 337 338 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, g_rndis_hs_desc.rndis_config, (uint16_t)len); 339 if (ret != EOK) 340 { 341 usb_err("memcpy_s fail, ret:%d\n", ret); 342 return -1; 343 } 344 total_len += len; 345 346 /* Copy RNDIS device configure descriptor. */ 347 348 buf += USB_CONFIG_DESC_SIZE; 349 len = sizeof(g_rndis_hs_func_desc); 350 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ - (uint16_t)total_len, g_rndis_hs_desc.rndis_func, (uint16_t)len); 351 if (ret != EOK) 352 { 353 usb_err("memcpy_s fail, ret:%d\n", ret); 354 return -1; 355 } 356 total_len += len; 357 358 return total_len; 359} 360 361int rndis_mkstrdesc(uint8_t id, uint8_t *buf) 362{ 363 const char *str; 364 errno_t ret; 365 int i; 366 367 for (i = 0; g_fether_device_strings[i].s != NULL; i++) 368 { 369 str = g_fether_device_strings[i].s; 370 if (g_fether_device_strings[i].id == id) 371 { 372 ret = memcpy_s(buf, USB_COMP_EP0_BUFSIZ, str, str[0]); 373 if (ret != EOK) 374 { 375 usb_err("memcpy_s failed, ret = %d\n", ret); 376 return -1; 377 } 378 return str[0]; 379 } 380 } 381 382 usb_err("Can not find the id = %u of string\n", id); 383 return -1; 384} 385 386void rndis_get_composite_devdesc(struct composite_devdesc_s *dev) 387{ 388 (void)memset_s(dev, sizeof(struct composite_devdesc_s), 0, sizeof(struct composite_devdesc_s)); 389 390 dev->mkdevdesc = rndis_mkdevdesc; 391 dev->mkconfdesc = rndis_mkcfgdesc; 392 dev->mkstrdesc = rndis_mkstrdesc; 393 dev->nconfigs = ETHER_NCONFIGS; /* Number of configurations supported */ 394 dev->configid = ETHER_CONFIGID; /* The only supported configuration ID */ 395 396 /* Interfaces. 397 * 398 * ifnobase must be provided by board-specific logic 399 */ 400 401 dev->devinfo.ninterfaces = ETHER_NINTERFACES; /* Number of interfaces in the configuration */ 402 403 /* Strings. 404 * 405 * strbase must be provided by board-specific logic 406 */ 407 408 dev->devinfo.nstrings = ETHER_NSTRIDS; /* Number of Strings */ 409 410 /* Endpoints. 411 * 412 * Endpoint numbers must be provided by board-specific logic. 413 */ 414 415 dev->devinfo.nendpoints = ETHER_NUM_EPS; 416} 417 418#ifdef __cplusplus 419#if __cplusplus 420} 421#endif /* __cplusplus */ 422#endif /* __cplusplus */