From patchwork Thu Jul 7 00:35:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iyappan Subramanian X-Patchwork-Id: 9217473 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 42DEA607D9 for ; Thu, 7 Jul 2016 00:38:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 31B2E28578 for ; Thu, 7 Jul 2016 00:38:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2617E28590; Thu, 7 Jul 2016 00:38:17 +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=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 57D6828578 for ; Thu, 7 Jul 2016 00:38:16 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bKxJ3-0000kq-RY; Thu, 07 Jul 2016 00:36:41 +0000 Received: from mail-pf0-x22b.google.com ([2607:f8b0:400e:c00::22b]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1bKxIA-0008EL-SF for linux-arm-kernel@lists.infradead.org; Thu, 07 Jul 2016 00:35:49 +0000 Received: by mail-pf0-x22b.google.com with SMTP id i123so904629pfg.0 for ; Wed, 06 Jul 2016 17:35:26 -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=ZCkqqqPqU44vCMRVzGjMqpMRnDLGuTbIX7VRSittaOg=; b=PO7yQcH9gX7v04fYyQe7Po4wdGdeX1XuxEqBEyn2KbPohwiM1NP2INcEGXW+BQAzOL ur99K+IdP/QPzByUe2FpkyWL46UX3Oj1hYeEWJv029D3vWnFch2+kWVk84rcF1q9ZzKp pYLN4OUctnixbT46oFAuKMLiKSczj7q0uEDMk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ZCkqqqPqU44vCMRVzGjMqpMRnDLGuTbIX7VRSittaOg=; b=mGcltM2zOtmlPUE2sw72fOJ1a3AOmt93GPqvci6QbixU7T8Cfl82oocmjNB5XvSvu1 kLel7EEnBHXkfyOCP5lwgPHC8IFM1cf5Ms09eDaiJnQdbT7aba9XFofmijrVcVJYrIsW aMvW+ekKpFaZ/2K9d6NP6aduJ47bsitOOqk7M2pn9b7lYIaHVeMQvHoTb5hxzZPAjUqV fHsXUINCwwOoRPQgswZVFTuvpC7G7QCvLYJG0xb26bIaG+bM58evnfATkl5L+GF/abTb Gt9GAhBN3yw3fiUwQKKj5nKqP1u9MDXQnBCyuOym8SGyBbt2kZGJ47amE/V5dXDw+WCe WZtA== X-Gm-Message-State: ALyK8tK808fAcd3xDivAI1ILvd4VTuc35/a7v/hdR6eW8YJ+6zhkRLzGXClalxMlBSebPwMS X-Received: by 10.98.8.156 with SMTP id 28mr310471pfi.89.1467851725765; Wed, 06 Jul 2016 17:35:25 -0700 (PDT) Received: from isubrama-dev.amcc.com ([206.80.4.98]) by smtp.gmail.com with ESMTPSA id p63sm6769956pfp.65.2016.07.06.17.35.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 06 Jul 2016 17:35:25 -0700 (PDT) From: Iyappan Subramanian To: davem@davemloft.net, netdev@vger.kernel.org, devicetree@vger.kernel.org Subject: [PATCH v4 06/11] drivers: net: xgene: Add backward compatibility Date: Wed, 6 Jul 2016 17:35:07 -0700 Message-Id: <1467851712-24780-7-git-send-email-isubramanian@apm.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1467851712-24780-1-git-send-email-isubramanian@apm.com> References: <1467851712-24780-1-git-send-email-isubramanian@apm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160706_173547_260021_D7FE37C5 X-CRM114-Status: GOOD ( 17.80 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: matthias.bgg@gmail.com, andrew@lunn.ch, 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 This patch adds xgene_enet_check_phy_hanlde() function that checks whether MDIO driver is probed successfully and sets pdata->mdio_driver to true. If MDIO driver is not probed, ethernet driver falls back to backward compatibility mode. Since enum xgene_enet_cmd is used by MDIO driver, removing this from ethernet driver. Signed-off-by: Iyappan Subramanian Tested-by: Fushen Chen Tested-by: Toan Le Tested-by: Matthias Brugger --- drivers/net/ethernet/apm/xgene/xgene_enet_hw.c | 46 +++++++++++++++++++- drivers/net/ethernet/apm/xgene/xgene_enet_hw.h | 7 +--- drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 51 +++++++++++++++++++---- drivers/net/ethernet/apm/xgene/xgene_enet_main.h | 30 +------------ drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c | 9 +++- 5 files changed, 99 insertions(+), 44 deletions(-) diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c index d394d1f..96f8de7 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c @@ -572,7 +572,9 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata) { u32 value; - xgene_gmac_reset(pdata); + if (!pdata->mdio_driver) + xgene_gmac_reset(pdata); + xgene_gmac_set_speed(pdata); xgene_gmac_set_mac_addr(pdata); @@ -680,6 +682,11 @@ static int xgene_enet_reset(struct xgene_enet_pdata *pdata) if (!xgene_ring_mgr_init(pdata)) return -ENODEV; + if (pdata->mdio_driver) { + xgene_enet_config_ring_if_assoc(pdata); + return 0; + } + if (dev->of_node) { clk_prepare_enable(pdata->clk); clk_disable_unprepare(pdata->clk); @@ -793,7 +800,26 @@ static void xgene_enet_adjust_link(struct net_device *ndev) } } -static int xgene_enet_phy_connect(struct net_device *ndev) +#ifdef CONFIG_ACPI +static struct acpi_device *acpi_phy_find_device(struct device *dev) +{ + struct acpi_reference_args args; + struct fwnode_handle *fw_node; + int status; + + fw_node = acpi_fwnode_handle(ACPI_COMPANION(dev)); + status = acpi_node_get_property_reference(fw_node, "phy-handle", 0, + &args); + if (ACPI_FAILURE(status)) { + dev_dbg(dev, "No matching phy in ACPI table\n"); + return NULL; + } + + return args.adev; +} +#endif + +int xgene_enet_phy_connect(struct net_device *ndev) { struct xgene_enet_pdata *pdata = netdev_priv(ndev); struct device_node *phy_np; @@ -816,6 +842,15 @@ static int xgene_enet_phy_connect(struct net_device *ndev) pdata->phy_dev = phy_dev; } else { +#ifdef CONFIG_ACPI + if (pdata->mdio_driver) { + struct acpi_device *adev; + + adev = acpi_phy_find_device(dev); + if (adev) + pdata->phy_dev = adev->driver_data; + } + phy_dev = pdata->phy_dev; if (!phy_dev || @@ -824,6 +859,7 @@ static int xgene_enet_phy_connect(struct net_device *ndev) netdev_err(ndev, "Could not connect to PHY\n"); return -ENODEV; } +#endif } pdata->phy_speed = SPEED_UNKNOWN; @@ -924,6 +960,12 @@ int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata) return ret; } +void xgene_enet_phy_disconnect(struct xgene_enet_pdata *pdata) +{ + if (pdata->phy_dev) + phy_disconnect(pdata->phy_dev); +} + void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata) { if (pdata->phy_dev) diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h index eec55c1..179a44d 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h @@ -301,11 +301,6 @@ enum xgene_enet_ring_bufnum { RING_BUFNUM_INVALID }; -enum xgene_enet_cmd { - XGENE_ENET_WR_CMD = BIT(31), - XGENE_ENET_RD_CMD = BIT(30) -}; - enum xgene_enet_err_code { HBF_READ_DATA = 3, HBF_LL_READ = 4, @@ -351,6 +346,8 @@ void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring, int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata); void xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata); bool xgene_ring_mgr_init(struct xgene_enet_pdata *p); +int xgene_enet_phy_connect(struct net_device *ndev); +void xgene_enet_phy_disconnect(struct xgene_enet_pdata *pdata); extern const struct xgene_mac_ops xgene_gmac_ops; extern const struct xgene_port_ops xgene_gport_ops; diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index 87e5929..a8693de 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -1295,6 +1295,29 @@ static int xgene_enet_get_irqs(struct xgene_enet_pdata *pdata) return 0; } +static int xgene_enet_check_phy_handle(struct xgene_enet_pdata *pdata) +{ + struct device *dev = &pdata->pdev->dev; + int ret; + + if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) + return 0; + + if (!IS_ENABLED(CONFIG_MDIO_XGENE)) + return 0; + + if (xgene_mdio_probe_successful()) { + ret = device_property_present(dev, "phy-handle"); + if (!ret) { + dev_err(dev, "Unable to find phy-handle\n"); + return -1; + } + pdata->mdio_driver = true; + } + + return 0; +} + static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) { struct platform_device *pdev; @@ -1380,6 +1403,10 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) if (ret) return ret; + ret = xgene_enet_check_phy_handle(pdata); + if (ret) + return ret; + pdata->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(pdata->clk)) { /* Firmware may have set up the clock already. */ @@ -1574,7 +1601,7 @@ static int xgene_enet_probe(struct platform_device *pdev) struct net_device *ndev; struct xgene_enet_pdata *pdata; struct device *dev = &pdev->dev; - const struct xgene_mac_ops *mac_ops; + void (*link_state)(struct work_struct *); const struct of_device_id *of_id; int ret; @@ -1636,14 +1663,19 @@ static int xgene_enet_probe(struct platform_device *pdev) if (ret) goto err_netdev; - mac_ops = pdata->mac_ops; - if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) { - ret = xgene_enet_mdio_config(pdata); - if (ret) - goto err_netdev; + link_state = pdata->mac_ops->link_state; + if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) { + INIT_DELAYED_WORK(&pdata->link_work, link_state); } else { - INIT_DELAYED_WORK(&pdata->link_work, mac_ops->link_state); + if (pdata->mdio_driver) + ret = xgene_enet_phy_connect(ndev); + else if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) + ret = xgene_enet_mdio_config(pdata); + else + INIT_DELAYED_WORK(&pdata->link_work, link_state); } + if (ret) + goto err; xgene_enet_napi_add(pdata); ret = register_netdev(ndev); @@ -1679,8 +1711,11 @@ static int xgene_enet_remove(struct platform_device *pdev) mac_ops->rx_disable(pdata); mac_ops->tx_disable(pdata); - if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) + if (pdata->mdio_driver) + xgene_enet_phy_disconnect(pdata); + else if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII) xgene_enet_mdio_remove(pdata); + unregister_netdev(ndev); pdata->port_ops->shutdown(pdata); xgene_enet_delete_desc_rings(pdata); diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h index 681a473..217546e 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h @@ -38,6 +38,7 @@ #include "xgene_enet_hw.h" #include "xgene_enet_cle.h" #include "xgene_enet_ring2.h" +#include "../../../phy/mdio-xgene.h" #define XGENE_DRV_VERSION "v1.0" #define XGENE_ENET_MAX_MTU 1536 @@ -214,6 +215,7 @@ struct xgene_enet_pdata { u32 mss; u8 tx_delay; u8 rx_delay; + bool mdio_driver; }; struct xgene_indirect_ctl { @@ -223,34 +225,6 @@ struct xgene_indirect_ctl { void __iomem *cmd_done; }; -/* Set the specified value into a bit-field defined by its starting position - * and length within a single u64. - */ -static inline u64 xgene_enet_set_field_value(int pos, int len, u64 val) -{ - return (val & ((1ULL << len) - 1)) << pos; -} - -#define SET_VAL(field, val) \ - xgene_enet_set_field_value(field ## _POS, field ## _LEN, val) - -#define SET_BIT(field) \ - xgene_enet_set_field_value(field ## _POS, 1, 1) - -/* Get the value from a bit-field defined by its starting position - * and length within the specified u64. - */ -static inline u64 xgene_enet_get_field_value(int pos, int len, u64 src) -{ - return (src >> pos) & ((1ULL << len) - 1); -} - -#define GET_VAL(field, src) \ - xgene_enet_get_field_value(field ## _POS, field ## _LEN, src) - -#define GET_BIT(field, src) \ - xgene_enet_get_field_value(field ## _POS, 1, src) - static inline struct device *ndev_to_dev(struct net_device *ndev) { return ndev->dev.parent; diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c index 7d37a80..b2e24ef 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_sgmac.c @@ -364,7 +364,9 @@ static void xgene_sgmac_init(struct xgene_enet_pdata *p) u32 cfg_bypass_reg, rx_dv_gate_reg; u32 data, offset; - xgene_sgmac_reset(p); + if (!(p->enet_id == XGENE_ENET2 && p->mdio_driver)) + xgene_sgmac_reset(p); + xgene_sgmii_enable_autoneg(p); xgene_sgmac_set_speed(p); xgene_sgmac_set_mac_addr(p); @@ -443,6 +445,11 @@ static int xgene_enet_reset(struct xgene_enet_pdata *p) if (!xgene_ring_mgr_init(p)) return -ENODEV; + if (p->mdio_driver && p->enet_id == XGENE_ENET2) { + xgene_enet_config_ring_if_assoc(p); + return 0; + } + if (p->enet_id == XGENE_ENET2) xgene_enet_wr_clkrst_csr(p, XGENET_CONFIG_REG_ADDR, SGMII_EN);