set interrupt aggregation parameters so we get around 10000 interrupts
authorjmatthew <jmatthew@openbsd.org>
Thu, 23 Aug 2018 00:22:53 +0000 (00:22 +0000)
committerjmatthew <jmatthew@openbsd.org>
Thu, 23 Aug 2018 00:22:53 +0000 (00:22 +0000)
per second, which makes a pretty sizable improvement to rx performance.

sys/dev/pci/if_bnxt.c

index 2025824..3920c8b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_bnxt.c,v 1.4 2018/07/11 06:48:58 jmatthew Exp $    */
+/*     $OpenBSD: if_bnxt.c,v 1.5 2018/08/23 00:22:53 jmatthew Exp $    */
 /*-
  * Broadcom NetXtreme-C/E network driver.
  *
@@ -386,7 +386,6 @@ int bnxt_hwrm_fw_set_time(struct bnxt_softc *softc, uint16_t year,
 uint16_t bnxt_hwrm_get_wol_fltrs(struct bnxt_softc *softc, uint16_t handle);
 int bnxt_hwrm_alloc_wol_fltr(struct bnxt_softc *softc);
 int bnxt_hwrm_free_wol_fltr(struct bnxt_softc *softc);
-int bnxt_hwrm_set_coal(struct bnxt_softc *softc);
 
 #endif
 
@@ -460,6 +459,7 @@ void
 bnxt_attach(struct device *parent, struct device *self, void *aux)
 {
        struct bnxt_softc *sc = (struct bnxt_softc *)self;
+       struct hwrm_ring_cmpl_ring_cfg_aggint_params_input aggint;
        struct ifnet *ifp = &sc->sc_ac.ac_if;
        struct pci_attach_args *pa = aux;
        pci_intr_handle_t ih;
@@ -585,6 +585,25 @@ bnxt_attach(struct device *parent, struct device *self, void *aux)
        }
        bnxt_write_cp_doorbell(sc, &sc->sc_cp_ring.ring, 1);
 
+       /*
+        * set interrupt aggregation parameters for around 10k interrupts
+        * per second.  the timers are in units of 80usec, and the counters
+        * are based on the minimum rx ring size of 32.
+        */
+       memset(&aggint, 0, sizeof(aggint));
+        bnxt_hwrm_cmd_hdr_init(sc, &aggint,
+           HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
+       aggint.ring_id = htole16(sc->sc_cp_ring.ring.phys_id);
+       aggint.num_cmpl_dma_aggr = htole16(32);
+       aggint.num_cmpl_dma_aggr_during_int  = aggint.num_cmpl_dma_aggr;
+       aggint.cmpl_aggr_dma_tmr = htole16((1000000000 / 20000) / 80);
+       aggint.cmpl_aggr_dma_tmr_during_int = aggint.cmpl_aggr_dma_tmr;
+       aggint.int_lat_tmr_min = htole16((1000000000 / 20000) / 80);
+       aggint.int_lat_tmr_max = htole16((1000000000 / 10000) / 80);
+       aggint.num_cmpl_aggr_int = htole16(16);
+       if (hwrm_send_message(sc, &aggint, sizeof(aggint)))
+               goto free_cp_mem;
+
        strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
        ifp->if_softc = sc;
        ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX;
@@ -3345,92 +3364,6 @@ bnxt_hwrm_free_wol_fltr(struct bnxt_softc *softc)
        return hwrm_send_message(softc, &req, sizeof(req));
 }
 
-static void bnxt_hwrm_set_coal_params(struct bnxt_softc *softc, uint32_t max_frames,
-        uint32_t buf_tmrs, uint16_t flags,
-        struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *req)
-{
-        req->flags = htole16(flags);
-        req->num_cmpl_dma_aggr = htole16((uint16_t)max_frames);
-        req->num_cmpl_dma_aggr_during_int = htole16(max_frames >> 16);
-        req->cmpl_aggr_dma_tmr = htole16((uint16_t)buf_tmrs);
-        req->cmpl_aggr_dma_tmr_during_int = htole16(buf_tmrs >> 16);
-        /* Minimum time between 2 interrupts set to buf_tmr x 2 */
-        req->int_lat_tmr_min = htole16((uint16_t)buf_tmrs * 2);
-        req->int_lat_tmr_max = htole16((uint16_t)buf_tmrs * 4);
-        req->num_cmpl_aggr_int = htole16((uint16_t)max_frames * 4);
-}
-
-
-int bnxt_hwrm_set_coal(struct bnxt_softc *softc)
-{
-        int i, rc = 0;
-        struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_rx = {0},
-                                                           req_tx = {0}, *req;
-        uint16_t max_buf, max_buf_irq;
-        uint16_t buf_tmr, buf_tmr_irq;
-        uint32_t flags;
-
-        bnxt_hwrm_cmd_hdr_init(softc, &req_rx,
-                               HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
-        bnxt_hwrm_cmd_hdr_init(softc, &req_tx,
-                               HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
-
-        /* Each rx completion (2 records) should be DMAed immediately.
-         * DMA 1/4 of the completion buffers at a time.
-         */
-        max_buf = min_t(uint16_t, softc->rx_coal_frames / 4, 2);
-        /* max_buf must not be zero */
-        max_buf = clamp_t(uint16_t, max_buf, 1, 63);
-        max_buf_irq = clamp_t(uint16_t, softc->rx_coal_frames_irq, 1, 63);
-        buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs);
-        /* buf timer set to 1/4 of interrupt timer */
-        buf_tmr = max_t(uint16_t, buf_tmr / 4, 1);
-        buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->rx_coal_usecs_irq);
-        buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1);
-
-        flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
-
-        /* RING_IDLE generates more IRQs for lower latency.  Enable it only
-         * if coal_usecs is less than 25 us.
-         */
-        if (softc->rx_coal_usecs < 25)
-                flags |= HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_RING_IDLE;
-
-        bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf,
-                                  buf_tmr_irq << 16 | buf_tmr, flags, &req_rx);
-
-        /* max_buf must not be zero */
-        max_buf = clamp_t(uint16_t, softc->tx_coal_frames, 1, 63);
-        max_buf_irq = clamp_t(uint16_t, softc->tx_coal_frames_irq, 1, 63);
-        buf_tmr = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs);
-        /* buf timer set to 1/4 of interrupt timer */
-        buf_tmr = max_t(uint16_t, buf_tmr / 4, 1);
-        buf_tmr_irq = BNXT_USEC_TO_COAL_TIMER(softc->tx_coal_usecs_irq);
-        buf_tmr_irq = max_t(uint16_t, buf_tmr_irq, 1);
-        flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
-        bnxt_hwrm_set_coal_params(softc, max_buf_irq << 16 | max_buf,
-                                  buf_tmr_irq << 16 | buf_tmr, flags, &req_tx);
-
-        for (i = 0; i < softc->nrxqsets; i++) {
-
-                
-               req = &req_rx;
-                /*
-                 * TBD:
-                *      Check if Tx also needs to be done
-                 *      So far, Tx processing has been done in softirq contest
-                 *
-                * req = &req_tx;
-                */
-               req->ring_id = htole16(softc->grp_info[i].cp_ring_id);
-
-                rc = hwrm_send_message(softc, req, sizeof(*req));
-                if (rc)
-                        break;
-        }
-        return rc;
-}
-
 #endif
 
 void