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
48 extern "C" {
49 #endif /* __cplusplus */
50 #endif /* __cplusplus */
51
52 const struct netif *g_ether_usb0;
53
54 /* device driver structure definition */
55
56 static 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
65 static devclass_t g_fethernet_devclass;
66 DRIVER_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
83 static const char g_rndis_string_id[RNDIS_STRING_ID_LEN] =
84 {
85 RNDIS_STRING_ID_LEN, UDESC_STRING, 0x09, 0x04
86 };
87
88 static 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
96 static 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
107 static 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
117 static 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
125 static 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
143 static 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
is_multicast_eth_addr(const uint8_t * addr)154 static inline int is_multicast_eth_addr(const uint8_t *addr)
155 {
156 return (0x01 & addr[0]);
157 }
158
eth_set_hwaddr(struct netif * usb_netif,uint8_t * addr,uint8_t len)159 uint8_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
eth_random_addr(uint8_t * addr)185 void 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
eth_tx(struct netif * usb_netif,struct pbuf * p)209 static 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
eth_rx(struct los_eth_driver * sc,const struct usbdev_req_s * req)225 void 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
eth_drv_config(struct netif * usb_netif,uint32_t cflags,uint8_t set_bit)257 static 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
netdev_register(struct los_eth_driver * sc)268 void 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
netdev_unregister(struct los_eth_driver * sc)308 void 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
rndis_mkdevdesc(uint8_t * buf)318 void 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
rndis_mkcfgdesc(uint8_t * buf,struct usbdev_devinfo_s * devinfo)328 int16_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
rndis_mkstrdesc(uint8_t id,uint8_t * buf)361 int 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
rndis_get_composite_devdesc(struct composite_devdesc_s * dev)386 void 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 */