Author: np
Date: Sat Sep 27 18:35:16 2014
New Revision: 272222
URL: http://svnweb.freebsd.org/changeset/base/272222

Log:
  cxgb(4): implement if_get_counter.

Modified:
  head/sys/dev/cxgb/cxgb_adapter.h
  head/sys/dev/cxgb/cxgb_main.c
  head/sys/dev/cxgb/cxgb_sge.c

Modified: head/sys/dev/cxgb/cxgb_adapter.h
==============================================================================
--- head/sys/dev/cxgb/cxgb_adapter.h    Sat Sep 27 18:20:45 2014        
(r272221)
+++ head/sys/dev/cxgb/cxgb_adapter.h    Sat Sep 27 18:35:16 2014        
(r272222)
@@ -97,6 +97,7 @@ struct port_info {
        const struct port_type_info *port_type;
        struct cphy     phy;
        struct cmac     mac;
+       struct timeval  last_refreshed;
        struct link_config link_config;
        struct ifmedia  media;
        struct mtx      lock;
@@ -575,4 +576,5 @@ void cxgb_tx_watchdog(void *arg);
 int cxgb_transmit(struct ifnet *ifp, struct mbuf *m);
 void cxgb_qflush(struct ifnet *ifp);
 void t3_iterate(void (*)(struct adapter *, void *), void *);
+void cxgb_refresh_stats(struct port_info *);
 #endif

Modified: head/sys/dev/cxgb/cxgb_main.c
==============================================================================
--- head/sys/dev/cxgb/cxgb_main.c       Sat Sep 27 18:20:45 2014        
(r272221)
+++ head/sys/dev/cxgb/cxgb_main.c       Sat Sep 27 18:35:16 2014        
(r272222)
@@ -96,6 +96,7 @@ static int cxgb_media_change(struct ifne
 static int cxgb_ifm_type(int);
 static void cxgb_build_medialist(struct port_info *);
 static void cxgb_media_status(struct ifnet *, struct ifmediareq *);
+static uint64_t cxgb_get_counter(struct ifnet *, ift_counter);
 static int setup_sge_qsets(adapter_t *);
 static void cxgb_async_intr(void *);
 static void cxgb_tick_handler(void *, int);
@@ -1022,6 +1023,7 @@ cxgb_port_attach(device_t dev)
        ifp->if_ioctl = cxgb_ioctl;
        ifp->if_transmit = cxgb_transmit;
        ifp->if_qflush = cxgb_qflush;
+       ifp->if_get_counter = cxgb_get_counter;
 
        ifp->if_capabilities = CXGB_CAP;
 #ifdef TCP_OFFLOAD
@@ -2189,6 +2191,71 @@ cxgb_media_status(struct ifnet *ifp, str
                            speed));
 }
 
+static uint64_t
+cxgb_get_counter(struct ifnet *ifp, ift_counter c)
+{
+       struct port_info *pi = ifp->if_softc;
+       struct adapter *sc = pi->adapter;
+       struct cmac *mac = &pi->mac;
+       struct mac_stats *mstats = &mac->stats;
+
+       cxgb_refresh_stats(pi);
+
+       switch (c) {
+       case IFCOUNTER_IPACKETS:
+               return (mstats->rx_frames);
+
+       case IFCOUNTER_IERRORS:
+               return (mstats->rx_jabber + mstats->rx_data_errs +
+                   mstats->rx_sequence_errs + mstats->rx_runt +
+                   mstats->rx_too_long + mstats->rx_mac_internal_errs +
+                   mstats->rx_short + mstats->rx_fcs_errs);
+
+       case IFCOUNTER_OPACKETS:
+               return (mstats->tx_frames);
+
+       case IFCOUNTER_OERRORS:
+               return (mstats->tx_excess_collisions + mstats->tx_underrun +
+                   mstats->tx_len_errs + mstats->tx_mac_internal_errs +
+                   mstats->tx_excess_deferral + mstats->tx_fcs_errs);
+
+       case IFCOUNTER_COLLISIONS:
+               return (mstats->tx_total_collisions);
+
+       case IFCOUNTER_IBYTES:
+               return (mstats->rx_octets);
+
+       case IFCOUNTER_OBYTES:
+               return (mstats->tx_octets);
+
+       case IFCOUNTER_IMCASTS:
+               return (mstats->rx_mcast_frames);
+
+       case IFCOUNTER_OMCASTS:
+               return (mstats->tx_mcast_frames);
+
+       case IFCOUNTER_IQDROPS:
+               return (mstats->rx_cong_drops);
+
+       case IFCOUNTER_OQDROPS: {
+               int i;
+               uint64_t drops;
+
+               drops = 0;
+               if (sc->flags & FULL_INIT_DONE) {
+                       for (i = pi->first_qset; i < pi->first_qset + 
pi->nqsets; i++)
+                               drops += 
sc->sge.qs[i].txq[TXQ_ETH].txq_mr->br_drops;
+               }
+
+               return (drops);
+
+       }
+
+       default:
+               return (if_get_counter_default(ifp, c));
+       }
+}
+
 static void
 cxgb_async_intr(void *data)
 {
@@ -2289,6 +2356,23 @@ cxgb_tick(void *arg)
        callout_reset(&sc->cxgb_tick_ch, hz, cxgb_tick, sc);
 }
 
+void
+cxgb_refresh_stats(struct port_info *pi)
+{
+       struct timeval tv;
+       const struct timeval interval = {0, 250000};    /* 250ms */
+
+       getmicrotime(&tv);
+       timevalsub(&tv, &interval);
+       if (timevalcmp(&tv, &pi->last_refreshed, <))
+               return;
+
+       PORT_LOCK(pi);
+       t3_mac_update_stats(&pi->mac);
+       PORT_UNLOCK(pi);
+       getmicrotime(&pi->last_refreshed);
+}
+
 static void
 cxgb_tick_handler(void *arg, int count)
 {
@@ -2333,48 +2417,12 @@ cxgb_tick_handler(void *arg, int count)
 
        for (i = 0; i < sc->params.nports; i++) {
                struct port_info *pi = &sc->port[i];
-               struct ifnet *ifp = pi->ifp;
                struct cmac *mac = &pi->mac;
-               struct mac_stats *mstats = &mac->stats;
-               int drops, j;
 
                if (!isset(&sc->open_device_map, pi->port_id))
                        continue;
 
-               PORT_LOCK(pi);
-               t3_mac_update_stats(mac);
-               PORT_UNLOCK(pi);
-
-               ifp->if_opackets = mstats->tx_frames;
-               ifp->if_ipackets = mstats->rx_frames;
-               ifp->if_obytes = mstats->tx_octets;
-               ifp->if_ibytes = mstats->rx_octets;
-               ifp->if_omcasts = mstats->tx_mcast_frames;
-               ifp->if_imcasts = mstats->rx_mcast_frames;
-               ifp->if_collisions = mstats->tx_total_collisions;
-               ifp->if_iqdrops = mstats->rx_cong_drops;
-
-               drops = 0;
-               for (j = pi->first_qset; j < pi->first_qset + pi->nqsets; j++)
-                       drops += sc->sge.qs[j].txq[TXQ_ETH].txq_mr->br_drops;
-               ifp->if_oqdrops = drops;
-
-               ifp->if_oerrors =
-                   mstats->tx_excess_collisions +
-                   mstats->tx_underrun +
-                   mstats->tx_len_errs +
-                   mstats->tx_mac_internal_errs +
-                   mstats->tx_excess_deferral +
-                   mstats->tx_fcs_errs;
-               ifp->if_ierrors =
-                   mstats->rx_jabber +
-                   mstats->rx_data_errs +
-                   mstats->rx_sequence_errs +
-                   mstats->rx_runt + 
-                   mstats->rx_too_long +
-                   mstats->rx_mac_internal_errs +
-                   mstats->rx_short +
-                   mstats->rx_fcs_errs;
+               cxgb_refresh_stats(pi);
 
                if (mac->multiport)
                        continue;

Modified: head/sys/dev/cxgb/cxgb_sge.c
==============================================================================
--- head/sys/dev/cxgb/cxgb_sge.c        Sat Sep 27 18:20:45 2014        
(r272221)
+++ head/sys/dev/cxgb/cxgb_sge.c        Sat Sep 27 18:35:16 2014        
(r272222)
@@ -3410,10 +3410,8 @@ sysctl_handle_macstat(SYSCTL_HANDLER_ARG
        if (!p)
                return (EINVAL);
 
+       cxgb_refresh_stats(p);
        parg = (uint64_t *) ((uint8_t *)&p->mac.stats + arg2);
-       PORT_LOCK(p);
-       t3_mac_update_stats(&p->mac);
-       PORT_UNLOCK(p);
 
        return (sysctl_handle_64(oidp, parg, 0, req));
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to