From patchwork Mon Nov 10 19:18:35 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Hill X-Patchwork-Id: 409042 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 E6FB31400E2 for ; Tue, 11 Nov 2014 06:18:42 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751412AbaKJTSi (ORCPT ); Mon, 10 Nov 2014 14:18:38 -0500 Received: from mail-ie0-f174.google.com ([209.85.223.174]:63886 "EHLO mail-ie0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751282AbaKJTSh (ORCPT ); Mon, 10 Nov 2014 14:18:37 -0500 Received: by mail-ie0-f174.google.com with SMTP id x19so9625712ier.5 for ; Mon, 10 Nov 2014 11:18:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:message-id:date:user-agent:mime-version:to :subject:content-type:content-transfer-encoding; bh=SPHyofgcagKJBQ9rY1HoYLympUgdy9m0NxlQCxdPSJk=; b=LC8yeHqrdubrqRZeUcAxjURnC3qYL3XiwSQsDhohtLOYB9lPaAsMBgeBL9V2H+tsxs mNmoGELepLWB7A87Ex2XYLqbhDS32XuogxzmYVxEi4QlavhrAwSDwYHPFnMxV0xj39GV haFw+LGsLJ3AB7pdnVOW5a6s5pRAbeiFPmCSw4Em65Y+PmEwXNLIi+BwlFM7dxm2iwgB Tah5vJUfL/VmzPMEtnxlOnXOcIDTh8kbij6DBbLBg58j7aMtK7pQA4l0BFu10M++eleI RfnxebKPKNAy/8SkSZabm8w1tsLw0J+tix35M5Bex1ZQew5dYnYVxPwwpComzrIqDRbS iBZA== X-Gm-Message-State: ALoCoQn5Tv96q4H1Gz7cdibFM1LBINDlNZcMi02pq96V4h/Mir65sAgZKGhFA17A88hB8dVbjmFx X-Received: by 10.107.164.196 with SMTP id d65mr28482681ioj.37.1415647116608; Mon, 10 Nov 2014 11:18:36 -0800 (PST) Received: from [192.168.1.173] (71-222-160-8.albq.qwest.net. [71.222.160.8]) by mx.google.com with ESMTPSA id mf8sm1816099igb.22.2014.11.10.11.18.35 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 10 Nov 2014 11:18:36 -0800 (PST) From: Brian Hill X-Google-Original-From: Brian Hill Message-ID: <54610F8B.2000600@houston-radar.com> Date: Mon, 10 Nov 2014 12:18:35 -0700 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.4.0 MIME-Version: 1.0 To: netdev@vger.kernel.org Subject: [PATCH] net: phy: Correctly handle MII ioctl which changes autonegotiation. Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When advertised capabilities are changed with mii-tool, such as: mii-tool -A 10baseT the existing handler has two errors. - An actual PHY register value is provided by mii-tool, and this must be mapped to internal state with mii_adv_to_ethtool_adv_t(). - The PHY state machine needs to be told that autonegotiation has again been performed. If not, the MAC will not be notified of the new link speed and duplex, resulting in a possible config mismatch. Signed-off-by: Brian Hill Acked-by: Florian Fainelli --- drivers/net/phy/phy.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) case SIOCGMIIPHY: @@ -367,22 +368,29 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) if (mii_data->phy_id == phydev->addr) { switch (mii_data->reg_num) { case MII_BMCR: - if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) + if ((val & (BMCR_RESET | BMCR_ANENABLE)) == 0) { + if (phydev->autoneg == AUTONEG_ENABLE) + change_autoneg = 1; phydev->autoneg = AUTONEG_DISABLE; - else + if (val & BMCR_FULLDPLX) + phydev->duplex = DUPLEX_FULL; + else + phydev->duplex = DUPLEX_HALF; + if (val & BMCR_SPEED1000) + phydev->speed = SPEED_1000; + else if (val & BMCR_SPEED100) + phydev->speed = SPEED_100; + else phydev->speed = SPEED_10; + } + else { + if (phydev->autoneg == AUTONEG_DISABLE) + change_autoneg = 1; phydev->autoneg = AUTONEG_ENABLE; - if (!phydev->autoneg && (val & BMCR_FULLDPLX)) - phydev->duplex = DUPLEX_FULL; - else - phydev->duplex = DUPLEX_HALF; - if (!phydev->autoneg && (val & BMCR_SPEED1000)) - phydev->speed = SPEED_1000; - else if (!phydev->autoneg && - (val & BMCR_SPEED100)) - phydev->speed = SPEED_100; + } break; case MII_ADVERTISE: - phydev->advertising = val; + phydev->advertising = mii_adv_to_ethtool_adv_t(val); + change_autoneg = 1; break; default: /* do nothing */ @@ -396,6 +404,10 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) if (mii_data->reg_num == MII_BMCR && val & BMCR_RESET) return phy_init_hw(phydev); + + if (change_autoneg) + return phy_start_aneg(phydev); + return 0; case SIOCSHWTSTAMP: diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index c94e2a2..ee9f0c9 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -352,6 +352,7 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) { struct mii_ioctl_data *mii_data = if_mii(ifr); u16 val = mii_data->val_in; + int change_autoneg = 0; switch (cmd) {