From patchwork Tue Mar 21 19:24:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iyappan Subramanian X-Patchwork-Id: 9637549 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 6C2086020B for ; Tue, 21 Mar 2017 19:53:05 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5A0D327C14 for ; Tue, 21 Mar 2017 19:53:05 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4AFD628304; Tue, 21 Mar 2017 19:53:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4FDFC27C14 for ; Tue, 21 Mar 2017 19:53:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=QhTS/ddI+R0mRCGYoon9QBReCy4Cl+Nci8HkAHBqkKQ=; b=u4VcRj0qdqpEEJtdwmQfZywoyp 9pvs/TqxkLR0vxWZH+lbgUAj3it4PVqg0nLY3EgWPC0X6OomTDef1jT8zuITOqOXacKfZfXaBRk3f Es3/21lDnqllBpRIpaLsRnKaMVKwQZIIxJdR41X0nWTGx9KFvI8/KI19YkCnfOZtChkmrWeG9XAw+ lYJHozL7ffBsJuB03Z1HYuuvl/i2x5/OATjfhrcIjhL/94lxdbrbi6Togy8alqmhbY1SebWMTUUIY AbC//lVS7WB4J3Yq4vyitTCwM53VZCkUkQBr5meUmvBXRkkL4v1Of9MIWtqQCXeV2ZnEvIeWkBZsI ecgZZRHw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cqPpy-0002wK-EE; Tue, 21 Mar 2017 19:52:58 +0000 Received: from casper.infradead.org ([2001:770:15f::2]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cqPpg-0002lX-CC for linux-arm-kernel@bombadil.infradead.org; Tue, 21 Mar 2017 19:52:40 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=ov9Qdbfs9Y00UTSuE79yqaMBECOH6/90/cAlv3cmFyI=; b=mQj/5ul2dGsUcxlBPm9qeKCTZ 2Vq6EMj7WqLXpz92WOkSRzW6bXRisG11GW/r29LsIreuPJDhrtaf7MALIMikryFShwaTXYilfQCtP TwXkKvEzN4R0s+hbl7T23Of42iwSZXoUwrpf3JHC+6FMUm32hId7T5G5sJ4xJwmI5v/7aHL5HQgtd VeMrMwJMllqaUYnX2s9eEDyoa/7/Htx4fvAZJDpz1SbDcDxv0ZeYb5OC5OT5bvvxvM7RIu5m1ElXU T0S2vGzCPb+rx0HRWYeSFZxQPMaFAv31vak+07G/6sfxUi1kxuDVITjgd/i5yecyFHWSELHic8K0i ysj651E1g==; Received: from mail-pg0-x22f.google.com ([2607:f8b0:400e:c05::22f]) by casper.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cqPNs-0004sC-KL for linux-arm-kernel@lists.infradead.org; Tue, 21 Mar 2017 19:23:59 +0000 Received: by mail-pg0-x22f.google.com with SMTP id t143so32208588pgb.2 for ; Tue, 21 Mar 2017 12:23:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=apm.com; s=apm; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ov9Qdbfs9Y00UTSuE79yqaMBECOH6/90/cAlv3cmFyI=; b=ihG2S5vV2x5UqllXI03aVggw86DJ+z1QeUtEd08yT+Z0VPXdPKHe0DcacEpsmq4K7D g1PMviInzxwFvseDzladiKqGgPjyjCI4AEyEKc2+DufYpBrL7vqXuE4SIDK8pj+WWEXZ EgOeUcl5emIAIskKWd+OhHECfCWxHj+3/hZ0Y= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ov9Qdbfs9Y00UTSuE79yqaMBECOH6/90/cAlv3cmFyI=; b=RvYTSrtnfLd3PQbWA5CU2LTl7bPz6N7vGgAxAqVS5MkRKNVP5t/Y4YfH81BroHjMTq ljVsGC66Q7FtiL2yTfEWRJHuI3ySaYi0H48XMYs/gN+7tOTejc89xMBDHoFAI2wa+IOp KoJGkdcx6x8DiAgf8EOuw6VgJpgWKMcWjlr/Pbzgh9tV+8y1Y+PG6kWHubiGVhtgWSJD KSRD7swSAIcVeMdTGGyzx6hwOaBWZK+X1twpi4yITD62x/Z/i55g+8fqoeUbupF/Iu2H y3TVti99ndKrJt/HpKo5asXuI6RXhSOZZT9NjQCzneuDmlpHQfzhVvpk2CPfv5ITku5f dcjw== X-Gm-Message-State: AFeK/H3lgc3jCGrMV0fK33iNnTPpdT9ERGzzeNzAy1rQtXmPbKq1aWjpjBGPhLYx/vUQS0l8 X-Received: by 10.98.70.28 with SMTP id t28mr41696214pfa.176.1490124207243; Tue, 21 Mar 2017 12:23:27 -0700 (PDT) Received: from isubrama-dev.amcc.com ([206.80.4.98]) by smtp.gmail.com with ESMTPSA id u69sm41113642pfg.121.2017.03.21.12.23.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 21 Mar 2017 12:23:26 -0700 (PDT) From: Iyappan Subramanian To: davem@davemloft.net, netdev@vger.kernel.org, andrew@lunn.ch, f.fainelli@gmail.com, David.Laight@aculab.com Subject: [PATCH net-next 1/4] drivers: net: xgene-v2: Add MDIO support Date: Tue, 21 Mar 2017 12:24:40 -0700 Message-Id: <1490124283-10371-2-git-send-email-isubramanian@apm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1490124283-10371-1-git-send-email-isubramanian@apm.com> References: <1490124283-10371-1-git-send-email-isubramanian@apm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170321_192357_150378_7D2C04DE X-CRM114-Status: GOOD ( 25.89 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kchudgar@apm.com, patches@apm.com, linux-arm-kernel@lists.infradead.org, Iyappan Subramanian MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Added phy management support by using phy abstraction layer APIs. Signed-off-by: Iyappan Subramanian --- drivers/net/ethernet/apm/xgene-v2/Makefile | 2 +- drivers/net/ethernet/apm/xgene-v2/mac.c | 2 +- drivers/net/ethernet/apm/xgene-v2/mac.h | 1 + drivers/net/ethernet/apm/xgene-v2/main.c | 13 ++- drivers/net/ethernet/apm/xgene-v2/main.h | 5 + drivers/net/ethernet/apm/xgene-v2/mdio.c | 178 +++++++++++++++++++++++++++++ 6 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 drivers/net/ethernet/apm/xgene-v2/mdio.c diff --git a/drivers/net/ethernet/apm/xgene-v2/Makefile b/drivers/net/ethernet/apm/xgene-v2/Makefile index 735309c..0fa5975 100644 --- a/drivers/net/ethernet/apm/xgene-v2/Makefile +++ b/drivers/net/ethernet/apm/xgene-v2/Makefile @@ -2,5 +2,5 @@ # Makefile for APM X-Gene Ethernet v2 driver # -xgene-enet-v2-objs := main.o mac.o enet.o ring.o +xgene-enet-v2-objs := main.o mac.o enet.o ring.o mdio.o obj-$(CONFIG_NET_XGENE_V2) += xgene-enet-v2.o diff --git a/drivers/net/ethernet/apm/xgene-v2/mac.c b/drivers/net/ethernet/apm/xgene-v2/mac.c index c3189de..ee431e3 100644 --- a/drivers/net/ethernet/apm/xgene-v2/mac.c +++ b/drivers/net/ethernet/apm/xgene-v2/mac.c @@ -27,7 +27,7 @@ void xge_mac_reset(struct xge_pdata *pdata) xge_wr_csr(pdata, MAC_CONFIG_1, 0); } -static void xge_mac_set_speed(struct xge_pdata *pdata) +void xge_mac_set_speed(struct xge_pdata *pdata) { u32 icm0, icm2, ecm0, mc2; u32 intf_ctrl, rgmii; diff --git a/drivers/net/ethernet/apm/xgene-v2/mac.h b/drivers/net/ethernet/apm/xgene-v2/mac.h index 0fce6ae..74397c9 100644 --- a/drivers/net/ethernet/apm/xgene-v2/mac.h +++ b/drivers/net/ethernet/apm/xgene-v2/mac.h @@ -101,6 +101,7 @@ static inline u32 xgene_get_reg_bits(u32 var, int pos, int len) struct xge_pdata; void xge_mac_reset(struct xge_pdata *pdata); +void xge_mac_set_speed(struct xge_pdata *pdata); void xge_mac_enable(struct xge_pdata *pdata); void xge_mac_disable(struct xge_pdata *pdata); void xge_mac_init(struct xge_pdata *pdata); diff --git a/drivers/net/ethernet/apm/xgene-v2/main.c b/drivers/net/ethernet/apm/xgene-v2/main.c index ae76977..10d4aff 100644 --- a/drivers/net/ethernet/apm/xgene-v2/main.c +++ b/drivers/net/ethernet/apm/xgene-v2/main.c @@ -500,9 +500,10 @@ static int xge_open(struct net_device *ndev) xge_intr_enable(pdata); xge_wr_csr(pdata, DMARXCTRL, 1); + + phy_start(ndev->phydev); xge_mac_enable(pdata); netif_start_queue(ndev); - netif_carrier_on(ndev); return 0; } @@ -511,9 +512,9 @@ static int xge_close(struct net_device *ndev) { struct xge_pdata *pdata = netdev_priv(ndev); - netif_carrier_off(ndev); netif_stop_queue(ndev); xge_mac_disable(pdata); + phy_stop(ndev->phydev); xge_intr_disable(pdata); xge_free_irq(ndev); @@ -683,9 +684,14 @@ static int xge_probe(struct platform_device *pdev) if (ret) goto err; + spin_lock_init(&pdata->mdio_lock); + + ret = xge_mdio_config(ndev); + if (ret) + goto err; + netif_napi_add(ndev, &pdata->napi, xge_napi, NAPI_POLL_WEIGHT); - netif_carrier_off(ndev); ret = register_netdev(ndev); if (ret) { netdev_err(ndev, "Failed to register netdev\n"); @@ -713,6 +719,7 @@ static int xge_remove(struct platform_device *pdev) dev_close(ndev); rtnl_unlock(); + xge_mdio_remove(ndev); unregister_netdev(ndev); free_netdev(ndev); diff --git a/drivers/net/ethernet/apm/xgene-v2/main.h b/drivers/net/ethernet/apm/xgene-v2/main.h index ada7b0e..3e98bb4 100644 --- a/drivers/net/ethernet/apm/xgene-v2/main.h +++ b/drivers/net/ethernet/apm/xgene-v2/main.h @@ -65,11 +65,16 @@ struct xge_pdata { struct xge_desc_ring *rx_ring; struct platform_device *pdev; char irq_name[IRQ_ID_SIZE]; + struct mii_bus *mdio_bus; struct net_device *ndev; struct napi_struct napi; struct xge_stats stats; + spinlock_t mdio_lock; /* mdio lock */ int phy_speed; u8 nbufs; }; +int xge_mdio_config(struct net_device *ndev); +void xge_mdio_remove(struct net_device *ndev); + #endif /* __XGENE_ENET_V2_MAIN_H__ */ diff --git a/drivers/net/ethernet/apm/xgene-v2/mdio.c b/drivers/net/ethernet/apm/xgene-v2/mdio.c new file mode 100644 index 0000000..43f454d --- /dev/null +++ b/drivers/net/ethernet/apm/xgene-v2/mdio.c @@ -0,0 +1,178 @@ +/* + * Applied Micro X-Gene SoC Ethernet v2 Driver + * + * Copyright (c) 2017, Applied Micro Circuits Corporation + * Author(s): Iyappan Subramanian + * Keyur Chudgar + * + * 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 + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "main.h" + +static int xge_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 data) +{ + struct xge_pdata *pdata = bus->priv; + u32 done, val = 0; + u8 wait = 10; + int ret = 0; + + spin_lock(&pdata->mdio_lock); + + SET_REG_BITS(&val, PHY_ADDR, phy_id); + SET_REG_BITS(&val, REG_ADDR, reg); + xge_wr_csr(pdata, MII_MGMT_ADDRESS, val); + + xge_wr_csr(pdata, MII_MGMT_CONTROL, data); + do { + usleep_range(5, 10); + done = xge_rd_csr(pdata, MII_MGMT_INDICATORS); + } while ((done & MII_MGMT_BUSY) && wait--); + + if (done & MII_MGMT_BUSY) { + dev_err(&bus->dev, "MII_MGMT write failed\n"); + ret = -ETIMEDOUT; + } + + spin_unlock(&pdata->mdio_lock); + + return ret; +} + +static int xge_mdio_read(struct mii_bus *bus, int phy_id, int reg) +{ + struct xge_pdata *pdata = bus->priv; + u32 data, done, val = 0; + u8 wait = 10; + + spin_lock(&pdata->mdio_lock); + + SET_REG_BITS(&val, PHY_ADDR, phy_id); + SET_REG_BITS(&val, REG_ADDR, reg); + xge_wr_csr(pdata, MII_MGMT_ADDRESS, val); + + xge_wr_csr(pdata, MII_MGMT_COMMAND, MII_READ_CYCLE); + do { + usleep_range(5, 10); + done = xge_rd_csr(pdata, MII_MGMT_INDICATORS); + } while ((done & MII_MGMT_BUSY) && wait--); + + if (done & MII_MGMT_BUSY) { + dev_err(&bus->dev, "MII_MGMT read failed\n"); + data = -ETIMEDOUT; + goto out; + } + + data = xge_rd_csr(pdata, MII_MGMT_STATUS); + xge_wr_csr(pdata, MII_MGMT_COMMAND, 0); + +out: + spin_unlock(&pdata->mdio_lock); + + return data; +} + +static void xge_adjust_link(struct net_device *ndev) +{ + struct xge_pdata *pdata = netdev_priv(ndev); + struct phy_device *phydev = ndev->phydev; + + if (phydev->link) { + if (pdata->phy_speed != phydev->speed) { + pdata->phy_speed = phydev->speed; + xge_mac_set_speed(pdata); + xge_mac_enable(pdata); + phy_print_status(phydev); + } + } else { + if (pdata->phy_speed != SPEED_UNKNOWN) { + pdata->phy_speed = SPEED_UNKNOWN; + xge_mac_disable(pdata); + phy_print_status(phydev); + } + } +} + +void xge_mdio_remove(struct net_device *ndev) +{ + struct xge_pdata *pdata = netdev_priv(ndev); + struct mii_bus *mdio_bus = pdata->mdio_bus; + + if (ndev->phydev) + phy_disconnect(ndev->phydev); + + if (mdio_bus->state == MDIOBUS_REGISTERED) + mdiobus_unregister(mdio_bus); + + mdiobus_free(mdio_bus); +} + +int xge_mdio_config(struct net_device *ndev) +{ + struct xge_pdata *pdata = netdev_priv(ndev); + struct device *dev = &pdata->pdev->dev; + struct mii_bus *mdio_bus; + struct phy_device *phydev; + int ret; + + mdio_bus = mdiobus_alloc(); + if (!mdio_bus) + return -ENOMEM; + + mdio_bus->name = "APM X-Gene Ethernet (v2) MDIO Bus"; + mdio_bus->read = xge_mdio_read; + mdio_bus->write = xge_mdio_write; + mdio_bus->priv = pdata; + mdio_bus->parent = dev; + snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(dev)); + pdata->mdio_bus = mdio_bus; + + mdio_bus->phy_mask = 0x1; + ret = mdiobus_register(mdio_bus); + if (ret) + goto err; + + phydev = phy_find_first(mdio_bus); + if (!phydev) { + dev_err(dev, "no PHY found\n"); + goto err; + } + phydev = phy_connect(ndev, phydev_name(phydev), + &xge_adjust_link, + pdata->resources.phy_mode); + + if (IS_ERR(phydev)) { + netdev_err(ndev, "Could not attach to PHY\n"); + ret = PTR_ERR(phydev); + goto err; + } + + phydev->supported &= ~(SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Half | + SUPPORTED_AUI | + SUPPORTED_MII | + SUPPORTED_FIBRE | + SUPPORTED_BNC); + phydev->advertising = phydev->supported; + pdata->phy_speed = SPEED_UNKNOWN; + + return 0; +err: + xge_mdio_remove(ndev); + + return ret; +}