Index: sys/dev/bnxt/bnxt_en/bnxt.h =================================================================== --- sys/dev/bnxt/bnxt_en/bnxt.h +++ sys/dev/bnxt/bnxt_en/bnxt.h @@ -1242,12 +1242,9 @@ uint8_t wol_filter_id; struct bnxt_coal_cap coal_cap; struct bnxt_coal rx_coal; + struct bnxt_coal tx_coal; uint32_t stats_coal_ticks; - uint16_t tx_coal_usecs; - uint16_t tx_coal_usecs_irq; - uint16_t tx_coal_frames; - uint16_t tx_coal_frames_irq; #define BNXT_USEC_TO_COAL_TIMER(x) ((x) * 25 / 2) #define BNXT_DEF_STATS_COAL_TICKS 1000000 Index: sys/dev/bnxt/bnxt_en/bnxt_sysctl.c =================================================================== --- sys/dev/bnxt/bnxt_en/bnxt_sysctl.c +++ sys/dev/bnxt/bnxt_en/bnxt_sysctl.c @@ -1398,18 +1398,21 @@ static int bnxt_set_coal_rx_usecs(SYSCTL_HANDLER_ARGS) { struct bnxt_softc *softc = arg1; + struct bnxt_coal *hw_coal; int rc; int val; if (softc == NULL) return EBUSY; - val = softc->rx_coal.coal_ticks; + hw_coal = &softc->rx_coal; + val = hw_coal->coal_ticks; + rc = sysctl_handle_int(oidp, &val, 0, req); if (rc || !req->newptr) return rc; - softc->rx_coal.coal_ticks = val; + hw_coal->coal_ticks = val; rc = bnxt_hwrm_set_coal(softc); return rc; @@ -1418,18 +1421,23 @@ static int bnxt_set_coal_rx_frames(SYSCTL_HANDLER_ARGS) { struct bnxt_softc *softc = arg1; + struct bnxt_coal *hw_coal; + uint16_t mult; int rc; int val; if (softc == NULL) return EBUSY; - val = softc->rx_coal.coal_bufs; + hw_coal = &softc->rx_coal; + mult = hw_coal->bufs_per_record; + val = hw_coal->coal_bufs / mult; + rc = sysctl_handle_int(oidp, &val, 0, req); if (rc || !req->newptr) return rc; - softc->rx_coal.coal_bufs = val; + hw_coal->coal_bufs = val * mult; rc = bnxt_hwrm_set_coal(softc); return rc; @@ -1438,18 +1446,21 @@ static int bnxt_set_coal_rx_usecs_irq(SYSCTL_HANDLER_ARGS) { struct bnxt_softc *softc = arg1; + struct bnxt_coal *hw_coal; int rc; int val; if (softc == NULL) return EBUSY; - val = softc->rx_coal.coal_ticks_irq; + hw_coal = &softc->rx_coal; + val = hw_coal->coal_ticks_irq; + rc = sysctl_handle_int(oidp, &val, 0, req); if (rc || !req->newptr) return rc; - softc->rx_coal.coal_ticks_irq = val; + hw_coal->coal_ticks_irq = val; rc = bnxt_hwrm_set_coal(softc); return rc; @@ -1458,18 +1469,23 @@ static int bnxt_set_coal_rx_frames_irq(SYSCTL_HANDLER_ARGS) { struct bnxt_softc *softc = arg1; + struct bnxt_coal *hw_coal; + uint16_t mult; int rc; int val; if (softc == NULL) return EBUSY; - val = softc->rx_coal.coal_bufs_irq; + hw_coal = &softc->rx_coal; + mult = hw_coal->bufs_per_record; + val = hw_coal->coal_bufs_irq / mult; + rc = sysctl_handle_int(oidp, &val, 0, req); if (rc || !req->newptr) return rc; - softc->rx_coal.coal_bufs_irq = val; + hw_coal->coal_bufs_irq = val * mult; rc = bnxt_hwrm_set_coal(softc); return rc; @@ -1478,18 +1494,21 @@ static int bnxt_set_coal_tx_usecs(SYSCTL_HANDLER_ARGS) { struct bnxt_softc *softc = arg1; + struct bnxt_coal *hw_coal; int rc; int val; if (softc == NULL) return EBUSY; - val = softc->tx_coal_usecs; + hw_coal = &softc->tx_coal; + val = hw_coal->coal_ticks; + rc = sysctl_handle_int(oidp, &val, 0, req); if (rc || !req->newptr) return rc; - softc->tx_coal_usecs = val; + hw_coal->coal_ticks = val; rc = bnxt_hwrm_set_coal(softc); return rc; @@ -1498,18 +1517,29 @@ static int bnxt_set_coal_tx_frames(SYSCTL_HANDLER_ARGS) { struct bnxt_softc *softc = arg1; + struct bnxt_coal *hw_coal; + uint16_t mult; int rc; int val; if (softc == NULL) return EBUSY; - val = softc->tx_coal_frames; + hw_coal = &softc->tx_coal; + mult = hw_coal->bufs_per_record; + + if (!mult) { + device_printf(softc->dev, + "%s: bufs_per_record is zero which is invalid\n", __func__); + return EINVAL; + } + val = hw_coal->coal_bufs / mult; + rc = sysctl_handle_int(oidp, &val, 0, req); if (rc || !req->newptr) return rc; - softc->tx_coal_frames = val; + hw_coal->coal_bufs = val * mult; rc = bnxt_hwrm_set_coal(softc); return rc; @@ -1518,18 +1548,21 @@ static int bnxt_set_coal_tx_usecs_irq(SYSCTL_HANDLER_ARGS) { struct bnxt_softc *softc = arg1; + struct bnxt_coal *hw_coal; int rc; int val; if (softc == NULL) return EBUSY; - val = softc->tx_coal_usecs_irq; + hw_coal = &softc->tx_coal; + val = hw_coal->coal_ticks_irq; + rc = sysctl_handle_int(oidp, &val, 0, req); if (rc || !req->newptr) return rc; - softc->tx_coal_usecs_irq = val; + hw_coal->coal_ticks_irq = val; rc = bnxt_hwrm_set_coal(softc); return rc; @@ -1538,23 +1571,53 @@ static int bnxt_set_coal_tx_frames_irq(SYSCTL_HANDLER_ARGS) { struct bnxt_softc *softc = arg1; + struct bnxt_coal *hw_coal; + uint16_t mult; int rc; int val; if (softc == NULL) return EBUSY; - val = softc->tx_coal_frames_irq; + hw_coal = &softc->tx_coal; + mult = hw_coal->bufs_per_record; + if (!mult) { + device_printf(softc->dev, + "%s: bufs_per_record is zero which is invalid\n", __func__); + return EINVAL; + } + val = hw_coal->coal_bufs_irq / mult; + rc = sysctl_handle_int(oidp, &val, 0, req); if (rc || !req->newptr) return rc; - softc->tx_coal_frames_irq = val; + hw_coal->coal_bufs_irq = val * mult; rc = bnxt_hwrm_set_coal(softc); return rc; } +static int +bnxt_set_stats_coal_ticks(SYSCTL_HANDLER_ARGS) { + struct bnxt_softc *softc = arg1; + int rc; + int val; + + if (softc == NULL) + return EBUSY; + + val = softc->stats_coal_ticks; + + rc = sysctl_handle_int(oidp, &val, 0, req); + if (rc || !req->newptr) + return rc; + + softc->stats_coal_ticks = val; + rc = bnxt_hwrm_set_coal(softc); + + return rc; +} static void simulate_reset(struct bnxt_softc *bp, char *fwcli_string) { @@ -1647,6 +1710,10 @@ CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0, bnxt_set_coal_tx_frames_irq, "I", "interrupt coalescing Tx Frames IRQ"); + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_stats_coal_ticks", + CTLTYPE_INT | CTLFLAG_RWTUN, softc, 0, + bnxt_set_stats_coal_ticks, "I", + "interrupt coalescing stats coal ticks"); SYSCTL_ADD_U32(ctx, children, OID_AUTO, "flags", CTLFLAG_RD, &softc->flags, 0, "flags"); SYSCTL_ADD_U64(ctx, children, OID_AUTO, "fw_cap", CTLFLAG_RD, Index: sys/dev/bnxt/bnxt_en/if_bnxt.c =================================================================== --- sys/dev/bnxt/bnxt_en/if_bnxt.c +++ sys/dev/bnxt/bnxt_en/if_bnxt.c @@ -269,6 +269,7 @@ void bnxt_queue_sp_work(struct bnxt_softc *bp); void bnxt_fw_reset(struct bnxt_softc *bp); +static void bnxt_init_dflt_coal(struct bnxt_softc *softc); /* * Device Interface Declaration */ @@ -2746,6 +2747,9 @@ goto failed; } + bnxt_hwrm_coal_params_qcaps(softc); + bnxt_init_dflt_coal(softc); + arc4rand(softc->vnic_info.rss_hash_key, HW_HASH_KEY_SIZE, 0); softc->vnic_info.rss_hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 | @@ -3134,6 +3138,48 @@ return; } +static void bnxt_init_dflt_coal(struct bnxt_softc *softc) +{ + struct bnxt_coal_cap *coal_cap = &softc->coal_cap; + struct bnxt_coal *coal; + uint16_t flags = 0; + + if (coal_cap->cmpl_params & + HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_TIMER_RESET) + flags |= HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET; + + /* Tick values in micro seconds. + * 1 coal_buf x bufs_per_record = 1 completion record. + */ + coal = &softc->rx_coal; + coal->coal_ticks = 6; + coal->coal_bufs = 12; + coal->coal_ticks_irq = 1; +#ifdef DEV_NETMAP + coal->coal_bufs_irq = 8; +#else + if (BNXT_CHIP_P7(softc)) { + coal->coal_bufs_irq = 4; + } else { + coal->coal_bufs_irq = 2; + } +#endif + coal->idle_thresh = 50; + coal->bufs_per_record = 2; + coal->budget = 64; + coal->flags = flags; + + coal = &softc->tx_coal; + coal->coal_ticks = 28; + coal->coal_bufs = 30; + coal->coal_ticks_irq = 2; + coal->coal_bufs_irq = 2; + coal->bufs_per_record = 1; + coal->flags = flags; + + softc->stats_coal_ticks = BNXT_MIN_STATS_COAL_TICKS; +} + /* Device configuration */ static void bnxt_init(if_ctx_t ctx) @@ -3317,7 +3363,10 @@ bnxt_get_port_module_status(softc, false); bnxt_media_status(softc->ctx, &ifmr); bnxt_hwrm_cfa_l2_set_rx_mask(softc, &softc->vnic_info); - bnxt_hwrm_coal_params_qcaps(softc); + if (softc->set_coal_pend) { + bnxt_hwrm_set_coal(softc); + softc->set_coal_pend = false; + } return; fail: