usbh_lwip.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. /*
  2. * Copyright (c) 2024, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "netif/etharp.h"
  7. #include "lwip/netif.h"
  8. #include "lwip/pbuf.h"
  9. #include "lwip/tcpip.h"
  10. #if LWIP_DHCP
  11. #include "lwip/dhcp.h"
  12. #include "lwip/prot/dhcp.h"
  13. #endif
  14. #include "usbh_core.h"
  15. #if LWIP_TCPIP_CORE_LOCKING_INPUT != 1
  16. #warning suggest you to set LWIP_TCPIP_CORE_LOCKING_INPUT to 1, usb handles eth input with own thread
  17. #endif
  18. #if LWIP_TCPIP_CORE_LOCKING != 1
  19. #error must set LWIP_TCPIP_CORE_LOCKING to 1
  20. #endif
  21. #if PBUF_POOL_BUFSIZE < 1600
  22. #error PBUF_POOL_BUFSIZE must be larger than 1600
  23. #endif
  24. #if TCPIP_THREAD_STACKSIZE < 1024
  25. #error TCPIP_THREAD_STACKSIZE must be >= 1024
  26. #endif
  27. #if !defined(CONFIG_USBHOST_PLATFORM_CDC_ECM) && \
  28. !defined(CONFIG_USBHOST_PLATFORM_CDC_RNDIS) && \
  29. !defined(CONFIG_USBHOST_PLATFORM_CDC_NCM) && \
  30. !defined(CONFIG_USBHOST_PLATFORM_ASIX) && \
  31. !defined(CONFIG_USBHOST_PLATFORM_RTL8152)
  32. #error "Please enable at least one USB Ethernet platform in usb_config.h or Kconfig"
  33. #endif
  34. // #define CONFIG_USBHOST_PLATFORM_CDC_ECM
  35. // #define CONFIG_USBHOST_PLATFORM_CDC_RNDIS
  36. // #define CONFIG_USBHOST_PLATFORM_CDC_NCM
  37. // #define CONFIG_USBHOST_PLATFORM_ASIX
  38. // #define CONFIG_USBHOST_PLATFORM_RTL8152
  39. ip_addr_t g_ipaddr;
  40. ip_addr_t g_netmask;
  41. ip_addr_t g_gateway;
  42. void usbh_lwip_eth_output_common(struct pbuf *p, uint8_t *buf)
  43. {
  44. struct pbuf *q;
  45. uint8_t *buffer;
  46. buffer = buf;
  47. for (q = p; q != NULL; q = q->next) {
  48. usb_memcpy(buffer, q->payload, q->len);
  49. buffer += q->len;
  50. }
  51. }
  52. void usbh_lwip_eth_input_common(struct netif *netif, uint8_t *buf, uint32_t len)
  53. {
  54. #if LWIP_TCPIP_CORE_LOCKING_INPUT
  55. pbuf_type type = PBUF_REF;
  56. #else
  57. pbuf_type type = PBUF_POOL;
  58. #endif
  59. err_t err;
  60. struct pbuf *p;
  61. p = pbuf_alloc(PBUF_RAW, len, type);
  62. if (p != NULL) {
  63. #if LWIP_TCPIP_CORE_LOCKING_INPUT
  64. p->payload = buf;
  65. #else
  66. usb_memcpy(p->payload, buf, len);
  67. #endif
  68. err = netif->input(p, netif);
  69. if (err != ERR_OK) {
  70. pbuf_free(p);
  71. }
  72. } else {
  73. USB_LOG_ERR("No memory to alloc pbuf\r\n");
  74. }
  75. }
  76. struct usb_osal_timer *dhcp_handle;
  77. static void dhcp_timeout(void *arg)
  78. {
  79. struct netif *netif = (struct netif *)arg;
  80. #if LWIP_DHCP
  81. struct dhcp *dhcp;
  82. #endif
  83. if (netif_is_up(netif)) {
  84. #if LWIP_DHCP
  85. dhcp = netif_dhcp_data(netif);
  86. if (dhcp && (dhcp->state == DHCP_STATE_BOUND)) {
  87. #endif
  88. USB_LOG_INFO("IPv4 Address : %s\r\n", ipaddr_ntoa(&netif->ip_addr));
  89. USB_LOG_INFO("IPv4 Subnet mask : %s\r\n", ipaddr_ntoa(&netif->netmask));
  90. USB_LOG_INFO("IPv4 Gateway : %s\r\n\r\n", ipaddr_ntoa(&netif->gw));
  91. usb_osal_timer_stop(dhcp_handle);
  92. #if LWIP_DHCP
  93. }
  94. #endif
  95. } else {
  96. }
  97. }
  98. #ifdef CONFIG_USBHOST_PLATFORM_CDC_ECM
  99. #include "usbh_cdc_ecm.h"
  100. struct netif g_cdc_ecm_netif;
  101. static err_t usbh_cdc_ecm_linkoutput(struct netif *netif, struct pbuf *p)
  102. {
  103. int ret;
  104. (void)netif;
  105. usbh_lwip_eth_output_common(p, usbh_cdc_ecm_get_eth_txbuf());
  106. ret = usbh_cdc_ecm_eth_output(p->tot_len);
  107. if (ret < 0) {
  108. return ERR_BUF;
  109. } else {
  110. return ERR_OK;
  111. }
  112. }
  113. void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen)
  114. {
  115. usbh_lwip_eth_input_common(&g_cdc_ecm_netif, buf, buflen);
  116. }
  117. static err_t usbh_cdc_ecm_if_init(struct netif *netif)
  118. {
  119. LWIP_ASSERT("netif != NULL", (netif != NULL));
  120. netif->mtu = 1500;
  121. netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
  122. netif->state = NULL;
  123. netif->name[0] = 'E';
  124. netif->name[1] = 'X';
  125. netif->output = etharp_output;
  126. netif->linkoutput = usbh_cdc_ecm_linkoutput;
  127. return ERR_OK;
  128. }
  129. void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
  130. {
  131. struct netif *netif = &g_cdc_ecm_netif;
  132. netif->hwaddr_len = 6;
  133. memcpy(netif->hwaddr, cdc_ecm_class->mac, 6);
  134. IP4_ADDR(&g_ipaddr, 0, 0, 0, 0);
  135. IP4_ADDR(&g_netmask, 0, 0, 0, 0);
  136. IP4_ADDR(&g_gateway, 0, 0, 0, 0);
  137. netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_cdc_ecm_if_init, tcpip_input);
  138. netif_set_default(netif);
  139. while (!netif_is_up(netif)) {
  140. }
  141. dhcp_handle = usb_osal_timer_create("dhcp", 200, dhcp_timeout, netif, true);
  142. if (dhcp_handle == NULL) {
  143. USB_LOG_ERR("timer creation failed! \r\n");
  144. while (1) {
  145. }
  146. }
  147. usb_osal_thread_create("usbh_cdc_ecm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ecm_rx_thread, NULL);
  148. #if LWIP_DHCP
  149. dhcp_start(netif);
  150. usb_osal_timer_start(dhcp_handle);
  151. #endif
  152. }
  153. void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
  154. {
  155. struct netif *netif = &g_cdc_ecm_netif;
  156. (void)cdc_ecm_class;
  157. #if LWIP_DHCP
  158. dhcp_stop(netif);
  159. dhcp_cleanup(netif);
  160. usb_osal_timer_delete(dhcp_handle);
  161. #endif
  162. netif_set_down(netif);
  163. netif_remove(netif);
  164. }
  165. #endif
  166. #ifdef CONFIG_USBHOST_PLATFORM_CDC_RNDIS
  167. #include "usbh_rndis.h"
  168. struct usb_osal_timer *timer_handle;
  169. static void rndis_dev_keepalive_timeout(void *arg)
  170. {
  171. struct usbh_rndis *rndis_class = (struct usbh_rndis *)arg;
  172. usbh_rndis_keepalive(rndis_class);
  173. }
  174. void timer_init(struct usbh_rndis *rndis_class)
  175. {
  176. timer_handle = usb_osal_timer_create("rndis_keepalive", 5000, rndis_dev_keepalive_timeout, rndis_class, true);
  177. if (NULL != timer_handle) {
  178. usb_osal_timer_start(timer_handle);
  179. } else {
  180. USB_LOG_ERR("timer creation failed! \r\n");
  181. for (;;) {
  182. ;
  183. }
  184. }
  185. }
  186. struct netif g_rndis_netif;
  187. static err_t usbh_rndis_linkoutput(struct netif *netif, struct pbuf *p)
  188. {
  189. int ret;
  190. (void)netif;
  191. usbh_lwip_eth_output_common(p, usbh_rndis_get_eth_txbuf());
  192. ret = usbh_rndis_eth_output(p->tot_len);
  193. if (ret < 0) {
  194. return ERR_BUF;
  195. } else {
  196. return ERR_OK;
  197. }
  198. }
  199. void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen)
  200. {
  201. usbh_lwip_eth_input_common(&g_rndis_netif, buf, buflen);
  202. }
  203. static err_t usbh_rndis_if_init(struct netif *netif)
  204. {
  205. LWIP_ASSERT("netif != NULL", (netif != NULL));
  206. netif->mtu = 1500;
  207. netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
  208. netif->state = NULL;
  209. netif->name[0] = 'E';
  210. netif->name[1] = 'X';
  211. netif->output = etharp_output;
  212. netif->linkoutput = usbh_rndis_linkoutput;
  213. return ERR_OK;
  214. }
  215. void usbh_rndis_run(struct usbh_rndis *rndis_class)
  216. {
  217. struct netif *netif = &g_rndis_netif;
  218. netif->hwaddr_len = 6;
  219. memcpy(netif->hwaddr, rndis_class->mac, 6);
  220. IP4_ADDR(&g_ipaddr, 0, 0, 0, 0);
  221. IP4_ADDR(&g_netmask, 0, 0, 0, 0);
  222. IP4_ADDR(&g_gateway, 0, 0, 0, 0);
  223. netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_rndis_if_init, tcpip_input);
  224. netif_set_default(netif);
  225. while (!netif_is_up(netif)) {
  226. }
  227. dhcp_handle = usb_osal_timer_create("dhcp", 200, dhcp_timeout, netif, true);
  228. if (dhcp_handle == NULL) {
  229. USB_LOG_ERR("timer creation failed! \r\n");
  230. while (1) {
  231. }
  232. }
  233. usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, NULL);
  234. //timer_init(rndis_class);
  235. #if LWIP_DHCP
  236. dhcp_start(netif);
  237. usb_osal_timer_start(dhcp_handle);
  238. #endif
  239. }
  240. void usbh_rndis_stop(struct usbh_rndis *rndis_class)
  241. {
  242. struct netif *netif = &g_rndis_netif;
  243. (void)rndis_class;
  244. #if LWIP_DHCP
  245. dhcp_stop(netif);
  246. dhcp_cleanup(netif);
  247. usb_osal_timer_delete(dhcp_handle);
  248. #endif
  249. netif_set_down(netif);
  250. netif_remove(netif);
  251. // xTimerStop(timer_handle, 0);
  252. // xTimerDelete(timer_handle, 0);
  253. }
  254. #endif
  255. #ifdef CONFIG_USBHOST_PLATFORM_CDC_NCM
  256. #include "usbh_cdc_ncm.h"
  257. struct netif g_cdc_ncm_netif;
  258. static err_t usbh_cdc_ncm_linkoutput(struct netif *netif, struct pbuf *p)
  259. {
  260. int ret;
  261. (void)netif;
  262. usbh_lwip_eth_output_common(p, usbh_cdc_ncm_get_eth_txbuf());
  263. ret = usbh_cdc_ncm_eth_output(p->tot_len);
  264. if (ret < 0) {
  265. return ERR_BUF;
  266. } else {
  267. return ERR_OK;
  268. }
  269. }
  270. void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen)
  271. {
  272. usbh_lwip_eth_input_common(&g_cdc_ncm_netif, buf, buflen);
  273. }
  274. static err_t usbh_cdc_ncm_if_init(struct netif *netif)
  275. {
  276. LWIP_ASSERT("netif != NULL", (netif != NULL));
  277. netif->mtu = 1500;
  278. netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
  279. netif->state = NULL;
  280. netif->name[0] = 'E';
  281. netif->name[1] = 'X';
  282. netif->output = etharp_output;
  283. netif->linkoutput = usbh_cdc_ncm_linkoutput;
  284. return ERR_OK;
  285. }
  286. void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)
  287. {
  288. struct netif *netif = &g_cdc_ncm_netif;
  289. netif->hwaddr_len = 6;
  290. memcpy(netif->hwaddr, cdc_ncm_class->mac, 6);
  291. IP4_ADDR(&g_ipaddr, 0, 0, 0, 0);
  292. IP4_ADDR(&g_netmask, 0, 0, 0, 0);
  293. IP4_ADDR(&g_gateway, 0, 0, 0, 0);
  294. netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_cdc_ncm_if_init, tcpip_input);
  295. netif_set_default(netif);
  296. while (!netif_is_up(netif)) {
  297. }
  298. dhcp_handle = usb_osal_timer_create("dhcp", 200, dhcp_timeout, netif, true);
  299. if (dhcp_handle == NULL) {
  300. USB_LOG_ERR("timer creation failed! \r\n");
  301. while (1) {
  302. }
  303. }
  304. usb_osal_thread_create("usbh_cdc_ncm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ncm_rx_thread, NULL);
  305. #if LWIP_DHCP
  306. dhcp_start(netif);
  307. usb_osal_timer_start(dhcp_handle);
  308. #endif
  309. }
  310. void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class)
  311. {
  312. struct netif *netif = &g_cdc_ncm_netif;
  313. (void)cdc_ncm_class;
  314. #if LWIP_DHCP
  315. dhcp_stop(netif);
  316. dhcp_cleanup(netif);
  317. usb_osal_timer_delete(dhcp_handle);
  318. #endif
  319. netif_set_down(netif);
  320. netif_remove(netif);
  321. }
  322. #endif
  323. #ifdef CONFIG_USBHOST_PLATFORM_ASIX
  324. #include "usbh_asix.h"
  325. struct netif g_asix_netif;
  326. static err_t usbh_asix_linkoutput(struct netif *netif, struct pbuf *p)
  327. {
  328. int ret;
  329. (void)netif;
  330. usbh_lwip_eth_output_common(p, usbh_asix_get_eth_txbuf());
  331. ret = usbh_asix_eth_output(p->tot_len);
  332. if (ret < 0) {
  333. return ERR_BUF;
  334. } else {
  335. return ERR_OK;
  336. }
  337. }
  338. void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen)
  339. {
  340. usbh_lwip_eth_input_common(&g_asix_netif, buf, buflen);
  341. }
  342. static err_t usbh_asix_if_init(struct netif *netif)
  343. {
  344. LWIP_ASSERT("netif != NULL", (netif != NULL));
  345. netif->mtu = 1500;
  346. netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
  347. netif->state = NULL;
  348. netif->name[0] = 'E';
  349. netif->name[1] = 'X';
  350. netif->output = etharp_output;
  351. netif->linkoutput = usbh_asix_linkoutput;
  352. return ERR_OK;
  353. }
  354. void usbh_asix_run(struct usbh_asix *asix_class)
  355. {
  356. struct netif *netif = &g_asix_netif;
  357. netif->hwaddr_len = 6;
  358. memcpy(netif->hwaddr, asix_class->mac, 6);
  359. IP4_ADDR(&g_ipaddr, 0, 0, 0, 0);
  360. IP4_ADDR(&g_netmask, 0, 0, 0, 0);
  361. IP4_ADDR(&g_gateway, 0, 0, 0, 0);
  362. netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_asix_if_init, tcpip_input);
  363. netif_set_default(netif);
  364. while (!netif_is_up(netif)) {
  365. }
  366. dhcp_handle = usb_osal_timer_create("dhcp", 200, dhcp_timeout, netif, true);
  367. if (dhcp_handle == NULL) {
  368. USB_LOG_ERR("timer creation failed! \r\n");
  369. while (1) {
  370. }
  371. }
  372. usb_osal_thread_create("usbh_asix_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_asix_rx_thread, NULL);
  373. #if LWIP_DHCP
  374. dhcp_start(netif);
  375. usb_osal_timer_start(dhcp_handle);
  376. #endif
  377. }
  378. void usbh_asix_stop(struct usbh_asix *asix_class)
  379. {
  380. struct netif *netif = &g_asix_netif;
  381. (void)asix_class;
  382. #if LWIP_DHCP
  383. dhcp_stop(netif);
  384. dhcp_cleanup(netif);
  385. usb_osal_timer_delete(dhcp_handle);
  386. #endif
  387. netif_set_down(netif);
  388. netif_remove(netif);
  389. }
  390. #endif
  391. #ifdef CONFIG_USBHOST_PLATFORM_RTL8152
  392. #include "usbh_rtl8152.h"
  393. struct netif g_rtl8152_netif;
  394. static err_t usbh_rtl8152_linkoutput(struct netif *netif, struct pbuf *p)
  395. {
  396. int ret;
  397. (void)netif;
  398. usbh_lwip_eth_output_common(p, usbh_rtl8152_get_eth_txbuf());
  399. ret = usbh_rtl8152_eth_output(p->tot_len);
  400. if (ret < 0) {
  401. return ERR_BUF;
  402. } else {
  403. return ERR_OK;
  404. }
  405. }
  406. void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen)
  407. {
  408. usbh_lwip_eth_input_common(&g_rtl8152_netif, buf, buflen);
  409. }
  410. static err_t usbh_rtl8152_if_init(struct netif *netif)
  411. {
  412. LWIP_ASSERT("netif != NULL", (netif != NULL));
  413. netif->mtu = 1500;
  414. netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
  415. netif->state = NULL;
  416. netif->name[0] = 'E';
  417. netif->name[1] = 'X';
  418. netif->output = etharp_output;
  419. netif->linkoutput = usbh_rtl8152_linkoutput;
  420. return ERR_OK;
  421. }
  422. void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class)
  423. {
  424. struct netif *netif = &g_rtl8152_netif;
  425. netif->hwaddr_len = 6;
  426. memcpy(netif->hwaddr, rtl8152_class->mac, 6);
  427. IP4_ADDR(&g_ipaddr, 0, 0, 0, 0);
  428. IP4_ADDR(&g_netmask, 0, 0, 0, 0);
  429. IP4_ADDR(&g_gateway, 0, 0, 0, 0);
  430. netif = netif_add(netif, &g_ipaddr, &g_netmask, &g_gateway, NULL, usbh_rtl8152_if_init, tcpip_input);
  431. netif_set_default(netif);
  432. while (!netif_is_up(netif)) {
  433. }
  434. dhcp_handle = usb_osal_timer_create("dhcp", 200, dhcp_timeout, netif, true);
  435. if (dhcp_handle == NULL) {
  436. USB_LOG_ERR("timer creation failed! \r\n");
  437. while (1) {
  438. }
  439. }
  440. usb_osal_thread_create("usbh_rtl8152_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rtl8152_rx_thread, NULL);
  441. #if LWIP_DHCP
  442. dhcp_start(netif);
  443. usb_osal_timer_start(dhcp_handle);
  444. #endif
  445. }
  446. void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class)
  447. {
  448. struct netif *netif = &g_rtl8152_netif;
  449. (void)rtl8152_class;
  450. #if LWIP_DHCP
  451. dhcp_stop(netif);
  452. dhcp_cleanup(netif);
  453. usb_osal_timer_delete(dhcp_handle);
  454. #endif
  455. netif_set_down(netif);
  456. netif_remove(netif);
  457. }
  458. #endif