1 /*
2  * Copyright (C) 2020-2022 Alibaba Group Holding Limited
3  */
4 
5 #include <string.h>
6 #include "k_api.h"
7 #include "aos/kernel.h"
8 
9 #include "lwip/err.h"
10 #include "lwip/netif.h"
11 #include "lwip/tcpip.h"
12 #include "lwip/ip_addr.h"
13 #include "netif/etharp.h"
14 
15 #include "uservice/uservice.h"
16 #include "uservice/eventid.h"
17 #include "ulog/ulog.h"
18 
19 #include "ch395_spi.h"
20 #include "ch395_cmd.h"
21 /* Private typedef -----------------------------------------------------------*/
22 typedef struct {
23     ip4_addr_t ip;
24     ip4_addr_t netmask;
25     ip4_addr_t gw;
26 } tcpip_ip_info_t;
27 
28 /* Private define ------------------------------------------------------------*/
29 /* Stack size of the interface thread */
30 #define CH395_TASK_PRIO 20
31 #define CH395_TASK_SIZE (6 * 1024)
32 #define CH395_MAX_DATA_SIZE 1514   /*max size is 1514 */
33 #define CH395_MIN_DATA_SZIE 60     /*min size is 64 include 4 bytes crc*/
34 
35 /* Define those to better describe your network interface. */
36 #define IFNAME0 'e'
37 #define IFNAME1 'n'
38 
39 #define TAG "ch395_lwip"
40 
41 static struct netif eth_lwip_netif;
42 static tcpip_ip_info_t eth_ip_info = {0};
43 static aos_task_t gst_ch395_lwip_int_task = {0};
44 static aos_task_t gst_ch395_input_task = {0};
45 static aos_sem_t gst_ch395_recv_sem = {0};
46 static st_ch395_info_t gst_lwipch395info = {0};
47 
48 static void ch395_lwip_inter_proc(void);
49 static int ch395_eth_sock_macraw(void);
50 
dump_ch395_packet(char * buf,int len)51 static void dump_ch395_packet(char *buf, int len)
52 {
53     int i = 0;
54     for (i = 0; i < len; i++) {
55         printf("0x%02x ", buf[i]);
56         if ((i + 1) % 32 == 0) {
57             printf("\r\n");
58         }
59     }
60     printf("\r\n");
61 }
62 
low_level_output(struct netif * netif,struct pbuf * p)63 static err_t low_level_output(struct netif *netif, struct pbuf *p)
64 {
65     struct pbuf *q = NULL;
66     uint8_t *data = NULL;
67     uint32_t datalen = 0;
68     int32_t ret = 0;
69     uint32_t first_copy = 0;
70     uint32_t copylen = 0;
71     void *src_buf = NULL;
72 
73     data = aos_malloc(CH395_MAX_DATA_SIZE);
74     memset(data, 0, CH395_MAX_DATA_SIZE);
75 
76     for (q = p; q != NULL; q = q->next) {
77         src_buf = q->payload;
78         copylen = q->len;
79         if (first_copy == 0) {
80             src_buf = (char *)src_buf + ETH_PAD_SIZE;
81             copylen = copylen - ETH_PAD_SIZE;
82             first_copy = 1;
83         }
84 
85         if (datalen + copylen >= CH395_MAX_DATA_SIZE) {
86             aos_free(data);
87             return ERR_BUF;
88         }
89         memcpy(&data[datalen], src_buf, copylen);
90         datalen = datalen + copylen;
91     }
92 
93     if (datalen < CH395_MIN_DATA_SZIE) {
94         datalen = CH395_MIN_DATA_SZIE;
95     }
96     /*for 4-byte alignment, 14 bytes ethernet header will cost 16 bytes;
97       so just we jump over the first two bytes */
98     ret = ch395_socket_data_send(0, datalen, data);
99     aos_free(data);
100     if (ret) {
101         printf("ch395 lwip low level output len %d fail", datalen);
102         return ERR_IF;
103     }
104 
105     return ERR_OK;
106 }
107 
108 /**
109   * @brief Should allocate a pbuf and transfer the bytes of the incoming
110   * packet from the interface into the pbuf.
111   *
112   * @param netif the lwip network interface structure for this ethernetif
113   * @return a pbuf filled with the received packet (including MAC header)
114   *         NULL on memory error
115   */
low_level_input(struct netif * netif,uint8_t * data,uint32_t datalen)116 static struct pbuf *low_level_input(struct netif *netif, uint8_t *data, uint32_t datalen)
117 {
118     struct pbuf *p = NULL, *q = NULL;
119     uint8_t *buffer = data;
120     uint32_t bufferoffset = 0;
121     uint32_t copylen = 0;
122     uint32_t leftlen = datalen;
123     uint32_t first_copy = 0;
124     uint32_t pbuf_len = 0;
125     void *dest_buf = NULL;
126 
127     /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */
128     p = pbuf_alloc(PBUF_RAW, datalen + ETH_PAD_SIZE, PBUF_POOL);
129     if (NULL == p) {
130         return NULL;
131     }
132 
133     for (q = p; q != NULL; q = q->next) {
134         dest_buf = q->payload;
135         pbuf_len = q->len;
136 
137         if (first_copy == 0) {
138             dest_buf = (char *)dest_buf + ETH_PAD_SIZE;
139             pbuf_len = pbuf_len - ETH_PAD_SIZE;
140             first_copy = 1;
141         }
142 
143         if (q->len > leftlen) {
144             copylen = leftlen;
145         } else {
146             copylen = pbuf_len;
147         }
148 
149         memcpy(dest_buf, &buffer[bufferoffset], copylen);
150         bufferoffset = bufferoffset + copylen;
151         leftlen = leftlen - copylen;
152     }
153 
154     return p;
155 }
156 
ethernetif_input(void const * argument)157 static void ethernetif_input(void const *argument)
158 {
159     struct pbuf *p;
160     int ret = 0;
161     uint8_t sock = 0;
162     uint16_t recv_len = 0;
163     uint8_t *precv_data = NULL;
164     struct netif *netif = (struct netif *)argument;
165 
166     /* then we need to recv the data */
167     precv_data = aos_malloc(CH395_MAX_DATA_SIZE);
168     if (NULL == precv_data) {
169         LOGE(TAG, "Fail to malloc %d ", recv_len);
170         return;
171     }
172 
173     while (1) {
174         ret = aos_sem_wait(&gst_ch395_recv_sem, AOS_WAIT_FOREVER);
175         if (ret) {
176             LOGE(TAG, "Fail to wait socket %d recv sem4 ", sock);
177             continue;
178         }
179 
180         ret = ch395_socket_recv_data_len(sock, &recv_len);
181         if (ret) {
182             LOGE(TAG, "Fail to get sock %d recv length", sock);
183             continue;
184         }
185 
186         if (recv_len == 0) {
187             LOGE(TAG, "sock %d no data need to recv ", sock);
188             continue;
189         }
190 
191         memset(precv_data, 0, CH395_MAX_DATA_SIZE);
192 
193         ret = ch395_socket_recv_data(sock, recv_len, precv_data);
194         if (ret) {
195             LOGE(TAG, "sock %d recv data fail len %d", sock, recv_len);
196             continue;
197         }
198 
199         p = low_level_input(netif, precv_data, recv_len);
200         if (p != NULL) {
201             if (netif->input(p, netif) != ERR_OK) {
202                 pbuf_free(p);
203             }
204         }
205     }
206 
207     /*shoudn't reach here incase memory leak */
208     aos_free(precv_data);
209 }
210 
low_level_init(struct netif * netif)211 static int low_level_init(struct netif *netif)
212 {
213     unsigned char macaddress[6] = {0};
214     int ret = 0;
215 
216     ret = ch395_get_mac_addr(macaddress);
217     if (ret) {
218         printf("eth fail to get mac addr ret %d \r\n", ret);
219         return -1;
220     }
221 
222     /* set netif MAC hardware address length */
223     netif->hwaddr_len = ETH_HWADDR_LEN;
224 
225     /* set netif MAC hardware address */
226     netif->hwaddr[0] = macaddress[0];
227     netif->hwaddr[1] = macaddress[1];
228     netif->hwaddr[2] = macaddress[2];
229     netif->hwaddr[3] = macaddress[3];
230     netif->hwaddr[4] = macaddress[4];
231     netif->hwaddr[5] = macaddress[5];
232 
233     /* set netif maximum transfer unit */
234     netif->mtu = 1500;
235 
236     /* Accept broadcast address and ARP traffic */
237     netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
238 
239     ret = aos_sem_new(&gst_ch395_recv_sem, 0);
240     if (ret) {
241         printf("creat to new ch395 lwip send sem4 0x%x\r\n", ret);
242         return -1;
243     }
244 
245     ret = aos_task_new_ext(&gst_ch395_input_task, "ch395_input",
246                            ethernetif_input, netif, CH395_TASK_SIZE, CH395_TASK_PRIO);
247     if (ret) {
248         printf("fail to start ch395 lwip input task 0x%x\r\n", ret);
249         aos_sem_free(&gst_ch395_recv_sem);
250         return -1;
251     }
252 
253     ret = aos_task_new_ext(&gst_ch395_lwip_int_task, "ch395_irq",
254                            ch395_lwip_inter_proc, NULL, CH395_TASK_SIZE, CH395_TASK_PRIO - 4);
255     if (ret) {
256         LOGE(TAG, "Fail to start chip interrupt proc task 0x%x", ret);
257         aos_task_delete(&gst_ch395_input_task);
258         aos_sem_free(&gst_ch395_recv_sem);
259         return -1;
260     }
261 
262     return 0;
263 }
264 
265 /**
266   * @brief Should be called at the beginning of the program to set up the
267   * network interface. It calls the function low_level_init() to do the
268   * actual setup of the hardware.
269   *
270   * This function should be passed as a parameter to netif_add().
271   *
272   * @param netif the lwip network interface structure for this ethernetif
273   * @return ERR_OK if the loopif is initialized
274   *         ERR_MEM if private data couldn't be allocated
275   *         any other err_t on error
276   */
ethernetif_init(struct netif * netif)277 static err_t ethernetif_init(struct netif *netif)
278 {
279     LWIP_ASSERT("netif != NULL", (netif != NULL));
280 
281 #if LWIP_NETIF_HOSTNAME
282     /* Initialize interface hostname */
283     netif->hostname = "haas_aos";
284 #endif /* LWIP_NETIF_HOSTNAME */
285 
286     netif->name[0] = IFNAME0;
287     netif->name[1] = IFNAME1;
288     /* set netif maximum transfer unit */
289     netif->mtu = 1500;
290 
291     /* Accept broadcast address and ARP traffic */
292     netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
293     netif->output = etharp_output;
294     netif->linkoutput = low_level_output;
295 
296     /* initialize the hardware */
297     if (low_level_init(netif) != 0) {
298         printf("ch395 lwip low level init fail\r\n");
299         return ERR_IF;
300     }
301 
302     return ERR_OK;
303 }
304 
post_ip_addr(tcpip_ip_info_t ip)305 void post_ip_addr(tcpip_ip_info_t ip)
306 {
307     /* post ip, mask and gateway in dhcp mode */
308     printf("************************************************** \r\n");
309     printf("DHCP Enable \r\n");
310     printf("ip = %s \r\n", ip4addr_ntoa(&eth_ip_info.ip));
311     printf("mask = %s \r\n", ip4addr_ntoa(&eth_ip_info.netmask));
312     printf("gateway = %s \r\n", ip4addr_ntoa(&eth_ip_info.gw));
313     printf("************************************************** \r\n");
314 }
315 
tcpip_dhcpc_cb(struct netif * pstnetif)316 static void tcpip_dhcpc_cb(struct netif *pstnetif)
317 {
318     uint8_t ip_addr[4] = {0};
319     uint8_t mask_addr[4] = {0};
320     uint8_t gw_addr[4] = {0};
321     int32_t ret = 0;
322 
323     if (!ip4_addr_cmp(ip_2_ip4(&pstnetif->ip_addr), IP4_ADDR_ANY4)) {
324         // check whether IP is changed
325         if (!ip4_addr_cmp(ip_2_ip4(&pstnetif->ip_addr), &eth_ip_info.ip) ||
326             !ip4_addr_cmp(ip_2_ip4(&pstnetif->netmask), &eth_ip_info.netmask) ||
327             !ip4_addr_cmp(ip_2_ip4(&pstnetif->gw), &eth_ip_info.gw)) {
328             ip4_addr_set(&eth_ip_info.ip, ip_2_ip4(&pstnetif->ip_addr));
329             ip4_addr_set(&eth_ip_info.netmask, ip_2_ip4(&pstnetif->netmask));
330             ip4_addr_set(&eth_ip_info.gw, ip_2_ip4(&pstnetif->gw));
331 
332             /* post the dhcp ip address */
333             post_ip_addr(eth_ip_info);
334             /*set ip addr for ch395*/
335             memcpy(ip_addr, &eth_ip_info.ip.addr, sizeof(ip_addr));
336             memcpy(mask_addr, &eth_ip_info.netmask.addr, sizeof(ip_addr));
337             memcpy(gw_addr, &eth_ip_info.gw.addr, sizeof(ip_addr));
338             printf("\r\nip: %d:%d:%d:%d mask: %d:%d:%d:%d gw:%d:%d:%d:%d \r\n",
339                 ip_addr[0], ip_addr[1], ip_addr[2], ip_addr[3],
340                 mask_addr[0], mask_addr[1], mask_addr[2], mask_addr[3],
341                 gw_addr[0], gw_addr[1], gw_addr[2], gw_addr[3]);
342             ret = ch395_set_ip_addr(ip_addr);
343             if (ret) {
344                 printf("set ip addr fail \r\n");
345             }
346             ret = ch395_set_gw_ip_addr(gw_addr);
347             if (ret) {
348                 printf("set gateway ip addr fail \r\n");
349             }
350             ch395_set_ip_mask_addr(mask_addr);
351             if (ret) {
352                 printf("set ip mask addr fail \r\n");
353             }
354         }
355         event_publish(EVENT_NETMGR_DHCP_SUCCESS, NULL);
356     }
357 
358     return;
359 }
360 
tcpip_dhcpc_start(struct netif * pstnetif)361 err_t tcpip_dhcpc_start(struct netif *pstnetif)
362 {
363     int ret = 0;
364     /*at first try to enable dhcp*/
365     if (NULL == pstnetif) {
366         printf("input netif is NULL \r\n");
367         return -1;
368     }
369 
370     if (netif_is_up(pstnetif)) {
371         if (dhcp_start(pstnetif) != ERR_OK) {
372             LOG("dhcp client start failed");
373             return -1;
374         }
375     }
376 
377     netif_set_status_callback(pstnetif, tcpip_dhcpc_cb);
378     return 0;
379 }
380 
tcpip_init_done(void * arg)381 static void tcpip_init_done(void *arg)
382 {
383 #if LWIP_IPV4
384     ip4_addr_t ipaddr, netmask, gw;
385     memset(&ipaddr, 0, sizeof(ipaddr));
386     memset(&netmask, 0, sizeof(netmask));
387     memset(&gw, 0, sizeof(gw));
388     netif_add(&eth_lwip_netif, &ipaddr, &netmask, &gw, NULL, ethernetif_init, tcpip_input);
389 #endif
390 
391     netif_set_default(&eth_lwip_netif);
392     netif_set_up(&eth_lwip_netif);
393 }
394 
395 /* should be called after dhcp is done */
ch395_eth_sock_macraw(void)396 static int ch395_eth_sock_macraw(void)
397 {
398     int ret = 0;
399 
400     ret = ch395_set_sock_proto_type(0, PROTO_TYPE_MAC_RAW);
401     if (ret) {
402         LOGE(TAG, "Fail to set sock 0 macraw mode fail");
403         return -1;
404     }
405 
406     ret = ch395_socket_open(0);
407     if (ret) {
408         LOGE(TAG, "ch395 lwip fail to open socket 0 macraw mode");
409         return -1;
410     }
411 
412     return 0;
413 }
414 
ch395_lwip_sock_interrupt_proc(uint8_t sockindex)415 static void ch395_lwip_sock_interrupt_proc(uint8_t sockindex)
416 {
417     uint8_t sock_int_socket = 0;
418     uint16_t recv_len = 0;
419     uint8_t *precv_data = NULL;
420     int32_t ret = 0;
421 
422     /* get sock interrupt status */
423     ret = ch395_get_sock_int_status(sockindex, &sock_int_socket);
424     /* send done proc */
425     if (sock_int_socket & SINT_STAT_SENBUF_FREE) {
426         // LOGI(TAG, "sock %d send data done ", sockindex);
427         /*it means send ok */
428     }
429 
430     if (sock_int_socket & SINT_STAT_SEND_OK) {
431         /*only one buf is ok, so do nothing for now*/
432     }
433 
434     if (sock_int_socket & SINT_STAT_CONNECT) {
435         /*the interrup only happened in tcp mode , in socket 0
436         macraw mode nothing todo */
437     }
438 
439     if (sock_int_socket & SINT_STAT_DISCONNECT) {
440         /*the interrup only happened in tcp mode , in socket 0
441         macraw mode nothing todo */
442     }
443 
444     if (sock_int_socket & SINT_STAT_TIM_OUT) {
445         /*the interrup only happened in tcp mode , in socket 0
446         macraw mode nothing todo */
447     }
448 
449     if (sock_int_socket & SINT_STAT_RECV) {
450         // LOGI(TAG, "sock %d recv data ", sockindex);
451         /*get recv data length*/
452         /*signal recv sem4*/
453         if (aos_sem_is_valid(&gst_ch395_recv_sem)) {
454             aos_sem_signal(&gst_ch395_recv_sem);
455         }
456     }
457 }
458 
ch395_lwip_inter_proc(void)459 static void ch395_lwip_inter_proc(void)
460 {
461     uint16_t ch395_int_status;
462     uint8_t dhcp_status = 0;
463     uint8_t phy_status = 0;
464     uint32_t retry = 0;
465     int32_t ret = 0;
466     ip4_addr_t ipaddr = {0};
467     ip4_addr_t netmask = {0};
468     ip4_addr_t gw = {0};
469 
470     while (1) {
471         /*every 50 ms proc the chip interrupt*/
472         aos_msleep(5);
473 
474         ch395_int_status = 0;
475         ret = ch395_get_global_all_int_status(&ch395_int_status);
476 
477         if (ch395_int_status & GINT_STAT_UNREACH) {
478             /* nothing to do for now*/
479             LOGI(TAG, "recv unreach interrupt, nothing to do for now");
480         }
481 
482         if (ch395_int_status & GINT_STAT_IP_CONFLI) {
483             LOGI(TAG, "recv ip confict interrupt, nothing to do for now");
484         }
485 
486         if (ch395_int_status & GINT_STAT_PHY_CHANGE) {
487             /*get phy status*/
488             ret = ch395_get_phy_status(&phy_status);
489             if (ret != 0) {
490                 LOGE(TAG, "Fail to get phy status");
491                 continue;
492             }
493             gst_lwipch395info.phystate = phy_status;
494             if (phy_status == PHY_DISCONN) {
495                 LOGI(TAG, "eth link down");
496                 event_publish(EVENT_ETHERNET_LINK_DOWN, NULL);
497             } else {
498                 /*start up to dhcp*/
499                 LOGI(TAG, "eth link up");
500                 event_publish(EVENT_ETHERNET_LINK_UP, &eth_lwip_netif);
501             }
502         }
503 
504         /* dhcp/pppoe interrup proc */
505         if (ch395_int_status & GINT_STAT_DHCP) {
506             ret = ch395_dhcp_get_status(&dhcp_status);
507             if (ret) {
508                 LOGE(TAG, "Fail to dhcp result");
509                 continue;
510             }
511 
512             if (dhcp_status == 0) {
513                 /*try to get ip interface */
514                 do {
515                     memset(&gst_lwipch395info.ip_info, 0, sizeof(gst_lwipch395info.ip_info));
516                     ret = ch395_get_ip_interface(&gst_lwipch395info.ip_info);
517                     if (ret) {
518                         LOGE(TAG, "Fail to get eth interface ip info");
519                         continue;
520                     }
521 
522                     if (gst_lwipch395info.ip_info.ipaddr[0] != 0 && gst_lwipch395info.ip_info.ipaddr[1] != 0) {
523                         /* Post got ip event */
524                         LOGI(TAG, "get ip info %d.%d.%d.%d gateway %d.%d.%d.%d mask %d.%d.%d.%d dns1 %d.%d.%d.%d dns2 %d.%d.%d.%d\r\n",
525                              gst_lwipch395info.ip_info.ipaddr[0], gst_lwipch395info.ip_info.ipaddr[1], gst_lwipch395info.ip_info.ipaddr[2], gst_lwipch395info.ip_info.ipaddr[3],
526                              gst_lwipch395info.ip_info.gateway[0], gst_lwipch395info.ip_info.gateway[1], gst_lwipch395info.ip_info.gateway[2], gst_lwipch395info.ip_info.gateway[3],
527                              gst_lwipch395info.ip_info.ip_mask[0], gst_lwipch395info.ip_info.ip_mask[1], gst_lwipch395info.ip_info.ip_mask[2], gst_lwipch395info.ip_info.ip_mask[3],
528                              gst_lwipch395info.ip_info.ip_dns1[0], gst_lwipch395info.ip_info.ip_dns1[1], gst_lwipch395info.ip_info.ip_dns1[2], gst_lwipch395info.ip_info.ip_dns1[3],
529                              gst_lwipch395info.ip_info.ip_dns2[0], gst_lwipch395info.ip_info.ip_dns2[1], gst_lwipch395info.ip_info.ip_dns2[2], gst_lwipch395info.ip_info.ip_dns2[3]);
530                         memcpy(&ipaddr.addr, gst_lwipch395info.ip_info.ipaddr, 4);
531                         memcpy(&netmask.addr, gst_lwipch395info.ip_info.ip_mask, 4);
532                         memcpy(&gw.addr, gst_lwipch395info.ip_info.gateway, 4);
533 
534                         netif_set_addr(&eth_lwip_netif, &ipaddr, &netmask, &gw);
535                         tcpip_dhcpc_cb(&eth_lwip_netif);
536                         break;
537                     }
538                     aos_msleep(1000);
539                     retry++;
540                 } while (retry < 10);
541             } else {
542                 // LOGD(TAG, "dhcp time out, cannot get ip addr, it will go on dhcp after 16 second");
543             }
544         }
545         if (ch395_int_status & GINT_STAT_SOCK0) {
546             ch395_lwip_sock_interrupt_proc(0);
547         }
548     }
549 }
550 
eth_lwip_tcpip_init(void)551 int eth_lwip_tcpip_init(void)
552 {
553     int ret = 0;
554     unsigned char chip_ver = 0;
555     unsigned char soft_ver = 0;
556     spi_dev_t eth_spi_dev = {0};
557 
558     eth_spi_dev.port = 0;
559     eth_spi_dev.config.data_size = SPI_DATA_SIZE_8BIT;
560     eth_spi_dev.config.mode = SPI_WORK_MODE_3;
561     eth_spi_dev.config.cs = SPI_CS_DIS;
562     eth_spi_dev.config.freq = 2000000;
563     eth_spi_dev.config.role = SPI_ROLE_MASTER;
564     eth_spi_dev.config.firstbit = SPI_FIRSTBIT_MSB;
565     eth_spi_dev.config.t_mode = SPI_TRANSFER_NORMAL;
566 
567     ret = ch395_module_init(&eth_spi_dev);
568     if (ret) {
569         printf("spi init fail 0x%x, port %d, spi role %d, firstbit %d, work_mode %d, freq %d",
570                ret, eth_spi_dev.port, eth_spi_dev.config.role, eth_spi_dev.config.firstbit,
571                eth_spi_dev.config.mode, eth_spi_dev.config.freq);
572         return -1;
573     }
574 
575     ret = ch395_get_version(&chip_ver, &soft_ver);
576     if (ret || chip_ver != 0x4) {
577         printf("Fail to get chip ver: 0x%x soft ver 0x%x ret : 0x%x", chip_ver, soft_ver, ret);
578         return -1;
579     }
580 
581     ret = ch395_set_func_param(SOCK_CTRL_FLAG_SOCKET_CLOSE);
582     if (ret) {
583         printf("eht init fail : ch395 set func param fail %d", ret);
584         return -1;
585     }
586 
587     ret = ch395_dev_init();
588     if (ret) {
589         printf("eht init fail : ch395 init fail %d", ret);
590         return -1;
591     }
592 
593     ret = ch395_eth_sock_macraw();
594     if (ret) {
595         printf("eth fail to set socket 0 macraw mode \r\n", ret);
596         return -1;
597     }
598 
599     ret = ch395_ping_enable(1);
600     if (ret) {
601         printf("eht init fail : ch395 ping enable fail %d", ret);
602     }
603 
604     tcpip_init_done(NULL);
605 
606     return 0;
607 }
608