From patchwork Fri Oct 7 14:51:21 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Collins X-Patchwork-Id: 164283 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 2D510B6FC4 for ; Tue, 12 Jun 2012 09:05:56 +1000 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SeDgC-0004KK-NH; Mon, 11 Jun 2012 23:05:48 +0000 Received: from mail-pb0-f49.google.com ([209.85.160.49]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SeDdM-0003iy-Fq for kernel-team@lists.ubuntu.com; Mon, 11 Jun 2012 23:02:52 +0000 Received: by mail-pb0-f49.google.com with SMTP id rq13so6562271pbb.8 for ; Mon, 11 Jun 2012 16:02:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:message-id:in-reply-to:references:from:date:subject:to; bh=bIV8FF6QTgPPd7VAxqx5qlKcC7iG5HifT1VF4xdXYIo=; b=vnX2Ae8HbA/STcBXDIrWcb1PC4XHCGmLs4jFrgARnBVn985kFSUDVsGAdwqaZ9Atfm CETk5nbypUJhwsykDt1XmXVGBU0bmes03QLXER5oxU5Rt6xetNvAQ0htdQdSZq8dDBbc /zJq0Lp/OK3yalEh+QbrcMOvO1jbUln7vRmDkoYVcWG0wiK55Uf5KasgIBTBHqCJfvfL YryMH/nunBLXIGacIGns+AjLd8FgQaFwZkdtXHKKGWYJv6mbjXkmqU2vamqBbHHaNBUs fmruwTzBHy4ZsiJGzTxZkKzrgn8BWDIQHwyhCpxllJjdxoCJBdwDIVh72jWQJI4xTfyn gjaA== Received: by 10.68.200.102 with SMTP id jr6mr31648071pbc.0.1339455772023; Mon, 11 Jun 2012 16:02:52 -0700 (PDT) Received: from localhost (ip68-13-200-36.hr.hr.cox.net. [68.13.200.36]) by mx.google.com with ESMTPS id hb5sm19924976pbc.58.2012.06.11.16.02.49 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 11 Jun 2012 16:02:51 -0700 (PDT) Received: by localhost (sSMTP sendmail emulation); Mon, 11 Jun 2012 19:02:47 -0400 Message-Id: In-Reply-To: References: From: Madalin Bucur Date: Fri, 7 Oct 2011 14:51:21 +0000 Subject: [PATCH 22/27] UBUNTU: SAUCE: net/phy: added autocross feature for forced links on VSC82x4 To: kernel-team@lists.ubuntu.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com Added auto MDI/MDI-X capability for forced (autonegotiation disabled) 10/100 Mbps speeds on Vitesse VSC82x4 PHYs. Exported previously static function genphy_setup_forced() required by the new config_aneg handler in the Vitesse PHY module. This patch is being maintained and will eventually be merged upstream by Freescale directly. The powerpc-e500mc flavour uses this. Signed-off-by: Madalin Bucur Signed-off-by: Ben Collins --- drivers/net/phy/phy_device.c | 5 +-- drivers/net/phy/vitesse.c | 69 ++++++++++++++++++++++++++++++++++++++++-- include/linux/phy.h | 3 +- 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 163e1e7..b7f026b 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -6,7 +6,7 @@ * * Author: Andy Fleming * - * Copyright (c) 2004-2006, 2008-2010 Freescale Semiconductor, Inc. + * Copyright (c) 2004-2006, 2008-2011 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -622,7 +622,7 @@ EXPORT_SYMBOL(gen10g_config_advert); * to the values in phydev. Assumes that the values are valid. * Please see phy_sanitize_settings(). */ -static int genphy_setup_forced(struct phy_device *phydev) +int genphy_setup_forced(struct phy_device *phydev) { int err; int ctl = 0; @@ -641,6 +641,7 @@ static int genphy_setup_forced(struct phy_device *phydev) return err; } +EXPORT_SYMBOL(genphy_setup_forced); int gen10g_setup_forced(struct phy_device *phydev) { diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index d0f36a1..92a60a3 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -3,7 +3,7 @@ * * Author: Kriston Carson * - * Copyright (c) 2005, 2009 Freescale Semiconductor, Inc. + * Copyright (c) 2005, 2009, 2011 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -45,6 +45,10 @@ /* Vitesse Auxiliary Control/Status Register */ #define MII_VSC8244_AUX_CONSTAT 0x1c +#define MII_VSC82X4_EXT_PAGE_16E 0x10 +#define MII_VSC82X4_EXT_PAGE_17E 0x11 +#define MII_VSC82X4_EXT_PAGE_18E 0x12 +#define MII_VSC82X4_EXT_PAGE_ACCESS 0x1f #define MII_VSC8244_AUXCONSTAT_INIT 0x0000 #define MII_VSC8244_AUXCONSTAT_DUPLEX 0x0020 #define MII_VSC8244_AUXCONSTAT_SPEED 0x0018 @@ -140,6 +144,65 @@ static int vsc82xx_config_intr(struct phy_device *phydev) return err; } +/* vsc82x4_config_autocross_enable - Enable auto MDI/MDI-X for forced links + * @phydev: target phy_device struct + * + * Enable auto MDI/MDI-X when in 10/100 forced link speeds by writing + * special values in the VSC8234/VSC8244 extended reserved registers + * + */ +static int vsc82x4_config_autocross_enable(struct phy_device *phydev) +{ + int ret; + + if (phydev->autoneg == AUTONEG_ENABLE || phydev->speed > SPEED_100) + return 0; + + /* map extended registers set 0x10 - 0x1e */ + ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_ACCESS, 0x52b5); + if (ret >= 0) + ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_18E, 0x0012); + if (ret >= 0) + ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_17E, 0x2803); + if (ret >= 0) + ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_16E, 0x87fa); + /* map standard registers set 0x10 - 0x1e */ + if (ret >= 0) + ret = phy_write(phydev, MII_VSC82X4_EXT_PAGE_ACCESS, 0x0000); + else + phy_write(phydev, MII_VSC82X4_EXT_PAGE_ACCESS, 0x0000); + + return ret; +} + +/** + * vsc82x4_config_aneg - restart auto-negotiation or write BMCR + * @phydev: target phy_device struct + * + * Description: If auto-negotiation is enabled, we configure the + * advertising, and then restart auto-negotiation. If it is not + * enabled, then we write the BMCR and also start the auto + * MDI/MDI-X feature + * + */ +static int vsc82x4_config_aneg(struct phy_device *phydev) +{ + int ret; + + /* Enable auto MDI/MDI-X when in 10/100 forced link speeds by + * writing special values in the VSC8234 extended reserved registers */ + if (phydev->autoneg != AUTONEG_ENABLE && phydev->speed <= SPEED_100) { + ret = genphy_setup_forced(phydev); + + if (ret < 0) /* error */ + return ret; + + return vsc82x4_config_autocross_enable(phydev); + } + + return genphy_config_aneg(phydev); +} + /* Vitesse 824x */ static struct phy_driver vsc8244_driver = { .phy_id = PHY_ID_VSC8244, @@ -148,7 +211,7 @@ static struct phy_driver vsc8244_driver = { .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, .config_init = &vsc824x_config_init, - .config_aneg = &genphy_config_aneg, + .config_aneg = &vsc82x4_config_aneg, .read_status = &genphy_read_status, .ack_interrupt = &vsc824x_ack_interrupt, .config_intr = &vsc82xx_config_intr, @@ -163,7 +226,7 @@ static struct phy_driver vsc8234_driver = { .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, .config_init = &vsc824x_config_init, - .config_aneg = &genphy_config_aneg, + .config_aneg = &vsc82x4_config_aneg, .read_status = &genphy_read_status, .ack_interrupt = &vsc824x_ack_interrupt, .config_intr = &vsc82xx_config_intr, diff --git a/include/linux/phy.h b/include/linux/phy.h index e44e8ec..8edd103 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -6,7 +6,7 @@ * * Author: Andy Fleming * - * Copyright (c) 2004-2010 Freescale Semiconductor, Inc. + * Copyright (c) 2004-2011 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -543,6 +543,7 @@ static inline int phy_read_status(struct phy_device *phydev) { return phydev->drv->read_status(phydev); } +int genphy_setup_forced(struct phy_device *phydev); int genphy_restart_aneg(struct phy_device *phydev); int genphy_config_aneg(struct phy_device *phydev); int genphy_update_link(struct phy_device *phydev);