From patchwork Tue May 12 19:23:07 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Lendacky X-Patchwork-Id: 471520 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 7C221140A99 for ; Wed, 13 May 2015 05:47:04 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933643AbbELTh7 (ORCPT ); Tue, 12 May 2015 15:37:59 -0400 Received: from mail-bn1on0131.outbound.protection.outlook.com ([157.56.110.131]:3296 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S933456AbbELThw (ORCPT ); Tue, 12 May 2015 15:37:52 -0400 X-Greylist: delayed 885 seconds by postgrey-1.27 at vger.kernel.org; Tue, 12 May 2015 15:37:51 EDT Received: from BY2PR02CA0033.namprd02.prod.outlook.com (10.141.216.23) by CO1PR02MB077.namprd02.prod.outlook.com (10.242.164.11) with Microsoft SMTP Server (TLS) id 15.1.154.19; Tue, 12 May 2015 19:23:10 +0000 Received: from BL2FFO11FD030.protection.gbl (2a01:111:f400:7c09::181) by BY2PR02CA0033.outlook.office365.com (2a01:111:e400:2c40::23) with Microsoft SMTP Server (TLS) id 15.1.160.19 via Frontend Transport; Tue, 12 May 2015 19:23:10 +0000 Authentication-Results: spf=none (sender IP is 165.204.84.221) smtp.mailfrom=amd.com; davemloft.net; dkim=none (message not signed) header.d=none; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) Received: from atltwp01.amd.com (165.204.84.221) by BL2FFO11FD030.mail.protection.outlook.com (10.173.161.40) with Microsoft SMTP Server id 15.1.160.8 via Frontend Transport; Tue, 12 May 2015 19:23:09 +0000 X-WSS-ID: 0NO94IK-07-832-02 X-M-MSG: Received: from satlvexedge01.amd.com (satlvexedge01.amd.com [10.177.96.28]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by atltwp01.amd.com (Axway MailGate 5.3.1) with ESMTPS id 2D494CAE666; Tue, 12 May 2015 15:23:07 -0400 (EDT) Received: from SATLEXDAG01.amd.com (10.181.40.3) by satlvexedge01.amd.com (10.177.96.28) with Microsoft SMTP Server (TLS) id 14.3.195.1; Tue, 12 May 2015 14:23:10 -0500 Received: from tlendack-t1.amdoffice.net (10.180.168.240) by SATLEXDAG01.amd.com (10.181.40.3) with Microsoft SMTP Server id 14.3.195.1; Tue, 12 May 2015 15:23:06 -0400 Subject: [PATCH net-next v1 6/7] amd-xgbe: Fix flow control setting logic From: Tom Lendacky To: CC: David Miller Date: Tue, 12 May 2015 14:23:07 -0500 Message-ID: <20150512192307.14091.14343.stgit@tlendack-t1.amdoffice.net> In-Reply-To: <20150512192229.14091.34354.stgit@tlendack-t1.amdoffice.net> References: <20150512192229.14091.34354.stgit@tlendack-t1.amdoffice.net> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11FD030; 1:rdG3n9dLoZBc7w7Flo1ig/GfccvDGJOdsqLxr6N8JScZrs0I9vWYqEAfe2bHxKfFjzRfi0eV6keAARSkv8lt9dZCIncZnzk5BhST4uoPXtgJu7r7KeGWGh14biKh54oQUev3oGNbtnq4ecfqLp9rqejzth5IJAsUcE2BQZ3F8i6lZSsl2thtw9kxap5TFj1dDbD4jz745bbEeOoyPESrWtmvNamL1IbhStBq9svbIvXoIRd3cC+uSxeDGLYXn9PpQ6AXOR+AS5HyuJ9eUIcmrHAJPI4A7pmp/8izNJtQsSrX/NcQ1Npp73wn9kSR35Py X-Forefront-Antispam-Report: CIP:165.204.84.221; CTRY:US; IPV:NLI; EFV:NLI; SFV:NSPM; SFS:(10019020)(6009001)(428002)(189002)(199003)(101416001)(76176999)(54356999)(53416004)(50986999)(229853001)(33646002)(2351001)(105586002)(46102003)(106466001)(86362001)(77096005)(19580395003)(19580405001)(83506001)(47776003)(62966003)(77156002)(23676002)(87936001)(4001350100001)(2950100001)(92566002)(103116003)(97746001)(189998001)(50466002)(110136002)(71626005); DIR:OUT; SFP:1102; SCL:1; SRVR:CO1PR02MB077; H:atltwp01.amd.com; FPR:; SPF:None; MLV:sfv; MX:1; A:1; LANG:en; X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CO1PR02MB077; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5005006)(3002001); SRVR:CO1PR02MB077; BCL:0; PCL:0; RULEID:; SRVR:CO1PR02MB077; X-Forefront-PRVS: 0574D4712B X-OriginatorOrg: amd4.onmicrosoft.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 May 2015 19:23:09.7334 (UTC) X-MS-Exchange-CrossTenant-Id: fde4dada-be84-483f-92cc-e026cbee8e96 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=fde4dada-be84-483f-92cc-e026cbee8e96; Ip=[165.204.84.221]; Helo=[atltwp01.amd.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO1PR02MB077 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The flow control negotiation logic is flawed and does not properly advertise and process auto-negotiation of the flow control settings. Update the flow control support to properly set the flow control auto-negotiation settings and process the results approrpriately. Signed-off-by: Tom Lendacky --- drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 2 - drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c | 29 ++++++---- drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 73 ++++++++++++++++++-------- drivers/net/ethernet/amd/xgbe/xgbe.h | 8 +-- 4 files changed, 72 insertions(+), 40 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index 637b6c9..99a4c12 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -787,8 +787,6 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) { pdata->phy_link = -1; pdata->phy_speed = SPEED_UNKNOWN; - pdata->phy_tx_pause = pdata->tx_pause; - pdata->phy_rx_pause = pdata->rx_pause; return pdata->phy_if.phy_reset(pdata); } diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c index b24a78c3..59e090e 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c @@ -247,9 +247,9 @@ static void xgbe_get_pauseparam(struct net_device *netdev, DBGPR("-->xgbe_get_pauseparam\n"); - pause->autoneg = pdata->pause_autoneg; - pause->tx_pause = pdata->tx_pause; - pause->rx_pause = pdata->rx_pause; + pause->autoneg = pdata->phy.pause_autoneg; + pause->tx_pause = pdata->phy.tx_pause; + pause->rx_pause = pdata->phy.rx_pause; DBGPR("<--xgbe_get_pauseparam\n"); } @@ -265,19 +265,24 @@ static int xgbe_set_pauseparam(struct net_device *netdev, DBGPR(" autoneg = %d, tx_pause = %d, rx_pause = %d\n", pause->autoneg, pause->tx_pause, pause->rx_pause); - pdata->pause_autoneg = pause->autoneg; - if (pause->autoneg) { - pdata->phy.advertising |= ADVERTISED_Pause; - pdata->phy.advertising |= ADVERTISED_Asym_Pause; + if (pause->autoneg && (pdata->phy.autoneg != AUTONEG_ENABLE)) + return -EINVAL; + + pdata->phy.pause_autoneg = pause->autoneg; + pdata->phy.tx_pause = pause->tx_pause; + pdata->phy.rx_pause = pause->rx_pause; - } else { - pdata->phy.advertising &= ~ADVERTISED_Pause; - pdata->phy.advertising &= ~ADVERTISED_Asym_Pause; + pdata->phy.advertising &= ~ADVERTISED_Pause; + pdata->phy.advertising &= ~ADVERTISED_Asym_Pause; - pdata->tx_pause = pause->tx_pause; - pdata->rx_pause = pause->rx_pause; + if (pause->rx_pause) { + pdata->phy.advertising |= ADVERTISED_Pause; + pdata->phy.advertising |= ADVERTISED_Asym_Pause; } + if (pause->tx_pause) + pdata->phy.advertising ^= ADVERTISED_Asym_Pause; + if (netif_running(netdev)) ret = pdata->phy_if.phy_config_aneg(pdata); diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c index 1ae4bfb..cea19a3 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c @@ -737,6 +737,18 @@ static void xgbe_an_init(struct xgbe_prv_data *pdata) XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg); } +static const char *xgbe_phy_fc_string(struct xgbe_prv_data *pdata) +{ + if (pdata->tx_pause && pdata->rx_pause) + return "rx/tx"; + else if (pdata->rx_pause) + return "rx"; + else if (pdata->tx_pause) + return "tx"; + else + return "off"; +} + static const char *xgbe_phy_speed_string(int speed) { switch (speed) { @@ -760,7 +772,7 @@ static void xgbe_phy_print_status(struct xgbe_prv_data *pdata) "Link is Up - %s/%s - flow control %s\n", xgbe_phy_speed_string(pdata->phy.speed), pdata->phy.duplex == DUPLEX_FULL ? "Full" : "Half", - pdata->phy.pause ? "rx/tx" : "off"); + xgbe_phy_fc_string(pdata)); else netdev_info(pdata->netdev, "Link is Down\n"); } @@ -771,24 +783,18 @@ static void xgbe_phy_adjust_link(struct xgbe_prv_data *pdata) if (pdata->phy.link) { /* Flow control support */ - if (pdata->pause_autoneg) { - if (pdata->phy.pause || pdata->phy.asym_pause) { - pdata->tx_pause = 1; - pdata->rx_pause = 1; - } else { - pdata->tx_pause = 0; - pdata->rx_pause = 0; - } - } + pdata->pause_autoneg = pdata->phy.pause_autoneg; - if (pdata->tx_pause != pdata->phy_tx_pause) { + if (pdata->tx_pause != pdata->phy.tx_pause) { + new_state = 1; pdata->hw_if.config_tx_flow_control(pdata); - pdata->phy_tx_pause = pdata->tx_pause; + pdata->tx_pause = pdata->phy.tx_pause; } - if (pdata->rx_pause != pdata->phy_rx_pause) { + if (pdata->rx_pause != pdata->phy.rx_pause) { + new_state = 1; pdata->hw_if.config_rx_flow_control(pdata); - pdata->phy_rx_pause = pdata->rx_pause; + pdata->rx_pause = pdata->phy.rx_pause; } /* Speed support */ @@ -835,9 +841,6 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata) if (pdata->phy.duplex != DUPLEX_FULL) return -EINVAL; - pdata->phy.pause = 0; - pdata->phy.asym_pause = 0; - return 0; } @@ -933,8 +936,6 @@ static void xgbe_phy_status_force(struct xgbe_prv_data *pdata) } } pdata->phy.duplex = DUPLEX_FULL; - pdata->phy.pause = 0; - pdata->phy.asym_pause = 0; } static void xgbe_phy_status_aneg(struct xgbe_prv_data *pdata) @@ -957,9 +958,21 @@ static void xgbe_phy_status_aneg(struct xgbe_prv_data *pdata) if (lp_reg & 0x800) pdata->phy.lp_advertising |= ADVERTISED_Asym_Pause; - ad_reg &= lp_reg; - pdata->phy.pause = (ad_reg & 0x400) ? 1 : 0; - pdata->phy.asym_pause = (ad_reg & 0x800) ? 1 : 0; + if (pdata->phy.pause_autoneg) { + /* Set flow control based on auto-negotiation result */ + pdata->phy.tx_pause = 0; + pdata->phy.rx_pause = 0; + + if (ad_reg & lp_reg & 0x400) { + pdata->phy.tx_pause = 1; + pdata->phy.rx_pause = 1; + } else if (ad_reg & lp_reg & 0x800) { + if (ad_reg & 0x400) + pdata->phy.rx_pause = 1; + else if (lp_reg & 0x400) + pdata->phy.tx_pause = 1; + } + } /* Compare Advertisement and Link Partner register 2 */ ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE + 1); @@ -1223,6 +1236,22 @@ static void xgbe_phy_init(struct xgbe_prv_data *pdata) pdata->phy.link = 0; + pdata->phy.pause_autoneg = pdata->pause_autoneg; + pdata->phy.tx_pause = pdata->tx_pause; + pdata->phy.rx_pause = pdata->rx_pause; + + /* Fix up Flow Control advertising */ + pdata->phy.advertising &= ~ADVERTISED_Pause; + pdata->phy.advertising &= ~ADVERTISED_Asym_Pause; + + if (pdata->rx_pause) { + pdata->phy.advertising |= ADVERTISED_Pause; + pdata->phy.advertising |= ADVERTISED_Asym_Pause; + } + + if (pdata->tx_pause) + pdata->phy.advertising ^= ADVERTISED_Asym_Pause; + if (netif_msg_drv(pdata)) xgbe_dump_phy_registers(pdata); } diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index f535d19..63d72a1 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -539,10 +539,12 @@ struct xgbe_phy { int autoneg; int speed; int duplex; - int pause; - int asym_pause; int link; + + int pause_autoneg; + int tx_pause; + int rx_pause; }; struct xgbe_mmc_stats { @@ -910,8 +912,6 @@ struct xgbe_prv_data { phy_interface_t phy_mode; int phy_link; int phy_speed; - unsigned int phy_tx_pause; - unsigned int phy_rx_pause; /* MDIO/PHY related settings */ struct xgbe_phy phy;