Page MenuHomeFreeBSD

D58599.id184629.diff
No OneTemporary

D58599.id184629.diff

Index: sys/dev/bnxt/bnxt_en/bnxt.h
===================================================================
--- sys/dev/bnxt/bnxt_en/bnxt.h
+++ sys/dev/bnxt/bnxt_en/bnxt.h
@@ -615,6 +615,7 @@
u32 db_key32;
};
uint32_t db_ring_mask;
+ uint32_t free_flow_cons; /* HW TX-completion-coalescing SQ consumer */
uint32_t db_epoch_mask;
uint8_t db_epoch_shift;
@@ -1321,6 +1322,7 @@
#define BNXT_FW_CAP_CFA_NTUPLE_RX_EXT_IP_PROTO BIT_ULL(47)
#define BNXT_FW_CAP_ENABLE_RDMA_SRIOV BIT_ULL(48)
#define BNXT_FW_CAP_RSS_TCAM BIT_ULL(49)
+ #define BNXT_FLAG_TX_COAL_CMPL BIT_ULL(51)
#define BNXT_FW_CAP_SW_MAX_RESOURCE_LIMITS BIT_ULL(61)
#define BNXT_SW_RES_LMT(bp) ((bp)->fw_cap & BNXT_FW_CAP_SW_MAX_RESOURCE_LIMITS)
@@ -1431,6 +1433,16 @@
#define BNXT_CAGR_TICK_RES_MAX 0x4
#define BNXT_CAGR_TICK_RES_OFFSET 16
uint32_t cagr_tick_res;
+ /*
+ * HW-based TX coalescing: firmware coalesces completions autonomously
+ * based on cmpl_coal_cnt set in HWRM_RING_ALLOC.
+ * Raw firmware code: 0=off, 1=4, 2=8, 3=12, 4=16, 5=24, 6=32, 7=48,
+ * 8=64, 9=96, 10=128, 11=192, 12=256, 13=320, 14=384, 15=MAX.
+ * Only valid when BNXT_FLAG_TX_COAL_CMPL firmware capability is set.
+ */
+#define BNXT_TX_HW_COAL_CNT_DEFAULT \
+ HWRM_RING_ALLOC_INPUT_CMPL_COAL_CNT_COAL_64 /* code 8 = up to 64 pkts */
+ uint8_t tx_hw_coal_cnt;
};
struct bnxt_filter_info {
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
@@ -1278,6 +1278,8 @@
if (BNXT_PF(softc) &&
(flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_VF_CFG_ASYNC_FOR_PF_SUPPORTED))
softc->fw_cap |= BNXT_FW_CAP_VF_CFG_FOR_PF;
+ if (flags_ext & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_TX_COAL_CMPL_CAP)
+ softc->fw_cap |= BNXT_FLAG_TX_COAL_CMPL;
flags_ext2 = htole32(resp->flags_ext2);
if (flags_ext2 & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT2_RX_ALL_PKTS_TIMESTAMPS_SUPPORTED)
@@ -1984,6 +1986,8 @@
req.stat_ctx_id = htole32(cp_ring->stats_ctx_id);
req.enables |= htole32(
HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID);
+ if (softc->fw_cap & BNXT_FLAG_TX_COAL_CMPL)
+ req.cmpl_coal_cnt = softc->tx_hw_coal_cnt;
break;
case HWRM_RING_ALLOC_INPUT_RING_TYPE_RX:
if (!BNXT_CHIP_P5_PLUS(softc))
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
@@ -1580,6 +1580,30 @@
return rc;
}
+static int
+bnxt_set_tx_hw_coal_cnt(SYSCTL_HANDLER_ARGS)
+{
+ struct bnxt_softc *softc = arg1;
+ uint32_t val;
+ int rc;
+
+ if (softc == NULL)
+ return EBUSY;
+
+ val = softc->tx_hw_coal_cnt;
+
+ rc = sysctl_handle_int(oidp, (int *)&val, 0, req);
+ if (rc || !req->newptr)
+ return rc;
+
+ if (val > HWRM_RING_ALLOC_INPUT_CMPL_COAL_CNT_LAST)
+ return EINVAL;
+
+ softc->tx_hw_coal_cnt = (uint8_t)val;
+
+ return 0;
+}
+
static
void simulate_reset(struct bnxt_softc *bp, char *fwcli_string)
{
@@ -1675,6 +1699,15 @@
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");
+
+ softc->tx_hw_coal_cnt = BNXT_TX_HW_COAL_CNT_DEFAULT;
+ SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_hw_coal_cnt",
+ CTLTYPE_INT | CTLFLAG_RDTUN | CTLFLAG_MPSAFE, softc, 0,
+ bnxt_set_tx_hw_coal_cnt, "I",
+ "HW-driven TX coalesced-completion packet count code for ring_alloc "
+ "(0=off 1=4 2=8 3=12 4=16 5=24 6=32 7=48 8=64[default] "
+ "9=96 10=128 11=192 12=256 13=320 14=384 15=MAX; "
+ "requires BNXT_FLAG_TX_COAL_CMPL firmware capability)");
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/bnxt_txrx.c
===================================================================
--- sys/dev/bnxt/bnxt_en/bnxt_txrx.c
+++ sys/dev/bnxt/bnxt_en/bnxt_txrx.c
@@ -225,6 +225,7 @@
struct bnxt_softc *softc = (struct bnxt_softc *)sc;
struct bnxt_cp_ring *cpr = &softc->tx_cp_rings[txqid];
struct tx_cmpl *cmpl = (struct tx_cmpl *)cpr->ring.vaddr;
+ struct bnxt_ring *txr;
int avail = 0;
uint32_t cons = cpr->cons;
uint32_t raw_cons = cpr->raw_cons;
@@ -266,6 +267,42 @@
if (!clear)
goto done;
break;
+ case TX_CMPL_COAL_TYPE_TX_L2_COAL:
+ if (softc->fw_cap & BNXT_FLAG_TX_COAL_CMPL) {
+ tx_cmpl_coal_t *cmpl_coal = (tx_cmpl_coal_t *)cmpl;
+ uint32_t sq_cons;
+
+ err = (le16toh(cmpl_coal[cons].errors_v) &
+ TX_CMPL_COAL_ERRORS_BUFFER_ERROR_MASK) >>
+ TX_CMPL_COAL_ERRORS_BUFFER_ERROR_SFT;
+ if (err)
+ device_printf(softc->dev,
+ "TX completion error %u\n", err);
+
+ sq_cons = le32toh(cmpl_coal[cons].sq_cons_idx) &
+ TX_CMPL_COAL_SQ_CONS_IDX_MASK;
+
+ txr = &softc->tx_rings[txqid];
+ avail += (sq_cons - txr->free_flow_cons) &
+ txr->db_ring_mask;
+
+ /*
+ * Only the consuming (clear) pass may advance
+ * free_flow_cons: the interrupt filter's peek
+ * calls (clear == false) must not claim SQ
+ * entries iflib hasn't actually reclaimed yet,
+ * or the mbufs there get orphaned and this
+ * completion's credits are lost for good the
+ * next time around. Gating the write on clear
+ * also means only the gtaskq ever writes this
+ * field, so no atomics are needed.
+ */
+ if (!clear)
+ goto done;
+ txr->free_flow_cons = sq_cons;
+ break;
+ }
+ /* FALLTHROUGH */
default:
if (type & 1) {
NEXT_CP_CONS_V(&cpr->ring, cons, v_bit);
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
@@ -3509,6 +3509,7 @@
HWRM_RING_ALLOC_INPUT_RING_TYPE_TX);
if (rc)
goto fail;
+ softc->tx_rings[i].free_flow_cons = 0;
softc->db_ops.bnxt_db_tx(&softc->tx_rings[i], 0);
}

File Metadata

Mime Type
text/plain
Expires
Sat, Sep 12, 4:14 AM (17 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38723868
Default Alt Text
D58599.id184629.diff (5 KB)

Event Timeline