Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177434324
D58621.1794379037.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
24 KB
Referenced Files
None
Subscribers
None
D58621.1794379037.diff
View Options
Index: sys/dev/bnxt/bnxt_en/bnxt.h
===================================================================
--- sys/dev/bnxt/bnxt_en/bnxt.h
+++ sys/dev/bnxt/bnxt_en/bnxt.h
@@ -813,6 +813,54 @@
uint32_t min_agg_len;
};
+#define BNXT_LEGACY_COAL_CMPL_PARAMS \
+ (HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_INT_LAT_TMR_MIN | \
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_INT_LAT_TMR_MAX | \
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_TIMER_RESET | \
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_RING_IDLE | \
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_NUM_CMPL_DMA_AGGR | \
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_NUM_CMPL_DMA_AGGR_DURING_INT | \
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_CMPL_AGGR_DMA_TMR | \
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_CMPL_AGGR_DMA_TMR_DURING_INT | \
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_NUM_CMPL_AGGR_INT)
+
+#define BNXT_COAL_CMPL_ENABLES \
+ (HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_NUM_CMPL_DMA_AGGR | \
+ HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_CMPL_AGGR_DMA_TMR | \
+ HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_INT_LAT_TMR_MAX | \
+ HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_NUM_CMPL_AGGR_INT)
+
+#define BNXT_COAL_CMPL_MIN_TMR_ENABLE \
+ HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_INT_LAT_TMR_MIN
+
+#define BNXT_COAL_CMPL_AGGR_TMR_DURING_INT_ENABLE \
+ HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_NUM_CMPL_DMA_AGGR_DURING_INT
+
+struct bnxt_coal_cap {
+ uint32_t cmpl_params;
+ uint32_t nq_params;
+ uint16_t num_cmpl_dma_aggr_max;
+ uint16_t num_cmpl_dma_aggr_during_int_max;
+ uint16_t cmpl_aggr_dma_tmr_max;
+ uint16_t cmpl_aggr_dma_tmr_during_int_max;
+ uint16_t int_lat_tmr_min_max;
+ uint16_t int_lat_tmr_max_max;
+ uint16_t num_cmpl_aggr_int_max;
+ uint16_t timer_units;
+};
+
+struct bnxt_coal {
+ uint16_t coal_ticks;
+ uint16_t coal_ticks_irq;
+ uint16_t coal_bufs;
+ uint16_t coal_bufs_irq;
+ uint16_t idle_thresh; /* RING_IDLE enabled when coal ticks < idle_thresh */
+ uint8_t bufs_per_record;
+ uint16_t budget;
+ uint16_t flags;
+ uint8_t timer_reset_during_ring_alloc;
+};
+
/* The hardware supports certain page sizes. Use the supported page sizes
* to allocate the rings.
*/
@@ -1365,15 +1413,12 @@
bool detached;
struct bnxt_hw_lro hw_lro;
uint8_t wol_filter_id;
- uint16_t rx_coal_usecs;
- uint16_t rx_coal_usecs_irq;
- uint16_t rx_coal_frames;
- uint16_t rx_coal_frames_irq;
- uint16_t tx_coal_usecs;
- uint16_t tx_coal_usecs_irq;
- uint16_t tx_coal_frames;
- uint16_t tx_coal_frames_irq;
+ struct bnxt_coal_cap coal_cap;
+ struct bnxt_coal rx_coal;
+ struct bnxt_coal tx_coal;
+
+ uint32_t stats_coal_ticks;
#define BNXT_USEC_TO_COAL_TIMER(x) ((x) * 25 / 2)
#define BNXT_DEF_STATS_COAL_TICKS 1000000
#define BNXT_MIN_STATS_COAL_TICKS 250000
@@ -1474,6 +1519,7 @@
#define BNXT_STATE_FW_NON_FATAL_COND 13
#define BNXT_STATE_FW_ACTIVATE_RESET 14
#define BNXT_STATE_HALF_OPEN 15
+#define BNXT_STATE_UP 16
#define BNXT_NO_FW_ACCESS(bp) \
test_bit(BNXT_STATE_FW_FATAL_COND, &(bp)->state)
struct pci_dev *pdev;
Index: sys/dev/bnxt/bnxt_en/bnxt_hwrm.h
===================================================================
--- sys/dev/bnxt/bnxt_en/bnxt_hwrm.h
+++ sys/dev/bnxt/bnxt_en/bnxt_hwrm.h
@@ -128,6 +128,7 @@
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);
+void bnxt_hwrm_coal_params_qcaps(struct bnxt_softc *softc);
int bnxt_hwrm_func_rgtr_async_events(struct bnxt_softc *softc, unsigned long *bmap,
int bmap_size);
int bnxt_hwrm_func_backing_store_qcaps(struct bnxt_softc *softc);
Index: sys/dev/bnxt/bnxt_en/bnxt_hwrm.c
===================================================================
--- sys/dev/bnxt/bnxt_en/bnxt_hwrm.c
+++ sys/dev/bnxt/bnxt_en/bnxt_hwrm.c
@@ -2115,6 +2115,9 @@
req.nq_ring_id = htole16(softc->nq_rings[idx].ring.phys_id);
req.enables |= htole32(
HWRM_RING_ALLOC_INPUT_ENABLES_NQ_RING_ID_VALID);
+
+ if (softc->rx_coal.timer_reset_during_ring_alloc)
+ req.flags |= HWRM_RING_ALLOC_INPUT_FLAGS_TIMER_RESET;
break;
case HWRM_RING_ALLOC_INPUT_RING_TYPE_NQ:
req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX;
@@ -3454,81 +3457,205 @@
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)
+static inline uint16_t
+bnxt_clamp_u16(uint16_t v, uint16_t lo, uint16_t hi)
{
- 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);
+
+ if (v < lo)
+ return (lo);
+ if (v > hi)
+ return (hi);
+ return (v);
}
-int bnxt_hwrm_set_coal(struct bnxt_softc *softc)
+void
+bnxt_hwrm_coal_params_qcaps(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;
+ struct bnxt_coal_cap *coal_cap = &softc->coal_cap;
+ struct hwrm_ring_aggint_qcaps_output *resp =
+ (void *)softc->hwrm_cmd_resp.idi_vaddr;
+ struct hwrm_ring_aggint_qcaps_input req = {0};
+ int rc;
- 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);
+ coal_cap->cmpl_params = BNXT_LEGACY_COAL_CMPL_PARAMS;
+ coal_cap->num_cmpl_dma_aggr_max = 63;
+ coal_cap->num_cmpl_dma_aggr_during_int_max = 63;
+ coal_cap->cmpl_aggr_dma_tmr_max = 65535;
+ coal_cap->cmpl_aggr_dma_tmr_during_int_max = 65535;
+ coal_cap->int_lat_tmr_min_max = 65535;
+ coal_cap->int_lat_tmr_max_max = 65535;
+ coal_cap->num_cmpl_aggr_int_max = 65535;
+ coal_cap->timer_units = 80;
+
+ if (softc->hwrm_spec_code < 0x10902)
+ return;
- /* 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)
+ bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_RING_AGGINT_QCAPS);
+
+ BNXT_HWRM_LOCK(softc);
+ rc = _hwrm_send_message(softc, &req, sizeof(req));
+ if (rc) {
+ BNXT_HWRM_UNLOCK(softc);
+ return;
+ }
+
+ coal_cap->cmpl_params = le32toh(resp->cmpl_params);
+ coal_cap->nq_params = le32toh(resp->nq_params);
+ coal_cap->num_cmpl_dma_aggr_max = le16toh(resp->num_cmpl_dma_aggr_max);
+ coal_cap->num_cmpl_dma_aggr_during_int_max =
+ le16toh(resp->num_cmpl_dma_aggr_during_int_max);
+ coal_cap->cmpl_aggr_dma_tmr_max = le16toh(resp->cmpl_aggr_dma_tmr_max);
+ coal_cap->cmpl_aggr_dma_tmr_during_int_max =
+ le16toh(resp->cmpl_aggr_dma_tmr_during_int_max);
+ coal_cap->int_lat_tmr_min_max = le16toh(resp->int_lat_tmr_min_max);
+ coal_cap->int_lat_tmr_max_max = le16toh(resp->int_lat_tmr_max_max);
+ coal_cap->num_cmpl_aggr_int_max = le16toh(resp->num_cmpl_aggr_int_max);
+ coal_cap->timer_units = le16toh(resp->timer_units);
+ BNXT_HWRM_UNLOCK(softc);
+}
+
+static uint16_t
+bnxt_usec_to_coal_tmr(struct bnxt_softc *softc, uint16_t usec)
+{
+ struct bnxt_coal_cap *coal_cap = &softc->coal_cap;
+
+ return (usec * 1000 / coal_cap->timer_units);
+}
+
+static void
+bnxt_hwrm_set_coal_params(struct bnxt_softc *softc, struct bnxt_coal *hw_coal,
+ struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *req)
+{
+ struct bnxt_coal_cap *coal_cap = &softc->coal_cap;
+ uint16_t val, tmr, max, flags = hw_coal->flags;
+ uint32_t cmpl_params = coal_cap->cmpl_params;
+
+ max = hw_coal->bufs_per_record * 128;
+ if (hw_coal->budget)
+ max = hw_coal->bufs_per_record * hw_coal->budget;
+ max = min_t(uint16_t, max, coal_cap->num_cmpl_aggr_int_max);
+
+ val = bnxt_clamp_u16(hw_coal->coal_bufs, 1, max);
+ req->num_cmpl_aggr_int = htole16(val);
+
+ val = min_t(uint16_t, val, coal_cap->num_cmpl_dma_aggr_max);
+ req->num_cmpl_dma_aggr = htole16(val);
+
+ val = bnxt_clamp_u16(hw_coal->coal_bufs_irq, 1,
+ coal_cap->num_cmpl_dma_aggr_during_int_max);
+ req->num_cmpl_dma_aggr_during_int = htole16(val);
+
+ tmr = bnxt_usec_to_coal_tmr(softc, hw_coal->coal_ticks);
+ tmr = bnxt_clamp_u16(tmr, 1, coal_cap->int_lat_tmr_max_max);
+ req->int_lat_tmr_max = htole16(tmr);
+
+ /* Minimum timer set to 1/2 of the interrupt timer. */
+ if (cmpl_params &
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_INT_LAT_TMR_MIN) {
+ val = tmr / 2;
+ val = bnxt_clamp_u16(val, 1, coal_cap->int_lat_tmr_min_max);
+ req->int_lat_tmr_min = htole16(val);
+ req->enables |= htole16(BNXT_COAL_CMPL_MIN_TMR_ENABLE);
+ }
+
+ /* Buf timer set to 1/4 of the interrupt timer. */
+ val = bnxt_clamp_u16(tmr / 4, 1, coal_cap->cmpl_aggr_dma_tmr_max);
+ req->cmpl_aggr_dma_tmr = htole16(val);
+
+ if (cmpl_params &
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_NUM_CMPL_DMA_AGGR_DURING_INT) {
+ tmr = bnxt_usec_to_coal_tmr(softc, hw_coal->coal_ticks_irq);
+ val = bnxt_clamp_u16(tmr, 1,
+ coal_cap->cmpl_aggr_dma_tmr_during_int_max);
+ req->cmpl_aggr_dma_tmr_during_int = htole16(val);
+ req->enables |=
+ htole16(BNXT_COAL_CMPL_AGGR_TMR_DURING_INT_ENABLE);
+ }
+
+ if ((cmpl_params & HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_RING_IDLE) &&
+ hw_coal->idle_thresh && hw_coal->coal_ticks < hw_coal->idle_thresh)
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);
+ req->flags = htole16(flags);
+ req->enables |= htole16(BNXT_COAL_CMPL_ENABLES);
+}
- for (i = 0; i < softc->nrxqsets; i++) {
+static int
+bnxt_hwrm_set_coal_nq(struct bnxt_softc *softc, uint32_t ring_id,
+ struct bnxt_coal *hw_coal)
+{
+ struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req = {0};
+ struct bnxt_coal_cap *coal_cap = &softc->coal_cap;
+ uint16_t tmr;
+
+ if (!(coal_cap->nq_params &
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_NQ_PARAMS_INT_LAT_TMR_MIN))
+ return (0);
+
+ bnxt_hwrm_cmd_hdr_init(softc, &req,
+ HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
+
+ req.ring_id = htole16(ring_id);
+ req.flags =
+ htole16(HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_IS_NQ);
+
+ tmr = bnxt_usec_to_coal_tmr(softc, hw_coal->coal_ticks) / 2;
+ tmr = bnxt_clamp_u16(tmr, 1, coal_cap->int_lat_tmr_min_max);
+ req.int_lat_tmr_min = htole16(tmr);
+ req.enables |= htole16(BNXT_COAL_CMPL_MIN_TMR_ENABLE);
+
+ return (hwrm_send_message(softc, &req, sizeof(req)));
+}
+
+int bnxt_hwrm_set_coal(struct bnxt_softc *softc)
+{
+ struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req = {0};
+ int i, rc = 0;
- req = &req_rx;
- req->ring_id = htole16(softc->grp_info[i].cp_ring_id);
+ if (!test_bit(BNXT_STATE_UP, &softc->state))
+ return (rc);
- rc = hwrm_send_message(softc, req, sizeof(*req));
+ bnxt_hwrm_cmd_hdr_init(softc, &req,
+ HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
+ bnxt_hwrm_set_coal_params(softc, &softc->rx_coal, &req);
+
+ for (i = 0; i < softc->nrxqsets; i++) {
+ req.ring_id = htole16(softc->grp_info[i].cp_ring_id);
+
+ rc = hwrm_send_message(softc, &req, sizeof(req));
if (rc)
break;
+
+ if (BNXT_CHIP_P5_PLUS(softc))
+ bnxt_hwrm_set_coal_nq(softc,
+ softc->nq_rings[i].ring.phys_id, &softc->rx_coal);
+ else
+ bnxt_hwrm_set_coal_nq(softc,
+ softc->rx_cp_rings[i].ring.phys_id, &softc->rx_coal);
}
- return rc;
+
+ if (softc->fw_cap & BNXT_FLAG_TX_COAL_CMPL) {
+ struct hwrm_ring_cmpl_ring_cfg_aggint_params_input req_tx = {0};
+
+ bnxt_hwrm_cmd_hdr_init(softc, &req_tx,
+ HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS);
+ bnxt_hwrm_set_coal_params(softc, &softc->tx_coal, &req_tx);
+
+ for (i = 0; i < softc->ntxqsets; i++) {
+ req_tx.ring_id =
+ htole16(softc->tx_cp_rings[i].ring.phys_id);
+
+ rc = hwrm_send_message(softc, &req_tx, sizeof(req_tx));
+ if (rc) {
+ device_printf(softc->dev,
+ "%s: Tx coalesce setting failed for queue %d\n",
+ __func__, i);
+ break;
+ }
+ }
+ }
+
+ return (rc);
}
void bnxt_hwrm_ring_info_get(struct bnxt_softc *softc, uint8_t ring_type,
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
@@ -1606,18 +1606,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_usecs;
+ 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_usecs = val;
+ hw_coal->coal_ticks = val;
rc = bnxt_hwrm_set_coal(softc);
return rc;
@@ -1626,18 +1629,29 @@
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_frames;
+ hw_coal = &softc->rx_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->rx_coal_frames = val;
+ hw_coal->coal_bufs = val * mult;
rc = bnxt_hwrm_set_coal(softc);
return rc;
@@ -1646,18 +1660,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_usecs_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_usecs_irq = val;
+ hw_coal->coal_ticks_irq = val;
rc = bnxt_hwrm_set_coal(softc);
return rc;
@@ -1666,38 +1683,102 @@
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_frames_irq;
+ hw_coal = &softc->rx_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->rx_coal_frames_irq = val;
+ hw_coal->coal_bufs_irq = val * mult;
rc = bnxt_hwrm_set_coal(softc);
return rc;
}
+static int
+bnxt_set_rx_coalesce_mode(SYSCTL_HANDLER_ARGS) {
+ struct bnxt_softc *softc = arg1;
+ struct bnxt_coal_cap *coal_cap;
+ struct bnxt_coal *hw_coal;
+ uint16_t flags;
+ int val;
+ int rc;
+
+ if (softc == NULL)
+ return EBUSY;
+
+ coal_cap = &softc->coal_cap;
+
+ if (coal_cap->cmpl_params &
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_TIMER_RESET) {
+ hw_coal = &softc->rx_coal;
+ flags = hw_coal->flags;
+
+ val = flags & HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
+ rc = sysctl_handle_int(oidp, &val, 0, req);
+ if (rc || !req->newptr)
+ return rc;
+
+ if (val)
+ flags |= HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
+ else
+ flags &= ~HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET;
+
+ hw_coal->flags = flags;
+ rc = bnxt_hwrm_set_coal(softc);
+ return rc;
+ }
+
+ if (coal_cap->cmpl_params &
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_TMR_RESET_ON_ALLOC) {
+ hw_coal = &softc->rx_coal;
+ val = hw_coal->timer_reset_during_ring_alloc;
+ rc = sysctl_handle_int(oidp, &val, 0, req);
+ if (rc || !req->newptr)
+ return rc;
+
+ hw_coal->timer_reset_during_ring_alloc = val ? 1 : 0;
+
+ return rc;
+ }
+
+ return EOPNOTSUPP;
+}
+
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;
@@ -1706,18 +1787,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;
@@ -1726,18 +1818,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;
@@ -1746,18 +1841,50 @@
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;
+
+ 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->tx_coal_frames_irq = val;
+ softc->stats_coal_ticks = val;
rc = bnxt_hwrm_set_coal(softc);
return rc;
@@ -1787,6 +1914,30 @@
return rc;
}
+static int
+bnxt_set_rx_coal_budget(SYSCTL_HANDLER_ARGS) {
+ struct bnxt_softc *softc = arg1;
+ struct bnxt_coal *hw_coal;
+ int rc;
+ int val;
+
+ if (softc == NULL)
+ return EBUSY;
+
+ hw_coal = &softc->rx_coal;
+
+ val = hw_coal->budget;
+
+ rc = sysctl_handle_int(oidp, &val, 0, req);
+ if (rc || !req->newptr)
+ return rc;
+
+ hw_coal->budget = val;
+ rc = bnxt_hwrm_set_coal(softc);
+
+ return rc;
+}
+
static int
bnxt_set_tx_host_coal_bds(SYSCTL_HANDLER_ARGS)
{
@@ -1913,6 +2064,10 @@
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
bnxt_set_coal_rx_frames_irq, "I",
"interrupt coalescing Rx Frames IRQ");
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rx_coalesce_mode",
+ CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
+ bnxt_set_rx_coalesce_mode, "I",
+ "set rx_coalesce_mode 0/1");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_coal_tx_usecs",
CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
bnxt_set_coal_tx_usecs, "I", "interrupt coalescing Tx Usces");
@@ -1927,9 +2082,17 @@
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 | CTLFLAG_MPSAFE, softc, 0,
+ bnxt_set_stats_coal_ticks, "I",
+ "interrupt coalescing stats coal ticks");
SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "cagr_tick_res",
CTLTYPE_INT | CTLFLAG_RDTUN | CTLFLAG_MPSAFE, softc, 0,
bnxt_set_cagr_tick_res, "I", "CAGR tick resolution");
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "intr_rx_coal_budget",
+ CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, softc, 0,
+ bnxt_set_rx_coal_budget, "I",
+ "Rx interrupt coalescing budget");
/*
* Default coal_bds to half the Tx BD ring depth so the forced-
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
@@ -220,6 +220,7 @@
/* Device configuration */
static void bnxt_init(if_ctx_t ctx);
static int bnxt_init_hw(if_ctx_t ctx);
+static void bnxt_init_dflt_coal(struct bnxt_softc *softc);
static void bnxt_stop(if_ctx_t ctx);
static void bnxt_if_led_func(if_ctx_t ctx, int onoff);
static bool bnxt_if_led_supported(if_ctx_t ctx);
@@ -3008,6 +3009,9 @@
scctx->isc_min_frame_size = BNXT_MIN_FRAME_SIZE;
scctx->isc_txrx = &bnxt_txrx;
+ bnxt_hwrm_coal_params_qcaps(softc);
+ bnxt_init_dflt_coal(softc);
+
if (scctx->isc_nrxd[0] <
((scctx->isc_nrxd[1] * 4) + scctx->isc_nrxd[2]))
device_printf(softc->dev,
@@ -3596,6 +3600,49 @@
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;
+
+ coal = &softc->rx_coal;
+ if (coal_cap->cmpl_params &
+ HWRM_RING_AGGINT_QCAPS_OUTPUT_CMPL_PARAMS_TMR_RESET_ON_ALLOC)
+ coal->timer_reset_during_ring_alloc = 1;
+
+ /*
+ * Tick values in microseconds.
+ * 1 coal_buf x bufs_per_record = 1 completion record.
+ */
+ coal->coal_ticks = 6;
+ coal->coal_bufs = 12;
+ coal->coal_ticks_irq = 1;
+ if (BNXT_CHIP_P7(softc))
+ coal->coal_bufs_irq = 4;
+ else
+ coal->coal_bufs_irq = 2;
+ 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)
@@ -3820,6 +3867,8 @@
bnxt_get_port_module_status(softc);
bnxt_media_status(softc->ctx, &ifmr);
bnxt_hwrm_cfa_l2_set_rx_mask(softc, &softc->vnic_info);
+ set_bit(BNXT_STATE_UP, &softc->state);
+ bnxt_hwrm_set_coal(softc);
return (0);
fail:
@@ -3839,6 +3888,7 @@
bnxt_ptp_stop_calibration(softc->ptp_cfg);
softc->rx_ts_enabled = false;
}
+ clear_bit(BNXT_STATE_UP, &softc->state);
softc->is_dev_init = false;
bnxt_do_disable_intr(&softc->def_cp_ring);
bnxt_func_reset(softc);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Nov 11, 6:37 AM (16 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41655052
Default Alt Text
D58621.1794379037.diff (24 KB)
Attached To
Mode
D58621: if_bnxt: rework interrupt coalescing onto the AGGINT_QCAPS scheme
Attached
Detach File
Event Timeline