summaryrefslogtreecommitdiffstats
path: root/sys/dev/sfxge
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2017-02-09 11:26:48 -0200
committerRenato Botelho <renato@netgate.com>2017-02-09 11:26:48 -0200
commit4a05f5440acda223e6a0ec5157bc32ecc0f09ff9 (patch)
tree4c2ece480e5d4155ed35bec62996de40eb179f18 /sys/dev/sfxge
parent681a482d8fc4bfc14a24f7a9d75cca6337f2a520 (diff)
parenta1e52233c91fd46e666297270ab655f1abff8535 (diff)
downloadFreeBSD-src-4a05f5440acda223e6a0ec5157bc32ecc0f09ff9.zip
FreeBSD-src-4a05f5440acda223e6a0ec5157bc32ecc0f09ff9.tar.gz
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'sys/dev/sfxge')
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.c24
-rw-r--r--sys/dev/sfxge/common/efx_mcdi.h2
-rw-r--r--sys/dev/sfxge/sfxge.c14
-rw-r--r--sys/dev/sfxge/sfxge.h3
-rw-r--r--sys/dev/sfxge/sfxge_port.c87
-rw-r--r--sys/dev/sfxge/sfxge_tx.c14
6 files changed, 119 insertions, 25 deletions
diff --git a/sys/dev/sfxge/common/efx_mcdi.c b/sys/dev/sfxge/common/efx_mcdi.c
index e4a918a..4e7ff53 100644
--- a/sys/dev/sfxge/common/efx_mcdi.c
+++ b/sys/dev/sfxge/common/efx_mcdi.c
@@ -1725,7 +1725,8 @@ static __checkReturn efx_rc_t
efx_mcdi_mac_stats(
__in efx_nic_t *enp,
__in_opt efsys_mem_t *esmp,
- __in efx_stats_action_t action)
+ __in efx_stats_action_t action,
+ __in uint16_t period_ms)
{
efx_mcdi_req_t req;
uint8_t payload[MAX(MC_CMD_MAC_STATS_IN_LEN,
@@ -1750,7 +1751,7 @@ efx_mcdi_mac_stats(
MAC_STATS_IN_PERIODIC_CHANGE, enable | events | disable,
MAC_STATS_IN_PERIODIC_ENABLE, enable | events,
MAC_STATS_IN_PERIODIC_NOEVENT, !events,
- MAC_STATS_IN_PERIOD_MS, (enable | events) ? 1000 : 0);
+ MAC_STATS_IN_PERIOD_MS, (enable | events) ? period_ms : 0);
if (esmp != NULL) {
int bytes = MC_CMD_MAC_NSTATS * sizeof (uint64_t);
@@ -1800,7 +1801,7 @@ efx_mcdi_mac_stats_clear(
{
efx_rc_t rc;
- if ((rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_CLEAR)) != 0)
+ if ((rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_CLEAR, 0)) != 0)
goto fail1;
return (0);
@@ -1823,7 +1824,7 @@ efx_mcdi_mac_stats_upload(
* avoid having to pull the statistics buffer into the cache to
* maintain cumulative statistics.
*/
- if ((rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_UPLOAD)) != 0)
+ if ((rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_UPLOAD, 0)) != 0)
goto fail1;
return (0);
@@ -1838,7 +1839,7 @@ fail1:
efx_mcdi_mac_stats_periodic(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp,
- __in uint16_t period,
+ __in uint16_t period_ms,
__in boolean_t events)
{
efx_rc_t rc;
@@ -1847,14 +1848,17 @@ efx_mcdi_mac_stats_periodic(
* The MC DMAs aggregate statistics for our convenience, so we can
* avoid having to pull the statistics buffer into the cache to
* maintain cumulative statistics.
- * Huntington uses a fixed 1sec period, so use that on Siena too.
+ * Huntington uses a fixed 1sec period.
+ * Medford uses a fixed 1sec period before v6.2.1.1033 firmware.
*/
- if (period == 0)
- rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_DISABLE);
+ if (period_ms == 0)
+ rc = efx_mcdi_mac_stats(enp, NULL, EFX_STATS_DISABLE, 0);
else if (events)
- rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_EVENTS);
+ rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_EVENTS,
+ period_ms);
else
- rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_NOEVENTS);
+ rc = efx_mcdi_mac_stats(enp, esmp, EFX_STATS_ENABLE_NOEVENTS,
+ period_ms);
if (rc != 0)
goto fail1;
diff --git a/sys/dev/sfxge/common/efx_mcdi.h b/sys/dev/sfxge/common/efx_mcdi.h
index ffa50f1..ee11789 100644
--- a/sys/dev/sfxge/common/efx_mcdi.h
+++ b/sys/dev/sfxge/common/efx_mcdi.h
@@ -218,7 +218,7 @@ extern __checkReturn efx_rc_t
efx_mcdi_mac_stats_periodic(
__in efx_nic_t *enp,
__in efsys_mem_t *esmp,
- __in uint16_t period,
+ __in uint16_t period_ms,
__in boolean_t events);
diff --git a/sys/dev/sfxge/sfxge.c b/sys/dev/sfxge/sfxge.c
index 8b9edb0..f91275e 100644
--- a/sys/dev/sfxge/sfxge.c
+++ b/sys/dev/sfxge/sfxge.c
@@ -94,14 +94,6 @@ SYSCTL_INT(_hw_sfxge, OID_AUTO, tx_ring, CTLFLAG_RDTUN,
&sfxge_tx_ring_entries, 0,
"Maximum number of descriptors in a transmit ring");
-#define SFXGE_PARAM_STATS_UPDATE_PERIOD SFXGE_PARAM(stats_update_period)
-static int sfxge_stats_update_period = SFXGE_CALLOUT_TICKS;
-TUNABLE_INT(SFXGE_PARAM_STATS_UPDATE_PERIOD,
- &sfxge_stats_update_period);
-SYSCTL_INT(_hw_sfxge, OID_AUTO, stats_update_period, CTLFLAG_RDTUN,
- &sfxge_stats_update_period, 0,
- "netstat interface statistics update period in ticks");
-
#define SFXGE_PARAM_RESTART_ATTEMPTS SFXGE_PARAM(restart_attempts)
static int sfxge_restart_attempts = 3;
TUNABLE_INT(SFXGE_PARAM_RESTART_ATTEMPTS, &sfxge_restart_attempts);
@@ -558,7 +550,8 @@ sfxge_tick(void *arg)
sfxge_port_update_stats(sc);
sfxge_tx_update_stats(sc);
- callout_reset(&sc->tick_callout, sfxge_stats_update_period,
+ callout_reset(&sc->tick_callout,
+ hz * sc->port.stats_update_period_ms / 1000,
sfxge_tick, sc);
}
@@ -623,7 +616,8 @@ sfxge_ifnet_init(struct ifnet *ifp, struct sfxge_softc *sc)
if ((rc = sfxge_port_ifmedia_init(sc)) != 0)
goto fail;
- callout_reset(&sc->tick_callout, sfxge_stats_update_period,
+ callout_reset(&sc->tick_callout,
+ hz * sc->port.stats_update_period_ms / 1000,
sfxge_tick, sc);
return (0);
diff --git a/sys/dev/sfxge/sfxge.h b/sys/dev/sfxge/sfxge.h
index 62b1dc3..1929318 100644
--- a/sys/dev/sfxge/sfxge.h
+++ b/sys/dev/sfxge/sfxge.h
@@ -158,7 +158,7 @@ enum sfxge_evq_state {
#define SFXGE_EV_BATCH 16384
-#define SFXGE_CALLOUT_TICKS 100
+#define SFXGE_STATS_UPDATE_PERIOD_MS 1000
struct sfxge_evq {
/* Structure members below are sorted by usage order */
@@ -247,6 +247,7 @@ struct sfxge_port {
#endif
struct sfxge_hw_stats phy_stats;
struct sfxge_hw_stats mac_stats;
+ uint16_t stats_update_period_ms;
efx_link_mode_t link_mode;
uint8_t mcast_addrs[EFX_MAC_MULTICAST_LIST_MAX *
EFX_MAC_ADDR_LEN];
diff --git a/sys/dev/sfxge/sfxge_port.c b/sys/dev/sfxge/sfxge_port.c
index 6e753a2..edc88ec 100644
--- a/sys/dev/sfxge/sfxge_port.c
+++ b/sys/dev/sfxge/sfxge_port.c
@@ -43,6 +43,15 @@ __FBSDID("$FreeBSD$");
#include "sfxge.h"
+#define SFXGE_PARAM_STATS_UPDATE_PERIOD_MS \
+ SFXGE_PARAM(stats_update_period_ms)
+static int sfxge_stats_update_period_ms = SFXGE_STATS_UPDATE_PERIOD_MS;
+TUNABLE_INT(SFXGE_PARAM_STATS_UPDATE_PERIOD_MS,
+ &sfxge_stats_update_period_ms);
+SYSCTL_INT(_hw_sfxge, OID_AUTO, stats_update_period_ms, CTLFLAG_RDTUN,
+ &sfxge_stats_update_period_ms, 0,
+ "netstat interface statistics update period in milliseconds");
+
static int sfxge_phy_cap_mask(struct sfxge_softc *, int, uint32_t *);
static int
@@ -51,6 +60,7 @@ sfxge_mac_stat_update(struct sfxge_softc *sc)
struct sfxge_port *port = &sc->port;
efsys_mem_t *esmp = &(port->mac_stats.dma_buf);
clock_t now;
+ unsigned int min_ticks;
unsigned int count;
int rc;
@@ -61,8 +71,10 @@ sfxge_mac_stat_update(struct sfxge_softc *sc)
goto out;
}
+ min_ticks = (unsigned int)hz * port->stats_update_period_ms / 1000;
+
now = ticks;
- if ((unsigned int)(now - port->mac_stats.update_time) < (unsigned int)hz) {
+ if ((unsigned int)(now - port->mac_stats.update_time) < min_ticks) {
rc = 0;
goto out;
}
@@ -483,9 +495,10 @@ sfxge_port_start(struct sfxge_softc *sc)
sfxge_mac_filter_set_locked(sc);
- /* Update MAC stats by DMA every second */
+ /* Update MAC stats by DMA every period */
if ((rc = efx_mac_stats_periodic(enp, &port->mac_stats.dma_buf,
- 1000, B_FALSE)) != 0)
+ port->stats_update_period_ms,
+ B_FALSE)) != 0)
goto fail6;
if ((rc = efx_mac_drain(enp, B_FALSE)) != 0)
@@ -642,6 +655,68 @@ sfxge_port_fini(struct sfxge_softc *sc)
port->sc = NULL;
}
+static uint16_t
+sfxge_port_stats_update_period_ms(struct sfxge_softc *sc)
+{
+ int period_ms = sfxge_stats_update_period_ms;
+
+ if (period_ms < 0) {
+ device_printf(sc->dev,
+ "treat negative stats update period %d as 0 (disable)\n",
+ period_ms);
+ period_ms = 0;
+ } else if (period_ms > UINT16_MAX) {
+ device_printf(sc->dev,
+ "treat too big stats update period %d as %u\n",
+ period_ms, UINT16_MAX);
+ period_ms = UINT16_MAX;
+ }
+
+ return period_ms;
+}
+
+static int
+sfxge_port_stats_update_period_ms_handler(SYSCTL_HANDLER_ARGS)
+{
+ struct sfxge_softc *sc;
+ struct sfxge_port *port;
+ unsigned int period_ms;
+ int error;
+
+ sc = arg1;
+ port = &sc->port;
+
+ if (req->newptr != NULL) {
+ error = SYSCTL_IN(req, &period_ms, sizeof(period_ms));
+ if (error != 0)
+ return (error);
+
+ if (period_ms > UINT16_MAX)
+ return (EINVAL);
+
+ SFXGE_PORT_LOCK(port);
+
+ if (port->stats_update_period_ms != period_ms) {
+ if (port->init_state == SFXGE_PORT_STARTED)
+ error = efx_mac_stats_periodic(sc->enp,
+ &port->mac_stats.dma_buf,
+ period_ms, B_FALSE);
+ if (error == 0)
+ port->stats_update_period_ms = period_ms;
+ }
+
+ SFXGE_PORT_UNLOCK(port);
+ } else {
+ SFXGE_PORT_LOCK(port);
+ period_ms = port->stats_update_period_ms;
+ SFXGE_PORT_UNLOCK(port);
+
+ error = SYSCTL_OUT(req, &period_ms, sizeof(period_ms));
+ }
+
+ return (error);
+}
+
int
sfxge_port_init(struct sfxge_softc *sc)
{
@@ -690,8 +765,14 @@ sfxge_port_init(struct sfxge_softc *sc)
M_SFXGE, M_WAITOK | M_ZERO);
if ((rc = sfxge_dma_alloc(sc, EFX_MAC_STATS_SIZE, mac_stats_buf)) != 0)
goto fail2;
+ port->stats_update_period_ms = sfxge_port_stats_update_period_ms(sc);
sfxge_mac_stat_init(sc);
+ SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
+ "stats_update_period_ms", CTLTYPE_UINT|CTLFLAG_RW, sc, 0,
+ sfxge_port_stats_update_period_ms_handler, "IU",
+ "interface statistics refresh period");
+
port->init_state = SFXGE_PORT_INITIALIZED;
DBGPRINT(sc->dev, "success");
diff --git a/sys/dev/sfxge/sfxge_tx.c b/sys/dev/sfxge/sfxge_tx.c
index cc6fb17..d8ccbf1 100644
--- a/sys/dev/sfxge/sfxge_tx.c
+++ b/sys/dev/sfxge/sfxge_tx.c
@@ -356,8 +356,22 @@ static int sfxge_tx_queue_mbuf(struct sfxge_txq *txq, struct mbuf *mbuf)
KASSERT(!txq->blocked, ("txq->blocked"));
+#if SFXGE_TX_PARSE_EARLY
+ /*
+ * If software TSO is used, we still need to copy packet header,
+ * even if we have already parsed it early before enqueue.
+ */
+ if ((mbuf->m_pkthdr.csum_flags & CSUM_TSO) &&
+ (txq->tso_fw_assisted == 0))
+ prefetch_read_many(mbuf->m_data);
+#else
+ /*
+ * Prefetch packet header since we need to parse it and extract
+ * IP ID, TCP sequence number and flags.
+ */
if (mbuf->m_pkthdr.csum_flags & CSUM_TSO)
prefetch_read_many(mbuf->m_data);
+#endif
if (__predict_false(txq->init_state != SFXGE_TXQ_STARTED)) {
rc = EINTR;
OpenPOWER on IntegriCloud