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