diff --git a/ChangeLog b/ChangeLog index 4b97bd8dfe0..55e099bcad9 100755 --- a/ChangeLog +++ b/ChangeLog @@ -11163,3 +11163,13 @@ loteardown() should not be called directory from applications. Rather, these functions are now available as IOCTL commands to the loop driver (2015-11-25). + * include/nuttx/net/netdev.h and several Ethernet drivers in arch/: + Most network drivers to not support statistics. Those that do only + support them when DEBUG is enabled. Each driver collects an + architecture specific set of statistics and there is no mechanism in + place to view those statistics. Thus, the driver feature was mostly + useless. This change standardizes the driver statistics and puts the + definition in the common network device structure defined in netdev.h + where they can be accessed by network applications. All Ethernet + drivers that collect statistics have been adapted to use these common + statistics (2015-11-26). \ No newline at end of file diff --git a/TODO b/TODO index 822cec198cb..ff34eeb102d 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -NuttX TODO List (Last updated November 25, 2015) +NuttX TODO List (Last updated November 26, 2015) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This file summarizes known NuttX bugs, limitations, inconsistencies with @@ -16,7 +16,7 @@ nuttx/ (0) Message Queues (sched/mqueue) (4) C++ Support (6) Binary loaders (binfmt/) - (12) Network (net/, drivers/net) + (11) Network (net/, drivers/net) (4) USB (drivers/usbdev, drivers/usbhost) (11) Libraries (libc/, libm/) (11) File system/Generic drivers (fs/, drivers/) @@ -829,25 +829,6 @@ o Network (net/, drivers/net) Status: Open Priority: Low - Title: STANDARDIZE ETHERNET DRIVER STATISTICS - Description: Need to standardize collection of statistics from network - drivers. Currently they are useless because they are not - accessible. The solution is to standardize the structure - that holds the drivers statistics. Then apps/nshlib - ifconfig command could present the driver statistics. - - Currently these drivers support non-standard statistics: - - arch/arm/src/kinetis/kinetis_enet.c - arch/arm/src/lpc17xx/lpc17_ethernet.c - arch/arm/src/tiva/lm3s_ethernet.c - arch/mips/src/pic32mx/pic32mx-ethernet.c - arch/z80/src/ez80/ez80_emac.c - - The other Ethernet drivers support no statistics. - Status: Open - Priority: Low. This is not a bug but an enhancement idea. - Title: CONCURRENT TCP SEND OPERATIONS Description: At present, there cannot be two concurrent active TCP send operations in progress using the same socket. This is because @@ -1728,9 +1709,9 @@ o ARM (arch/arm/) issues if, for example, floating point or perhaps long long operations were performed in an interrupt handler. - This issue exists for ARM7, ARM9, Cortex-M0, Cortex-M3, and - Cortex-M4 but has been addressed for the Cortex-A5. The fix - is really simple can cannot be incorporated without some + This issue exists for ARM7, ARM9, and Cortex-M0 but has been + addressed for the Cortex-M3/4/7 and Cortex-A5/8. The fix + is really simple but cannot be incorporated without some substantial testing. For ARM, the fix is the following logic arround each call into C code from assembly: diff --git a/arch b/arch index c4013ed7893..ee23d9991d2 160000 --- a/arch +++ b/arch @@ -1 +1 @@ -Subproject commit c4013ed78934974b2463cadb97db892bb1756bf0 +Subproject commit ee23d9991d2fa2cb58a834dee03181558a03b855 diff --git a/configs b/configs index 931d2ed2790..8fcf1ca2b7e 160000 --- a/configs +++ b/configs @@ -1 +1 @@ -Subproject commit 931d2ed27909e6265eb2eefae1346b758c37a739 +Subproject commit 8fcf1ca2b7ec45e4c5bd29258b5e5adc5ed8fcdc diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index c28f6005215..c1461e9153c 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -10,6 +10,7 @@ config NETDEV_LOOPBACK default n if !NET_LOOPBACK default y if NET_LOOPBACK select NET_NOINTS + select ARCH_HAVE_NETDEV_STATISTICS ---help--- Add support for the local network loopback device, lo. Any additional networking devices that are enabled must be compatible with @@ -25,6 +26,17 @@ config NETDEV_MULTINIC is considered to be a a link layer driver so if local loopback support is used you probably need to select this option. +config ARCH_HAVE_NETDEV_STATISTICS + bool + default n + +config NETDEV_STATISTICS + bool "Network device driver statistics" + depends on NET_STATISTICS && ARCH_HAVE_NETDEV_STATISTICS + ---help--- + Enable to collect statistics from the network drivers (if supported + by the network driver). + config NETDEV_LATEINIT bool "Late driver initialization" default n @@ -68,6 +80,7 @@ comment "External Ethernet MAC Device Support" menuconfig NET_DM90x0 bool "Davicom dm9000/dm9010 support" default n + select ARCH_HAVE_NETDEV_STATISTICS ---help--- References: Davicom data sheets (DM9000-DS-F03-041906.pdf, DM9010-DS-F01-103006.pdf) and looking at lots of other DM90x0 @@ -132,23 +145,21 @@ config DM9X_NINTERFACES default 1 depends on EXPERIMENTAL -config DM9X_STATS - bool "DM90x0 statistics" - default n - -endif # NET_DM90x0 +endif # NET_DM90x0 config NET_CS89x0 bool "CS89x0 support" default n depends on EXPERIMENTAL + select ARCH_HAVE_NETDEV_STATISTICS ---help--- - Under construction -- do not use + Under construction -- do not use menuconfig ENC28J60 bool "Microchip ENC28J60 support" default n select SPI + select ARCH_HAVE_NETDEV_STATISTICS ---help--- References: ENC28J60 Data Sheet, Stand-Alone Ethernet Controller with SPI Interface, @@ -180,12 +191,6 @@ config ENC28J60_FREQUENCY ---help--- Define to use a different bus frequency -config ENC28J60_STATS - bool "Network statistics support" - default n - ---help--- - Collect network statistics - config ENC28J60_HALFDUPPLEX bool "Enable half dupplex" default n @@ -213,6 +218,7 @@ menuconfig ENCX24J600 default n select SPI select NET_RXAVAIL + select ARCH_HAVE_NETDEV_STATISTICS ---help--- References: ENC424J600/624J600 Data Sheet Stand-Alone 10/100 Ethernet Controller @@ -253,12 +259,6 @@ config ENCX24J600_NRXDESCR The ENC has a relative large packet buffer of 24kB which can be used to buffer multiple packets silmutaneously -config ENCX24J600_STATS - bool "Network statistics support" - default n - ---help--- - Collect network statistics - config ENCX24J600_DUMPPACKET bool "Dump Packets" default n @@ -298,6 +298,7 @@ endif # NET_E1000 menuconfig NET_SLIP bool "SLIP (serial line) support" default n + select ARCH_HAVE_NETDEV_STATISTICS ---help--- Reference: RFC 1055 diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index 8a9f1814361..5adbe421354 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/net/cs89x0.c * - * Copyright (C) 2009-2011, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2009-2011, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -408,31 +408,31 @@ static void cs89x0_receive(FAR struct cs89x0_driver_s *cs89x0, uint16_t isq) rxlength = cs89x0_getreg(PPR_RXLENGTH); if ((isq & RX_OK) == 0) { -#ifdef CONFIG_C89x0_STATISTICS - cd89x0->cs_stats.rx_errors++; +#ifdef CONFIG_NETDEV_STATISTICS + NETDEV_RXERRORS(&cd89x0->cs_dev); + +#if 0 if ((isq & RX_RUNT) != 0) { - cd89x0->cs_stats.rx_lengtherrors++; } if ((isq & RX_EXTRA_DATA) != 0) { - cd89x0->cs_stats.rx_lengtherrors++; } if (isq & RX_CRC_ERROR) != 0) { if (!(isq & (RX_EXTRA_DATA | RX_RUNT))) { - cd89x0->cs_stats.rx_crcerrors++; } } if ((isq & RX_DRIBBLE) != 0) { - cd89x0->cs_stats.rx_frameerrors++; } #endif +#endif + return; } @@ -440,10 +440,7 @@ static void cs89x0_receive(FAR struct cs89x0_driver_s *cs89x0, uint16_t isq) if (rxlength > ???) { -#ifdef CONFIG_C89x0_STATISTICS - cd89x0->cs_stats.rx_errors++; - cd89x0->cs_stats.rx_lengtherrors++; -#endif + NETDEV_RXERRORS(&cd89x0->cs_dev); return; } @@ -457,9 +454,7 @@ static void cs89x0_receive(FAR struct cs89x0_driver_s *cs89x0, uint16_t isq) *dest++ = cs89x0_getreg(PPR_RXFRAMELOCATION); } -#ifdef CONFIG_C89x0_STATISTICS - cd89x0->cs_stats.rx_packets++; -#endif + NETDEV_RXPACKETS(&cd89x0->cs_dev); #ifdef CONFIG_NET_PKT /* When packet sockets are enabled, feed the frame into the packet tap */ @@ -473,6 +468,7 @@ static void cs89x0_receive(FAR struct cs89x0_driver_s *cs89x0, uint16_t isq) if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->cs_dev); /* Handle ARP on input then give the IPv4 packet to the network * layer @@ -513,6 +509,7 @@ static void cs89x0_receive(FAR struct cs89x0_driver_s *cs89x0, uint16_t isq) if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->cs_dev); /* Give the IPv6 packet to the network layer */ @@ -549,6 +546,7 @@ static void cs89x0_receive(FAR struct cs89x0_driver_s *cs89x0, uint16_t isq) #ifdef CONFIG_NET_ARP if (BUF->type == htons(ETHTYPE_ARP)) { + NETDEV_RXARP(&priv->cs_dev); arp_arpin(&cs89x0->cs_dev); /* If the above function invocation resulted in data that should be @@ -564,6 +562,7 @@ static void cs89x0_receive(FAR struct cs89x0_driver_s *cs89x0, uint16_t isq) #endif { nllvdbg("Unrecognized packet type %02x\n", BUF->type); + NETDEV_RXDROPPED(&priv->cs_dev); } } @@ -589,28 +588,30 @@ static void cs89x0_txdone(struct cs89x0_driver_s *cs89x0, uint16_t isq) * hold the register address causing the interrupt. We got here because * those bits indicated */ -#ifdef CONFIG_C89x0_STATISTICS - cd89x0->cs_stats.tx_packets++; +#ifdef CONFIG_NETDEV_STATISTICS + NETDEV_TXPACKETS(&cd89x0->cs_dev); if ((isq & ISQ_TXEVENT_TXOK) == 0) { - cd89x0->cs_stats.tx_errors++; + NETDEV_TXERRORS(&cd89x0->cs_dev); } + +#if 0 if ((isq & ISQ_TXEVENT_LOSSOFCRS) != 0) { - cd89x0->cs_stats.tx_carriererrors++; } + if ((isq & ISQ_TXEVENT_SQEERROR) != 0) { - cd89x0->cs_stats.tx_heartbeaterrors++; } + if (i(sq & ISQ_TXEVENT_OUTWINDOW) != 0) { - cd89x0->cs_stats.tx_windowerrors++; } + if (isq & TX_16_COL) { - cd89x0->cs_stats.tx_abortederrors++; } +#endif #endif /* If no further xmits are pending, then cancel the TX timeout */ @@ -719,15 +720,11 @@ static int cs89x0_interrupt(int irq, FAR void *context) break; case ISQ_RXMISSEVENT: -#ifdef CONFIG_C89x0_STATISTICS - cd89x0->cs_stats.rx_missederrors += (isq >> 6); -#endif + NETDEV_RXERRORS(&cd89x0->cs_dev); break; case ISQ_TXCOLEVENT: -#ifdef CONFIG_C89x0_STATISTICS - cd89x0->cs_stats.collisions += (isq >> 6); -#endif + NETDEV_TXERRORS(&cd89x0->cs_dev); break; } } diff --git a/drivers/net/dm90x0.c b/drivers/net/dm90x0.c index fd785e9e77e..e810c6b6727 100644 --- a/drivers/net/dm90x0.c +++ b/drivers/net/dm90x0.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/net/dm9x.c * - * Copyright (C) 2007-2010, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * References: Davicom data sheets (DM9000-DS-F03-041906.pdf, @@ -310,20 +310,6 @@ struct dm9x_driver_s void (*dm_write)(const uint8_t *ptr, int len); void (*dm_discard)(int len); -#if defined(CONFIG_DM9X_STATS) - uint32_t dm_ntxpackets; /* Count of packets sent */ - uint32_t dm_ntxbytes; /* Count of bytes sent */ - uint32_t dm_ntxerrors; /* Count of TX errors */ - uint32_t dm_nrxpackets; /* Count of packets received */ - uint32_t dm_nrxbytes; /* Count of bytes received */ - uint32_t dm_nrxfifoerrors; /* Count of RX FIFO overflow errors */ - uint32_t dm_nrxcrcerrors; /* Count of RX CRC errors */ - uint32_t dm_nrxlengtherrors; /* Count of RX length errors */ - uint32_t dm_nphyserrors; /* Count of physical layer errors */ - uint32_t dm_nresets; /* Counts number of resets */ - uint32_t dm_ntxtimeouts; /* Counts resets caused by TX timeouts */ -#endif - /* This holds the information visible to uIP/NuttX */ struct net_driver_s dm_dev; @@ -359,18 +345,6 @@ static void write32(const uint8_t *ptr, int len); static uint16_t dm9x_phyread(struct dm9x_driver_s *dm9x, int reg); static void dm9x_phywrite(struct dm9x_driver_s *dm9x, int reg, uint16_t value); -#if defined(CONFIG_DM9X_STATS) -static void dm9x_resetstatistics(struct dm9x_driver_s *dm9x); -#else -# define dm9x_resetstatistics(dm9x) -#endif - -#if defined(CONFIG_DM9X_STATS) && defined(CONFIG_DEBUG) -static void dm9x_dumpstatistics(struct dm9x_driver_s *dm9x); -#else -# define dm9x_dumpstatistics(dm9x) -#endif - #if defined(CONFIG_DM9X_CHECKSUM) static bool dm9x_rxchecksumready(uint8_t); #else @@ -665,72 +639,6 @@ static void dm9x_phywrite(struct dm9x_driver_s *dm9x, int reg, uint16_t value) putreg(DM9X_EEPHYC, 0x0); } -/**************************************************************************** - * Function: dm9x_resetstatistics - * - * Description: - * Reset all DM90x0 statistics - * - * Parameters: - * dm9x - Reference to the driver state structure - * - * Returned Value: - * None - * - * Assumptions: - * - ****************************************************************************/ - -#if defined(CONFIG_DM9X_STATS) -static void dm9x_resetstatistics(struct dm9x_driver_s *dm9x) -{ - dm9x->dm_ntxpackets = 0; /* Count of packets sent */ - dm9x->dm_ntxbytes = 0; /* Count of bytes sent */ - dm9x->dm_ntxerrors = 0; /* Count of TX errors */ - dm9x->dm_nrxpackets = 0; /* Count of packets received */ - dm9x->dm_nrxbytes = 0; /* Count of bytes received */ - dm9x->dm_nrxfifoerrors = 0; /* Count of RX FIFO overflow errors */ - dm9x->dm_nrxcrcerrors = 0; /* Count of RX CRC errors */ - dm9x->dm_nrxlengtherrors = 0; /* Count of RX length errors */ - dm9x->dm_nphyserrors = 0; /* Count of physical layer errors */ - dm9x->dm_nresets = 0; /* Counts number of resets */ - dm9x->dm_ntxtimeouts = 0; /* Counts resets caused by TX timeouts */ -} -#endif - -/**************************************************************************** - * Function: dm9x_dumpstatistics - * - * Description: - * Print the current value of all DM90x0 statistics - * - * Parameters: - * dm9x - Reference to the driver state structure - * - * Returned Value: - * None - * - * Assumptions: - * - ****************************************************************************/ - -#if defined(CONFIG_DM9X_STATS) && defined(CONFIG_DEBUG) -static void dm9x_dumpstatistics(struct dm9x_driver_s *dm9x) -{ - ndbg("TX packets: %d\n", dm9x->dm_ntxpackets); - ndbg(" bytes: %d\n", dm9x->dm_ntxbytes); - ndbg(" errors: %d\n", dm9x->dm_ntxerrors); - ndbg("RX packets: %d\n", dm9x->dm_nrxpackets); - ndbg(" bytes: %d\n", dm9x->dm_nrxbytes); - ndbg(" FIFO overflows: %d\n", dm9x->dm_nrxfifoerrors); - ndbg(" CRC errors: %d\n", dm9x->dm_nrxcrcerrors); - ndbg(" length errors: %d\n", dm9x->dm_nrxlengtherrors); - ndbg("Physical layer errors: %d\n", dm9x->dm_nphyserrors); - ndbg("Resets: %d\n", dm9x->dm_nresets); - ndbg("TX timeout resets: %d\n", dm9x->dm_ntxtimeouts); -} -#endif - /**************************************************************************** * Function: dm9x_rxchecksumready * @@ -787,10 +695,7 @@ static int dm9x_transmit(struct dm9x_driver_s *dm9x) /* Increment count of packets transmitted */ dm9x->dm_ntxpending++; -#if defined(CONFIG_DM9X_STATS) - dm9x->dm_ntxpackets++; - dm9x->dm_ntxbytes += dm9x->dm_dev.d_len; -#endif + NETDEV_TXPACKETS(&dm9x0->dm_dev); /* Disable all DM90x0 interrupts */ @@ -960,33 +865,9 @@ static void dm9x_receive(FAR struct dm9x_driver_s *dm9x) { /* Bad RX packet... update statistics */ -#if defined(CONFIG_DM9X_STATS) - if (rx.desc.rx_status & 0x01) - { - dm9x->dm_nrxfifoerrors++; - ndbg("RX FIFO error: %d\n", dm9x->dm_nrxfifoerrors); - } - - if (rx.desc.rx_status & 0x02) - { - dm9x->dm_nrxcrcerrors++; - ndbg("RX CRC error: %d\n", dm9x->dm_nrxcrcerrors); - } - - if (rx.desc.rx_status & 0x80) - { - dm9x->dm_nrxlengtherrors++; - ndbg("RX length error: %d\n", dm9x->dm_nrxlengtherrors); - } - - if (rx.desc.rx_status & 0x08) - { - dm9x->dm_nphyserrors++; - ndbg("Physical Layer error: %d\n", dm9x->dm_nphyserrors); - } -#else ndbg("Received packet with errors: %02x\n", rx.desc.rx_status); -#endif + NETDEV_RXERRORS(&dm9x->dm_dev); + /* Drop this packet and continue to check the next packet */ dm9x->dm_discard(rx.desc.rx_len); @@ -996,10 +877,9 @@ static void dm9x_receive(FAR struct dm9x_driver_s *dm9x) else if (rx.desc.rx_len < ETH_HDRLEN || rx.desc.rx_len > (CONFIG_NET_ETH_MTU + 2)) { -#if defined(CONFIG_DM9X_STATS) - dm9x->dm_nrxlengtherrors++; - ndbg("RX length error: %d\n", dm9x->dm_nrxlengtherrors); -#endif + ndbg("RX length error\n"); + NETDEV_RXERRORS(&dm9x->dm_dev); + /* Drop this packet and continue to check the next packet */ dm9x->dm_discard(rx.desc.rx_len); @@ -1023,6 +903,7 @@ static void dm9x_receive(FAR struct dm9x_driver_s *dm9x) if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->dm_dev); /* Handle ARP on input then give the IPv4 packet to the network * layer @@ -1063,6 +944,7 @@ static void dm9x_receive(FAR struct dm9x_driver_s *dm9x) if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->dm_dev); /* Give the IPv6 packet to the network layer */ @@ -1100,6 +982,7 @@ static void dm9x_receive(FAR struct dm9x_driver_s *dm9x) if (BUF->type == htons(ETHTYPE_ARP)) { arp_arpin(&dm9x->dm_dev); + NETDEV_RXARP(&priv->dm_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. @@ -1111,12 +994,13 @@ static void dm9x_receive(FAR struct dm9x_driver_s *dm9x) } } #endif + else + { + NETDEV_RXDROPPED(&priv->dm_dev); + } } -#if defined(CONFIG_DM9X_STATS) - dm9x->dm_nrxpackets++; - dm9x->dm_nrxbytes += rx.desc.rx_len; -#endif + NETDEV_RXPACKETS(&dm9x->dm_dev); dm9x->ncrxpackets++; } while ((rxbyte & 0x01) == DM9X_PKTRDY && dm9x->ncrxpackets < DM9X_CRXTHRES); @@ -1326,15 +1210,9 @@ static void dm9x_txtimeout(int argc, uint32_t arg, ...) /* Increment statistics and dump debug info */ -#if defined(CONFIG_DM9X_STATS) - dm9x->dm_ntxtimeouts++; - dm9x->dm_ntxerrors++; -#endif + NETDEV_TXTIMEOUTS(dm9x->dm_dev); ndbg(" TX packet count: %d\n", dm9x->dm_ntxpending); -#if defined(CONFIG_DM9X_STATS) - ndbg(" TX timeouts: %d\n", dm9x->dm_ntxtimeouts); -#endif ndbg(" TX read pointer address: 0x%02x:%02x\n", getreg(DM9X_TRPAH), getreg(DM9X_TRPAL)); ndbg(" Memory data write address: 0x%02x:%02x (DM9010)\n", @@ -1549,10 +1427,6 @@ static int dm9x_ifdown(struct net_driver_s *dev) dm9x->dm_bifup = false; irqrestore(flags); - - /* Dump statistics */ - - dm9x_dumpstatistics(dm9x); return OK; } @@ -1751,7 +1625,7 @@ static void dm9x_bringup(struct dm9x_driver_s *dm9x) dm9x->ncrxpackets = 0; /* Number of continuous RX packets */ dm9x->dm_ntxpending = 0; /* Number of pending TX packets */ - dm9x_resetstatistics(dm9x); + NETDEV_RESET_STATISTICS(&dm9x->dm_dev); /* Activate DM9000A/DM9010 */ @@ -1789,10 +1663,6 @@ static void dm9x_reset(struct dm9x_driver_s *dm9x) /* Save previous register address */ save = (uint8_t)DM9X_INDEX; - -#if defined(CONFIG_DM9X_STATS) - dm9x->dm_nresets++; -#endif dm9x_bringup(dm9x); /* Wait up to 1 second for the link to be OK */ diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index e707ff63cfc..e0b063af1a5 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -435,8 +435,6 @@ static int e1000_transmit(struct e1000_dev *e1000) return -1; } - /* Increment statistics */ - /* Send the packet: address=skel->sk_dev.d_buf, length=skel->sk_dev.d_len */ memcpy(cp, e1000->netdev.d_buf, e1000->netdev.d_len); @@ -564,8 +562,6 @@ static void e1000_receive(struct e1000_dev *e1000) while (e1000->rx_ring.desc[head].desc_status) { - /* Check for errors and update statistics */ - /* Here we do not handle packets that exceed packet-buffer size */ if ((e1000->rx_ring.desc[head].desc_status & 3) == 1) @@ -728,8 +724,6 @@ static void e1000_txtimeout(int argc, uint32_t arg, ...) { struct e1000_dev *e1000 = (struct e1000_dev *)arg; - /* Increment statistics and dump debug info */ - /* Then reset the hardware */ e1000_init(e1000); diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index 8c90f4c8e98..7df9597a82b 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/net/enc28j60.c * - * Copyright (C) 2010-2012, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2010-2012, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * References: @@ -85,7 +85,6 @@ * CONFIG_ENC28J60_FREQUENCY - Define to use a different bus frequency * CONFIG_ENC28J60_NINTERFACES - Specifies the number of physical ENC28J60 * devices that will be supported. - * CONFIG_ENC28J60_STATS - Collect network statistics * CONFIG_ENC28J60_HALFDUPPLEX - Default is full duplex */ @@ -257,12 +256,6 @@ struct enc_driver_s /* This holds the information visible to uIP/NuttX */ struct net_driver_s dev; /* Interface understood by uIP */ - - /* Statistics */ - -#ifdef CONFIG_ENC28J60_STATS - struct enc_stats_s stats; -#endif }; /**************************************************************************** @@ -1113,9 +1106,7 @@ static int enc_transmit(FAR struct enc_driver_s *priv) /* Increment statistics */ nllvdbg("Sending packet, pktlen: %d\n", priv->dev.d_len); -#ifdef CONFIG_ENC28J60_STATS - priv->stats.txrequests++; -#endif + NETDEV_TXPACKETS(&priv->dev); /* Verify that the hardware is ready to send another packet. The driver * starts a transmission process by setting ECON1.TXRTS. When the packet is @@ -1290,13 +1281,7 @@ static void enc_txif(FAR struct enc_driver_s *priv) { /* Update statistics */ -#ifdef CONFIG_ENC28J60_STATS - priv->stats.txifs++; - if (enc_rdgreg(priv, ENC_ESTAT) & ESTAT_TXABRT) - { - priv->stats.txabrts++; - } -#endif + NETDEV_TXDONE(&priv->dev); /* Clear the request to send bit */ @@ -1331,9 +1316,7 @@ static void enc_txerif(FAR struct enc_driver_s *priv) { /* Update statistics */ -#ifdef CONFIG_ENC28J60_STATS - priv->stats.txerifs++; -#endif + NETDEV_TXERRORS(&priv->dev); /* Reset TX */ @@ -1375,11 +1358,7 @@ static void enc_txerif(FAR struct enc_driver_s *priv) static void enc_rxerif(FAR struct enc_driver_s *priv) { - /* Update statistics */ - -#ifdef CONFIG_ENC28J60_STATS - priv->stats.rxerifs++; -#endif + /* REVISIT: Update statistics */ } /**************************************************************************** @@ -1413,6 +1392,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->dev); /* Handle ARP on input then give the IPv4 packet to the network * layer @@ -1453,6 +1433,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->dev); /* Give the IPv6 packet to the network layer */ @@ -1490,6 +1471,8 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) if (BUF->type == htons(ETHTYPE_ARP)) { nllvdbg("ARP packet received (%02x)\n", BUF->type); + NETDEV_RXARP(&priv->dev); + arp_arpin(&priv->dev); /* If the above function invocation resulted in data that should be @@ -1505,6 +1488,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) #endif { nlldbg("Unsupported packet type dropped (%02x)\n", htons(BUF->type)); + NETDEV_RXDROPPED(&priv->dev); } } @@ -1533,9 +1517,7 @@ static void enc_pktif(FAR struct enc_driver_s *priv) /* Update statistics */ -#ifdef CONFIG_ENC28J60_STATS - priv->stats.pktifs++; -#endif + NETDEV_RXPACKETS(&priv->dev); /* Set the read pointer to the start of the received packet (ERDPT) */ @@ -1572,9 +1554,7 @@ static void enc_pktif(FAR struct enc_driver_s *priv) if ((rxstat & RXSTAT_OK) == 0) { nlldbg("ERROR: RXSTAT: %04x\n", rxstat); -#ifdef CONFIG_ENC28J60_STATS - priv->stats.rxnotok++; -#endif + NETDEV_RXERRORS(&priv->dev); } /* Check for a usable packet length (4 added for the CRC) */ @@ -1582,9 +1562,7 @@ static void enc_pktif(FAR struct enc_driver_s *priv) else if (pktlen > (CONFIG_NET_ETH_MTU + 4) || pktlen <= (ETH_HDRLEN + 4)) { nlldbg("Bad packet size dropped (%d)\n", pktlen); -#ifdef CONFIG_ENC28J60_STATS - priv->stats.rxpktlen++; -#endif + NETDEV_RXERRORS(&priv->dev); } /* Otherwise, read and process the packet */ @@ -1787,18 +1765,13 @@ static void enc_irqworker(FAR void *arg) /* Ignore PKTIF because is unreliable. Use EPKTCNT instead */ /* if ((eir & EIR_PKTIF) != 0) */ + { uint8_t pktcnt = enc_rdbreg(priv, ENC_EPKTCNT); if (pktcnt > 0) { nllvdbg("EPKTCNT: %02x\n", pktcnt); -#ifdef CONFIG_ENC28J60_STATS - if (pktcnt > priv->stats.maxpktcnt) - { - priv->stats.maxpktcnt = pktcnt; - } -#endif /* Handle packet receipt */ enc_pktif(priv); @@ -1917,9 +1890,7 @@ static void enc_toworker(FAR void *arg) /* Increment statistics and dump debug info */ -#ifdef CONFIG_ENC28J60_STATS - priv->stats.txtimeouts++; -#endif + NETDEV_TXTIMEOUTS(&priv->dev); /* Then reset the hardware: Take the interface down, then bring it * back up @@ -2693,42 +2664,4 @@ int enc_initialize(FAR struct spi_dev_s *spi, return netdev_register(&priv->dev, NET_LL_ETHERNET); } -/**************************************************************************** - * Function: enc_stats - * - * Description: - * Return accumulated ENC28J60 statistics. Statistics are cleared after - * being returned. - * - * Parameters: - * devno - If more than one ENC28J60 is supported, then this is the - * zero based number that identifies the ENC28J60; - * stats - The user-provided location to return the statistics. - * - * Returned Value: - * OK on success; Negated errno on failure. - * - * Assumptions: - * - ****************************************************************************/ - -#ifdef CONFIG_ENC28J60_STATS -int enc_stats(unsigned int devno, struct enc_stats_s *stats) -{ - FAR struct enc_driver_s *priv ; - irqstate_t flags; - - DEBUGASSERT(devno < CONFIG_ENC28J60_NINTERFACES); - priv = &g_enc28j60[devno]; - - /* Disable the Ethernet interrupt */ - - flags = irqsave(); - memcpy(stats, &priv->stats, sizeof(struct enc_stats_s)); - memset(&priv->stats, 0, sizeof(struct enc_stats_s)); - irqrestore(flags); - return OK; -} -#endif #endif /* CONFIG_NET && CONFIG_ENC28J60_NET */ - diff --git a/drivers/net/enc28j60.h b/drivers/net/enc28j60.h index d717ff82a30..faa15461188 100644 --- a/drivers/net/enc28j60.h +++ b/drivers/net/enc28j60.h @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/net/enc28j60.h * - * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2010, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * References: diff --git a/drivers/net/encx24j600.c b/drivers/net/encx24j600.c index 18057f325fd..4de0d694cad 100644 --- a/drivers/net/encx24j600.c +++ b/drivers/net/encx24j600.c @@ -91,7 +91,6 @@ * CONFIG_ENCX24J600_FREQUENCY - Define to use a different bus frequency * CONFIG_ENCX24J600_NINTERFACES - Specifies the number of physical ENCX24J600 * devices that will be supported. - * CONFIG_ENCX24J600_STATS - Collect network statistics */ /* The ENCX24J600 spec says that it supports SPI mode 0,0 only: "The @@ -272,12 +271,6 @@ struct enc_driver_s /* This holds the information visible to uIP/NuttX */ struct net_driver_s dev; /* Interface understood by uIP */ - - /* Statistics */ - -#ifdef CONFIG_ENCX24J600_STATS - struct enc_stats_s stats; -#endif }; /**************************************************************************** @@ -1143,9 +1136,7 @@ static int enc_txenqueue(FAR struct enc_driver_s *priv) /* Increment statistics */ -#ifdef CONFIG_ENCX24J600_STATS - priv->stats.txrequests++; -#endif + NETDEV_TXPACKETS(&priv->dev); descr = (FAR struct enc_descr_s *)sq_remfirst(&priv->txfreedescr); @@ -1330,6 +1321,8 @@ static void enc_linkstatus(FAR struct enc_driver_s *priv) static void enc_txif(FAR struct enc_driver_s *priv) { + NETDEV_TXDONE(&priv->dev); + if (sq_empty(&priv->txqueue)) { /* If no further xmits are pending, then cancel the TX timeout */ @@ -1342,7 +1335,7 @@ static void enc_txif(FAR struct enc_driver_s *priv) } else { - /* process txqueue */ + /* Process txqueue */ enc_transmit(priv); } @@ -1531,6 +1524,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->dev); /* Handle ARP on input then give the IPv4 packet to the network * layer @@ -1580,6 +1574,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->dev); /* Give the IPv6 packet to the network layer */ @@ -1626,6 +1621,8 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) if (BUF->type == htons(ETHTYPE_ARP)) { nllvdbg("ARP packet received (%02x)\n", BUF->type); + NETDEV_RXARP(&priv->dev); + arp_arpin(&priv->dev); /* ARP packets are freed immediately */ @@ -1649,6 +1646,7 @@ static void enc_rxdispatch(FAR struct enc_driver_s *priv) enc_rxrmpkt(priv, descr); nlldbg("Unsupported packet type dropped (%02x)\n", htons(BUF->type)); + NETDEV_RXDROPPED(&priv->dev); } descr = next; @@ -1747,10 +1745,7 @@ static void enc_pktif(FAR struct enc_driver_s *priv) /* Discard packet */ enc_rxrmpkt(priv, descr); - -#ifdef CONFIG_ENCX24J600_STATS - priv->stats.rxnotok++; -#endif + NETDEV_RXERRORS(&priv->dev); } /* Check for a usable packet length (4 added for the CRC) */ @@ -1762,10 +1757,7 @@ static void enc_pktif(FAR struct enc_driver_s *priv) /* Discard packet */ enc_rxrmpkt(priv, descr); - -#ifdef CONFIG_ENCX24J600_STATS - priv->stats.rxpktlen++; -#endif + NETDEV_RXERRORS(&priv->dev); } /* Decrement PKTCNT */ @@ -1951,9 +1943,7 @@ static void enc_irqworker(FAR void *arg) if ((eir & EIR_RXABTIF) != 0) /* Receive Abort */ { -#ifdef CONFIG_ENCX24J600_STATS - priv->stats.rxerifs++; -#endif + NETDEV_RXERRORS(&priv->dev); enc_rxabtif(priv); enc_bfc(priv, ENC_EIR, EIR_RXABTIF); /* Clear the RXABTIF interrupt */ } @@ -1980,7 +1970,7 @@ static void enc_irqworker(FAR void *arg) */ } -#ifdef CONFIG_ENCX24J600_STATS +#ifdef CONFIG_NETDEV_STATISTICS /* The transmit abort interrupt occurs when the transmission of a frame * has been aborted. An abort can occur for any of the following reasons: * @@ -2004,7 +1994,7 @@ static void enc_irqworker(FAR void *arg) if ((eir & EIR_TXABTIF) != 0) /* Transmit Abort */ { - priv->stats.txerifs++; + NETDEV_TXERRORS(&priv->dev); enc_bfc(priv, ENC_EIR, EIR_TXABTIF); /* Clear the TXABTIF interrupt */ } #endif @@ -2095,9 +2085,7 @@ static void enc_toworker(FAR void *arg) /* Increment statistics and dump debug info */ -#ifdef CONFIG_ENCX24J600_STATS - priv->stats.txtimeouts++; -#endif + NETDEV_TXTIMEOUTS(&priv->dev); /* Then reset the hardware: Take the interface down, then bring it * back up @@ -2302,7 +2290,7 @@ static int enc_ifup(struct net_driver_s *dev) EIE_PKTIE | EIE_RXABTIE | EIE_TXIE); -#ifdef CONFIG_ENCX24J600_STATS +#ifdef CONFIG_NETDEV_STATISTICS enc_bfs(priv, ENC_EIE, EIE_TXABTIE); #endif @@ -2961,41 +2949,4 @@ int enc_initialize(FAR struct spi_dev_s *spi, return netdev_register(&priv->dev, NET_LL_ETHERNET); } -/**************************************************************************** - * Function: enc_stats - * - * Description: - * Return accumulated ENCX24J600 statistics. Statistics are cleared after - * being returned. - * - * Parameters: - * devno - If more than one ENCX24J600 is supported, then this is the - * zero based number that identifies the ENCX24J600; - * stats - The user-provided location to return the statistics. - * - * Returned Value: - * OK on success; Negated errno on failure. - * - * Assumptions: - * - ****************************************************************************/ - -#ifdef CONFIG_ENCX24J600_STATS -int enc_stats(unsigned int devno, struct enc_stats_s *stats) -{ - FAR struct enc_driver_s *priv ; - irqstate_t flags; - - DEBUGASSERT(devno < CONFIG_ENCX24J600_NINTERFACES); - priv = &g_encx24j600[devno]; - - /* Disable the Ethernet interrupt */ - - flags = irqsave(); - memcpy(stats, &priv->stats, sizeof(struct enc_stats_s)); - memset(&priv->stats, 0, sizeof(struct enc_stats_s)); - irqrestore(flags); - return OK; -} -#endif #endif /* CONFIG_NET && CONFIG_ENCX24J600_NET */ diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c index 2a980ed5ccc..eecc4c96150 100644 --- a/drivers/net/ftmac100.c +++ b/drivers/net/ftmac100.c @@ -163,6 +163,7 @@ struct ftmac100_driver_s uint32_t iobase; /* NuttX net data */ + bool ft_bifup; /* true:ifup false:ifdown */ WDOG_ID ft_txpoll; /* TX poll timer */ WDOG_ID ft_txtimeout; /* TX timeout timer */ @@ -294,8 +295,6 @@ static int ftmac100_transmit(FAR struct ftmac100_driver_s *priv) * must have assured that there is no transmission in progress. */ - /* Increment statistics */ - len = len < ETH_ZLEN ? ETH_ZLEN : len; /* Send the packet: address=priv->ft_dev.d_buf, length=priv->ft_dev.d_len */ @@ -669,10 +668,6 @@ static void ftmac100_receive(FAR struct ftmac100_driver_s *priv) nvdbg ("RX buffer %d (%08x), %x received (%d)\n", priv->rx_pointer, data, len, (rxdes->rxdes0 & FTMAC100_RXDES0_LRS)); - /* Check for errors and update statistics */ - - /* Check if the packet is a valid size for the uIP buffer configuration */ - /* Copy the data data from the hardware to priv->ft_dev.d_buf. Set * amount of data in priv->ft_dev.d_len */ @@ -810,7 +805,7 @@ static void ftmac100_txdone(FAR struct ftmac100_driver_s *priv) { FAR struct ftmac100_txdes_s *txdes; - /* Check for errors and update statistics */ + /* Check if a Tx was pending */ while (priv->tx_pending) { @@ -1081,8 +1076,6 @@ static int ftmac100_interrupt(int irq, FAR void *context) static inline void ftmac100_txtimeout_process(FAR struct ftmac100_driver_s *priv) { - /* Increment statistics and dump debug info */ - /* Then reset the hardware */ nvdbg("TXTIMEOUT\n"); diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 79b8bfc5bf3..7bb99c17446 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -174,6 +174,9 @@ static int lo_txpoll(FAR struct net_driver_s *dev) while (priv->lo_dev.d_len > 0) { + NETDEV_TXPACKETS(&priv->lo_dev); + NETDEV_RXPACKETS(&priv->lo_dev); + #ifdef CONFIG_NET_PKT /* When packet sockets are enabled, feed the frame into the packet tap */ @@ -186,6 +189,7 @@ static int lo_txpoll(FAR struct net_driver_s *dev) if ((IPv4BUF->vhl & IP_VERSION_MASK) == IPv4_VERSION) { nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->lo_dev); ipv4_input(&priv->lo_dev); } else @@ -194,16 +198,19 @@ static int lo_txpoll(FAR struct net_driver_s *dev) if ((IPv6BUF->vtc & IP_VERSION_MASK) == IPv6_VERSION) { nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->lo_dev); ipv6_input(&priv->lo_dev); } else #endif { ndbg("WARNING: Unrecognized packet type dropped: %02x\n", IPv4BUF->vhl); + NETDEV_RXDROPPED(&priv->lo_dev); priv->lo_dev.d_len = 0; } priv->lo_txdone = true; + NETDEV_TXDONE(&priv->lo_dev); } return 0; diff --git a/drivers/net/skeleton.c b/drivers/net/skeleton.c index c59498e6bde..a395b2eda1b 100644 --- a/drivers/net/skeleton.c +++ b/drivers/net/skeleton.c @@ -208,6 +208,8 @@ static int skel_transmit(FAR struct skel_driver_s *priv) /* Increment statistics */ + NETDEV_TXPACKETS(priv->sk_dev); + /* Send the packet: address=priv->sk_dev.d_buf, length=priv->sk_dev.d_len */ /* Enable Tx interrupts */ @@ -334,6 +336,7 @@ static void skel_receive(FAR struct skel_driver_s *priv) if (BUF->type == HTONS(ETHTYPE_IP)) { nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->sk_dev); /* Handle ARP on input then give the IPv4 packet to the network * layer @@ -374,6 +377,7 @@ static void skel_receive(FAR struct skel_driver_s *priv) if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->sk_dev); /* Give the IPv6 packet to the network layer */ @@ -411,6 +415,7 @@ static void skel_receive(FAR struct skel_driver_s *priv) if (BUF->type == htons(ETHTYPE_ARP)) { arp_arpin(&priv->sk_dev); + NETDEV_RXARP(&priv->sk_dev); /* If the above function invocation resulted in data that should be * sent out on the network, the field d_len will set to a value > 0. @@ -422,6 +427,10 @@ static void skel_receive(FAR struct skel_driver_s *priv) } } #endif + else + { + NETDEV_RXDROPPED(&priv->sk_dev); + } } while (); /* While there are more packets to be processed */ } @@ -447,6 +456,8 @@ static void skel_txdone(FAR struct skel_driver_s *priv) { /* Check for errors and update statistics */ + NETDEV_TXDONE(priv->sk_dev); + /* If no further xmits are pending, then cancel the TX timeout and * disable further Tx interrupts. */ @@ -607,6 +618,8 @@ static inline void skel_txtimeout_process(FAR struct skel_driver_s *priv) { /* Increment statistics and dump debug info */ + NETDEV_TXTIMEOUTS(priv->sk_dev); + /* Then reset the hardware */ /* Then poll the network for new XMIT data */ diff --git a/drivers/net/slip.c b/drivers/net/slip.c index a7db1780ce7..6026ec3d5bf 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -130,28 +130,10 @@ #define SLIP_WDDELAY (1*1000000) #define SLIP_POLLHSEC (1*2) -/* Statistics helper */ - -#ifdef CONFIG_NET_STATISTICS -# define SLIP_STAT(p,f) (p->stats.f)++ -#else -# define SLIP_STAT(p,f) -#endif - /**************************************************************************** * Private Types ****************************************************************************/ -/* Driver statistics */ - -#ifdef CONFIG_NET_STATISTICS -struct slip_statistics_s -{ - uint32_t transmitted; /* Number of packets transmitted */ - uint32_t received /* Number of packets received */ -}; -#endif - /* The slip_driver_s encapsulates all state information for a single hardware * interface */ @@ -166,12 +148,6 @@ struct slip_driver_s pid_t txpid; /* Transmitter thread ID */ sem_t waitsem; /* Mutually exclusive access to uIP */ - /* Driver statistics */ - -#ifdef CONFIG_NET_STATISTICS - struct slip_statistics_s stats; -#endif - /* This holds the information visible to uIP/NuttX */ struct net_driver_s dev; /* Interface understood by uIP */ @@ -312,7 +288,7 @@ static int slip_transmit(FAR struct slip_driver_s *priv) /* Increment statistics */ nvdbg("Sending packet size %d\n", priv->dev.d_len); - SLIP_STAT(priv, transmitted); + NETDEV_TXPACKETS(&priv->dev); /* Send an initial END character to flush out any data that may have * accumulated in the receiver due to line noise @@ -393,6 +369,7 @@ static int slip_transmit(FAR struct slip_driver_s *priv) /* And send the END token */ slip_putc(priv, SLIP_END); + NETDEV_TXDONE(&priv->dev); priv->txnodelay = true; return OK; } @@ -736,7 +713,7 @@ static int slip_rxtask(int argc, FAR char *argv[]) */ slip_receive(priv); - SLIP_STAT(priv, received); + NETDEV_RXPACKETS(&priv->dev); /* All packets are assumed to be IP packets (we don't have a choice.. * there is no Ethernet header containing the EtherType). So pass the @@ -746,6 +723,8 @@ static int slip_rxtask(int argc, FAR char *argv[]) if (priv->rxlen >= IPv4_HDRLEN) { + NETDEV_RXIPV4(&priv->dev); + /* Handle the IP input. Get exclusive access to uIP. */ slip_semtake(priv); @@ -770,7 +749,7 @@ static int slip_rxtask(int argc, FAR char *argv[]) } else { - SLIP_STAT(priv, rxsmallpacket); + NETDEV_RXERRORS(&priv->dev); } } diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 39f52665687..088e063ab19 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -325,6 +325,8 @@ static void tun_pollnotify(FAR struct tun_device_s *priv, pollevent_t eventset) static int tun_transmit(FAR struct tun_device_s *priv) { + NETDEV_TXPACKETS(&priv->dev); + /* Verify that the hardware is ready to send another packet. If we get * here, then we are committed to sending a packet; Higher level logic * must have assured that there is no transmission in progress. @@ -413,6 +415,8 @@ static void tun_receive(FAR struct tun_device_s *priv) * data in priv->dev.d_len */ + NETDEV_RXPACKETS(&priv->dev); + #ifdef CONFIG_NET_PKT /* When packet sockets are enabled, feed the frame into the packet tap */ @@ -424,6 +428,7 @@ static void tun_receive(FAR struct tun_device_s *priv) #ifdef CONFIG_NET_IPv4 { nllvdbg("IPv4 frame\n"); + NETDEV_RXIPV4(&priv->dev); /* Give the IPv4 packet to the network layer */ @@ -444,6 +449,7 @@ static void tun_receive(FAR struct tun_device_s *priv) tun_pollnotify(priv, POLLOUT); } } + else #endif #if 0 @@ -451,6 +457,7 @@ static void tun_receive(FAR struct tun_device_s *priv) if (BUF->type == HTONS(ETHTYPE_IP6)) { nllvdbg("Iv6 frame\n"); + NETDEV_RXIPV6(&priv->dev); /* Give the IPv6 packet to the network layer */ @@ -482,7 +489,11 @@ static void tun_receive(FAR struct tun_device_s *priv) tun_transmit(priv); } } + else #endif + { + NETDEV_RXDROPPED(&priv->dev); + } #endif } @@ -507,6 +518,8 @@ static void tun_txdone(FAR struct tun_device_s *priv) { /* Check for errors and update statistics */ + NETDEV_TXDONE(&priv->dev); + /* Then poll uIP for new XMIT data */ priv->dev.d_buf = priv->read_buf; diff --git a/drivers/net/vnet.c b/drivers/net/vnet.c index abd08a3caec..d8849d81947 100644 --- a/drivers/net/vnet.c +++ b/drivers/net/vnet.c @@ -177,8 +177,6 @@ static int vnet_transmit(FAR struct vnet_driver_s *vnet) * must have assured that there is not transmission in progress. */ - /* Increment statistics */ - /* Send the packet: address=vnet->sk_dev.d_buf, length=vnet->sk_dev.d_len */ err = vnet_xmit(vnet->vnet, (char *)vnet->sk_dev.d_buf, vnet->sk_dev.d_len); @@ -476,11 +474,7 @@ static void vnet_txtimeout(int argc, uint32_t arg, ...) { FAR struct vnet_driver_s *vnet = (FAR struct vnet_driver_s *)arg; - /* Increment statistics and dump debug info */ - - /* Then reset the hardware */ - - /* Then poll the network for new XMIT data */ + /* Poll the network for new XMIT data */ (void)devif_poll(&vnet->sk_dev, vnet_txpoll); } diff --git a/include/nuttx/net/cs89x0.h b/include/nuttx/net/cs89x0.h index 493a552a182..9d92a193117 100644 --- a/include/nuttx/net/cs89x0.h +++ b/include/nuttx/net/cs89x0.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/net/cs89x0.h * - * Copyright (C) 2009, 2012, 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2012, 2014-2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,29 +49,6 @@ * Public Types ****************************************************************************/ -/* This structure returns driver statistics (if enabled) */ - -#ifdef CONFIG_C89x0_STATISTICS -struct cs89x0_statistics_s -{ - uint32_t tx_packets; - uint32_t tx_errors; - uint32_t tx_carriererrors; - uint32_t tx_heartbeaterrors; - uint32_t tx_windowerrors; - uint32_t tx_abortederrors; - uint32_t rx_missederrors; - uint32_t rx_packets; - uint32_t rx_errors; - uint32_t rx_lengtherrors; - uint32_t rx_crcerrors; - uint32_t rx_frameerrors; - uint32_t rx_dropped; - uint32_t rx_missederrors; - uint32_t collisions; -}; -#endif - /* This structure encapsulates all state information for a single hardware * interface. It includes values that must be provided by the user to in * to describe details of the CS89x00 implementation on a particular board. @@ -112,12 +89,6 @@ struct cs89x0_driver_s /* This holds the information visible to uIP/NuttX */ struct net_driver_s cs_dev; /* Interface understood by uIP */ - - /* Driver statistics */ - -#ifdef CONFIG_C89x0_STATISTICS - struct cs89x0_statistics_s cs_stats; -#endif }; /**************************************************************************** diff --git a/include/nuttx/net/enc28j60.h b/include/nuttx/net/enc28j60.h index aeb8e516621..b5d31e46542 100644 --- a/include/nuttx/net/enc28j60.h +++ b/include/nuttx/net/enc28j60.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/net/enc28j60.h * - * Copyright (C) 2010, 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2010, 2012, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -56,7 +56,6 @@ * CONFIG_ENC28J60_FREQUENCY - Define to use a different bus frequency * CONFIG_ENC28J60_NINTERFACES - Specifies the number of physical ENC28J60 * devices that will be supported. - * CONFIG_ENC28J60_STATS - Collect network statistics * CONFIG_ENC28J60_HALFDUPPLEX - Default is full duplex */ @@ -64,24 +63,6 @@ * Public Types ****************************************************************************/ -/* This structure returns driver statistics (if enabled) */ - -#ifdef CONFIG_ENC28J60_STATS -struct enc_stats_s -{ - uint8_t maxpktcnt; /* Max. number of buffered RX packets */ - uint32_t txrequests; /* Number of TX packets queued */ - uint32_t txifs; /* TXIF completion events */ - uint32_t txabrts; /* TXIF completions with ESTAT.TXABRT */ - uint32_t txerifs; /* TXERIF error events */ - uint32_t txtimeouts; /* S/W detected TX timeouts */ - uint32_t pktifs; /* PKTIF RX completion events */ - uint32_t rxnotok; /* PKTIF without RXSTAT_OK */ - uint32_t rxpktlen; /* PKTIF with bad pktlen */ - uint32_t rxerifs; /* RXERIF error evernts */ -}; -#endif - /* The ENC28J60 normal provides interrupts to the MCU via a GPIO pin. The * following structure provides an MCU-independent mechanixm for controlling * the ENC28J60 GPIO interrupt. @@ -151,29 +132,6 @@ struct spi_dev_s; /* see nuttx/spi/spi.h */ int enc_initialize(FAR struct spi_dev_s *spi, FAR const struct enc_lower_s *lower, unsigned int devno); -/**************************************************************************** - * Function: enc_stats - * - * Description: - * Return accumulated ENC28J60 statistics. Statistics are cleared after - * being returned. - * - * Parameters: - * devno - If more than one ENC28J60 is supported, then this is the - * zero based number that identifies the ENC28J60; - * stats - The user-provided location to return the statistics. - * - * Returned Value: - * OK on success; Negated errno on failure. - * - * Assumptions: - * - ****************************************************************************/ - -#ifdef CONFIG_ENC28J60_STATS -int enc_stats(unsigned int devno, struct enc_stats_s *stats); -#endif - #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/net/encx24j600.h b/include/nuttx/net/encx24j600.h index 0a39373a822..39ce6c8664e 100644 --- a/include/nuttx/net/encx24j600.h +++ b/include/nuttx/net/encx24j600.h @@ -1,7 +1,7 @@ /**************************************************************************** * include/nuttx/net/encx24j600.h * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -56,7 +56,6 @@ * CONFIG_ENCX24J600_FREQUENCY - Define to use a different bus frequency * CONFIG_ENCX24J600_NINTERFACES - Specifies the number of physical ENCX24J600 * devices that will be supported. - * CONFIG_ENCX24J600_STATS - Collect network statistics * CONFIG_ENCX24J600_HALFDUPPLEX - Default is full duplex */ @@ -64,24 +63,6 @@ * Public Types ****************************************************************************/ -/* This structure returns driver statistics (if enabled) */ - -#ifdef CONFIG_ENCX24J600_STATS -struct enc_stats_s -{ - uint8_t maxpktcnt; /* Max. number of buffered RX packets */ - uint32_t txrequests; /* Number of TX packets queued */ - uint32_t txifs; /* TXIF completion events */ - uint32_t txabrts; /* TXIF completions with ESTAT.TXABRT */ - uint32_t txerifs; /* TXERIF error events */ - uint32_t txtimeouts; /* S/W detected TX timeouts */ - uint32_t pktifs; /* PKTIF RX completion events */ - uint32_t rxnotok; /* PKTIF without RXSTAT_OK */ - uint32_t rxpktlen; /* PKTIF with bad pktlen */ - uint32_t rxerifs; /* RXERIF error evernts */ -}; -#endif - /* The ENCX24J600 normal provides interrupts to the MCU via a GPIO pin. The * following structure provides an MCU-independent mechanixm for controlling * the ENCX24J600 GPIO interrupt. @@ -150,30 +131,6 @@ extern "C" struct spi_dev_s; /* see nuttx/spi/spi.h */ int enc_initialize(FAR struct spi_dev_s *spi, FAR const struct enc_lower_s *lower, unsigned int devno); - -/**************************************************************************** - * Function: enc_stats - * - * Description: - * Return accumulated ENCX24J600 statistics. Statistics are cleared after - * being returned. - * - * Parameters: - * devno - If more than one ENCX24J600 is supported, then this is the - * zero based number that identifies the ENCX24J600; - * stats - The user-provided location to return the statistics. - * - * Returned Value: - * OK on success; Negated errno on failure. - * - * Assumptions: - * - ****************************************************************************/ - -#ifdef CONFIG_ENCX24J600_STATS -int enc_stats(unsigned int devno, struct enc_stats_s *stats); -#endif - #undef EXTERN #ifdef __cplusplus } diff --git a/include/nuttx/net/netdev.h b/include/nuttx/net/netdev.h index 2fada4fdbf0..859e0e3e10d 100644 --- a/include/nuttx/net/netdev.h +++ b/include/nuttx/net/netdev.h @@ -66,17 +66,113 @@ * Pre-processor Definitions ****************************************************************************/ +/* Helper macros for network device statistics */ + +#ifdef CONFIG_NETDEV_STATISTICS +# define NETDEV_RESET_STATISTICS(dev) \ + memset(&(dev)->d_statistics, 0, sizeof(struct netdev_statistics_s)) + +# define _NETDEV_STATISTIC(dev,name) ((dev)->d_statistics.name) +# define _NETDEV_ERROR(dev,name) \ + do \ + { \ + (dev)->d_statistics.name++; \ + (dev)->d_statistics.errors++; \ + } \ + while (0) + +# define NETDEV_RXPACKETS(dev) _NETDEV_STATISTIC(dev,rx_packets) +# define NETDEV_RXFRAGMENTS(dev) _NETDEV_STATISTIC(dev,rx_fragments) +# define NETDEV_RXERRORS(dev) _NETDEV_ERROR(dev,rx_errors) +# ifdef CONFIG_NET_IPv4 +# define NETDEV_RXIPV4(dev) _NETDEV_STATISTIC(dev,rx_ipv4) +# else +# define NETDEV_RXIPV4(dev) +# endif +# ifdef CONFIG_NET_IPv6 +# define NETDEV_RXIPV6(dev) _NETDEV_STATISTIC(dev,rx_ipv6) +# else +# define NETDEV_RXIPV6(dev) +# endif +# ifdef CONFIG_NET_ARP +# define NETDEV_RXARP(dev) _NETDEV_STATISTIC(dev,rx_arp) +# else +# define NETDEV_RXARP(dev) +# endif +# define NETDEV_RXDROPPED(dev) _NETDEV_STATISTIC(dev,rx_dropped) + +# define NETDEV_TXPACKETS(dev) _NETDEV_STATISTIC(dev,tx_packets) +# define NETDEV_TXDONE(dev) _NETDEV_STATISTIC(dev,tx_done) +# define NETDEV_TXERRORS(dev) _NETDEV_ERROR(dev,tx_errors) +# define NETDEV_TXTIMEOUTS(dev) _NETDEV_ERROR(dev,tx_timeouts) + +# define NETDEV_ERRORS(dev) _NETDEV_STATISTIC(dev,errors) + +#else +# define NETDEV_RXPACKETS(dev) +# define NETDEV_RXFRAGMENTS(dev) +# define NETDEV_RXERRORS(dev) +# define NETDEV_RXIPV4(dev) +# define NETDEV_RXIPV6(dev) +# define NETDEV_RXARP(dev) +# define NETDEV_RXDROPPED(dev) + +# define NETDEV_TXPACKETS(dev) +# define NETDEV_TXDONE(dev) +# define NETDEV_TXERRORS(dev) +# define NETDEV_TXTIMEOUTS(dev) + +# define NETDEV_ERRORS(dev) +#endif + /**************************************************************************** * Public Types ****************************************************************************/ -struct devif_callback_s; /* Forward reference */ +#ifdef CONFIG_NETDEV_STATISTICS +/* If CONFIG_NETDEV_STATISTICS is enabled and if the driver supports + * statistics, then this structure holds the counts of network driver + * events. + */ + +struct netdev_statistics_s +{ + /* Rx Status */ + + uint32_t rx_packets; /* Number of packets received */ + uint32_t rx_fragments; /* Number of fragments received */ + uint32_t rx_errors; /* Number of receive errors */ +#ifdef CONFIG_NET_IPv4 + uint32_t rx_ipv4; /* Number of Rx IPv4 packets received */ +#endif +#ifdef CONFIG_NET_IPv6 + uint32_t rx_ipv6; /* Number of Rx IPv6 packets received */ +#endif +#ifdef CONFIG_NET_ARP + uint32_t rx_arp; /* Number of Rx ARP packets received */ +#endif + uint32_t rx_dropped; /* Unsupported Rx packets received */ + + /* Tx Status */ + + uint32_t tx_packets; /* Number of Tx packets queued */ + unit32_t tx_done; /* Number of packets completed */ + uint32_t tx_errors; /* Number of receive errors (incl timeouts) */ + uint32_t tx_timeouts; /* Number of Tx timeout errors */ + + /* Other status */ + + uint32_t errors; /* Total umber of errors */ +}; +#endif /* This structure collects information that is specific to a specific network * interface driver. If the hardware platform supports only a single instance * of this structure. */ +struct devif_callback_s; /* Forward reference */ + struct net_driver_s { /* This link is used to maintain a single-linked list of ethernet drivers. @@ -192,6 +288,15 @@ struct net_driver_s sq_queue_t grplist; #endif +#ifdef CONFIG_NETDEV_STATISTICS + /* If CONFIG_NETDEV_STATISTICS is enabled and if the driver supports + * statistics, then this structure holds the counts of network driver + * events. + */ + + struct netdev_statistics_s d_statistics; +#endif + /* Application callbacks: * * Network device event handlers are retained in a 'list' and are called diff --git a/net/Kconfig b/net/Kconfig index b13a38351cb..9c0951e2892 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -24,10 +24,12 @@ config NET_NOINTS bool "Not interrupt driven" default n ---help--- - NET_NOINT indicates that uIP is not called from the interrupt level. - If NET_NOINTS is defined, critical sections will be managed with semaphores; - Otherwise, it assumed that uIP will be called from interrupt level handling - and critical sections will be managed by enabling and disabling interrupts. + NET_NOINT indicates that network layer is not called from the + interrupt level. If NET_NOINTS is defined, critical sections + will be managed with semaphores; Otherwise, it assumed that + network layer will be called from interrupt level handling + and critical sections will be managed by enabling and disabling + interrupts. config NET_PROMISCUOUS bool "Promiscuous mode" @@ -42,12 +44,12 @@ config NET_MULTIBUFFER bool "Use multiple device-side I/O buffers" default n ---help--- - Traditionally, uIP has used a single buffer for all incoming and - outgoing traffic. If this configuration is selected, then the - driver can manage multiple I/O buffers and can, for example, - be filling one input buffer while sending another output buffer. - Or, as another example, the driver may support queuing of concurrent - input/ouput and output transfers for better performance. + Traditionally, the uIP stacl has used a single buffer for all + incoming and outgoing traffic. If this configuration is selected, + then the driver can manage multiple I/O buffers and can, for + example, be filling one input buffer while sending another output + buffer. Or, as another example, the driver may support queuing of + concurrent input/ouput and output transfers for better performance. config NET_ETH_MTU int "Ethernet packet buffer size (MTU)" @@ -184,10 +186,10 @@ config NET_SLIP network settings: NET_NOINTS and NET_MULTIBUFFER. SLIP supports point-to-point IP communications over a serial port. - The default data link layer for uIP is Ethernet. If NET_SLIP is - defined in the NuttX configuration file, then SLIP will be supported. - The basic differences between the SLIP and Ethernet configurations is - that when SLIP is selected: + The default data link layer for network layer is Ethernet. If + NET_SLIP is defined in the NuttX configuration file, then SLIP will + be supported. The basic differences between the SLIP and Ethernet + configurations is that when SLIP is selected: * The link level header (that comes before the IP header) is omitted. * All MAC address processing is suppressed. @@ -226,6 +228,7 @@ config NET_TUN default n select NETDEV_MULTINIC if NET_ETHERNET || NET_LOOPBACK || NET_SLIP select NET_MULTILINK if NET_ETHERNET || NET_LOOPBACK || NET_SLIP + select ARCH_HAVE_NETDEV_STATISTICS if NET_TUN @@ -278,7 +281,7 @@ config NET_STATISTICS bool "Collect network statistics" default n ---help--- - uIP statistics on or off + Network layer statistics on or off source "net/route/Kconfig"