From patchwork Thu Aug 30 00:40:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moritz Fischer X-Patchwork-Id: 963715 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 4213n41zz9z9ryt for ; Thu, 30 Aug 2018 10:50:16 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727255AbeH3EtZ (ORCPT ); Thu, 30 Aug 2018 00:49:25 -0400 Received: from mail-pl1-f195.google.com ([209.85.214.195]:44602 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727233AbeH3EtY (ORCPT ); Thu, 30 Aug 2018 00:49:24 -0400 Received: by mail-pl1-f195.google.com with SMTP id ba4-v6so3037367plb.11 for ; Wed, 29 Aug 2018 17:49:55 -0700 (PDT) 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=sZdAF1HX9BbdV1yfLCar67yxiHmtRQzQeHqMiNrKbPs=; b=NbRbxnA4tmprtn9CsUyvkjfd0dmxbS2QOKZ6E3ng6+Brdz5r/R93em5AqvpXPDeTjo gw0VXKDwzBBzXMNA7f/oQPGZhsNHbj4j6WHv6IUEh+NL6jnOA3eLSSXz7/yexfAngZ0K Pe7akdQqkuukgwHbHuQRX+aEO4Z36FQqD+EAVSlADo7yaNpHlT8vw8PkMMpZjx6HLFNi afVINf3qmeIl5tByq/jawhtr61tEumsApZRjeQCebgW7Piz9TjAlLmYnTvtFy/CZIkt7 QQ2CJ1cZIHbi1BzYE6FQZjQqPIR6I1k8WJHS82o8y85JEZRRTEQIkHzyxJznWLaF73Nb uXRg== X-Gm-Message-State: APzg51AaqTMbx3lDlQ4hM2ZL4NDAwDSNMxTyiPnpQ6+Ne8+AA0OhJL1V 92ICcX9DMbkpx4hfyco8WLX7Bg== X-Google-Smtp-Source: ANB0VdZzNiZOPPWdii9hE3dkkI694wXXyffNNIdd97RySz8gu7J2FItgi6KavfQEW6qCKObye6GhHA== X-Received: by 2002:a17:902:b7c5:: with SMTP id v5-v6mr8142653plz.49.1535590195049; Wed, 29 Aug 2018 17:49:55 -0700 (PDT) Received: from localhost ([207.114.172.147]) by smtp.gmail.com with ESMTPSA id c68-v6sm8942472pfj.51.2018.08.29.17.49.54 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 29 Aug 2018 17:49:54 -0700 (PDT) From: Moritz Fischer To: davem@davemloft.net Cc: keescook@chromium.org, f.fainelli@gmail.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, alex.williams@ni.com, Moritz Fischer Subject: [PATCH net-next 1/3] net: nixge: Add support for fixed-link subnodes Date: Wed, 29 Aug 2018 17:40:44 -0700 Message-Id: <20180830004046.9417-2-mdf@kernel.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180830004046.9417-1-mdf@kernel.org> References: <20180830004046.9417-1-mdf@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add support for fixed-link cases where no MDIO is actually required to run the device. In that case no MDIO bus is instantiated since the actual registers are not available in hardware. Signed-off-by: Moritz Fischer --- drivers/net/ethernet/ni/nixge.c | 72 ++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 19 deletions(-) diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c index 74cf52e3fb09..670249313ff0 100644 --- a/drivers/net/ethernet/ni/nixge.c +++ b/drivers/net/ethernet/ni/nixge.c @@ -1189,9 +1189,36 @@ static int nixge_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val) return err; } +static int nixge_of_get_phy(struct nixge_priv *priv, struct device_node *np) +{ + priv->phy_mode = of_get_phy_mode(np); + if (priv->phy_mode < 0) { + dev_err(priv->dev, "not find \"phy-mode\" property\n"); + return -EINVAL; + } + + if (of_phy_is_fixed_link(np)) { + if (of_phy_register_fixed_link(np) < 0) { + dev_err(priv->dev, "broken fixed link spec\n"); + return -EINVAL; + } + + priv->phy_node = of_node_get(np); + } else { + priv->phy_node = of_parse_phandle(np, "phy-handle", 0); + if (!priv->phy_node) { + dev_err(priv->dev, "not find \"phy-handle\" property\n"); + return -EINVAL; + } + } + + return 0; +} + static int nixge_mdio_setup(struct nixge_priv *priv, struct device_node *np) { struct mii_bus *bus; + int err; bus = devm_mdiobus_alloc(priv->dev); if (!bus) @@ -1230,6 +1257,7 @@ static int nixge_probe(struct platform_device *pdev) struct nixge_priv *priv; struct net_device *ndev; struct resource *dmares; + struct device_node *np; const u8 *mac_addr; int err; @@ -1237,6 +1265,8 @@ static int nixge_probe(struct platform_device *pdev) if (!ndev) return -ENOMEM; + np = pdev->dev.of_node; + platform_set_drvdata(pdev, ndev); SET_NETDEV_DEV(ndev, &pdev->dev); @@ -1286,24 +1316,19 @@ static int nixge_probe(struct platform_device *pdev) priv->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD; priv->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD; - err = nixge_mdio_setup(priv, pdev->dev.of_node); - if (err) { - netdev_err(ndev, "error registering mdio bus"); - goto free_netdev; - } - - priv->phy_mode = of_get_phy_mode(pdev->dev.of_node); - if (priv->phy_mode < 0) { - netdev_err(ndev, "not find \"phy-mode\" property\n"); - err = -EINVAL; - goto unregister_mdio; + if (np) { + err = nixge_of_get_phy(priv, np); + if (err) + goto free_netdev; } - priv->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); - if (!priv->phy_node) { - netdev_err(ndev, "not find \"phy-handle\" property\n"); - err = -EINVAL; - goto unregister_mdio; + /* only if it's not a fixed link, do we care about MDIO at all */ + if (priv->phy_node && !of_phy_is_fixed_link(np)) { + err = nixge_mdio_setup(priv, np); + if (err) { + dev_err(&pdev->dev, "error registering mdio bus"); + goto free_phy; + } } err = register_netdev(priv->ndev); @@ -1315,8 +1340,13 @@ static int nixge_probe(struct platform_device *pdev) return 0; unregister_mdio: - mdiobus_unregister(priv->mii_bus); - + if (priv->mii_bus) + mdiobus_unregister(priv->mii_bus); +free_phy: + if (np && of_phy_is_fixed_link(np)) { + of_phy_deregister_fixed_link(np); + of_node_put(np); + } free_netdev: free_netdev(ndev); @@ -1330,7 +1360,11 @@ static int nixge_remove(struct platform_device *pdev) unregister_netdev(ndev); - mdiobus_unregister(priv->mii_bus); + if (priv->mii_bus) + mdiobus_unregister(priv->mii_bus); + + if (np && of_phy_is_fixed_link(np)) + of_phy_deregister_fixed_link(np); free_netdev(ndev); From patchwork Thu Aug 30 00:40:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moritz Fischer X-Patchwork-Id: 963714 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 4213n15MJ8z9ryt for ; Thu, 30 Aug 2018 10:50:13 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727104AbeH3Etl (ORCPT ); Thu, 30 Aug 2018 00:49:41 -0400 Received: from mail-pl1-f196.google.com ([209.85.214.196]:46640 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727239AbeH3EtZ (ORCPT ); Thu, 30 Aug 2018 00:49:25 -0400 Received: by mail-pl1-f196.google.com with SMTP id a4-v6so3029673plm.13 for ; Wed, 29 Aug 2018 17:49:56 -0700 (PDT) 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=o6IzGJkykKui6d4lBUMa65Is4NWVCcNClpviZh4VeX0=; b=eBgrWrFjchja45okSsHEIipBbns0PP1qBxc9fsiZnHehddcra1fMwMixtnztE3CL+2 XcjF6TbsQqAHttszdGK1eYisWWDRpwG4v390LzCGstChuU0c6SiE6MrdAsiFzfyH53KB UahH3RIOx+R6sgJXyobufrYtR/CEMjdj4CO+Iwt0q6nGRTrbv1ITvnrL21SEhsOUrg9w wM/9cIt7eQGC1VnQA25415nQs1DyBH1mmJHtO4CBXjiUeSB67adU+B9xi0ylQsFN7IAs m7jmssIHnmaVMEygL9MRm1orzQ1+qnAwx4iuhhpYn+79C/SYWHkAN+E2Lm/Kg/g2RBHh vqlQ== X-Gm-Message-State: APzg51AeQpq4NFbdgZSO5ZSa2gN0QtIHDPLJWPgLNfblopFBnk0VB6A8 pTZFJz10QUTkg7FazFchrWlld+/Y3ac= X-Google-Smtp-Source: ANB0VdbBKpWf970uY7YQLJbmrmEtCkhtVjUssLSNJjvLH3H+7IEKndZantekjfVZ3u7GT5MUT7PvQA== X-Received: by 2002:a17:902:5998:: with SMTP id p24-v6mr8028762pli.36.1535590196136; Wed, 29 Aug 2018 17:49:56 -0700 (PDT) Received: from localhost ([207.114.172.147]) by smtp.gmail.com with ESMTPSA id y86-v6sm8600130pfk.84.2018.08.29.17.49.55 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 29 Aug 2018 17:49:55 -0700 (PDT) From: Moritz Fischer To: davem@davemloft.net Cc: keescook@chromium.org, f.fainelli@gmail.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, alex.williams@ni.com, Moritz Fischer Subject: [PATCH net-next 2/3] net: nixge: Add support for having nixge as subdevice Date: Wed, 29 Aug 2018 17:40:45 -0700 Message-Id: <20180830004046.9417-3-mdf@kernel.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180830004046.9417-1-mdf@kernel.org> References: <20180830004046.9417-1-mdf@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add support for instantiating nixge as subdevice using fixed-link and platform data to configure it. Signed-off-by: Moritz Fischer --- Hi, not this patch is still in the early stages, and as the rest of this series goes on top of [1]. The actual platform data might still change since the parent device driver is still under development. Thanks for your time, Moritz [1] https://lkml.org/lkml/2018/8/28/1011 --- drivers/net/ethernet/ni/nixge.c | 71 ++++++++++++++++++++++++++--- include/linux/platform_data/nixge.h | 19 ++++++++ 2 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 include/linux/platform_data/nixge.h diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c index 670249313ff0..fd8e5b02c459 100644 --- a/drivers/net/ethernet/ni/nixge.c +++ b/drivers/net/ethernet/ni/nixge.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include #include @@ -167,6 +169,7 @@ struct nixge_priv { /* Connection to PHY device */ struct device_node *phy_node; phy_interface_t phy_mode; + struct phy_device *phydev; int link; unsigned int speed; @@ -859,15 +862,25 @@ static void nixge_dma_err_handler(unsigned long data) static int nixge_open(struct net_device *ndev) { struct nixge_priv *priv = netdev_priv(ndev); - struct phy_device *phy; + struct phy_device *phy = NULL; int ret; nixge_device_reset(ndev); - phy = of_phy_connect(ndev, priv->phy_node, - &nixge_handle_link_change, 0, priv->phy_mode); - if (!phy) - return -ENODEV; + if (priv->dev->of_node) { + phy = of_phy_connect(ndev, priv->phy_node, + &nixge_handle_link_change, 0, + priv->phy_mode); + if (!phy) + return -ENODEV; + } else if (priv->phydev) { + ret = phy_connect_direct(ndev, priv->phydev, + &nixge_handle_link_change, + priv->phy_mode); + if (ret) + return ret; + phy = priv->phydev; + } phy_start(phy); @@ -1215,10 +1228,41 @@ static int nixge_of_get_phy(struct nixge_priv *priv, struct device_node *np) return 0; } +static int nixge_pdata_get_phy(struct nixge_priv *priv, + struct nixge_platform_data *pdata) +{ + struct phy_device *phy = NULL; + + if (!pdata) + return -EINVAL; + + if (pdata && pdata->phy_interface == PHY_INTERFACE_MODE_NA) { + struct fixed_phy_status fphy_status = { + .link = 1, + .duplex = pdata->phy_duplex, + .speed = pdata->phy_speed, + .pause = 0, + .asym_pause = 0, + }; + + /* TODO: Pull out GPIO from pdata */ + phy = fixed_phy_register(PHY_POLL, &fphy_status, -1, + NULL); + if (IS_ERR_OR_NULL(phy)) { + dev_err(priv->dev, + "failed to register fixed PHY device\n"); + return -ENODEV; + } + } + priv->phy_mode = pdata->phy_interface; + priv->phydev = phy; + + return 0; +} + static int nixge_mdio_setup(struct nixge_priv *priv, struct device_node *np) { struct mii_bus *bus; - int err; bus = devm_mdiobus_alloc(priv->dev); if (!bus) @@ -1254,6 +1298,7 @@ static void *nixge_get_nvmem_address(struct device *dev) static int nixge_probe(struct platform_device *pdev) { + struct nixge_platform_data *pdata = NULL; struct nixge_priv *priv; struct net_device *ndev; struct resource *dmares; @@ -1320,10 +1365,16 @@ static int nixge_probe(struct platform_device *pdev) err = nixge_of_get_phy(priv, np); if (err) goto free_netdev; + } else { + pdata = dev_get_platdata(&pdev->dev); + err = nixge_pdata_get_phy(priv, pdata); + if (err) + goto free_netdev; } /* only if it's not a fixed link, do we care about MDIO at all */ - if (priv->phy_node && !of_phy_is_fixed_link(np)) { + if ((priv->phy_node && !of_phy_is_fixed_link(np)) || + (pdata && pdata->phy_interface != PHY_INTERFACE_MODE_NA)) { err = nixge_mdio_setup(priv, np); if (err) { dev_err(&pdev->dev, "error registering mdio bus"); @@ -1347,6 +1398,9 @@ static int nixge_probe(struct platform_device *pdev) of_phy_deregister_fixed_link(np); of_node_put(np); } + + if (priv->phydev && phy_is_pseudo_fixed_link(priv->phydev)) + fixed_phy_unregister(priv->phydev); free_netdev: free_netdev(ndev); @@ -1357,6 +1411,7 @@ static int nixge_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); struct nixge_priv *priv = netdev_priv(ndev); + struct device_node *np = pdev->dev.of_node; unregister_netdev(ndev); @@ -1365,6 +1420,8 @@ static int nixge_remove(struct platform_device *pdev) if (np && of_phy_is_fixed_link(np)) of_phy_deregister_fixed_link(np); + else if (priv->phydev && phy_is_pseudo_fixed_link(priv->phydev)) + fixed_phy_unregister(priv->phydev); free_netdev(ndev); diff --git a/include/linux/platform_data/nixge.h b/include/linux/platform_data/nixge.h new file mode 100644 index 000000000000..aa5dd5760074 --- /dev/null +++ b/include/linux/platform_data/nixge.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2018 National Instruments Corp. + * + * Author: Moritz Fischer + */ + +#ifndef __NIXGE_PDATA_H__ +#define __NIXGE_PDATA_H__ + +#include + +struct nixge_platform_data { + phy_interface_t phy_interface; + int phy_speed; + int phy_duplex; +}; + +#endif /* __NIXGE_PDATA_H__ */ + From patchwork Thu Aug 30 00:40:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Moritz Fischer X-Patchwork-Id: 963713 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 4213ms1PyGz9s4v for ; Thu, 30 Aug 2018 10:50:05 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727317AbeH3Et1 (ORCPT ); Thu, 30 Aug 2018 00:49:27 -0400 Received: from mail-pf1-f196.google.com ([209.85.210.196]:45931 "EHLO mail-pf1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727272AbeH3Et1 (ORCPT ); Thu, 30 Aug 2018 00:49:27 -0400 Received: by mail-pf1-f196.google.com with SMTP id i26-v6so3036872pfo.12 for ; Wed, 29 Aug 2018 17:49:57 -0700 (PDT) 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=NShTzSlFYlqtga5d7M/J1wLZLiAga3Nbz09nG1fvud0=; b=ss21+v3AvEhUW8VnYqogGh21e6s+xfZCDj54DYVQY+TCOo4pnP+BCeotn7APHEqtN5 AziI2TZesqOdURHt02MXnpkvgkh1ug3LVsVQV1suWPxRwgupZCPnKvZndJ/7sZldrR+5 2SA6O7ioHx3cga2IMZR/jxCXcodgP3azDjbiOknO1qYitsIR+Z+MBRr5zoSbTgNHiCUV U/Q9/aR41Wgv9ZcHUL0bS/ZCeBqlLolpqIZ1JbNlKJudqFrSzIbMA1g5gcYC1pKLkJ4B J0GzwTpjHNFBR0J5ihAllcfpCjYWORiVZl5LQMZgXsEt6cIywnbuzdJJ9GI+61+jSIQ0 2WIA== X-Gm-Message-State: APzg51D5Hp0bC0Nj+oBrfhosys6/x60W8lzF7gIggkDf28VgHh6mGT2v HxaJU85bK1CkLf0kTW0tGgkSOg== X-Google-Smtp-Source: ANB0VdYaAvlMtvwEj/UTMyZC0S4pswjiBy76pneVoc3OadgIYggBoKFK5nSe4WhVWbwBUxWDSm5GzQ== X-Received: by 2002:a62:858c:: with SMTP id m12-v6mr8159709pfk.173.1535590197251; Wed, 29 Aug 2018 17:49:57 -0700 (PDT) Received: from localhost ([207.114.172.147]) by smtp.gmail.com with ESMTPSA id a15-v6sm8736529pfe.32.2018.08.29.17.49.56 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 29 Aug 2018 17:49:56 -0700 (PDT) From: Moritz Fischer To: davem@davemloft.net Cc: keescook@chromium.org, f.fainelli@gmail.com, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, alex.williams@ni.com, Moritz Fischer Subject: [PATCH net-next 3/3] net: nixge: Use sysdev instead of ndev->dev.parent for DMA Date: Wed, 29 Aug 2018 17:40:46 -0700 Message-Id: <20180830004046.9417-4-mdf@kernel.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180830004046.9417-1-mdf@kernel.org> References: <20180830004046.9417-1-mdf@kernel.org> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Use sysdev instead of ndev->dev.parent for DMA in order to enable usecases where an IOMMU might get in the way otherwise. In the PCIe wrapper case on x86 the IOMMU group is not inherited by the platform device that is created as a subdevice of the PCI wrapper driver. Signed-off-by: Moritz Fischer --- Hi, not this patch is still in the early stages, and as the rest of this series goes on top of [1]. The actual parent device might still change since the parent device driver is still under development. If there are clever suggestions on how to generalize the assignment of sysdev, I'm all ears. Thanks for your time, Moritz [1] https://lkml.org/lkml/2018/8/28/1011 --- drivers/net/ethernet/ni/nixge.c | 50 +++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c index fd8e5b02c459..25fb1642d558 100644 --- a/drivers/net/ethernet/ni/nixge.c +++ b/drivers/net/ethernet/ni/nixge.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -165,6 +166,7 @@ struct nixge_priv { struct net_device *ndev; struct napi_struct napi; struct device *dev; + struct device *sysdev; /* Connection to PHY device */ struct device_node *phy_node; @@ -250,7 +252,7 @@ static void nixge_hw_dma_bd_release(struct net_device *ndev) phys_addr = nixge_hw_dma_bd_get_addr(&priv->rx_bd_v[i], phys); - dma_unmap_single(ndev->dev.parent, phys_addr, + dma_unmap_single(priv->sysdev, phys_addr, NIXGE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); @@ -261,16 +263,16 @@ static void nixge_hw_dma_bd_release(struct net_device *ndev) } if (priv->rx_bd_v) - dma_free_coherent(ndev->dev.parent, + dma_free_coherent(priv->sysdev, sizeof(*priv->rx_bd_v) * RX_BD_NUM, priv->rx_bd_v, priv->rx_bd_p); if (priv->tx_skb) - devm_kfree(ndev->dev.parent, priv->tx_skb); + devm_kfree(priv->sysdev, priv->tx_skb); if (priv->tx_bd_v) - dma_free_coherent(ndev->dev.parent, + dma_free_coherent(priv->sysdev, sizeof(*priv->tx_bd_v) * TX_BD_NUM, priv->tx_bd_v, priv->tx_bd_p); @@ -290,19 +292,19 @@ static int nixge_hw_dma_bd_init(struct net_device *ndev) priv->rx_bd_ci = 0; /* Allocate the Tx and Rx buffer descriptors. */ - priv->tx_bd_v = dma_zalloc_coherent(ndev->dev.parent, + priv->tx_bd_v = dma_zalloc_coherent(priv->sysdev, sizeof(*priv->tx_bd_v) * TX_BD_NUM, &priv->tx_bd_p, GFP_KERNEL); if (!priv->tx_bd_v) goto out; - priv->tx_skb = devm_kcalloc(ndev->dev.parent, + priv->tx_skb = devm_kcalloc(priv->sysdev, TX_BD_NUM, sizeof(*priv->tx_skb), GFP_KERNEL); if (!priv->tx_skb) goto out; - priv->rx_bd_v = dma_zalloc_coherent(ndev->dev.parent, + priv->rx_bd_v = dma_zalloc_coherent(priv->sysdev, sizeof(*priv->rx_bd_v) * RX_BD_NUM, &priv->rx_bd_p, GFP_KERNEL); if (!priv->rx_bd_v) @@ -327,7 +329,7 @@ static int nixge_hw_dma_bd_init(struct net_device *ndev) goto out; nixge_hw_dma_bd_set_offset(&priv->rx_bd_v[i], skb); - phys = dma_map_single(ndev->dev.parent, skb->data, + phys = dma_map_single(priv->sysdev, skb->data, NIXGE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); @@ -438,10 +440,10 @@ static void nixge_tx_skb_unmap(struct nixge_priv *priv, { if (tx_skb->mapping) { if (tx_skb->mapped_as_page) - dma_unmap_page(priv->ndev->dev.parent, tx_skb->mapping, + dma_unmap_page(priv->sysdev, tx_skb->mapping, tx_skb->size, DMA_TO_DEVICE); else - dma_unmap_single(priv->ndev->dev.parent, + dma_unmap_single(priv->sysdev, tx_skb->mapping, tx_skb->size, DMA_TO_DEVICE); tx_skb->mapping = 0; @@ -519,9 +521,9 @@ static int nixge_start_xmit(struct sk_buff *skb, struct net_device *ndev) return NETDEV_TX_OK; } - cur_phys = dma_map_single(ndev->dev.parent, skb->data, + cur_phys = dma_map_single(priv->sysdev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); - if (dma_mapping_error(ndev->dev.parent, cur_phys)) + if (dma_mapping_error(priv->sysdev, cur_phys)) goto drop; nixge_hw_dma_bd_set_phys(cur_p, cur_phys); @@ -539,10 +541,10 @@ static int nixge_start_xmit(struct sk_buff *skb, struct net_device *ndev) tx_skb = &priv->tx_skb[priv->tx_bd_tail]; frag = &skb_shinfo(skb)->frags[ii]; - cur_phys = skb_frag_dma_map(ndev->dev.parent, frag, 0, + cur_phys = skb_frag_dma_map(priv->sysdev, frag, 0, skb_frag_size(frag), DMA_TO_DEVICE); - if (dma_mapping_error(ndev->dev.parent, cur_phys)) + if (dma_mapping_error(priv->sysdev, cur_phys)) goto frag_err; nixge_hw_dma_bd_set_phys(cur_p, cur_phys); @@ -579,7 +581,7 @@ static int nixge_start_xmit(struct sk_buff *skb, struct net_device *ndev) cur_p = &priv->tx_bd_v[priv->tx_bd_tail]; cur_p->status = 0; } - dma_unmap_single(priv->ndev->dev.parent, + dma_unmap_single(priv->sysdev, tx_skb->mapping, tx_skb->size, DMA_TO_DEVICE); drop: @@ -611,7 +613,7 @@ static int nixge_recv(struct net_device *ndev, int budget) if (length > NIXGE_MAX_JUMBO_FRAME_SIZE) length = NIXGE_MAX_JUMBO_FRAME_SIZE; - dma_unmap_single(ndev->dev.parent, + dma_unmap_single(priv->sysdev, nixge_hw_dma_bd_get_addr(cur_p, phys), NIXGE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); @@ -636,10 +638,10 @@ static int nixge_recv(struct net_device *ndev, int budget) if (!new_skb) return packets; - cur_phys = dma_map_single(ndev->dev.parent, new_skb->data, + cur_phys = dma_map_single(priv->sysdev, new_skb->data, NIXGE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE); - if (dma_mapping_error(ndev->dev.parent, cur_phys)) { + if (dma_mapping_error(priv->sysdev, cur_phys)) { /* FIXME: bail out and clean up */ netdev_err(ndev, "Failed to map ...\n"); } @@ -1303,6 +1305,7 @@ static int nixge_probe(struct platform_device *pdev) struct net_device *ndev; struct resource *dmares; struct device_node *np; + struct device *sysdev; const u8 *mac_addr; int err; @@ -1331,9 +1334,20 @@ static int nixge_probe(struct platform_device *pdev) eth_hw_addr_random(ndev); } + sysdev = &pdev->dev; +#ifdef CONFIG_PCI + /* if this is a subdevice of a PCI device we'll have to + * make sure we'll use parent instead of our own platform + * device to make sure the DMA API if we use an IOMMU + */ + if (sysdev->parent && sysdev->parent->bus == &pci_bus_type) + sysdev = sysdev->parent; +#endif + priv = netdev_priv(ndev); priv->ndev = ndev; priv->dev = &pdev->dev; + priv->sysdev = sysdev; netif_napi_add(ndev, &priv->napi, nixge_poll, NAPI_POLL_WEIGHT);