boolean_t mac_stats_reset_pending;
uint16_t mac_stats_update_period_ms;
uint32_t mac_stats_update_generation;
+ boolean_t mac_stats_periodic_dma_supported;
+ uint64_t mac_stats_last_request_timestamp;
uint32_t mac_stats_mask[EFX_MAC_STATS_MASK_NPAGES];
};
/* Just for symmetry of the API */
}
+/** Get the number of milliseconds since boot from the default timer */
+static inline uint64_t
+sfc_get_system_msecs(void)
+{
+ return rte_get_timer_cycles() * MS_PER_S / rte_get_timer_hz();
+}
+
int sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id,
size_t len, int socket_id, efsys_mem_t *esmp);
void sfc_dma_free(const struct sfc_adapter *sa, efsys_mem_t *esmp);
if (sa->state != SFC_ADAPTER_STARTED)
return EINVAL;
- /* If periodic statistics DMA'ing is off, request explicitly */
- if (port->mac_stats_update_period_ms == 0) {
+ /*
+ * If periodic statistics DMA'ing is off or if not supported,
+ * make a manual request and keep an eye on timer if need be
+ */
+ if (!port->mac_stats_periodic_dma_supported ||
+ (port->mac_stats_update_period_ms == 0)) {
+ if (port->mac_stats_update_period_ms != 0) {
+ uint64_t timestamp = sfc_get_system_msecs();
+
+ if ((timestamp -
+ port->mac_stats_last_request_timestamp) <
+ port->mac_stats_update_period_ms)
+ return 0;
+
+ port->mac_stats_last_request_timestamp = timestamp;
+ }
+
rc = efx_mac_stats_upload(sa->nic, esmp);
if (rc != 0)
return rc;
rc = efx_mac_stats_periodic(sa->nic, &port->mac_stats_dma_mem,
port->mac_stats_update_period_ms,
B_FALSE);
- if (rc != 0)
+ if (rc == 0) {
+ port->mac_stats_periodic_dma_supported = B_TRUE;
+ } else if (rc == EOPNOTSUPP) {
+ port->mac_stats_periodic_dma_supported = B_FALSE;
+ port->mac_stats_last_request_timestamp = 0;
+ } else {
goto fail_mac_stats_periodic;
+ }
}
sfc_log_init(sa, "disable MAC drain");