Author: loos
Date: Tue Sep 27 18:19:29 2016
New Revision: 306376
URL: https://svnweb.freebsd.org/changeset/base/306376

Log:
  Add a sysctl to control the interrupt pacing on AM335x integrated switch.
  
  The hardware can be set to limit the number of interrupts from 2 to 63
  interrupts per ms.
  
  To keep the compatibility with the TI documentation the sysctl take the
  interval between the interrupts pulses: 16~500 us.
  
  Sponsored by: Rubicon Communications, LLC (Netgate)

Modified:
  head/sys/arm/ti/cpsw/if_cpsw.c
  head/sys/arm/ti/cpsw/if_cpswreg.h
  head/sys/arm/ti/cpsw/if_cpswvar.h

Modified: head/sys/arm/ti/cpsw/if_cpsw.c
==============================================================================
--- head/sys/arm/ti/cpsw/if_cpsw.c      Tue Sep 27 18:08:38 2016        
(r306375)
+++ head/sys/arm/ti/cpsw/if_cpsw.c      Tue Sep 27 18:19:29 2016        
(r306376)
@@ -583,6 +583,11 @@ cpsw_init(struct cpsw_softc *sc)
        struct cpsw_slot *slot;
        uint32_t reg;
 
+       /* Disable the interrupt pacing. */
+       reg = cpsw_read_4(sc, CPSW_WR_INT_CONTROL);
+       reg &= ~(CPSW_WR_INT_PACE_EN | CPSW_WR_INT_PRESCALE_MASK);
+       cpsw_write_4(sc, CPSW_WR_INT_CONTROL, reg);
+
        /* Clear ALE */
        cpsw_write_4(sc, CPSW_ALE_CONTROL, CPSW_ALE_CTL_CLEAR_TBL);
 
@@ -2492,6 +2497,51 @@ cpsw_stat_attached(SYSCTL_HANDLER_ARGS)
 }
 
 static int
+cpsw_intr_coalesce(SYSCTL_HANDLER_ARGS)
+{
+       int error;
+       struct cpsw_softc *sc;
+       uint32_t ctrl, intr_per_ms;
+
+       sc = (struct cpsw_softc *)arg1;
+       error = sysctl_handle_int(oidp, &sc->coal_us, 0, req);
+       if (error != 0 || req->newptr == NULL)
+               return (error);
+
+       ctrl = cpsw_read_4(sc, CPSW_WR_INT_CONTROL);
+       ctrl &= ~(CPSW_WR_INT_PACE_EN | CPSW_WR_INT_PRESCALE_MASK);
+       if (sc->coal_us == 0) {
+               /* Disable the interrupt pace hardware. */
+               cpsw_write_4(sc, CPSW_WR_INT_CONTROL, ctrl);
+               cpsw_write_4(sc, CPSW_WR_C_RX_IMAX(0), 0);
+               cpsw_write_4(sc, CPSW_WR_C_TX_IMAX(0), 0);
+               return (0);
+       }
+
+       if (sc->coal_us > CPSW_WR_C_IMAX_US_MAX)
+               sc->coal_us = CPSW_WR_C_IMAX_US_MAX;
+       if (sc->coal_us < CPSW_WR_C_IMAX_US_MIN)
+               sc->coal_us = CPSW_WR_C_IMAX_US_MIN;
+       intr_per_ms = 1000 / sc->coal_us;
+       /* Just to make sure... */
+       if (intr_per_ms > CPSW_WR_C_IMAX_MAX)
+               intr_per_ms = CPSW_WR_C_IMAX_MAX;
+       if (intr_per_ms < CPSW_WR_C_IMAX_MIN)
+               intr_per_ms = CPSW_WR_C_IMAX_MIN;
+
+       /* Set the prescale to produce 4us pulses from the 125 Mhz clock. */
+       ctrl |= (125 * 4) & CPSW_WR_INT_PRESCALE_MASK;
+
+       /* Enable the interrupt pace hardware. */
+       cpsw_write_4(sc, CPSW_WR_C_RX_IMAX(0), intr_per_ms);
+       cpsw_write_4(sc, CPSW_WR_C_TX_IMAX(0), intr_per_ms);
+       ctrl |= CPSW_WR_INT_C0_RX_PULSE | CPSW_WR_INT_C0_TX_PULSE;
+       cpsw_write_4(sc, CPSW_WR_INT_CONTROL, ctrl);
+
+       return (0);
+}
+
+static int
 cpsw_stat_uptime(SYSCTL_HANDLER_ARGS)
 {
        struct cpsw_softc *swsc;
@@ -2576,6 +2626,10 @@ cpsw_add_sysctls(struct cpsw_softc *sc)
            CTLTYPE_UINT | CTLFLAG_RD, sc, 0, cpsw_stat_attached, "IU",
            "Time since driver attach");
 
+       SYSCTL_ADD_PROC(ctx, parent, OID_AUTO, "intr_coalesce_us",
+           CTLTYPE_UINT | CTLFLAG_RW, sc, 0, cpsw_intr_coalesce, "IU",
+           "minimum time between interrupts");
+
        node = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "ports",
            CTLFLAG_RD, NULL, "CPSW Ports Statistics");
        ports_parent = SYSCTL_CHILDREN(node);

Modified: head/sys/arm/ti/cpsw/if_cpswreg.h
==============================================================================
--- head/sys/arm/ti/cpsw/if_cpswreg.h   Tue Sep 27 18:08:38 2016        
(r306375)
+++ head/sys/arm/ti/cpsw/if_cpswreg.h   Tue Sep 27 18:19:29 2016        
(r306376)
@@ -138,6 +138,17 @@
 #define        CPSW_WR_SOFT_RESET              (CPSW_WR_OFFSET + 0x04)
 #define        CPSW_WR_CONTROL                 (CPSW_WR_OFFSET + 0x08)
 #define        CPSW_WR_INT_CONTROL             (CPSW_WR_OFFSET + 0x0c)
+#define         CPSW_WR_INT_C0_RX_PULSE        (1 << 16)
+#define         CPSW_WR_INT_C0_TX_PULSE        (1 << 17)
+#define         CPSW_WR_INT_C1_RX_PULSE        (1 << 18)
+#define         CPSW_WR_INT_C1_TX_PULSE        (1 << 19)
+#define         CPSW_WR_INT_C2_RX_PULSE        (1 << 20)
+#define         CPSW_WR_INT_C2_TX_PULSE        (1 << 21)
+#define         CPSW_WR_INT_PACE_EN                                            
\
+       (CPSW_WR_INT_C0_RX_PULSE | CPSW_WR_INT_C0_TX_PULSE |            \
+        CPSW_WR_INT_C1_RX_PULSE | CPSW_WR_INT_C1_TX_PULSE |            \
+        CPSW_WR_INT_C2_RX_PULSE | CPSW_WR_INT_C2_TX_PULSE)
+#define         CPSW_WR_INT_PRESCALE_MASK      0xfff
 #define        CPSW_WR_C_RX_THRESH_EN(p)       (CPSW_WR_OFFSET + (0x10 * (p)) 
+ 0x10)
 #define        CPSW_WR_C_RX_EN(p)              (CPSW_WR_OFFSET + (0x10 * (p)) 
+ 0x14)
 #define        CPSW_WR_C_TX_EN(p)              (CPSW_WR_OFFSET + (0x10 * (p)) 
+ 0x18)
@@ -151,6 +162,13 @@
 #define         CPSW_WR_C_MISC_HOST_PEND       (1 << 2)
 #define         CPSW_WR_C_MISC_MDIOLINK        (1 << 1)
 #define         CPSW_WR_C_MISC_MDIOUSER        (1 << 0)
+#define        CPSW_WR_C_RX_IMAX(p)            (CPSW_WR_OFFSET + (0x08 * (p)) 
+ 0x70)
+#define        CPSW_WR_C_TX_IMAX(p)            (CPSW_WR_OFFSET + (0x08 * (p)) 
+ 0x74)
+#define         CPSW_WR_C_IMAX_MASK            0x3f
+#define         CPSW_WR_C_IMAX_MAX             63
+#define         CPSW_WR_C_IMAX_MIN             2
+#define         CPSW_WR_C_IMAX_US_MAX          500
+#define         CPSW_WR_C_IMAX_US_MIN          16
 
 #define        CPSW_CPPI_RAM_OFFSET            0x2000
 #define        CPSW_CPPI_RAM_SIZE              0x2000

Modified: head/sys/arm/ti/cpsw/if_cpswvar.h
==============================================================================
--- head/sys/arm/ti/cpsw/if_cpswvar.h   Tue Sep 27 18:08:38 2016        
(r306375)
+++ head/sys/arm/ti/cpsw/if_cpswvar.h   Tue Sep 27 18:19:29 2016        
(r306376)
@@ -80,6 +80,7 @@ struct cpsw_softc {
        phandle_t       node;
        struct bintime  attach_uptime; /* system uptime when attach happened. */
        struct cpsw_port port[2];
+       unsigned        coal_us;
 
        /* RX and TX buffer tracking */
        struct cpsw_queue rx, tx;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to