• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */