]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - rpp-test-sw/commands/cmd_netstats.c
Convert doc from MediaWiki syntax to Markdown
[pes-rpp/rpp-test-sw.git] / rpp-test-sw / commands / cmd_netstats.c
1 /*
2  * Copyright (C) 2012-2013 Czech Technical University in Prague
3  *
4  * Created on: Aug 23, 2013
5  *
6  * Authors:
7  *     - Jan Dolezal <pm.jenik@gmail.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * File : cmd_netstats.c
23  *
24  * Abstract:
25  *      This file contains commands for net statistics (ethernet interface and LwIP)
26  *
27  */
28
29 #include "cmd_netstats.h"
30
31 #ifndef DOCGEN
32
33 #include <string.h>
34
35 #include "rpp/rpp.h"
36 #include "drv/emac.h"
37 #include "lwip/opt.h"
38 #include "lwip/stats.h"
39
40 #define INTERFACE_INSTANCE_NUMBER 0
41
42 int cmd_do_read_linkstat(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
43 {
44         if(!isPostInitialized())
45         {
46                 rpp_sci_printf("Eth not initialized run 'ethinit' command first.\n");
47                 return FAILURE;
48         }
49         struct netif *netif = rpp_eth_get_netif(INTERFACE_INSTANCE_NUMBER);
50         if(rpp_eth_phylinkstat(INTERFACE_INSTANCE_NUMBER))
51         rpp_sci_printf("%c%c%d : UP\r\n", netif->name[0], netif->name[1], netif->num);
52     else
53         rpp_sci_printf("%c%c%d : DOWN\r\n", netif->name[0], netif->name[1], netif->num);
54     return SUCCESS;
55 }
56
57 int cmd_do_read_mac(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
58 {
59         if(!isPostInitialized())
60         {
61                 rpp_sci_printf("Eth not initialized run 'ethinit' command first.\n");
62                 return FAILURE;
63         }
64     uint8_t macaddr[18];
65     rpp_eth_get_macAddrStr(INTERFACE_INSTANCE_NUMBER,macaddr);
66     rpp_sci_printf((const char*)"%s\n", macaddr);
67     return SUCCESS;
68 }
69
70 int cmd_do_read_ip(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
71 {
72         if(!isPostInitialized())
73         {
74                 rpp_sci_printf("Eth not initialized run 'ethinit' command first.\n");
75                 return FAILURE;
76         }
77     struct netif *netif = rpp_eth_get_netif(INTERFACE_INSTANCE_NUMBER);
78     uint8_t ipString[16];
79     rpp_eth_getIPDecimalStr(netif->ip_addr, ipString);
80     rpp_sci_printf("Address: %s\r\n", ipString);
81     rpp_eth_getIPDecimalStr(netif->netmask, ipString);
82     rpp_sci_printf("Netmask: %s\r\n", ipString);
83     rpp_eth_getIPDecimalStr(netif->gw, ipString);
84     rpp_sci_printf("Gateway: %s\r\n", ipString);
85     return SUCCESS;
86 }
87
88
89
90
91 /*      --- EMAC DESCRIPTOR FORMAT ---
92  *                                         bit fields
93  * WORD   |
94  * OFFSET | 31                               16 | 15                                 0
95  * ------------------------------------------------------------------------------------
96  *    0   |                         *Next Descriptor Pointer
97  *    1   |                           *Data Buffer Pointer
98  *    2   |            Buffer Offset            |            Buffer Length
99  *    3   |                Flags                |            Packet Length
100  *    4   |                                  *pbuf
101  */
102
103 boolean_t bd_SOP(volatile struct emac_tx_bd *bufferDescriptor)
104 {
105         return (bufferDescriptor->flags_pktlen & EMAC_DSC_FLAG_SOP);
106 }
107
108 boolean_t bd_EOP(volatile struct emac_tx_bd *bufferDescriptor)
109 {
110         return (bufferDescriptor->flags_pktlen & EMAC_DSC_FLAG_EOP);
111 }
112
113 boolean_t bd_OWNER(volatile struct emac_tx_bd *bufferDescriptor)
114 {
115         return (bufferDescriptor->flags_pktlen & EMAC_DSC_FLAG_OWNER);
116 }
117
118 boolean_t bd_EOQ(volatile struct emac_tx_bd *bufferDescriptor)
119 {
120         return (bufferDescriptor->flags_pktlen & EMAC_DSC_FLAG_EOQ);
121 }
122
123 uint32_t bd_addr(uint16_t bd_num)
124 {
125         return EMAC_CTRL_RAM_BASE_m(0) + bd_num*sizeof(struct emac_tx_bd);
126 }
127
128 volatile struct emac_tx_bd *findPreviousBD(volatile struct emac_tx_bd *bufferDescriptor)
129 {
130         volatile struct emac_tx_bd *temporary = bufferDescriptor - 1;
131
132         /* first try space before given bd */
133         if((uint32_t) temporary >= EMAC_CTRL_RAM_BASE_m(0) && temporary->next == bufferDescriptor)
134                 return temporary;
135         temporary = bufferDescriptor->next;
136     while(temporary != bufferDescriptor && temporary != NULL)
137     {
138         if(temporary->next == bufferDescriptor)
139                 return temporary;
140         temporary = (temporary + 1); /* going through memory, if you want to go through bd chains put here 'temporary = temporary->next;' */
141         if( (uint32_t)(temporary+1) > EMAC_CTRL_RAM_BASE_m(0)+SIZE_EMAC_CTRL_RAM){ /* when out of CPPI RAM */
142                 temporary = (struct emac_tx_bd *) EMAC_CTRL_RAM_BASE_m(0); /* continue scanning from the beginning */
143         }
144     }
145         return (struct emac_tx_bd *)-1; /* not found */
146 }
147
148 void print_bd_content(volatile struct emac_tx_bd *bufferDescriptor, boolean_t humanReadable)
149 {
150     uint16_t data;
151     rpp_sci_printf("Buffer Descriptor at 0x%08x\n", bufferDescriptor);
152     rpp_sci_printf("Next BD:\t0x%08x\n", bufferDescriptor->next);
153     rpp_sci_printf("Data ptr:\t0x%08x\n", bufferDescriptor->bufptr);
154     rpp_sci_printf("Buf offset:\t%d\tBuf length:\t%d\n", (bufferDescriptor->bufoff_len >> 16), (bufferDescriptor->bufoff_len & 0xffff));
155     if(!humanReadable)
156     {
157     rpp_sci_printf("Flags:\t\t0x%04x\t", (bufferDescriptor->flags_pktlen >> 16));
158     }
159     else
160     {
161     data = bufferDescriptor->flags_pktlen;
162     rpp_sci_printf("Flags:\t%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n", (data & EMAC_DSC_FLAG_SOP)?"SOP":"", (data & EMAC_DSC_FLAG_EOP)?"EOP":"", (data & EMAC_DSC_FLAG_OWNER)?"OWNER":"", (data & EMAC_DSC_FLAG_EOQ)?"EOQ":"", (data & EMAC_DSC_FLAG_TDOWNCMPLT)?"TDWN":"", (data & EMAC_DSC_FLAG_PASSCRC)?"PSCRC":"", (data & EMAC_DSC_FLAG_JABBER)?"JBR":"", (data & EMAC_DSC_FLAG_OVERSIZE)?"OVSZ":"", (data & EMAC_DSC_FLAG_FRAGMENT)?"FRGM":"", (data & EMAC_DSC_FLAG_UNDERSIZED)?"UNSZ":"", (data & EMAC_DSC_FLAG_CONTROL)?"CTRL":"", (data & EMAC_DSC_FLAG_OVERRUN)?"OVRUN":"", (data & EMAC_DSC_FLAG_CODEERROR)?"CODEERR":"", (data & EMAC_DSC_FLAG_ALIGNERROR)?"ALGNERR":"", (data & EMAC_DSC_FLAG_CRCERROR)?"CRCERR":"", (data & EMAC_DSC_FLAG_NOMATCH)?"NOMATCH":"");
163     }
164     rpp_sci_printf("Pkt length:\t%d\n", (bufferDescriptor->flags_pktlen & 0xffff));
165     rpp_sci_printf("Pbuf ptr:\t0x%08x\n", bufferDescriptor->pbuf);
166 }
167
168 /*
169  * mode: 0 flags -> param says which flag (0-15)
170  *       1 bd->next == NULL, no param
171  */
172 void print_bds_state(uint8_t mode, uint8_t param)
173 {
174         volatile struct emac_tx_bd *bufferDescriptor = (struct emac_tx_bd *) EMAC_CTRL_RAM_BASE_m(0);
175         uint16_t index = 0;
176         rpp_sci_printf("TX:");
177         while(index < 409)
178         {
179                 if(!(index%10)){
180                         rpp_sci_printf(" ");
181                         if(!(index%50))rpp_sci_printf("\n");
182                 }
183                 if(index == 204){
184                         rpp_sci_printf("\nRX: ");
185                 }
186             if      (mode == 0){
187             if(bufferDescriptor->flags_pktlen & ((1 << 15) >> (param%16))){
188                 rpp_sci_printf("f");
189             }else{
190                 rpp_sci_printf(".");
191             }
192             }else if(mode == 1){
193             if(bufferDescriptor->next == NULL){
194                 rpp_sci_printf("0");
195             }else{
196                 rpp_sci_printf(".");
197             }
198             }else return;
199             bufferDescriptor++;
200             index++;
201         }
202         rpp_sci_printf("\n");
203 }
204
205 #define BUF_SIZE 15
206
207 unsigned long readNum(uint8_t minamount, uint8_t maxamount, boolean_t hex){
208         unsigned long out = 0;
209         uint8_t input_buffer[BUF_SIZE];
210         uint8_t buf_index = 0;
211         uint8_t input;
212     do{
213         input = rpp_sci_getc();
214         if(input == '\b' && buf_index>0){
215                 input_buffer[buf_index] = '\0';
216                 buf_index--;
217                 echo('\b');
218                 echo( ' ');
219                 echo('\b');
220         }else if(buf_index>=maxamount){
221                 continue;
222         }else if(input <= '9' && input >= '0'){
223                 input_buffer[buf_index] = input - '0';
224                 echo(input);
225                 buf_index++;
226         }else if(hex && (input <= 'f' && input >= 'a')){
227                 input_buffer[buf_index] = input - ('a' - 10);
228                 echo(input);
229                 buf_index++;
230         }else if(hex && (input <= 'F' && input >= 'A')){
231                 input_buffer[buf_index] = input - ('A' - 10);
232                 echo((input + ('a' - 'A')));
233                 buf_index++;
234         }
235     }while( (input != '\r' && input != '\n' && buf_index<BUF_SIZE) || buf_index<minamount);
236     input = 0; /* use as index */
237     while(input < buf_index){
238         if(hex){
239                 out = (out << 4) + input_buffer[input];
240         }else{
241                 out = (out*10) + input_buffer[input];
242         }
243         input++;
244     }
245     return out;
246 }
247
248 int cmd_do_bufferdescriptors(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
249 {
250     uint8_t pindex;
251         uint8_t input;
252         volatile struct emac_tx_bd *bufferDescriptor;
253         boolean_t run = TRUE, interactive = FALSE, overview = FALSE;
254 #if RPP_ETH_STATS
255         boolean_t isrRun = FALSE, rb = FALSE, tb = FALSE;
256 #endif
257
258         /* if eth not initialized return */
259         if(!isPostInitialized())
260         {
261                 rpp_sci_printf("Eth not initialized run 'ethinit' command first.\n");
262                 return FAILURE;
263         }
264
265     /* examine parameters */
266     for(pindex = 1;param[pindex] != 0;pindex++)
267     {
268         if        (strncmp((char *) param[pindex], "-i", 3) == 0) {
269             interactive = TRUE;
270             break;
271         } else if (strncmp((char *) param[pindex], "-o", 3) == 0) {
272                 overview = TRUE;
273                 break;
274         }
275 #if RPP_ETH_STATS
276           else if (strncmp((char *) param[pindex], "-r", 3) == 0) {
277                 isrRun = TRUE;
278                 break;
279         }
280           else if (strncmp((char *) param[pindex], "-rb", 4) == 0) {
281                 rb = TRUE;
282                 break;
283         } else if (strncmp((char *) param[pindex], "-tb", 4) == 0) {
284                 tb = TRUE;
285                 break;
286         }
287 #endif
288     }
289         struct netif *netif = rpp_eth_get_netif(INTERFACE_INSTANCE_NUMBER);
290         if(netif == NULL)
291         {
292                 rpp_sci_printf("netif err\n");
293                 return -1;
294         }
295
296         if(interactive)
297                 while(run){
298                         input = rpp_sci_getc();
299
300                         if(input == 'b'){ /* print buffer descriptor at given address */
301                                 rpp_sci_printf("-? 0x");
302                                 bufferDescriptor = (struct emac_tx_bd *) readNum(8,8,TRUE);
303                                 rpp_sci_printf("\n");
304                                 /* check it fits EMAC CPPI RAM */
305                                 /*if(bufferDescriptor >= EMAC_CTRL_RAM_BASE_m(INTERFACE_INSTANCE_NUMBER) && (bufferDescriptor + sizeof(struct emac_tx_bd)) <= EMAC_CTRL_RAM_BASE_m(INTERFACE_INSTANCE_NUMBER) + SIZE_EMAC_CTRL_RAM)
306                                 {*/
307                                         print_bd_content(bufferDescriptor, FALSE);
308                                 /*}
309                                 else
310                                 {
311                                         rpp_sci_printf("address not from BD CPPI RAM range\n");
312                                 }*/
313                                 while(1){
314                                         input = rpp_sci_getc();
315                                         if      (input == 'n'){ /* next */
316                                                 bufferDescriptor = bufferDescriptor->next;
317                                                 if(bufferDescriptor != NULL){
318                                                         print_bd_content(bufferDescriptor, FALSE);
319                                                 }else{
320                                                         rpp_sci_printf("NULL\n");
321                                                         break;
322                                                 }
323                                         }else if(input == 'p'){ /* previous */
324                                                 bufferDescriptor = findPreviousBD(bufferDescriptor);
325                                                 if((int32_t)bufferDescriptor != -1)
326                                                 {
327                                 if(bufferDescriptor == NULL){
328                                                         rpp_sci_printf("NULL\n");
329                                                         break;
330                                 }else{
331                                         print_bd_content(bufferDescriptor, FALSE);
332                                 }
333                                                 }
334                                                 else
335                                                 {
336                                                         rpp_sci_printf("not found\n");
337                                                         break;
338                                                 }
339                                         }else if(input == 'r'){ /* reprint */
340                                                 if((int32_t)bufferDescriptor == -1 || bufferDescriptor == NULL)break;
341                             print_bd_content(bufferDescriptor, FALSE);
342                                         }else break;
343                                 }
344                         }
345
346                         if      (input == 'q'){ /* quit */
347                                 run = FALSE;
348                                 continue;
349                         }
350 #if RPP_ETH_STATS
351                         else if(input == 's'){ /* general statistics */
352                                 printStatistics();
353                         }else if(input == 't'){ /* print tx channel */
354                                 print_tx_channel_stat();
355                                 continue;
356                         }else if(input == 'r'){ /* print rx channel */
357                                 print_rx_channel_stat();
358                                 continue;
359                         }
360 #endif
361                         else if(input == 'a'){ /* autocheck consistency of buffer descriptors */
362
363                         }else if(input == 'o'){ /* overview */
364                     uint8_t mode = rpp_sci_getc() - '0';
365                     uint8_t param = rpp_sci_getc() - '0';
366                     print_bds_state(mode, param);
367                         }else if(input == 'c'){ /* convert */
368                                 rpp_sci_printf("0x%08x", bd_addr((uint16_t)readNum(1, 3, FALSE)));
369                         }
370                 }
371         else
372         {
373                 if(overview){
374                 rpp_sci_printf(" --- OVERVIEWS ---\n");
375                         rpp_sci_printf("bd->next points to NULL\n");
376                 print_bds_state(1, 0);
377                         rpp_sci_printf("bds with EMAC_DSC_FLAG_SOP\n");
378                 print_bds_state(0, 0);
379                         rpp_sci_printf("bds with EMAC_DSC_FLAG_EOP\n");
380                 print_bds_state(0, 1);
381                         rpp_sci_printf("bds with EMAC_DSC_FLAG_OWNER\n");
382                 print_bds_state(0, 2);
383                         rpp_sci_printf("bds with EMAC_DSC_FLAG_EOQ\n");
384                 print_bds_state(0, 3);
385                         rpp_sci_printf("bds with EMAC_DSC_FLAG_TDOWNCMPLT\n");
386                 print_bds_state(0, 4);
387                         rpp_sci_printf("bds with EMAC_DSC_FLAG_PASSCRC\n");
388                 print_bds_state(0, 5);
389                 rpp_sci_printf("\nPress any key ...\r");
390                 rpp_sci_getc();
391                 /* These flags are not so much important */
392                         rpp_sci_printf("bds with EMAC_DSC_FLAG_JABBER\n");
393                 print_bds_state(0, 6);
394                         rpp_sci_printf("bds with EMAC_DSC_FLAG_OVERSIZE\n");
395                 print_bds_state(0, 7);
396                         rpp_sci_printf("bds with EMAC_DSC_FLAG_FRAGMENT\n");
397                 print_bds_state(0, 8);
398                         rpp_sci_printf("bds with EMAC_DSC_FLAG_UNDERSIZED\n");
399                 print_bds_state(0, 9);
400                         rpp_sci_printf("bds with EMAC_DSC_FLAG_CONTROL\n");
401                 print_bds_state(0, 10);
402                         rpp_sci_printf("bds with EMAC_DSC_FLAG_OVERRUN\n");
403                 print_bds_state(0, 11);
404                         rpp_sci_printf("bds with EMAC_DSC_FLAG_CODEERROR\n");
405                 print_bds_state(0, 12);
406                         rpp_sci_printf("bds with EMAC_DSC_FLAG_ALIGNERROR\n");
407                 print_bds_state(0, 13);
408                         rpp_sci_printf("bds with EMAC_DSC_FLAG_CRCERROR\n");
409                 print_bds_state(0, 14);
410                         rpp_sci_printf("bds with EMAC_DSC_FLAG_NOMATCH\n");
411                 print_bds_state(0, 15);
412                 }
413 #if RPP_ETH_STATS
414                 if(isrRun){
415                         rpp_sci_printf(" --- NUMBER OF ISR RUNS ---\n");
416                         rpp_sci_printf("TxIsr: %d", countEMACCore0TxIsr);
417                         rpp_sci_printf("RxIsr: %d", countEMACCore0RxIsr);
418                 }
419 #endif
420
421
422         }
423     return ERR_OK;
424 }
425
426 #if LWIP_DHCP
427 int cmd_do_dhcp(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
428 {
429         if(!isPostInitialized())
430         {
431                 rpp_sci_printf("Eth not initialized run 'ethinit' command first.\n");
432                 return FAILURE;
433         }
434     rpp_sci_printf("not implemented yet.");
435     return ERR_OK;
436 }
437 #endif
438
439 #if LWIP_STATS_DISPLAY
440 int cmd_do_lwip(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
441 {
442         if(!isPostInitialized())
443         {
444                 rpp_sci_printf("Eth not initialized run 'ethinit' command first.\n");
445                 return FAILURE;
446         }
447         stats_display();
448         rpp_sci_printf("\n");
449     return ERR_OK;
450 }
451 #endif
452
453 int cmd_do_ethinit(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
454 {
455         int8_t retVal = rpp_eth_init_postInit(0, NULL); /* post OS startup init of eth (LwIP) for application usage -- waits for a while, for auto-negotiation of ethernet speed and DHCP if used */
456
457         switch(retVal){
458         case FAILURE:
459                 rpp_sci_printf("already initialized\n");
460                 break;
461         case NETIF_ADD_ERR:
462                 rpp_sci_printf("initialization of physical part of ethernet failed\n");
463                 break;
464         case DHCP_MEM_ERR:
465                 rpp_sci_printf("DHCP couldn't be started due to insufficient memory\n");
466                 break;
467         case PHY_LINK_DOWN:
468                 rpp_sci_printf("cable is not connected\n");
469                 break;
470         default:
471                 rpp_sci_printf("ethinit DONE\n");
472         }
473         return retVal;
474 }
475
476 #endif  /* DOCGEN */
477
478 cmd_des_t const cmd_des_linkstat={
479     0,0,
480     "ethlinkstat","Print current status of ethernet interface",
481
482     "### Command syntax ###\n"
483     "\n"
484     "    ethlinkstat\n"
485     "\n"
486     "### Description ###\n"
487     "\n"
488     "This command reads PHY link status assigned to ethernet interface and\n"
489     "prints interface name and informs about PHY's status to the output.\n"
490     "\n"
491     "### Example ###\n"
492     "\n"
493     "    --> ethlinkstat\n"
494     "    et0 : UP\n"
495     "\n"
496     "    --> ethlinkstat\n"
497     "    et0 : DOWN\n",
498     CMD_HANDLER(cmd_do_read_linkstat), (void *)&cmd_list_netstats
499 };
500
501 cmd_des_t const cmd_des_mac={
502     0,0,
503     "ethmac","Print current MAC address of ethernet interface",
504
505     "### Command syntax ###\n"
506     "\n"
507     "    ethmac\n"
508     "\n"
509     "### Description ###\n"
510     "\n"
511     "This command obtains MAC address from ethernet interface structure\n"
512     "and prints it to the output.\n"
513     "\n"
514     "### Example ###\n"
515     "\n"
516     "    --> ethmac\n"
517     "    12:34:56:78:9a:bc\n",
518     CMD_HANDLER(cmd_do_read_mac), (void *)&cmd_list_netstats
519 };
520
521 cmd_des_t const cmd_des_ip={
522     0,0,
523     "ethip","Print current IP address of network interface",
524
525     "### Command syntax ###\n"
526     "\n"
527     "    ethip\n"
528     "\n"
529     "### Description ###\n"
530     "\n"
531     "This command reads current IP address, netmask and gateway of network\n"
532     "interface and prints these to the output.\n"
533     "\n"
534     "### Example ###\n"
535     "\n"
536     "    --> ethip\n"
537     "    Address: 192.168.247.1\n"
538     "    Netmask: 255.255.255.0\n"
539     "    Gateway: 192.168.247.255\n",
540     CMD_HANDLER(cmd_do_read_ip), (void *)&cmd_list_netstats
541 };
542
543 cmd_des_t const cmd_des_bufferdescriptors={
544     0,CDESM_SPACE_SEP,
545     "ethbd","Examine emac buffer descriptors",
546
547     "### Command syntax ###\n"
548     "\n"
549     "    ethbd\n"
550     "\n"
551     "### Description ###\n"
552     "After startup you use keys to control what will be done.\n"
553     "\n"
554     "- q - quit\n"
555     "- s - general statistics\n"
556     "- t - transmit channel status\n"
557     "- r - receive channel status\n"
558     "- b - after giving address of bd it prints bd content\n"
559     "- a - checks consistency of buffer descriptors\n"
560     "\n"
561     "\n"
562     "### Example ###\n"
563     "\n"
564     "    --> ethbd\n",
565     CMD_HANDLER(cmd_do_bufferdescriptors), (void *)&cmd_list_netstats
566 };
567
568 #if LWIP_DHCP
569 cmd_des_t const cmd_des_dhcp={
570     0,0,
571     "dhcp","Prints and controls DHCP",
572
573     "### Command syntax ###\n"
574     "\n"
575     "    dhcp\n"
576     "\n"
577     "### Description ###\n"
578     "\n"
579     "\n"
580     ".\n"
581     "\n"
582     "### Example ###\n"
583     "\n"
584     "    --> dhcp\n"
585     "    \n",
586     CMD_HANDLER(cmd_do_dhcp), (void *)&cmd_list_netstats
587 };
588 #endif
589
590 #if LWIP_STATS_DISPLAY
591 cmd_des_t const cmd_des_lwip={
592     0,0,
593     "lwip","Prints statistics for the LwIP stack",
594
595     "### Command syntax ###\n"
596     "\n"
597     "    lwip\n"
598     "\n"
599     "### Description ###\n"
600     "\n"
601     "Sections printed:\n"
602     "LINK\n"
603     "ETHARP\n"
604     "IP\n"
605     "ICMP\n"
606     "UDP\n"
607     "TCP\n"
608     "MEM HEAP\n"
609     "MEM RAW_PCB\n"
610     "MEM UDP_PCB\n"
611     "MEM TCP_PCB\n"
612     "MEM TCP_PCB_LISTEN\n"
613     "MEM TCP_SEB\n"
614     "MEM NETBUF\n"
615     "MEM NETCONN\n"
616     "MEM TCPIP_MSG_API\n"
617     "MEM TCPIP_MSG_INPKT\n"
618     "MEM SYS_TIMEOUT\n"
619     "MEM PBUF_REF/ROM\n"
620     "MEM PBUF_POOL\n"
621     "SYS\n"
622     ".\n"
623     "Shown sections depends on modules compiled in.\n"
624     "    \n",
625     CMD_HANDLER(cmd_do_lwip), (void *)&cmd_list_netstats
626 };
627 #endif
628
629 cmd_des_t const cmd_des_ethinit={
630     0,0,
631     "ethinit","Post OS startup eth initialization",
632
633     "### Command syntax ###\n"
634     "\n"
635     "    ethinit\n"
636     "\n"
637     "### Description ###\n"
638     "This command finishes autonegotiation of PHY and initialize LwIP stack.\n"
639     "\n"
640     "\n"
641     "### Example ###\n"
642     "\n"
643     "    --> ethinit\n"
644     "    \n",
645     CMD_HANDLER(cmd_do_ethinit), (void *)&cmd_list_netstats
646 };
647
648 /** List of commands for lwip, defined as external */
649 cmd_des_t const *cmd_list_netstats[]={
650   &cmd_des_linkstat,
651   &cmd_des_mac,
652   &cmd_des_ip,
653   &cmd_des_bufferdescriptors,
654 #if LWIP_DHCP
655   &cmd_des_dhcp,
656 #endif
657 #if LWIP_STATS_DISPLAY
658   &cmd_des_lwip,
659 #endif
660   &cmd_des_ethinit,
661   NULL
662 };