usbh_net.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /*
  2. * Copyright (c) 2024, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <nuttx/net/ip.h>
  7. #include <nuttx/net/netdev.h>
  8. #include "usbh_core.h"
  9. #if CONFIG_NET_ETH_PKTSIZE < 1514
  10. #error "CONFIG_NET_ETH_PKTSIZE must be at least 1514"
  11. #endif
  12. #if CONFIG_IOB_BUFSIZE < 1514
  13. #error "CONFIG_IOB_BUFSIZE must be at least 1514"
  14. #endif
  15. #ifndef CONFIG_NETDEV_LATEINIT
  16. #error "CONFIG_NETDEV_LATEINIT must be enabled"
  17. #endif
  18. #ifndef CONFIG_NETUTILS_DHCPC
  19. #error "CONFIG_NETUTILS_DHCPC must be enabled"
  20. #endif
  21. #ifndef CONFIG_NETINIT_DHCPC
  22. #error "CONFIG_NETINIT_DHCPC must be enabled"
  23. #endif
  24. // #define CONFIG_USBHOST_PLATFORM_CDC_ECM
  25. #define CONFIG_USBHOST_PLATFORM_CDC_RNDIS
  26. // #define CONFIG_USBHOST_PLATFORM_CDC_NCM
  27. // #define CONFIG_USBHOST_PLATFORM_ASIX
  28. // #define CONFIG_USBHOST_PLATFORM_RTL8152
  29. struct usbh_net {
  30. struct net_driver_s netdev;
  31. struct work_s txpollwork;
  32. bool linkup;
  33. };
  34. void usbh_net_eth_output_common(struct net_driver_s *dev, uint8_t *buf)
  35. {
  36. usb_memcpy(buf, dev->d_buf, dev->d_len);
  37. }
  38. void usbh_net_eth_input_common(struct net_driver_s *dev, uint8_t *buf, size_t len, uint8_t* (*eth_input)(void), int (*eth_output)(uint32_t buflen))
  39. {
  40. FAR struct eth_hdr_s *hdr;
  41. net_lock();
  42. NETDEV_RXPACKETS(dev);
  43. /* Any ACK or other response packet generated by the network stack
  44. * will always be shorter than the received packet, therefore it is
  45. * safe to pass the received frame buffer directly.
  46. */
  47. dev->d_buf = buf;
  48. dev->d_len = len;
  49. hdr = (FAR struct eth_hdr_s *)dev->d_buf;
  50. #ifdef CONFIG_NET_IPv4
  51. if (hdr->type == HTONS(ETHTYPE_IP)) {
  52. NETDEV_RXIPV4(dev);
  53. /* Receive an IPv4 packet from the network device */
  54. ipv4_input(dev);
  55. if (dev->d_len > 0) {
  56. /* And send the packet */
  57. usbh_net_eth_output_common(dev, eth_input());
  58. eth_output(dev->d_len);
  59. }
  60. } else
  61. #endif
  62. #ifdef CONFIG_NET_IPv6
  63. if (hdr->type == HTONS(ETHTYPE_IP6)) {
  64. NETDEV_RXIPV6(dev);
  65. /* Give the IPv6 packet to the network layer */
  66. ipv6_input(dev);
  67. if (dev->d_len > 0) {
  68. /* And send the packet */
  69. usbh_net_eth_output_common(dev, eth_input());
  70. eth_output(dev->d_len);
  71. }
  72. } else
  73. #endif
  74. #ifdef CONFIG_NET_ARP
  75. if (hdr->type == HTONS(ETHTYPE_ARP)) {
  76. NETDEV_RXARP(dev);
  77. arp_input(dev);
  78. if (dev->d_len > 0) {
  79. usbh_net_eth_output_common(dev, eth_input());
  80. eth_output(dev->d_len);
  81. }
  82. } else
  83. #endif
  84. {
  85. NETDEV_RXDROPPED(dev);
  86. }
  87. net_unlock();
  88. }
  89. #ifdef CONFIG_USBHOST_PLATFORM_CDC_RNDIS
  90. #include "usbh_rndis.h"
  91. struct usbh_net g_rndis_dev;
  92. static int rndis_ifup(struct net_driver_s *dev)
  93. {
  94. printf("rndis if up\r\n");
  95. g_rndis_dev.linkup = true;
  96. usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, NULL);
  97. return OK;
  98. }
  99. static int rndis_ifdown(struct net_driver_s *dev)
  100. {
  101. printf("rndis if down\r\n");
  102. g_rndis_dev.linkup = false;
  103. return OK;
  104. }
  105. static int rndis_txpoll(struct net_driver_s *dev)
  106. {
  107. usbh_net_eth_output_common(&g_rndis_dev.netdev, usbh_rndis_get_eth_txbuf());
  108. return usbh_rndis_eth_output(g_rndis_dev.netdev.d_len);
  109. }
  110. static void rndis_txavail_work(void *arg)
  111. {
  112. net_lock();
  113. if (g_rndis_dev.linkup) {
  114. devif_poll(&g_rndis_dev.netdev, rndis_txpoll);
  115. } else {
  116. }
  117. net_unlock();
  118. }
  119. static int rndis_txavail(struct net_driver_s *dev)
  120. {
  121. if (work_available(&g_rndis_dev.txpollwork)) {
  122. work_queue(LPWORK, &g_rndis_dev.txpollwork, rndis_txavail_work, NULL, 0);
  123. } else {
  124. return -1;
  125. }
  126. return OK;
  127. }
  128. void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen)
  129. {
  130. usbh_net_eth_input_common(&g_rndis_dev.netdev, buf, buflen, usbh_rndis_get_eth_txbuf, usbh_rndis_eth_output);
  131. }
  132. void usbh_rndis_run(struct usbh_rndis *rndis_class)
  133. {
  134. memset(&g_rndis_dev.netdev, 0, sizeof(struct net_driver_s));
  135. g_rndis_dev.netdev.d_ifup = rndis_ifup;
  136. g_rndis_dev.netdev.d_ifdown = rndis_ifdown;
  137. g_rndis_dev.netdev.d_txavail = rndis_txavail;
  138. g_rndis_dev.netdev.d_private = rndis_class;
  139. for (uint8_t j = 0; j < 6; j++) {
  140. g_rndis_dev.netdev.d_mac.ether.ether_addr_octet[j] = rndis_class->mac[j];
  141. }
  142. netdev_register(&g_rndis_dev.netdev, NET_LL_ETHERNET);
  143. netinit_bringup();
  144. }
  145. void usbh_rndis_stop(struct usbh_rndis *rndis_class)
  146. {
  147. }
  148. #endif