summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornp <np@FreeBSD.org>2015-02-24 18:40:10 +0000
committernp <np@FreeBSD.org>2015-02-24 18:40:10 +0000
commita440d3c6946f1e8915cdd335eb020896cf1c57b4 (patch)
tree7142e7be3e4f7d45ea3686d3d09913cbd2d59d1a
parent7fa70f2f6509b633511f2e20b1eb1a0163321594 (diff)
downloadFreeBSD-src-a440d3c6946f1e8915cdd335eb020896cf1c57b4.zip
FreeBSD-src-a440d3c6946f1e8915cdd335eb020896cf1c57b4.tar.gz
cxgbe(4): set up congestion management for netmap rx queues.
The hw.cxgbe.cong_drop knob controls the response of the chip when netmap queues are congested.
-rw-r--r--sys/dev/cxgbe/adapter.h1
-rw-r--r--sys/dev/cxgbe/t4_netmap.c39
-rw-r--r--sys/dev/cxgbe/t4_sge.c2
3 files changed, 38 insertions, 4 deletions
diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h
index 31e8f39..2655dae 100644
--- a/sys/dev/cxgbe/adapter.h
+++ b/sys/dev/cxgbe/adapter.h
@@ -1030,6 +1030,7 @@ void t4_update_fl_bufsize(struct ifnet *);
int parse_pkt(struct mbuf **);
void *start_wrq_wr(struct sge_wrq *, int, struct wrq_cookie *);
void commit_wrq_wr(struct sge_wrq *, void *, struct wrq_cookie *);
+int tnl_cong(struct port_info *);
/* t4_tracer.c */
struct t4_tracer;
diff --git a/sys/dev/cxgbe/t4_netmap.c b/sys/dev/cxgbe/t4_netmap.c
index 1f97b9b..c0bdfe3 100644
--- a/sys/dev/cxgbe/t4_netmap.c
+++ b/sys/dev/cxgbe/t4_netmap.c
@@ -226,9 +226,9 @@ cxgbe_nm_qflush(struct ifnet *ifp)
}
static int
-alloc_nm_rxq_hwq(struct port_info *pi, struct sge_nm_rxq *nm_rxq)
+alloc_nm_rxq_hwq(struct port_info *pi, struct sge_nm_rxq *nm_rxq, int cong)
{
- int rc, cntxt_id;
+ int rc, cntxt_id, i;
__be32 v;
struct adapter *sc = pi->adapter;
struct netmap_adapter *na = NA(pi->nm_ifp);
@@ -267,6 +267,11 @@ alloc_nm_rxq_hwq(struct port_info *pi, struct sge_nm_rxq *nm_rxq)
V_FW_IQ_CMD_IQESIZE(ilog2(IQ_ESIZE) - 4));
c.iqsize = htobe16(pi->qsize_rxq);
c.iqaddr = htobe64(nm_rxq->iq_ba);
+ if (cong >= 0) {
+ c.iqns_to_fl0congen = htobe32(F_FW_IQ_CMD_IQFLINTCONGEN |
+ V_FW_IQ_CMD_FL0CNGCHMAP(cong) | F_FW_IQ_CMD_FL0CONGCIF |
+ F_FW_IQ_CMD_FL0CONGEN);
+ }
c.iqns_to_fl0congen |=
htobe32(V_FW_IQ_CMD_FL0HOSTFCMODE(X_HOSTFCMODE_NONE) |
F_FW_IQ_CMD_FL0FETCHRO | F_FW_IQ_CMD_FL0DATARO |
@@ -310,6 +315,34 @@ alloc_nm_rxq_hwq(struct port_info *pi, struct sge_nm_rxq *nm_rxq)
if (is_t5(sc))
nm_rxq->fl_db_val |= F_DBTYPE;
+ if (is_t5(sc) && cong >= 0) {
+ uint32_t param, val;
+
+ param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) |
+ V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_CONM_CTXT) |
+ V_FW_PARAMS_PARAM_YZ(nm_rxq->iq_cntxt_id);
+ param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DMAQ) |
+ V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DMAQ_CONM_CTXT) |
+ V_FW_PARAMS_PARAM_YZ(nm_rxq->iq_cntxt_id);
+ if (cong == 0)
+ val = 1 << 19;
+ else {
+ val = 2 << 19;
+ for (i = 0; i < 4; i++) {
+ if (cong & (1 << i))
+ val |= 1 << (i << 2);
+ }
+ }
+
+ rc = -t4_set_params(sc, sc->mbox, sc->pf, 0, 1, &param, &val);
+ if (rc != 0) {
+ /* report error but carry on */
+ device_printf(sc->dev,
+ "failed to set congestion manager context for "
+ "ingress queue %d: %d\n", nm_rxq->iq_cntxt_id, rc);
+ }
+ }
+
t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS),
V_SEINTARM(V_QINTR_TIMER_IDX(1)) |
V_INGRESSQID(nm_rxq->iq_cntxt_id));
@@ -450,7 +483,7 @@ cxgbe_netmap_on(struct adapter *sc, struct port_info *pi, struct ifnet *ifp,
nm_set_native_flags(na);
for_each_nm_rxq(pi, i, nm_rxq) {
- alloc_nm_rxq_hwq(pi, nm_rxq);
+ alloc_nm_rxq_hwq(pi, nm_rxq, tnl_cong(pi));
nm_rxq->fl_hwidx = hwidx;
slot = netmap_reset(na, NR_RX, i, 0);
MPASS(slot != NULL); /* XXXNM: error check, not assert */
diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c
index 05eca21..da26af2 100644
--- a/sys/dev/cxgbe/t4_sge.c
+++ b/sys/dev/cxgbe/t4_sge.c
@@ -2912,7 +2912,7 @@ free_mgmtq(struct adapter *sc)
return free_wrq(sc, &sc->sge.mgmtq);
}
-static inline int
+int
tnl_cong(struct port_info *pi)
{
OpenPOWER on IntegriCloud