return 0;
}
+int
+sfc_port_reset_mac_stats(struct sfc_adapter *sa)
+{
+ struct sfc_port *port = &sa->port;
+ int rc;
+
+ rte_spinlock_lock(&port->mac_stats_lock);
+ rc = efx_mac_stats_clear(sa->nic);
+ rte_spinlock_unlock(&port->mac_stats_lock);
+
+ return rc;
+}
+
static int
sfc_port_init_dev_link(struct sfc_adapter *sa)
{
{
struct sfc_port *port = &sa->port;
int rc;
+ uint32_t phy_adv_cap;
+ const uint32_t phy_pause_caps =
+ ((1u << EFX_PHY_CAP_PAUSE) | (1u << EFX_PHY_CAP_ASYM));
sfc_log_init(sa, "entry");
if (rc != 0)
goto fail_mac_fcntl_set;
- sfc_log_init(sa, "set phy adv caps to %#x", port->phy_adv_cap);
- rc = efx_phy_adv_cap_set(sa->nic, port->phy_adv_cap);
+ /* Preserve pause capabilities set by above efx_mac_fcntl_set() */
+ efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_CURRENT, &phy_adv_cap);
+ SFC_ASSERT((port->phy_adv_cap & phy_pause_caps) == 0);
+ phy_adv_cap = port->phy_adv_cap | (phy_adv_cap & phy_pause_caps);
+
+ sfc_log_init(sa, "set phy adv caps to %#x", phy_adv_cap);
+ rc = efx_phy_adv_cap_set(sa->nic, phy_adv_cap);
if (rc != 0)
goto fail_phy_adv_cap_set;
if (rc != 0)
goto fail_mac_filter_set;
+ if (port->mac_stats_reset_pending) {
+ rc = sfc_port_reset_mac_stats(sa);
+ if (rc != 0)
+ sfc_err(sa, "statistics reset failed (requested "
+ "before the port was started)");
+
+ port->mac_stats_reset_pending = B_FALSE;
+ }
+
efx_mac_stats_get_mask(sa->nic, port->mac_stats_mask,
sizeof(port->mac_stats_mask));
if (rc != 0)
goto fail_mac_stats_dma_alloc;
+ port->mac_stats_reset_pending = B_FALSE;
+
sfc_log_init(sa, "done");
return 0;