From: Andrew Rybchenko <arybchenko@solarflare.com>
Date: Thu, 12 Jan 2017 09:03:23 +0000 (+0000)
Subject: net/sfc: fix flow control settings on port start
X-Git-Tag: spdx-start~4626
X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=0e7449cabc318e262d2f3e1cc75db76b706aeb67;p=dpdk.git

net/sfc: fix flow control settings on port start

efx_phy_adv_cap_set() sets all advertised phy capabilities including
pause capabilities which are also configured using efx_mac_fcntl_set().

If we set speed and autonegotiation capabilities only, we should
preserve already configured pause capabilities.

Fixes: d23f3a89ab54 ("net/sfc: support link speed and duplex settings")

Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andrew Lee <alee@solarflare.com>
---

diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index e2d85443bb..5998a9904f 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -87,6 +87,9 @@ sfc_port_start(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");
 
@@ -107,8 +110,13 @@ sfc_port_start(struct sfc_adapter *sa)
 	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;