From 021e94ee6a916a52f56bc749889c316ca0bdd19f Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Thu, 11 Feb 2016 23:06:07 +0100 Subject: [PATCH] netdev2: introduce linklayer netstats --- cpu/native/netdev2_tap/netdev2_tap.c | 19 ++++++++++++++++++- drivers/at86rf2xx/at86rf2xx.c | 3 +++ drivers/at86rf2xx/at86rf2xx_netdev.c | 11 +++++++++++ drivers/enc28j60/enc28j60.c | 11 +++++++++++ drivers/include/net/netdev2.h | 4 ++++ drivers/netdev2_eth/netdev2_eth.c | 9 +++++++++ .../netdev2_ieee802154/netdev2_ieee802154.c | 2 ++ .../gnrc/link_layer/netdev2/gnrc_netdev2.c | 8 ++++++++ .../link_layer/netdev2/gnrc_netdev2_eth.c | 9 +++++++++ .../netdev2/gnrc_netdev2_ieee802154.c | 8 ++++++++ sys/shell/commands/sc_netif.c | 6 +++--- 11 files changed, 86 insertions(+), 4 deletions(-) diff --git a/cpu/native/netdev2_tap/netdev2_tap.c b/cpu/native/netdev2_tap/netdev2_tap.c index 7d3c06528..ba501ff10 100644 --- a/cpu/native/netdev2_tap/netdev2_tap.c +++ b/cpu/native/netdev2_tap/netdev2_tap.c @@ -240,6 +240,10 @@ static int _recv(netdev2_t *netdev2, char *buf, int len, void *info) _native_in_syscall--; +#ifdef MODULE_NETSTATS_L2 + netdev2->stats.rx_count++; + netdev2->stats.rx_bytes += nread; +#endif return nread; } else if (nread == -1) { @@ -262,7 +266,17 @@ static int _recv(netdev2_t *netdev2, char *buf, int len, void *info) static int _send(netdev2_t *netdev, const struct iovec *vector, int n) { netdev2_tap_t *dev = (netdev2_tap_t*)netdev; - return _native_writev(dev->tap_fd, vector, n); + int res = _native_writev(dev->tap_fd, vector, n); +#ifdef MODULE_NETSTATS_L2 + size_t bytes = 0; + for (int i = 0; i < n; i++) { + bytes += vector->iov_len; + vector++; + } + netdev->stats.tx_bytes += bytes; +#endif + netdev->event_callback(netdev, NETDEV2_EVENT_TX_COMPLETE, NULL); + return res; } void netdev2_tap_setup(netdev2_tap_t *dev, const char *name) { @@ -367,6 +381,9 @@ static int _init(netdev2_t *netdev) err(EXIT_FAILURE, "gnrc_tabnet_init(): fcntl(F_SETFL)"); } #endif /* not OSX */ +#ifdef MODULE_NETSTATS_L2 + memset(&netdev->stats, 0, sizeof(netstats_t)); +#endif DEBUG("gnrc_tapnet: initialized.\n"); return 0; } diff --git a/drivers/at86rf2xx/at86rf2xx.c b/drivers/at86rf2xx/at86rf2xx.c index 4b9159228..8fb979f7e 100644 --- a/drivers/at86rf2xx/at86rf2xx.c +++ b/drivers/at86rf2xx/at86rf2xx.c @@ -106,6 +106,9 @@ void at86rf2xx_reset(at86rf2xx_t *dev) at86rf2xx_set_option(dev, AT86RF2XX_OPT_CSMA, true); at86rf2xx_set_option(dev, AT86RF2XX_OPT_TELL_RX_START, false); at86rf2xx_set_option(dev, AT86RF2XX_OPT_TELL_RX_END, true); +#ifdef NETSTATS + at86rf2xx_set_option(dev, AT86RF2XX_OPT_TELL_TX_END, true); +#endif /* set default protocol */ #ifdef MODULE_GNRC_SIXLOWPAN dev->netdev.proto = GNRC_NETTYPE_SIXLOWPAN; diff --git a/drivers/at86rf2xx/at86rf2xx_netdev.c b/drivers/at86rf2xx/at86rf2xx_netdev.c index 488ed33d2..75a5e5d1f 100644 --- a/drivers/at86rf2xx/at86rf2xx_netdev.c +++ b/drivers/at86rf2xx/at86rf2xx_netdev.c @@ -21,6 +21,7 @@ * @} */ +#include #include #include @@ -87,6 +88,9 @@ static int _init(netdev2_t *netdev) return -1; } +#ifdef MODULE_NETSTATS_L2 + memset(&netdev->stats, 0, sizeof(netstats_t)); +#endif /* reset device to default values and put it into RX state */ at86rf2xx_reset(dev); @@ -109,6 +113,9 @@ static int _send(netdev2_t *netdev, const struct iovec *vector, int count) (unsigned)len + 2); return -EOVERFLOW; } +#ifdef MODULE_NETSTATS_L2 + netdev->stats.tx_bytes += len; +#endif len = at86rf2xx_tx_load(dev, ptr->iov_base, ptr->iov_len, len); } @@ -141,6 +148,10 @@ static int _recv(netdev2_t *netdev, char *buf, int len, void *info) at86rf2xx_fb_stop(dev); return pkt_len; } +#ifdef MODULE_NETSTATS_L2 + netdev->stats.rx_count++; + netdev->stats.rx_bytes += pkt_len; +#endif /* not enough space in buf */ if (pkt_len > len) { at86rf2xx_fb_stop(dev); diff --git a/drivers/enc28j60/enc28j60.c b/drivers/enc28j60/enc28j60.c index 8b2e541c5..2dc4e7598 100644 --- a/drivers/enc28j60/enc28j60.c +++ b/drivers/enc28j60/enc28j60.c @@ -19,6 +19,7 @@ */ #include +#include #include "mutex.h" #include "xtimer.h" @@ -226,6 +227,9 @@ static int nd_send(netdev2_t *netdev, const struct iovec *data, int count) mutex_lock(&dev->devlock); +#ifdef MODULE_NETSTATS_L2 + netdev->stats.tx_bytes += count; +#endif /* set write pointer */ cmd_w_addr(dev, ADDR_WRITE_PTR, BUF_TX_START); /* write control byte and the actual data into the buffer */ @@ -262,6 +266,10 @@ static int nd_recv(netdev2_t *netdev, char *buf, int max_len, void *info) size = (size_t)((head[3] << 8) | head[2]) - 4; /* discard CRC */ if (buf != NULL) { +#ifdef MODULE_NETSTATS_L2 + netdev->stats.rx_count++; + netdev2->stats.rx_bytes += size; +#endif /* read packet content into the supplied buffer */ if (size <= max_len) { cmd_rbm(dev, (uint8_t *)buf, size); @@ -416,6 +424,9 @@ static void nd_isr(netdev2_t *netdev) } eir = cmd_rcr(dev, REG_EIR, -1); } +#ifdef MODULE_NETSTATS_L2 + memset(&netdev->stats, 0, sizeof(netstats_t)); +#endif } static int nd_get(netdev2_t *netdev, netopt_t opt, void *value, size_t max_len) diff --git a/drivers/include/net/netdev2.h b/drivers/include/net/netdev2.h index 8fdd97163..6b9238c8e 100644 --- a/drivers/include/net/netdev2.h +++ b/drivers/include/net/netdev2.h @@ -46,6 +46,7 @@ extern "C" { #include #include +#include "net/netstats.h" #include "net/netopt.h" enum { @@ -106,6 +107,9 @@ struct netdev2 { const struct netdev2_driver *driver; /**< ptr to that driver's interface. */ netdev2_event_cb_t event_callback; /**< callback for device events */ void *isr_arg; /**< argument to pass on isr event */ +#ifdef MODULE_NETSTATS_L2 + netstats_t stats; /**< transceiver's statistics */ +#endif }; /** diff --git a/drivers/netdev2_eth/netdev2_eth.c b/drivers/netdev2_eth/netdev2_eth.c index 8c1be8c39..6e7b641f2 100644 --- a/drivers/netdev2_eth/netdev2_eth.c +++ b/drivers/netdev2_eth/netdev2_eth.c @@ -79,6 +79,15 @@ int netdev2_eth_get(netdev2_t *dev, netopt_t opt, void *value, size_t max_len) { return _get_iid(dev, value, max_len); } +#ifdef MODULE_NETSTATS_L2 + case NETOPT_STATS: + { + assert(max_len >= sizeof(uintptr_t)); + *((netstats_t**)value) = &dev->stats; + res = sizeof(uintptr_t); + break; + } +#endif default: { res = -ENOTSUP; diff --git a/drivers/netdev2_ieee802154/netdev2_ieee802154.c b/drivers/netdev2_ieee802154/netdev2_ieee802154.c index 40f3dfbcc..5736a0b7e 100644 --- a/drivers/netdev2_ieee802154/netdev2_ieee802154.c +++ b/drivers/netdev2_ieee802154/netdev2_ieee802154.c @@ -148,6 +148,7 @@ int netdev2_ieee802154_get(netdev2_ieee802154_t *dev, netopt_t opt, void *value, case NETOPT_IPV6_IID: res = _get_iid(dev, value, max_len); break; +#ifdef MODULE_NETSTATS_L2 case NETOPT_STATS: if (max_len < sizeof(uintptr_t)) { res = -EOVERFLOW; @@ -156,6 +157,7 @@ int netdev2_ieee802154_get(netdev2_ieee802154_t *dev, netopt_t opt, void *value, *((netstats_t**)value) = &dev->netdev.stats; res = sizeof(uintptr_t); break; +#endif default: break; } diff --git a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2.c b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2.c index 10a010fdc..d8a223534 100644 --- a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2.c +++ b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2.c @@ -75,6 +75,14 @@ static void _event_cb(netdev2_t *dev, netdev2_event_t event, void *data) break; } +#ifdef MODULE_NETSTATS_L2 + case NETDEV2_EVENT_TX_MEDIUM_BUSY: + dev->stats.tx_failed++; + break; + case NETDEV2_EVENT_TX_COMPLETE: + dev->stats.tx_success++; + break; +#endif default: DEBUG("gnrc_netdev2: warning: unhandled event %u.\n", event); } diff --git a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_eth.c b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_eth.c index 2672a56d7..eab49221d 100644 --- a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_eth.c +++ b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_eth.c @@ -203,6 +203,15 @@ static int _send(gnrc_netdev2_t *gnrc_netdev2, gnrc_pktsnip_t *pkt) struct iovec *vector = (struct iovec *)pkt->data; vector[0].iov_base = (char*)&hdr; vector[0].iov_len = sizeof(ethernet_hdr_t); +#ifdef MODULE_NETSTATS_L2 + if ((netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_BROADCAST) || + (netif_hdr->flags & GNRC_NETIF_HDR_FLAGS_MULTICAST)) { + gnrc_netdev2->dev->stats.tx_mcast_count++; + } + else { + gnrc_netdev2->dev->stats.tx_unicast_count++; + } +#endif res = dev->driver->send(dev, vector, n); } diff --git a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_ieee802154.c b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_ieee802154.c index 311726dfe..36075de18 100644 --- a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_ieee802154.c +++ b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2_ieee802154.c @@ -198,6 +198,14 @@ static int _send(gnrc_netdev2_t *gnrc_netdev2, gnrc_pktsnip_t *pkt) vector = (struct iovec *)pkt->data; vector[0].iov_base = mhr; vector[0].iov_len = (size_t)res; +#ifdef MODULE_NETSTATS_L2 + if (flags & IEEE802154_BCAST) { + gnrc_netdev2->dev->stats.tx_mcast_count++; + } + else { + gnrc_netdev2->dev->stats.tx_unicast_count++; + } +#endif res = netdev->driver->send(netdev, vector, n); } else { diff --git a/sys/shell/commands/sc_netif.c b/sys/shell/commands/sc_netif.c index d1a693c73..3636e4c2b 100644 --- a/sys/shell/commands/sc_netif.c +++ b/sys/shell/commands/sc_netif.c @@ -73,7 +73,7 @@ static bool _is_iface(kernel_pid_t dev) return false; } -#ifdef MODULE_NETSTATS +#ifdef MODULE_NETSTATS_L2 static int _netif_stats(kernel_pid_t dev) { netstats_t *stats; @@ -448,7 +448,7 @@ static void _netif_list(kernel_pid_t dev) } #endif -#ifdef MODULE_NETSTATS +#ifdef MODULE_NETSTATS_L2 puts(""); _netif_stats(dev); #endif @@ -987,7 +987,7 @@ int _netif_config(int argc, char **argv) return _netif_mtu((kernel_pid_t)dev, argv[3]); } -#ifdef MODULE_NETSTATS +#ifdef MODULE_NETSTATS_L2 else if (strcmp(argv[2], "stats") == 0) { return _netif_stats((kernel_pid_t)dev); }