From 46464b95b0597d42d579f48b5f0b99fc8ab112d0 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Tue, 7 Jun 2016 00:27:55 +0000 Subject: [PATCH] cxgbe(4): Track the state of the hardware traffic schedulers in the driver. This works as long as everyone uses set_sched_class_params to program them. Sponsored by: Chelsio Communications --- sys/dev/cxgbe/adapter.h | 14 ++++++++++++++ sys/dev/cxgbe/t4_main.c | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h index 5800faa51500..1fd2a1531e36 100644 --- a/sys/dev/cxgbe/adapter.h +++ b/sys/dev/cxgbe/adapter.h @@ -54,6 +54,7 @@ #include #include "offload.h" +#include "t4_ioctl.h" #include "common/t4_msg.h" #include "firmware/t4fw_interface.h" @@ -264,6 +265,17 @@ struct vi_info { uint8_t hw_addr[ETHER_ADDR_LEN]; /* factory MAC address, won't change */ }; +enum { + /* tx_sched_class flags */ + TX_SC_OK = (1 << 0), /* Set up in hardware, active. */ +}; + +struct tx_sched_class { + int refcount; + int flags; + struct t4_sched_class_params params; +}; + struct port_info { device_t dev; struct adapter *adapter; @@ -273,6 +285,8 @@ struct port_info { int up_vis; int uld_vis; + struct tx_sched_class *tc; /* traffic classes for this channel */ + struct mtx pi_lock; char lockname[16]; unsigned long flags; diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 2cb565c9d83b..6d0f0359d12b 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -875,6 +875,9 @@ t4_attach(device_t dev) mtx_init(&pi->pi_lock, pi->lockname, 0, MTX_DEF); sc->chan_map[pi->tx_chan] = i; + pi->tc = malloc(sizeof(struct tx_sched_class) * + sc->chip_params->nsched_cls, M_CXGBE, M_ZERO | M_WAITOK); + if (is_10G_port(pi) || is_40G_port(pi)) { n10g++; for_each_vi(pi, j, vi) { @@ -1131,6 +1134,7 @@ t4_detach(device_t dev) mtx_destroy(&pi->pi_lock); free(pi->vi, M_CXGBE); + free(pi->tc, M_CXGBE); free(pi, M_CXGBE); } } @@ -8319,6 +8323,7 @@ set_sched_class_params(struct adapter *sc, struct t4_sched_class_params *p, { int rc, top_speed, fw_level, fw_mode, fw_rateunit, fw_ratemode; struct port_info *pi; + struct tx_sched_class *tc; if (p->level == SCHED_CLASS_LEVEL_CL_RL) fw_level = FW_SCHED_PARAMS_LEVEL_CL_RL; @@ -8401,9 +8406,20 @@ set_sched_class_params(struct adapter *sc, struct t4_sched_class_params *p, sleep_ok ? (SLEEP_OK | INTR_OK) : HOLD_LOCK, "t4sscp"); if (rc) return (rc); + tc = &pi->tc[p->cl]; + tc->params = *p; rc = -t4_sched_params(sc, FW_SCHED_TYPE_PKTSCHED, fw_level, fw_mode, fw_rateunit, fw_ratemode, p->channel, p->cl, p->minrate, p->maxrate, p->weight, p->pktsize, sleep_ok); + if (rc == 0) + tc->flags |= TX_SC_OK; + else { + /* + * Unknown state at this point, see tc->params for what was + * attempted. + */ + tc->flags &= ~TX_SC_OK; + } end_synchronized_op(sc, sleep_ok ? 0 : LOCK_HELD); return (rc);