From patchwork Sat Dec 21 19:36:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 1214572 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 (no SPF record) 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="WlaS7byV"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47gG8N2Cf4z9sPc for ; Sun, 22 Dec 2019 06:36:52 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727173AbfLUTgo (ORCPT ); Sat, 21 Dec 2019 14:36:44 -0500 Received: from mail-pl1-f196.google.com ([209.85.214.196]:41973 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726107AbfLUTgn (ORCPT ); Sat, 21 Dec 2019 14:36:43 -0500 Received: by mail-pl1-f196.google.com with SMTP id bd4so5534123plb.8; Sat, 21 Dec 2019 11:36:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+LgVazWFqvVcdctdDKHy4vuxqcL6YZfeaQzb1I4YFjU=; b=WlaS7byVzvG1Wlro8BIzXOv1kC2r2PnuHfrhpNThLLwCGXpy61kSKxnQOxyFVp8h1d C1dQKYsu211z+iYkO2RX6o80c+81ulcRfU/wY42cMKCsSg/IHusFRPs4vDadpZpcR9aS /H1081xabVqu+XznpOakrTEZ3JjKmi/xbQ321gehTsgU8keXVeFkkKGZRYAfHrEpUyyh 958epaOMAGT3Cub3jvWPOEMV/F0axi7HuWdjuy5rUCQz9Swh9Qopn/kcRqZRAzX8CcRi ZnaMJapYky8EVm6jXQSJdBXx8R74AoGgQJmlCZhQYATniYkVvKsGYuLTxdlJbWyjvl9H SinQ== 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:mime-version:content-transfer-encoding; bh=+LgVazWFqvVcdctdDKHy4vuxqcL6YZfeaQzb1I4YFjU=; b=byo7kbg8TyyHhiAweFXZAiKnAH3v6XOzlwjeYZidttIArXydyfbx2X0rm8ILJ93L8q h+/+PMjeyvA+YJIJe+M03tx9l/Be2NRHsDbwUL4OJaLsPxLEvq0vwo9fuZK5I1wW8UhM 31eM1/GChKrqsKvyWPKH/vpsEAMIaiE7bZppSuuy2aXpIM3z49u897r+K/i+nQrOsu4k LqW3KQDpiCCFUdw88WCQ30o+0l1jm3doj1+NSMjBqJLqBt6Gb/6FjsFUX94mHYJElaLN kE5OgR/BoLTT4Ps47pkWLquUAXAwhFIcmyFa3fvQ0MMA8dN2CzUjup/ivlGb9Y9Q7521 5IIg== X-Gm-Message-State: APjAAAVqymZ6e6vLaiR9Ed60qZ22uxi7g7Zk3wIp2ZVc+nV7Ojbp0N0M 7xiIK/ikTZNfIiXJW19E2CNpTETP X-Google-Smtp-Source: APXvYqy+Ex51csdgdISZG+G9ikjtP1SCgW4Ef9+vFCZjpcaXFapDQKz8n7OPURMrV56bc+tGgLhfRQ== X-Received: by 2002:a17:902:7042:: with SMTP id h2mr2814272plt.271.1576957002655; Sat, 21 Dec 2019 11:36:42 -0800 (PST) Received: from localhost.localdomain (c-73-241-114-122.hsd1.ca.comcast.net. [73.241.114.122]) by smtp.gmail.com with ESMTPSA id y197sm18512603pfc.79.2019.12.21.11.36.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 11:36:42 -0800 (PST) From: Richard Cochran To: netdev@vger.kernel.org Cc: David Miller , devicetree@vger.kernel.org, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Jacob Keller , Jakub Kicinski , Mark Rutland , Miroslav Lichvar , Murali Karicheri , Rob Herring , Willem de Bruijn , Wingman Kwok Subject: [PATCH V8 net-next 01/12] net: phy: Introduce helper functions for time stamping support. Date: Sat, 21 Dec 2019 11:36:27 -0800 Message-Id: <5d7df80cc0dfce0204124f7dc4283c7126f24c33.1576956342.git.richardcochran@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Some parts of the networking stack and at least one driver test fields within the 'struct phy_device' in order to query time stamping capabilities and to invoke time stamping methods. This patch adds a functional interface around the time stamping fields. This will allow insulating the callers from future changes to the details of the time stamping implemenation. Signed-off-by: Richard Cochran Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli --- include/linux/phy.h | 60 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/include/linux/phy.h b/include/linux/phy.h index 5032d453ac66..fc51aacb03a7 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -936,6 +936,66 @@ static inline bool phy_polling_mode(struct phy_device *phydev) return phydev->irq == PHY_POLL; } +/** + * phy_has_hwtstamp - Tests whether a PHY time stamp configuration. + * @phydev: the phy_device struct + */ +static inline bool phy_has_hwtstamp(struct phy_device *phydev) +{ + return phydev && phydev->drv && phydev->drv->hwtstamp; +} + +/** + * phy_has_rxtstamp - Tests whether a PHY supports receive time stamping. + * @phydev: the phy_device struct + */ +static inline bool phy_has_rxtstamp(struct phy_device *phydev) +{ + return phydev && phydev->drv && phydev->drv->rxtstamp; +} + +/** + * phy_has_tsinfo - Tests whether a PHY reports time stamping and/or + * PTP hardware clock capabilities. + * @phydev: the phy_device struct + */ +static inline bool phy_has_tsinfo(struct phy_device *phydev) +{ + return phydev && phydev->drv && phydev->drv->ts_info; +} + +/** + * phy_has_txtstamp - Tests whether a PHY supports transmit time stamping. + * @phydev: the phy_device struct + */ +static inline bool phy_has_txtstamp(struct phy_device *phydev) +{ + return phydev && phydev->drv && phydev->drv->txtstamp; +} + +static inline int phy_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) +{ + return phydev->drv->hwtstamp(phydev, ifr); +} + +static inline bool phy_rxtstamp(struct phy_device *phydev, struct sk_buff *skb, + int type) +{ + return phydev->drv->rxtstamp(phydev, skb, type); +} + +static inline int phy_ts_info(struct phy_device *phydev, + struct ethtool_ts_info *tsinfo) +{ + return phydev->drv->ts_info(phydev, tsinfo); +} + +static inline void phy_txtstamp(struct phy_device *phydev, struct sk_buff *skb, + int type) +{ + phydev->drv->txtstamp(phydev, skb, type); +} + /** * phy_is_internal - Convenience function for testing if a PHY is internal * @phydev: the phy_device struct From patchwork Sat Dec 21 19:36:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 1214573 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 (no SPF record) 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="QyW7hbI+"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47gG8N6SWTz9sPh for ; Sun, 22 Dec 2019 06:36:52 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727282AbfLUTgp (ORCPT ); Sat, 21 Dec 2019 14:36:45 -0500 Received: from mail-pj1-f65.google.com ([209.85.216.65]:53712 "EHLO mail-pj1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726107AbfLUTgp (ORCPT ); Sat, 21 Dec 2019 14:36:45 -0500 Received: by mail-pj1-f65.google.com with SMTP id n96so5634391pjc.3; Sat, 21 Dec 2019 11:36:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ORrC0T+zd9DLceUTGoVwHDDyI0A9+B1dcciiqwr3CkI=; b=QyW7hbI+sxpDkg85PTgKX5AXFOk6ScXlz2Idq6eGLPXjmaubwFHk7Tk8ywcmpCRmLv E2Jc6gXjdGdsl/+/zxpV/ciEUnw1Px9kEN4YETDYoHwUL6ZQp8t1fEtpnyEV/OHG9vB0 FMQRm1EisEkEvWF59d7AL1nBtDGGZeDktTku8ejV320/H/ETQDEMlkqoSlobkq6QMHwv m4o2p/ClTKpOAYKA6Q4CsWvDAHrGUIa33SgmPJBiVf1nZ0YdxyaDgpRKcq1IXKwual+h zLNF1vvXnzxcrd6JONcQmQBvpX3a42TtHAQHfEnOdPydqzJQNcxZ1c1/PgvPhuHEF83M 9MCQ== 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:mime-version:content-transfer-encoding; bh=ORrC0T+zd9DLceUTGoVwHDDyI0A9+B1dcciiqwr3CkI=; b=HZaYi206rrz/iVJo/nWeMvDx6F0fORlEzxXZhT5bECwGWjp96OqzBFWk/LS4MMiJrY 9DDs3Pf3ZwLZ9s6C7NyZk2klsFcn7HeWQeEOSr8FE8iWlIgJewbdERv/PZQsJo6SsiF3 ZNDDHji5bewBD4HAehOg3f7f0C/DKF1DyrN6FoLzDrixZiej7Lo4owqyXr5rTwA4op53 sNs7xi/MmzFGg5izyWX2QG24Nl8AxucLwkWMvw205zAS1y8YMxtbflyuEaqtKPH+tzIL E/BBJAL/8ne/GbFz97hOB0v8BCEzQYXyuye6J1NuPidr7KTblCBVgdMwzLU671nbNltB J4FA== X-Gm-Message-State: APjAAAUyNc7TWYUBCC2cEPH3jNHJbNgvRXy8NaIyWJx+btaT1AnONWUd OG9NzW5kX7jRN1maGfGu619/LtbN X-Google-Smtp-Source: APXvYqzfi1wKrKw8CopwrAcp7jQxmLtEJO/yPB8W4iXzW1RHQzPNZHRY377dleM5nKbRMhxB94IsTA== X-Received: by 2002:a17:902:d686:: with SMTP id v6mr22893200ply.266.1576957004117; Sat, 21 Dec 2019 11:36:44 -0800 (PST) Received: from localhost.localdomain (c-73-241-114-122.hsd1.ca.comcast.net. [73.241.114.122]) by smtp.gmail.com with ESMTPSA id y197sm18512603pfc.79.2019.12.21.11.36.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 11:36:43 -0800 (PST) From: Richard Cochran To: netdev@vger.kernel.org Cc: David Miller , devicetree@vger.kernel.org, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Jacob Keller , Jakub Kicinski , Mark Rutland , Miroslav Lichvar , Murali Karicheri , Rob Herring , Willem de Bruijn , Wingman Kwok Subject: [PATCH V8 net-next 02/12] net: macvlan: Use the PHY time stamping interface. Date: Sat, 21 Dec 2019 11:36:28 -0800 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The macvlan layer tests fields of the phy_device in order to determine whether to invoke the PHY's tsinfo ethtool callback. This patch replaces the open coded logic with an invocation of the proper methods. Signed-off-by: Richard Cochran Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli --- drivers/net/macvlan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 05631d97eeb4..d066cf58c926 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -1036,8 +1036,8 @@ static int macvlan_ethtool_get_ts_info(struct net_device *dev, const struct ethtool_ops *ops = real_dev->ethtool_ops; struct phy_device *phydev = real_dev->phydev; - if (phydev && phydev->drv && phydev->drv->ts_info) { - return phydev->drv->ts_info(phydev, info); + if (phy_has_tsinfo(phydev)) { + return phy_ts_info(phydev, info); } else if (ops->get_ts_info) { return ops->get_ts_info(real_dev, info); } else { From patchwork Sat Dec 21 19:36:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 1214574 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 (no SPF record) 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="nc+efDrQ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47gG8P2dlxz9sP3 for ; Sun, 22 Dec 2019 06:36:53 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727334AbfLUTgr (ORCPT ); Sat, 21 Dec 2019 14:36:47 -0500 Received: from mail-pg1-f196.google.com ([209.85.215.196]:35710 "EHLO mail-pg1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726107AbfLUTgq (ORCPT ); Sat, 21 Dec 2019 14:36:46 -0500 Received: by mail-pg1-f196.google.com with SMTP id l24so6717548pgk.2; Sat, 21 Dec 2019 11:36:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=TUdlEwyS6RYa1hXdLY5fHxlvIjKv50oIs66wiKRqcgw=; b=nc+efDrQoSKHiso5ElHqNul4V+XLgFUCmQOc7x9j+51uEFrAI8oqBxtP3jgcEMWVYD QAOooNu3hpjz1an5J54xHEH5hVV0lPteuBmLmORxZjE9InFHgqzFiUeFfPfQ0pFMsh/g v8rCPkZKhOujgeeMKXzh9s9cVXPSw/rSwgdEvfl2D8Ny61s6Xm83PQdBp4uoZ3zPNuev imQ9luhztwzNvBTkAsLk593rMxxWNLfDOtWFK7MW5gpYukMBT4sa+Cg/ev99+vLg2wsm WpE3yjjvWQ65lJ+RKOqzAZIqK62wa2b2vUItn4HCK1N7s0eEzqZJakl0WQ/ojWa/J6yB GqIw== 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:mime-version:content-transfer-encoding; bh=TUdlEwyS6RYa1hXdLY5fHxlvIjKv50oIs66wiKRqcgw=; b=jHSKO+gNM3Goq+DUz1wvo/cK2QAG5OQCrPPBgWCN1C5Qsf0J70kBwQ3utjUCnK0kS1 V++DdJBUVyqlniVFD/E6xqJb40/vfOSTjtSPL50lkj22fXOApx7M0mRHltoIegLOF8y0 6KlKXZBDNKw46JezZqQ48BAPTQLPFBaBAfqU1+WJk+5pXj9pBybRIIEMRdT9c8AfI5T0 8WPWUkI3bMrH7IDCxjpIVToymOl+8kgGoml/angG/kWsfAc+cZ5aPIDOxV9aM6G8AS8a 0sgoH4EgEfPGPcGV2TNabICG1icj7si/TI01+mLTUogTLHv+Nh+roEgAmCBFoDCTqYk4 Gjjw== X-Gm-Message-State: APjAAAWficQLbv+wuLxfeZIp3OaD08BH4no2FcFMXt9lfTfFKJMu2jCP QNliJ5C47ocMuX10ytEkiYN5wH4t X-Google-Smtp-Source: APXvYqyI3FccCVZg+oNY382QRbFZhTd3bSlEINfGQXaxFZ2HXmrADFKCbthurkNmBP/M+49ZurfeFA== X-Received: by 2002:a62:d407:: with SMTP id a7mr21300061pfh.242.1576957005574; Sat, 21 Dec 2019 11:36:45 -0800 (PST) Received: from localhost.localdomain (c-73-241-114-122.hsd1.ca.comcast.net. [73.241.114.122]) by smtp.gmail.com with ESMTPSA id y197sm18512603pfc.79.2019.12.21.11.36.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 11:36:44 -0800 (PST) From: Richard Cochran To: netdev@vger.kernel.org Cc: David Miller , devicetree@vger.kernel.org, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Jacob Keller , Jakub Kicinski , Mark Rutland , Miroslav Lichvar , Murali Karicheri , Rob Herring , Willem de Bruijn , Wingman Kwok Subject: [PATCH V8 net-next 03/12] net: vlan: Use the PHY time stamping interface. Date: Sat, 21 Dec 2019 11:36:29 -0800 Message-Id: <1febd2b2d0a5bd99d70e9e46e8d794bbf8d118cd.1576956342.git.richardcochran@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The vlan layer tests fields of the phy_device in order to determine whether to invoke the PHY's tsinfo ethtool callback. This patch replaces the open coded logic with an invocation of the proper methods. Signed-off-by: Richard Cochran Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli --- net/8021q/vlan_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index e5bff5cc6f97..5ff8059837b4 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -646,8 +646,8 @@ static int vlan_ethtool_get_ts_info(struct net_device *dev, const struct ethtool_ops *ops = vlan->real_dev->ethtool_ops; struct phy_device *phydev = vlan->real_dev->phydev; - if (phydev && phydev->drv && phydev->drv->ts_info) { - return phydev->drv->ts_info(phydev, info); + if (phy_has_tsinfo(phydev)) { + return phy_ts_info(phydev, info); } else if (ops->get_ts_info) { return ops->get_ts_info(vlan->real_dev, info); } else { From patchwork Sat Dec 21 19:36:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 1214575 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 (no SPF record) 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="JWCyDute"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47gG8R2mVMz9sPc for ; Sun, 22 Dec 2019 06:36:54 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727363AbfLUTgt (ORCPT ); Sat, 21 Dec 2019 14:36:49 -0500 Received: from mail-pl1-f193.google.com ([209.85.214.193]:41973 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726107AbfLUTgs (ORCPT ); Sat, 21 Dec 2019 14:36:48 -0500 Received: by mail-pl1-f193.google.com with SMTP id bd4so5534161plb.8; Sat, 21 Dec 2019 11:36:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qdiVljbiL8yD+9AexClzPzh6XW5pK8fMUd89Hf0ztvQ=; b=JWCyDuteLY7rdO/0kmySTegc3VO54aYSr/KZXA8bCLh0Xqy3ZABzEfW2mS/iMz2cAI kOfwPM5IWtqdU/quo5cNwBZMvFqxRCg6F6Ydjc0x3ntRiZfts0Q2HmGTzlEhDbmc6fI9 BA/B7QSEw+wHVH9jfRZ5KzM5sV8KmswYUkRjmceIHzpbQM+MT8koEw4pIgwRAzfJ4jSc rbba8FcXtXaxm0rphcIdVrpVnzqNDXgTzHa3XENFMD5120Hvivt/Ti4gPp+/PnlUhDVb RD1u2OP1DXQLngeHiQA/WGYe6ixfkZZ0AfsBJKbgzyi5IcloUN5TMqYG5uXGURBy8ctj EmDg== 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:mime-version:content-transfer-encoding; bh=qdiVljbiL8yD+9AexClzPzh6XW5pK8fMUd89Hf0ztvQ=; b=nes1JDdlnalwHx4sk/rO+We4RUeVWUVLfou3JFAS27JurMBD2ggLJDMLXVCR+HIY3f WczFFRZ87hJ+KW7nUErA84KDb1W/RZ/c8QoVnmVCIuk0LrjB+1sBelG4rR2gF69IeHSQ fgGMQ2aQ3/z5tgURU94xI2W2/ZMTMru8GUmAmNC4mFEVGKKDHTdYV/IlqTqvWG2ed3dO wUbiQBXhKlBEJls7Db81MdiXwsMRlvUMA2vglosS3O/DSiRjbxhkH7vFSSkohqe/vFRB b6FPEpJZIipZe2o5Nz/cgujdkwB/4tD45L0ZjIi0LKfwrB6Qw+n3Ht9h+Gm1Lfb3nfML xj4w== X-Gm-Message-State: APjAAAVcyUHDGGkFR+D1oMpx2kNtOI3vDHsf8FJY4WZkWAqSkNZ0i2S4 DQQyU3ysD/MNCoACvar/7Kcvg1or X-Google-Smtp-Source: APXvYqyC2g6qvEgsRkqOdN0HiECDlYAABfwx33kVk0U6KryuAIi2gB8Q79TgEF9TecKgf1hBl4+2yg== X-Received: by 2002:a17:902:724a:: with SMTP id c10mr22890345pll.39.1576957006941; Sat, 21 Dec 2019 11:36:46 -0800 (PST) Received: from localhost.localdomain (c-73-241-114-122.hsd1.ca.comcast.net. [73.241.114.122]) by smtp.gmail.com with ESMTPSA id y197sm18512603pfc.79.2019.12.21.11.36.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 11:36:46 -0800 (PST) From: Richard Cochran To: netdev@vger.kernel.org Cc: David Miller , devicetree@vger.kernel.org, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Jacob Keller , Jakub Kicinski , Mark Rutland , Miroslav Lichvar , Murali Karicheri , Rob Herring , Willem de Bruijn , Wingman Kwok Subject: [PATCH V8 net-next 04/12] net: ethtool: Use the PHY time stamping interface. Date: Sat, 21 Dec 2019 11:36:30 -0800 Message-Id: <6dbc095ff1744a2ddeecf98912faddab828affd4.1576956342.git.richardcochran@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The ethtool layer tests fields of the phy_device in order to determine whether to invoke the PHY's tsinfo ethtool callback. This patch replaces the open coded logic with an invocation of the proper methods. Signed-off-by: Richard Cochran Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli --- net/ethtool/ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index aed2c2cf1623..88f7cddf5a6f 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -2096,8 +2096,8 @@ static int ethtool_get_ts_info(struct net_device *dev, void __user *useraddr) memset(&info, 0, sizeof(info)); info.cmd = ETHTOOL_GET_TS_INFO; - if (phydev && phydev->drv && phydev->drv->ts_info) { - err = phydev->drv->ts_info(phydev, &info); + if (phy_has_tsinfo(phydev)) { + err = phy_ts_info(phydev, &info); } else if (ops->get_ts_info) { err = ops->get_ts_info(dev, &info); } else { From patchwork Sat Dec 21 19:36:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 1214576 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 (no SPF record) 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ahk83Fg5"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47gG8T346Wz9sPc for ; Sun, 22 Dec 2019 06:36:57 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727405AbfLUTgz (ORCPT ); Sat, 21 Dec 2019 14:36:55 -0500 Received: from mail-pl1-f195.google.com ([209.85.214.195]:35177 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727339AbfLUTgt (ORCPT ); Sat, 21 Dec 2019 14:36:49 -0500 Received: by mail-pl1-f195.google.com with SMTP id g6so5545575plt.2; Sat, 21 Dec 2019 11:36:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=LZ93AY1+fKpm1lkv7HOM3paCh/zw2D/T/ZiNFPokrAw=; b=ahk83Fg5iFOr5LxXXHbH5RT9e9MD2eV6kteRw7B8tdtbjaxE+slOVsiWHsEo35v5GR sK9oMVGLBtYa6d+3a/DpIGtXcQx+kJ0LZLcbxmIXzi/WuTmnln4bX1RUvDQiISxFC9E6 a3B7g52k+dTMXcQH85oc1mReOWpRaT1QfKjM1/785S9Bju/30w1TQk5PXo/TN0LFW2A7 4gayD9A/Oz76q42h8xFgFZw4butA6ciZGKRbiYpWEYKYsw8oRlU4HRMRNZK+iFsXpzVG 1uSEkcwOzR7OZJWOLR5BFiqH8WXTZf2qwyVmRAAHKBc4kKxh5/TKbPBk5kqUn/AOP8/L T5LQ== 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:mime-version:content-transfer-encoding; bh=LZ93AY1+fKpm1lkv7HOM3paCh/zw2D/T/ZiNFPokrAw=; b=IMrZ8TpGTVY2EfrNle7nZ7jIgX5X4gq/OlahgKGKGCVu/5vwdwAlrrnKluDN+WwUsF q2NV4wnrN/twPzh+ChEo/QU1sfRPR2LGaObNU347xDO3NclzrFlzSEk2wFCdwY2HRVTJ 7WeyIczfWdfpOeSlOsM5zvmJaPCkhgCmccMLxGCcJeULpvrcQUmk6cuQdtV/edqz2fUX Zls6JpblyVk61z9siZ4uGAIZCjy4DnbVzvL7/vCp3RgX0AuflIVLK18BEOFV8Jdu71We lqhwzI1WdPCBp3jrV+F3yMbHhocVeB8W4E0ttyjbm1hu6GGhozkjwiA7zjppQ6EWJZmb am+Q== X-Gm-Message-State: APjAAAUQAMqjCo+V+hJY3nFKjUTeEOZNr82qb6579ubPv+QKlni3zLgG TaN7aO8J2Ic36kqvni6X8+rCCvyT X-Google-Smtp-Source: APXvYqyaWfVImWgFzZFryPWHuiQ/Oc9qphIn8ajBahnOWf9g3de5R8OF0TwGPiyXMIvf8xAio76BMA== X-Received: by 2002:a17:90a:a88d:: with SMTP id h13mr23038652pjq.55.1576957008437; Sat, 21 Dec 2019 11:36:48 -0800 (PST) Received: from localhost.localdomain (c-73-241-114-122.hsd1.ca.comcast.net. [73.241.114.122]) by smtp.gmail.com with ESMTPSA id y197sm18512603pfc.79.2019.12.21.11.36.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 11:36:47 -0800 (PST) From: Richard Cochran To: netdev@vger.kernel.org Cc: David Miller , devicetree@vger.kernel.org, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Jacob Keller , Jakub Kicinski , Mark Rutland , Miroslav Lichvar , Murali Karicheri , Rob Herring , Willem de Bruijn , Wingman Kwok Subject: [PATCH V8 net-next 05/12] net: netcp_ethss: Use the PHY time stamping interface. Date: Sat, 21 Dec 2019 11:36:31 -0800 Message-Id: <76cd58c2032f894184aeb2f1e23a59b368f3eb2c.1576956342.git.richardcochran@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The netcp_ethss driver tests fields of the phy_device in order to determine whether to defer to the PHY's time stamping functionality. This patch replaces the open coded logic with an invocation of the proper methods. Signed-off-by: Richard Cochran Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli --- drivers/net/ethernet/ti/netcp_ethss.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/ti/netcp_ethss.c b/drivers/net/ethernet/ti/netcp_ethss.c index 86a3f42a3dcc..1280ccd581d4 100644 --- a/drivers/net/ethernet/ti/netcp_ethss.c +++ b/drivers/net/ethernet/ti/netcp_ethss.c @@ -2533,8 +2533,6 @@ static int gbe_del_vid(void *intf_priv, int vid) } #if IS_ENABLED(CONFIG_TI_CPTS) -#define HAS_PHY_TXTSTAMP(p) ((p)->drv && (p)->drv->txtstamp) -#define HAS_PHY_RXTSTAMP(p) ((p)->drv && (p)->drv->rxtstamp) static void gbe_txtstamp(void *context, struct sk_buff *skb) { @@ -2566,7 +2564,7 @@ static int gbe_txtstamp_mark_pkt(struct gbe_intf *gbe_intf, * We mark it here because skb_tx_timestamp() is called * after all the txhooks are called. */ - if (phydev && HAS_PHY_TXTSTAMP(phydev)) { + if (phy_has_txtstamp(phydev)) { skb_shinfo(p_info->skb)->tx_flags |= SKBTX_IN_PROGRESS; return 0; } @@ -2588,7 +2586,7 @@ static int gbe_rxtstamp(struct gbe_intf *gbe_intf, struct netcp_packet *p_info) if (p_info->rxtstamp_complete) return 0; - if (phydev && HAS_PHY_RXTSTAMP(phydev)) { + if (phy_has_rxtstamp(phydev)) { p_info->rxtstamp_complete = true; return 0; } @@ -2830,7 +2828,7 @@ static int gbe_ioctl(void *intf_priv, struct ifreq *req, int cmd) struct gbe_intf *gbe_intf = intf_priv; struct phy_device *phy = gbe_intf->slave->phy; - if (!phy || !phy->drv->hwtstamp) { + if (!phy_has_hwtstamp(phy)) { switch (cmd) { case SIOCGHWTSTAMP: return gbe_hwtstamp_get(gbe_intf, req); From patchwork Sat Dec 21 19:36:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 1214583 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 (no SPF record) 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="MyGjMkqM"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47gG8f4gwMz9sP3 for ; Sun, 22 Dec 2019 06:37:06 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727386AbfLUTgx (ORCPT ); Sat, 21 Dec 2019 14:36:53 -0500 Received: from mail-pj1-f67.google.com ([209.85.216.67]:50537 "EHLO mail-pj1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726107AbfLUTgu (ORCPT ); Sat, 21 Dec 2019 14:36:50 -0500 Received: by mail-pj1-f67.google.com with SMTP id r67so5628856pjb.0; Sat, 21 Dec 2019 11:36:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=iufX15HyInYqkt5BpnF9hIl241zgF1i5PO7B69MX67w=; b=MyGjMkqM0mdZt4j5JnOVa5hLXaWM63cQX4YChVDAoDaG2TTHoozJ4+w/E/kdimkgX+ pc6ibfflP+lWfnG3VQqZvm5W/k0zU8yspfxwZbf/Kbft8v6Fx6JSsQ6B8VOqlHp7L0GE pDjM86Bn/X+jr6hMSN6CQEQKuKEAg7siXSJvKCJBOTyM11Og7GMukeGq5LStAy2R8E2T aTYJhuNNp3Le6JUxI2YafsRfn7vkAAiNhv/XoyLelUTFs/p6o7Srf6bGD81WefiFs+vo HJPfW6nZGC634albWGQx1T5A/9q0lz+1xkPEABGKaWxs8zQAEzsoFLJ4evDUI6Xwl6vo SogQ== 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:mime-version:content-transfer-encoding; bh=iufX15HyInYqkt5BpnF9hIl241zgF1i5PO7B69MX67w=; b=adH0w8BwuLREjj6OTNCypTZr5fimzuPtriMfGNqb25zGoEdnT2aENN8SZa7xLKjHPZ WIkNeusGfm3lfOEqaBZodcLRg9foFvMn9okqpza5D50e3d1DxhGobT0teQFae36PLN6x 3IILl6Pvf7Wv4/rApzwAQNzACJrChJlJD3SruQ+HGZHQzSar8LKMuisB1CntqmDHdU9o gQ+mbAckUWfS0739wfrRklPa6GIDIzhIjf2wZJzZIK+IumaefthY345pKItjBMJiKGcX Qd4PJC3EB/cIy7pjMizCxl1jsPaMmzEiV4fITyIhyoxuFYS+gz2SBciEcruXfzPJ0OKO qPSg== X-Gm-Message-State: APjAAAV7k4UfDm8wvm8RU7qOKTSy6ErRI5MnmUjSK09qWOBQrjilyvqZ c5qqFF3b/1/XVT4/5Voutbtf1KSI X-Google-Smtp-Source: APXvYqzqvg9i0YnGGTSSZN17isYLVDaza6jFl7oSWzlolylv0vZvQ7NE479FGzbsIpdq7LFuT7eLuA== X-Received: by 2002:a17:90b:4383:: with SMTP id in3mr5519564pjb.111.1576957009810; Sat, 21 Dec 2019 11:36:49 -0800 (PST) Received: from localhost.localdomain (c-73-241-114-122.hsd1.ca.comcast.net. [73.241.114.122]) by smtp.gmail.com with ESMTPSA id y197sm18512603pfc.79.2019.12.21.11.36.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 11:36:49 -0800 (PST) From: Richard Cochran To: netdev@vger.kernel.org Cc: David Miller , devicetree@vger.kernel.org, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Jacob Keller , Jakub Kicinski , Mark Rutland , Miroslav Lichvar , Murali Karicheri , Rob Herring , Willem de Bruijn , Wingman Kwok Subject: [PATCH V8 net-next 06/12] net: phy: dp83640: Move the probe and remove methods around. Date: Sat, 21 Dec 2019 11:36:32 -0800 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org An upcoming patch will change how the PHY time stamping functions are registered with the networking stack, and adapting this driver would entail adding forward declarations for four time stamping methods. However, forward declarations are considered to be stylistic defects. This patch avoids the issue by moving the probe and remove methods immediately above the phy_driver interface structure. Signed-off-by: Richard Cochran Reviewed-by: Andrew Lunn --- drivers/net/phy/dp83640.c | 180 +++++++++++++++++++------------------- 1 file changed, 90 insertions(+), 90 deletions(-) diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 8f241b57fcf6..b58abdb5491e 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -1131,96 +1131,6 @@ static void dp83640_clock_put(struct dp83640_clock *clock) mutex_unlock(&clock->clock_lock); } -static int dp83640_probe(struct phy_device *phydev) -{ - struct dp83640_clock *clock; - struct dp83640_private *dp83640; - int err = -ENOMEM, i; - - if (phydev->mdio.addr == BROADCAST_ADDR) - return 0; - - clock = dp83640_clock_get_bus(phydev->mdio.bus); - if (!clock) - goto no_clock; - - dp83640 = kzalloc(sizeof(struct dp83640_private), GFP_KERNEL); - if (!dp83640) - goto no_memory; - - dp83640->phydev = phydev; - INIT_DELAYED_WORK(&dp83640->ts_work, rx_timestamp_work); - - INIT_LIST_HEAD(&dp83640->rxts); - INIT_LIST_HEAD(&dp83640->rxpool); - for (i = 0; i < MAX_RXTS; i++) - list_add(&dp83640->rx_pool_data[i].list, &dp83640->rxpool); - - phydev->priv = dp83640; - - spin_lock_init(&dp83640->rx_lock); - skb_queue_head_init(&dp83640->rx_queue); - skb_queue_head_init(&dp83640->tx_queue); - - dp83640->clock = clock; - - if (choose_this_phy(clock, phydev)) { - clock->chosen = dp83640; - clock->ptp_clock = ptp_clock_register(&clock->caps, - &phydev->mdio.dev); - if (IS_ERR(clock->ptp_clock)) { - err = PTR_ERR(clock->ptp_clock); - goto no_register; - } - } else - list_add_tail(&dp83640->list, &clock->phylist); - - dp83640_clock_put(clock); - return 0; - -no_register: - clock->chosen = NULL; - kfree(dp83640); -no_memory: - dp83640_clock_put(clock); -no_clock: - return err; -} - -static void dp83640_remove(struct phy_device *phydev) -{ - struct dp83640_clock *clock; - struct list_head *this, *next; - struct dp83640_private *tmp, *dp83640 = phydev->priv; - - if (phydev->mdio.addr == BROADCAST_ADDR) - return; - - enable_status_frames(phydev, false); - cancel_delayed_work_sync(&dp83640->ts_work); - - skb_queue_purge(&dp83640->rx_queue); - skb_queue_purge(&dp83640->tx_queue); - - clock = dp83640_clock_get(dp83640->clock); - - if (dp83640 == clock->chosen) { - ptp_clock_unregister(clock->ptp_clock); - clock->chosen = NULL; - } else { - list_for_each_safe(this, next, &clock->phylist) { - tmp = list_entry(this, struct dp83640_private, list); - if (tmp == dp83640) { - list_del_init(&tmp->list); - break; - } - } - } - - dp83640_clock_put(clock); - kfree(dp83640); -} - static int dp83640_soft_reset(struct phy_device *phydev) { int ret; @@ -1526,6 +1436,96 @@ static int dp83640_ts_info(struct phy_device *dev, struct ethtool_ts_info *info) return 0; } +static int dp83640_probe(struct phy_device *phydev) +{ + struct dp83640_clock *clock; + struct dp83640_private *dp83640; + int err = -ENOMEM, i; + + if (phydev->mdio.addr == BROADCAST_ADDR) + return 0; + + clock = dp83640_clock_get_bus(phydev->mdio.bus); + if (!clock) + goto no_clock; + + dp83640 = kzalloc(sizeof(struct dp83640_private), GFP_KERNEL); + if (!dp83640) + goto no_memory; + + dp83640->phydev = phydev; + INIT_DELAYED_WORK(&dp83640->ts_work, rx_timestamp_work); + + INIT_LIST_HEAD(&dp83640->rxts); + INIT_LIST_HEAD(&dp83640->rxpool); + for (i = 0; i < MAX_RXTS; i++) + list_add(&dp83640->rx_pool_data[i].list, &dp83640->rxpool); + + phydev->priv = dp83640; + + spin_lock_init(&dp83640->rx_lock); + skb_queue_head_init(&dp83640->rx_queue); + skb_queue_head_init(&dp83640->tx_queue); + + dp83640->clock = clock; + + if (choose_this_phy(clock, phydev)) { + clock->chosen = dp83640; + clock->ptp_clock = ptp_clock_register(&clock->caps, + &phydev->mdio.dev); + if (IS_ERR(clock->ptp_clock)) { + err = PTR_ERR(clock->ptp_clock); + goto no_register; + } + } else + list_add_tail(&dp83640->list, &clock->phylist); + + dp83640_clock_put(clock); + return 0; + +no_register: + clock->chosen = NULL; + kfree(dp83640); +no_memory: + dp83640_clock_put(clock); +no_clock: + return err; +} + +static void dp83640_remove(struct phy_device *phydev) +{ + struct dp83640_clock *clock; + struct list_head *this, *next; + struct dp83640_private *tmp, *dp83640 = phydev->priv; + + if (phydev->mdio.addr == BROADCAST_ADDR) + return; + + enable_status_frames(phydev, false); + cancel_delayed_work_sync(&dp83640->ts_work); + + skb_queue_purge(&dp83640->rx_queue); + skb_queue_purge(&dp83640->tx_queue); + + clock = dp83640_clock_get(dp83640->clock); + + if (dp83640 == clock->chosen) { + ptp_clock_unregister(clock->ptp_clock); + clock->chosen = NULL; + } else { + list_for_each_safe(this, next, &clock->phylist) { + tmp = list_entry(this, struct dp83640_private, list); + if (tmp == dp83640) { + list_del_init(&tmp->list); + break; + } + } + } + + dp83640_clock_put(clock); + kfree(dp83640); +} + static struct phy_driver dp83640_driver = { .phy_id = DP83640_PHY_ID, .phy_id_mask = 0xfffffff0, From patchwork Sat Dec 21 19:36:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 1214585 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 (no SPF record) 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Ju8F89K+"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47gG8m1k97z9sQp for ; Sun, 22 Dec 2019 06:37:11 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727464AbfLUThK (ORCPT ); Sat, 21 Dec 2019 14:37:10 -0500 Received: from mail-pl1-f196.google.com ([209.85.214.196]:35180 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727370AbfLUTgw (ORCPT ); Sat, 21 Dec 2019 14:36:52 -0500 Received: by mail-pl1-f196.google.com with SMTP id g6so5545590plt.2; Sat, 21 Dec 2019 11:36:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=dzpxMgQGPBxKFPxA2ZWhu0FYgZIkokXEkuR+Pbt8+yo=; b=Ju8F89K+YTXrPc3laetjNwYwkNpNWJRBXBbXV7Dglup96/2v6l8/BVkL8qgyMcw4jg 3+XQGfAY7JbMs5nskSsRkOif8MEQqC1K/5/jVFA3btO9SXxkzgYOhJzvFN8/tYwUal53 4YtK8F4gVB6xUN4OpuA/go++565BKLHHhSraS7niug2k+fPwcmpSfEFsTKnjIsPzKTca jReCl988NX2gQuuxnZKJ2n0ZumZ0+yk6pdO7NdsV+u+Z/mj2rW4QaXT3BPFotd+X6JZ4 14kkTedSbOhepoSoSaC23NgWFRT9lGJmEeGM5kFpVfQOa5OWTJ9cxrradBU9/acDyeOJ JQdg== 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:mime-version:content-transfer-encoding; bh=dzpxMgQGPBxKFPxA2ZWhu0FYgZIkokXEkuR+Pbt8+yo=; b=tEt+1s3W7lBEAiWbU4T18c4ONSHjrX4YXqHDlnNICCfBpARwhdlfK7iqZz23Mirfeb pcv5VJopgX+p4zUFlJMwvESepdR1CDB7QDtpS/XmPJ4LeHhEEsKHwBtf5S5m2iD5E9lQ BtUckue5QDiSLshh6K4h+qeBixcXke00NXlFwMCczqmTrsdGC3XRCVbAadiPehE4W29e V5PcAqaK18Og9XraM2AbVi0tLpbMSG6rD6vEnIMe3yf7W/3bdSofeXM1XnqVV9Yw5CgB Y4iE3n3uFiOm3dm5GZMw8WkyOe0sz9SFk5YZk9oAztjZ/DEoIV5X3wsF8W+qO4zZsZpi 6vEQ== X-Gm-Message-State: APjAAAVZX62GwHUDyTcmGPCYUd209iNdFgjxLwePI6WY4kwhYwAlyH82 D69w7Lo7sZGAhrzQbgKw49farkkj X-Google-Smtp-Source: APXvYqyJKiGfwFGb4okd3ffyvD9DaZs9i1a9/7/VK/wXHYKV2xV5lyx3VmP9RD8/J3Yr5+QxuSQEZA== X-Received: by 2002:a17:90a:b10a:: with SMTP id z10mr24826938pjq.115.1576957011194; Sat, 21 Dec 2019 11:36:51 -0800 (PST) Received: from localhost.localdomain (c-73-241-114-122.hsd1.ca.comcast.net. [73.241.114.122]) by smtp.gmail.com with ESMTPSA id y197sm18512603pfc.79.2019.12.21.11.36.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 11:36:50 -0800 (PST) From: Richard Cochran To: netdev@vger.kernel.org Cc: David Miller , devicetree@vger.kernel.org, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Jacob Keller , Jakub Kicinski , Mark Rutland , Miroslav Lichvar , Murali Karicheri , Rob Herring , Willem de Bruijn , Wingman Kwok Subject: [PATCH V8 net-next 07/12] net: Introduce a new MII time stamping interface. Date: Sat, 21 Dec 2019 11:36:33 -0800 Message-Id: <08ba968da04b8d0f2d663fd018109b52dfafe5c6.1576956342.git.richardcochran@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Currently the stack supports time stamping in PHY devices. However, there are newer, non-PHY devices that can snoop an MII bus and provide time stamps. In order to support such devices, this patch introduces a new interface to be used by both PHY and non-PHY devices. In addition, the one and only user of the old PHY time stamping API is converted to the new interface. Signed-off-by: Richard Cochran Reviewed-by: Andrew Lunn --- drivers/net/phy/dp83640.c | 39 +++++++++++++--------- drivers/net/phy/phy.c | 4 +-- drivers/net/phy/phy_device.c | 2 ++ include/linux/mii_timestamper.h | 58 +++++++++++++++++++++++++++++++++ include/linux/phy.h | 41 ++++++----------------- net/core/timestamping.c | 20 ++++++------ 6 files changed, 106 insertions(+), 58 deletions(-) create mode 100644 include/linux/mii_timestamper.h diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index b58abdb5491e..ac72a324fcd1 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -98,6 +98,7 @@ struct dp83640_private { struct list_head list; struct dp83640_clock *clock; struct phy_device *phydev; + struct mii_timestamper mii_ts; struct delayed_work ts_work; int hwts_tx_en; int hwts_rx_en; @@ -1229,9 +1230,10 @@ static int dp83640_config_intr(struct phy_device *phydev) } } -static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) +static int dp83640_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr) { - struct dp83640_private *dp83640 = phydev->priv; + struct dp83640_private *dp83640 = + container_of(mii_ts, struct dp83640_private, mii_ts); struct hwtstamp_config cfg; u16 txcfg0, rxcfg0; @@ -1307,8 +1309,8 @@ static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) mutex_lock(&dp83640->clock->extreg_lock); - ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0); - ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0); + ext_write(0, dp83640->phydev, PAGE5, PTP_TXCFG0, txcfg0); + ext_write(0, dp83640->phydev, PAGE5, PTP_RXCFG0, rxcfg0); mutex_unlock(&dp83640->clock->extreg_lock); @@ -1338,10 +1340,11 @@ static void rx_timestamp_work(struct work_struct *work) schedule_delayed_work(&dp83640->ts_work, SKB_TIMESTAMP_TIMEOUT); } -static bool dp83640_rxtstamp(struct phy_device *phydev, +static bool dp83640_rxtstamp(struct mii_timestamper *mii_ts, struct sk_buff *skb, int type) { - struct dp83640_private *dp83640 = phydev->priv; + struct dp83640_private *dp83640 = + container_of(mii_ts, struct dp83640_private, mii_ts); struct dp83640_skb_info *skb_info = (struct dp83640_skb_info *)skb->cb; struct list_head *this, *next; struct rxts *rxts; @@ -1387,11 +1390,12 @@ static bool dp83640_rxtstamp(struct phy_device *phydev, return true; } -static void dp83640_txtstamp(struct phy_device *phydev, +static void dp83640_txtstamp(struct mii_timestamper *mii_ts, struct sk_buff *skb, int type) { struct dp83640_skb_info *skb_info = (struct dp83640_skb_info *)skb->cb; - struct dp83640_private *dp83640 = phydev->priv; + struct dp83640_private *dp83640 = + container_of(mii_ts, struct dp83640_private, mii_ts); switch (dp83640->hwts_tx_en) { @@ -1414,9 +1418,11 @@ static void dp83640_txtstamp(struct phy_device *phydev, } } -static int dp83640_ts_info(struct phy_device *dev, struct ethtool_ts_info *info) +static int dp83640_ts_info(struct mii_timestamper *mii_ts, + struct ethtool_ts_info *info) { - struct dp83640_private *dp83640 = dev->priv; + struct dp83640_private *dp83640 = + container_of(mii_ts, struct dp83640_private, mii_ts); info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | @@ -1454,13 +1460,18 @@ static int dp83640_probe(struct phy_device *phydev) goto no_memory; dp83640->phydev = phydev; - INIT_DELAYED_WORK(&dp83640->ts_work, rx_timestamp_work); + dp83640->mii_ts.rxtstamp = dp83640_rxtstamp; + dp83640->mii_ts.txtstamp = dp83640_txtstamp; + dp83640->mii_ts.hwtstamp = dp83640_hwtstamp; + dp83640->mii_ts.ts_info = dp83640_ts_info; + INIT_DELAYED_WORK(&dp83640->ts_work, rx_timestamp_work); INIT_LIST_HEAD(&dp83640->rxts); INIT_LIST_HEAD(&dp83640->rxpool); for (i = 0; i < MAX_RXTS; i++) list_add(&dp83640->rx_pool_data[i].list, &dp83640->rxpool); + phydev->mii_ts = &dp83640->mii_ts; phydev->priv = dp83640; spin_lock_init(&dp83640->rx_lock); @@ -1501,6 +1512,8 @@ static void dp83640_remove(struct phy_device *phydev) if (phydev->mdio.addr == BROADCAST_ADDR) return; + phydev->mii_ts = NULL; + enable_status_frames(phydev, false); cancel_delayed_work_sync(&dp83640->ts_work); @@ -1537,10 +1550,6 @@ static struct phy_driver dp83640_driver = { .config_init = dp83640_config_init, .ack_interrupt = dp83640_ack_interrupt, .config_intr = dp83640_config_intr, - .ts_info = dp83640_ts_info, - .hwtstamp = dp83640_hwtstamp, - .rxtstamp = dp83640_rxtstamp, - .txtstamp = dp83640_txtstamp, }; static int __init dp83640_init(void) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 80be4d691e5b..541ed01496bf 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -422,8 +422,8 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) return 0; case SIOCSHWTSTAMP: - if (phydev->drv && phydev->drv->hwtstamp) - return phydev->drv->hwtstamp(phydev, ifr); + if (phydev->mii_ts && phydev->mii_ts->hwtstamp) + return phydev->mii_ts->hwtstamp(phydev->mii_ts, ifr); /* fall through */ default: diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 0887ed2bb050..ee45838f90c9 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -919,6 +919,8 @@ static void phy_link_change(struct phy_device *phydev, bool up, bool do_carrier) netif_carrier_off(netdev); } phydev->adjust_link(netdev); + if (phydev->mii_ts && phydev->mii_ts->link_state) + phydev->mii_ts->link_state(phydev->mii_ts, phydev); } /** diff --git a/include/linux/mii_timestamper.h b/include/linux/mii_timestamper.h new file mode 100644 index 000000000000..36002386029c --- /dev/null +++ b/include/linux/mii_timestamper.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Support for generic time stamping devices on MII buses. + * Copyright (C) 2018 Richard Cochran + */ +#ifndef _LINUX_MII_TIMESTAMPER_H +#define _LINUX_MII_TIMESTAMPER_H + +#include +#include +#include + +struct phy_device; + +/** + * struct mii_timestamper - Callback interface to MII time stamping devices. + * + * @rxtstamp: Requests a Rx timestamp for 'skb'. If the skb is accepted, + * the MII time stamping device promises to deliver it using + * netif_rx() as soon as a timestamp becomes available. One of + * the PTP_CLASS_ values is passed in 'type'. The function + * must return true if the skb is accepted for delivery. + * + * @txtstamp: Requests a Tx timestamp for 'skb'. The MII time stamping + * device promises to deliver it using skb_complete_tx_timestamp() + * as soon as a timestamp becomes available. One of the PTP_CLASS_ + * values is passed in 'type'. + * + * @hwtstamp: Handles SIOCSHWTSTAMP ioctl for hardware time stamping. + * + * @link_state: Allows the device to respond to changes in the link + * state. The caller invokes this function while holding + * the phy_device mutex. + * + * @ts_info: Handles ethtool queries for hardware time stamping. + * + * Drivers for PHY time stamping devices should embed their + * mii_timestamper within a private structure, obtaining a reference + * to it using container_of(). + */ +struct mii_timestamper { + bool (*rxtstamp)(struct mii_timestamper *mii_ts, + struct sk_buff *skb, int type); + + void (*txtstamp)(struct mii_timestamper *mii_ts, + struct sk_buff *skb, int type); + + int (*hwtstamp)(struct mii_timestamper *mii_ts, + struct ifreq *ifreq); + + void (*link_state)(struct mii_timestamper *mii_ts, + struct phy_device *phydev); + + int (*ts_info)(struct mii_timestamper *mii_ts, + struct ethtool_ts_info *ts_info); +}; + +#endif diff --git a/include/linux/phy.h b/include/linux/phy.h index fc51aacb03a7..a34266deba3c 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -441,6 +442,7 @@ struct phy_device { struct sfp_bus *sfp_bus; struct phylink *phylink; struct net_device *attached_dev; + struct mii_timestamper *mii_ts; u8 mdix; u8 mdix_ctrl; @@ -546,29 +548,6 @@ struct phy_driver { */ int (*match_phy_device)(struct phy_device *phydev); - /* Handles ethtool queries for hardware time stamping. */ - int (*ts_info)(struct phy_device *phydev, struct ethtool_ts_info *ti); - - /* Handles SIOCSHWTSTAMP ioctl for hardware time stamping. */ - int (*hwtstamp)(struct phy_device *phydev, struct ifreq *ifr); - - /* - * Requests a Rx timestamp for 'skb'. If the skb is accepted, - * the phy driver promises to deliver it using netif_rx() as - * soon as a timestamp becomes available. One of the - * PTP_CLASS_ values is passed in 'type'. The function must - * return true if the skb is accepted for delivery. - */ - bool (*rxtstamp)(struct phy_device *dev, struct sk_buff *skb, int type); - - /* - * Requests a Tx timestamp for 'skb'. The phy driver promises - * to deliver it using skb_complete_tx_timestamp() as soon as a - * timestamp becomes available. One of the PTP_CLASS_ values - * is passed in 'type'. - */ - void (*txtstamp)(struct phy_device *dev, struct sk_buff *skb, int type); - /* Some devices (e.g. qnap TS-119P II) require PHY register changes to * enable Wake on LAN, so set_wol is provided to be called in the * ethernet driver's set_wol function. */ @@ -942,7 +921,7 @@ static inline bool phy_polling_mode(struct phy_device *phydev) */ static inline bool phy_has_hwtstamp(struct phy_device *phydev) { - return phydev && phydev->drv && phydev->drv->hwtstamp; + return phydev && phydev->mii_ts && phydev->mii_ts->hwtstamp; } /** @@ -951,7 +930,7 @@ static inline bool phy_has_hwtstamp(struct phy_device *phydev) */ static inline bool phy_has_rxtstamp(struct phy_device *phydev) { - return phydev && phydev->drv && phydev->drv->rxtstamp; + return phydev && phydev->mii_ts && phydev->mii_ts->rxtstamp; } /** @@ -961,7 +940,7 @@ static inline bool phy_has_rxtstamp(struct phy_device *phydev) */ static inline bool phy_has_tsinfo(struct phy_device *phydev) { - return phydev && phydev->drv && phydev->drv->ts_info; + return phydev && phydev->mii_ts && phydev->mii_ts->ts_info; } /** @@ -970,30 +949,30 @@ static inline bool phy_has_tsinfo(struct phy_device *phydev) */ static inline bool phy_has_txtstamp(struct phy_device *phydev) { - return phydev && phydev->drv && phydev->drv->txtstamp; + return phydev && phydev->mii_ts && phydev->mii_ts->txtstamp; } static inline int phy_hwtstamp(struct phy_device *phydev, struct ifreq *ifr) { - return phydev->drv->hwtstamp(phydev, ifr); + return phydev->mii_ts->hwtstamp(phydev->mii_ts, ifr); } static inline bool phy_rxtstamp(struct phy_device *phydev, struct sk_buff *skb, int type) { - return phydev->drv->rxtstamp(phydev, skb, type); + return phydev->mii_ts->rxtstamp(phydev->mii_ts, skb, type); } static inline int phy_ts_info(struct phy_device *phydev, struct ethtool_ts_info *tsinfo) { - return phydev->drv->ts_info(phydev, tsinfo); + return phydev->mii_ts->ts_info(phydev->mii_ts, tsinfo); } static inline void phy_txtstamp(struct phy_device *phydev, struct sk_buff *skb, int type) { - phydev->drv->txtstamp(phydev, skb, type); + phydev->mii_ts->txtstamp(phydev->mii_ts, skb, type); } /** diff --git a/net/core/timestamping.c b/net/core/timestamping.c index 7911235706a9..04840697fe79 100644 --- a/net/core/timestamping.c +++ b/net/core/timestamping.c @@ -13,7 +13,7 @@ static unsigned int classify(const struct sk_buff *skb) { if (likely(skb->dev && skb->dev->phydev && - skb->dev->phydev->drv)) + skb->dev->phydev->mii_ts)) return ptp_classify_raw(skb); else return PTP_CLASS_NONE; @@ -21,7 +21,7 @@ static unsigned int classify(const struct sk_buff *skb) void skb_clone_tx_timestamp(struct sk_buff *skb) { - struct phy_device *phydev; + struct mii_timestamper *mii_ts; struct sk_buff *clone; unsigned int type; @@ -32,22 +32,22 @@ void skb_clone_tx_timestamp(struct sk_buff *skb) if (type == PTP_CLASS_NONE) return; - phydev = skb->dev->phydev; - if (likely(phydev->drv->txtstamp)) { + mii_ts = skb->dev->phydev->mii_ts; + if (likely(mii_ts->txtstamp)) { clone = skb_clone_sk(skb); if (!clone) return; - phydev->drv->txtstamp(phydev, clone, type); + mii_ts->txtstamp(mii_ts, clone, type); } } EXPORT_SYMBOL_GPL(skb_clone_tx_timestamp); bool skb_defer_rx_timestamp(struct sk_buff *skb) { - struct phy_device *phydev; + struct mii_timestamper *mii_ts; unsigned int type; - if (!skb->dev || !skb->dev->phydev || !skb->dev->phydev->drv) + if (!skb->dev || !skb->dev->phydev || !skb->dev->phydev->mii_ts) return false; if (skb_headroom(skb) < ETH_HLEN) @@ -62,9 +62,9 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb) if (type == PTP_CLASS_NONE) return false; - phydev = skb->dev->phydev; - if (likely(phydev->drv->rxtstamp)) - return phydev->drv->rxtstamp(phydev, skb, type); + mii_ts = skb->dev->phydev->mii_ts; + if (likely(mii_ts->rxtstamp)) + return mii_ts->rxtstamp(mii_ts, skb, type); return false; } From patchwork Sat Dec 21 19:36:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 1214584 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 (no SPF record) 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="gYTTTTA2"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47gG8j5Lm2z9sPc for ; Sun, 22 Dec 2019 06:37:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727456AbfLUThI (ORCPT ); Sat, 21 Dec 2019 14:37:08 -0500 Received: from mail-pl1-f196.google.com ([209.85.214.196]:35181 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727384AbfLUTgx (ORCPT ); Sat, 21 Dec 2019 14:36:53 -0500 Received: by mail-pl1-f196.google.com with SMTP id g6so5545604plt.2; Sat, 21 Dec 2019 11:36:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=n8ih2AdQhlW0qNsJZLfHPrYXlYifMpkcfOvwkII2NAs=; b=gYTTTTA28DWs/bGXQ6p1UqK97lFu1R5NCRJ3QSekV9X8vm32L+HJJJ4YVsfg0pjN7c +8CMvPsFQgztDVB2elw5oGjpbwiK1Ou0NF1sDhaRZbi6QuiJNMmG1LZZNY2XiSj5abU0 KEJDEh2uQSsQcnHAA2Ve5ZvQax9M+yfE0i2eSPI4OauSVb/tO7XIJyo7qCzYLsqtjSBj 6UvbK6gfhQynFVHT+Xv0SDlslT2ZlhfCi3+OKP48muUC2AAxZUlDlqVjsdgNec85dZLZ Q519rV5xlCnf5Td4EQC/wFXGEkBVfnZ9eUzstY2zEhncujtQhSHN4SBIYUVCRt1qeogB vNbw== 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:mime-version:content-transfer-encoding; bh=n8ih2AdQhlW0qNsJZLfHPrYXlYifMpkcfOvwkII2NAs=; b=W80SnxZeARvWFmbN4snXPDQfebsP0lvWQmWjL7CFnfG5l0dijDi7crh5JiNRs4agTn 92aQdcpd5GQC2oB/DoyklmzKgDEaSANIZ09b1LZ7kxwVS3mTwfRBCN3TtXrWdCXa8qBU cAV2zJ7t1tPRIDOs3VJwqyWWkM4MMmGuGv9Quk9PYJFQY/xW1cvuqH/xyTA7ENgvD8co 5+2RkZUahXz//a0fpat9Feecz0/bAgY+zJRANNGgkNqX4rInm7EQsNW5hvI8ldlq4MSS Xd30WSdinZ0ErS6NPdHn94PtdbY3/hLKk6+UDgxBB+RIkCtshNmBcwjHYN3jiM+VkDNw l2gg== X-Gm-Message-State: APjAAAWyUIom2CWzGY0AQxHvnOzarn6pAkLmdJtzemQ2xMWu412Pjvf8 d94RCY1zfFnKqrKtfnE+mrO3dlYC X-Google-Smtp-Source: APXvYqzBdAShUEOmV9lOkUHJaaC0bmcvQqpOfCQrUpSNwa451veYhl5v4YwabtJzo6iVLdEB2xRIhw== X-Received: by 2002:a17:90a:3d0d:: with SMTP id h13mr24374049pjc.1.1576957012659; Sat, 21 Dec 2019 11:36:52 -0800 (PST) Received: from localhost.localdomain (c-73-241-114-122.hsd1.ca.comcast.net. [73.241.114.122]) by smtp.gmail.com with ESMTPSA id y197sm18512603pfc.79.2019.12.21.11.36.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 11:36:51 -0800 (PST) From: Richard Cochran To: netdev@vger.kernel.org Cc: David Miller , devicetree@vger.kernel.org, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Jacob Keller , Jakub Kicinski , Mark Rutland , Miroslav Lichvar , Murali Karicheri , Rob Herring , Willem de Bruijn , Wingman Kwok Subject: [PATCH V8 net-next 08/12] net: Add a layer for non-PHY MII time stamping drivers. Date: Sat, 21 Dec 2019 11:36:34 -0800 Message-Id: <764c9d51a47533609acb3dc2431d0c316371f443.1576956342.git.richardcochran@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org While PHY time stamping drivers can simply attach their interface directly to the PHY instance, stand alone drivers require support in order to manage their services. Non-PHY MII time stamping drivers have a control interface over another bus like I2C, SPI, UART, or via a memory mapped peripheral. The controller device will be associated with one or more time stamping channels, each of which sits snoops in on a MII bus. This patch provides a glue layer that will enable time stamping channels to find their controlling device. Signed-off-by: Richard Cochran Reviewed-by: Andrew Lunn --- drivers/net/phy/Makefile | 2 + drivers/net/phy/mii_timestamper.c | 125 ++++++++++++++++++++++++++++++ include/linux/mii_timestamper.h | 63 +++++++++++++++ net/Kconfig | 7 +- 4 files changed, 194 insertions(+), 3 deletions(-) create mode 100644 drivers/net/phy/mii_timestamper.c diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index d846b4dc1c68..fe5badf13b65 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -43,6 +43,8 @@ obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o +obj-$(CONFIG_NETWORK_PHY_TIMESTAMPING) += mii_timestamper.o + obj-$(CONFIG_SFP) += sfp.o sfp-obj-$(CONFIG_SFP) += sfp-bus.o obj-y += $(sfp-obj-y) $(sfp-obj-m) diff --git a/drivers/net/phy/mii_timestamper.c b/drivers/net/phy/mii_timestamper.c new file mode 100644 index 000000000000..2f12c5d901df --- /dev/null +++ b/drivers/net/phy/mii_timestamper.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Support for generic time stamping devices on MII buses. +// Copyright (C) 2018 Richard Cochran +// + +#include + +static LIST_HEAD(mii_timestamping_devices); +static DEFINE_MUTEX(tstamping_devices_lock); + +struct mii_timestamping_desc { + struct list_head list; + struct mii_timestamping_ctrl *ctrl; + struct device *device; +}; + +/** + * register_mii_tstamp_controller() - registers an MII time stamping device. + * + * @device: The device to be registered. + * @ctrl: Pointer to device's control interface. + * + * Returns zero on success or non-zero on failure. + */ +int register_mii_tstamp_controller(struct device *device, + struct mii_timestamping_ctrl *ctrl) +{ + struct mii_timestamping_desc *desc; + + desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + + INIT_LIST_HEAD(&desc->list); + desc->ctrl = ctrl; + desc->device = device; + + mutex_lock(&tstamping_devices_lock); + list_add_tail(&mii_timestamping_devices, &desc->list); + mutex_unlock(&tstamping_devices_lock); + + return 0; +} +EXPORT_SYMBOL(register_mii_tstamp_controller); + +/** + * unregister_mii_tstamp_controller() - unregisters an MII time stamping device. + * + * @device: A device previously passed to register_mii_tstamp_controller(). + */ +void unregister_mii_tstamp_controller(struct device *device) +{ + struct mii_timestamping_desc *desc; + struct list_head *this, *next; + + mutex_lock(&tstamping_devices_lock); + list_for_each_safe(this, next, &mii_timestamping_devices) { + desc = list_entry(this, struct mii_timestamping_desc, list); + if (desc->device == device) { + list_del_init(&desc->list); + kfree(desc); + break; + } + } + mutex_unlock(&tstamping_devices_lock); +} +EXPORT_SYMBOL(unregister_mii_tstamp_controller); + +/** + * register_mii_timestamper - Enables a given port of an MII time stamper. + * + * @node: The device tree node of the MII time stamp controller. + * @port: The index of the port to be enabled. + * + * Returns a valid interface on success or ERR_PTR otherwise. + */ +struct mii_timestamper *register_mii_timestamper(struct device_node *node, + unsigned int port) +{ + struct mii_timestamper *mii_ts = NULL; + struct mii_timestamping_desc *desc; + struct list_head *this; + + mutex_lock(&tstamping_devices_lock); + list_for_each(this, &mii_timestamping_devices) { + desc = list_entry(this, struct mii_timestamping_desc, list); + if (desc->device->of_node == node) { + mii_ts = desc->ctrl->probe_channel(desc->device, port); + if (!IS_ERR(mii_ts)) { + mii_ts->device = desc->device; + get_device(desc->device); + } + break; + } + } + mutex_unlock(&tstamping_devices_lock); + + return mii_ts ? mii_ts : ERR_PTR(-EPROBE_DEFER); +} +EXPORT_SYMBOL(register_mii_timestamper); + +/** + * unregister_mii_timestamper - Disables a given MII time stamper. + * + * @mii_ts: An interface obtained via register_mii_timestamper(). + * + */ +void unregister_mii_timestamper(struct mii_timestamper *mii_ts) +{ + struct mii_timestamping_desc *desc; + struct list_head *this; + + mutex_lock(&tstamping_devices_lock); + list_for_each(this, &mii_timestamping_devices) { + desc = list_entry(this, struct mii_timestamping_desc, list); + if (desc->device == mii_ts->device) { + desc->ctrl->release_channel(desc->device, mii_ts); + put_device(desc->device); + break; + } + } + mutex_unlock(&tstamping_devices_lock); +} +EXPORT_SYMBOL(unregister_mii_timestamper); diff --git a/include/linux/mii_timestamper.h b/include/linux/mii_timestamper.h index 36002386029c..fa940bbaf8ae 100644 --- a/include/linux/mii_timestamper.h +++ b/include/linux/mii_timestamper.h @@ -33,10 +33,15 @@ struct phy_device; * the phy_device mutex. * * @ts_info: Handles ethtool queries for hardware time stamping. + * @device: Remembers the device to which the instance belongs. * * Drivers for PHY time stamping devices should embed their * mii_timestamper within a private structure, obtaining a reference * to it using container_of(). + * + * Drivers for non-PHY time stamping devices should return a pointer + * to a mii_timestamper from the probe_channel() callback of their + * mii_timestamping_ctrl interface. */ struct mii_timestamper { bool (*rxtstamp)(struct mii_timestamper *mii_ts, @@ -53,6 +58,64 @@ struct mii_timestamper { int (*ts_info)(struct mii_timestamper *mii_ts, struct ethtool_ts_info *ts_info); + + struct device *device; +}; + +/** + * struct mii_timestamping_ctrl - MII time stamping controller interface. + * + * @probe_channel: Callback into the controller driver announcing the + * presence of the 'port' channel. The 'device' field + * had been passed to register_mii_tstamp_controller(). + * The driver must return either a pointer to a valid + * MII timestamper instance or PTR_ERR. + * + * @release_channel: Releases an instance obtained via .probe_channel. + */ +struct mii_timestamping_ctrl { + struct mii_timestamper *(*probe_channel)(struct device *device, + unsigned int port); + void (*release_channel)(struct device *device, + struct mii_timestamper *mii_ts); }; +#ifdef CONFIG_NETWORK_PHY_TIMESTAMPING + +int register_mii_tstamp_controller(struct device *device, + struct mii_timestamping_ctrl *ctrl); + +void unregister_mii_tstamp_controller(struct device *device); + +struct mii_timestamper *register_mii_timestamper(struct device_node *node, + unsigned int port); + +void unregister_mii_timestamper(struct mii_timestamper *mii_ts); + +#else + +static inline +int register_mii_tstamp_controller(struct device *device, + struct mii_timestamping_ctrl *ctrl) +{ + return -EOPNOTSUPP; +} + +static inline void unregister_mii_tstamp_controller(struct device *device) +{ +} + +static inline +struct mii_timestamper *register_mii_timestamper(struct device_node *node, + unsigned int port) +{ + return NULL; +} + +static inline void unregister_mii_timestamper(struct mii_timestamper *mii_ts) +{ +} + +#endif + #endif diff --git a/net/Kconfig b/net/Kconfig index bd191f978a23..52af65e5d28c 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -108,9 +108,10 @@ config NETWORK_PHY_TIMESTAMPING bool "Timestamping in PHY devices" select NET_PTP_CLASSIFY help - This allows timestamping of network packets by PHYs with - hardware timestamping capabilities. This option adds some - overhead in the transmit and receive paths. + This allows timestamping of network packets by PHYs (or + other MII bus snooping devices) with hardware timestamping + capabilities. This option adds some overhead in the transmit + and receive paths. If you are unsure how to answer this question, answer N. From patchwork Sat Dec 21 19:36:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 1214578 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 (no SPF record) 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="qUYmbyc3"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47gG8W2ZvDz9sP3 for ; Sun, 22 Dec 2019 06:36:59 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727421AbfLUTg4 (ORCPT ); Sat, 21 Dec 2019 14:36:56 -0500 Received: from mail-pl1-f196.google.com ([209.85.214.196]:41980 "EHLO mail-pl1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727401AbfLUTgz (ORCPT ); Sat, 21 Dec 2019 14:36:55 -0500 Received: by mail-pl1-f196.google.com with SMTP id bd4so5534227plb.8; Sat, 21 Dec 2019 11:36:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JibM5raV/YAFw3oVHiGpDr4SxeM+CWDiIkx7ilTDLCM=; b=qUYmbyc3wvwfq+WzSe3ojeTh/xFwS9sMJR1HuJUGsyFayEqX++0GtMR4IPcXr+SB2n nSbggx41PNZsLAb+ynt8Sw5qW76hNbWvwxf0S/2XzdBHNnX9O5tJXYUXGryfMGLQJ2ft l4Jjb2iweErtMWtxTxRh4TYZmOljYgDqmYKCj5eznNxItIylq3EIREMQL0Rabuq0kWA6 uQYZ+E7vxM3nGoN1KfCpZ8t+N7KB8R7QFBbudlEXFYmaEt7fRO8tzoe8v/I9/bSGBtnG TVifjLFIOYPUYBV3+BcZaNlyjz0nwL5OwbxC1Ngc/Txzbq6MsclHLicVKT0v1dEAp75Z cvDw== 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:mime-version:content-transfer-encoding; bh=JibM5raV/YAFw3oVHiGpDr4SxeM+CWDiIkx7ilTDLCM=; b=m+tKtlReroUlrJ6a83gACnR8HpgPasNDAKgBenqxGq1Wk9bCnwwS9Hb1Op1wqLhLxO 7krkK4Q7MmOlYCoN6s4EhnEb0J1wBOJBpbDGKjrPBX2sbKV70iW5hVGuBrEw/CCY2ETf naOuXMUm++rD/zittMGynlDrEP957QeX0s+nreQzazDOKPahm/wR+ASW9h5QlvHtjgNC tnvmzW3OUDpaGmwYEAmooqTy7RdTRvIM9hr0sDxMOqZhbTpuy0hgnNpfgVqsjDL72zaE MUyZuZYToJQYOq5jETgDJO3XpcfosRgWNuhfZrbjLusIa7lT6aWcaiGSu3bUFhB3JGCM TmqQ== X-Gm-Message-State: APjAAAVHO+9ER/wejYqfu0bZw+mhjC0NmF1aIFq7u9DHr85vgVVC1Bjo Pdk47oW0QUSPcHubPnA1R2MZ3ms/ X-Google-Smtp-Source: APXvYqwx9DHa3YrBPG+gsYZ0uBqquM2cZEnFt1FYahORWDXVNEdnWL3YaGV5c4c0YgnksuDonjjpOw== X-Received: by 2002:a17:90a:e291:: with SMTP id d17mr25019384pjz.116.1576957014100; Sat, 21 Dec 2019 11:36:54 -0800 (PST) Received: from localhost.localdomain (c-73-241-114-122.hsd1.ca.comcast.net. [73.241.114.122]) by smtp.gmail.com with ESMTPSA id y197sm18512603pfc.79.2019.12.21.11.36.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 11:36:53 -0800 (PST) From: Richard Cochran To: netdev@vger.kernel.org Cc: David Miller , devicetree@vger.kernel.org, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Jacob Keller , Jakub Kicinski , Mark Rutland , Miroslav Lichvar , Murali Karicheri , Rob Herring , Willem de Bruijn , Wingman Kwok Subject: [PATCH V8 net-next 09/12] dt-bindings: ptp: Introduce MII time stamping devices. Date: Sat, 21 Dec 2019 11:36:35 -0800 Message-Id: <40fce97d7717ce74bedf64a79f4b96ee07003de0.1576956342.git.richardcochran@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This patch add a new binding that allows non-PHY MII time stamping devices to find their buses. The new documentation covers both the generic binding and one upcoming user. Signed-off-by: Richard Cochran Reviewed-by: Andrew Lunn --- .../devicetree/bindings/ptp/ptp-ines.txt | 35 ++++++++++++++++ .../devicetree/bindings/ptp/timestamper.txt | 42 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 Documentation/devicetree/bindings/ptp/ptp-ines.txt create mode 100644 Documentation/devicetree/bindings/ptp/timestamper.txt diff --git a/Documentation/devicetree/bindings/ptp/ptp-ines.txt b/Documentation/devicetree/bindings/ptp/ptp-ines.txt new file mode 100644 index 000000000000..4c242bd1ce9c --- /dev/null +++ b/Documentation/devicetree/bindings/ptp/ptp-ines.txt @@ -0,0 +1,35 @@ +ZHAW InES PTP time stamping IP core + +The IP core needs two different kinds of nodes. The control node +lives somewhere in the memory map and specifies the address of the +control registers. There can be up to three port handles placed as +attributes of PHY nodes. These associate a particular MII bus with a +port index within the IP core. + +Required properties of the control node: + +- compatible: "ines,ptp-ctrl" +- reg: physical address and size of the register bank + +Required format of the port handle within the PHY node: + +- timestamper: provides control node reference and + the port channel within the IP core + +Example: + + tstamper: timestamper@60000000 { + compatible = "ines,ptp-ctrl"; + reg = <0x60000000 0x80>; + }; + + ethernet@80000000 { + ... + mdio { + ... + ethernet-phy@3 { + ... + timestamper = <&tstamper 0>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/ptp/timestamper.txt b/Documentation/devicetree/bindings/ptp/timestamper.txt new file mode 100644 index 000000000000..fc550ce4d4ea --- /dev/null +++ b/Documentation/devicetree/bindings/ptp/timestamper.txt @@ -0,0 +1,42 @@ +Time stamps from MII bus snooping devices + +This binding supports non-PHY devices that snoop the MII bus and +provide time stamps. In contrast to PHY time stamping drivers (which +can simply attach their interface directly to the PHY instance), stand +alone MII time stamping drivers use this binding to specify the +connection between the snooping device and a given network interface. + +Non-PHY MII time stamping drivers typically talk to the control +interface over another bus like I2C, SPI, UART, or via a memory mapped +peripheral. This controller device is associated with one or more +time stamping channels, each of which snoops on a MII bus. + +The "timestamper" property lives in a phy node and links a time +stamping channel from the controller device to that phy's MII bus. + +Example: + + tstamper: timestamper@10000000 { + compatible = "ines,ptp-ctrl"; + reg = <0x10000000 0x80>; + }; + + ethernet@20000000 { + mdio { + ethernet-phy@1 { + timestamper = <&tstamper 0>; + }; + }; + }; + + ethernet@30000000 { + mdio { + ethernet-phy@2 { + timestamper = <&tstamper 1>; + }; + }; + }; + +In this example, time stamps from the MII bus attached to phy@1 will +appear on time stamp channel 0 (zero), and those from phy@2 appear on +channel 1. From patchwork Sat Dec 21 19:36:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 1214580 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 (no SPF record) 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="uq0WKq1x"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47gG8Z1C2sz9sPc for ; Sun, 22 Dec 2019 06:37:02 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727434AbfLUThA (ORCPT ); Sat, 21 Dec 2019 14:37:00 -0500 Received: from mail-pj1-f66.google.com ([209.85.216.66]:52976 "EHLO mail-pj1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727419AbfLUTg4 (ORCPT ); Sat, 21 Dec 2019 14:36:56 -0500 Received: by mail-pj1-f66.google.com with SMTP id w23so5626595pjd.2; Sat, 21 Dec 2019 11:36:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0xNn8rOhvQ0q/eVsblgqPKWbsQdxuQgNbseY+ebe5zk=; b=uq0WKq1xfqlvfbOs4ZEc3axSxXF+JMndyqB3W5jlkV/S4kNeEf0rhkHQgbiw/+K7OG W2dj5oqOBo+71/xGfByUNzFy6PjUO2xgvNGDCbg4R2GwV0cnvKnrx1qbC8J2A+n+1Yhj NU+mAAEGBbsTqdWolWNhK2vVKBJ+RQeRAMooyVcaLCySQuapyrfGUWzEo3ErNzgRl0Av XDg9VGh1+8G1aNT3NpwCO3V74VauSNYV5+D5A/0cFdWJ+CDyaPVomAFDbHyULKw1byTF wLXRMfdJ7QIopVEVUxh2dzdNTFloDum5wQ/heHwsFwyrMbF3t5/CuCTtvysxdjJmY3tL nLXQ== 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:mime-version:content-transfer-encoding; bh=0xNn8rOhvQ0q/eVsblgqPKWbsQdxuQgNbseY+ebe5zk=; b=RCyewUMA5ae/u26wJi43DbbdEhoB0m494x9iWpVq3aRub5vsUW512mw5X3oO7X4FrR VBITr5lthio+Y4/6k+aZ+z4uwzTtKrhDfjwM8gvKpEWatmJlqTuwHnqN0lIJAcfwfmFS Qz7TvvlZ5FQfCNaOHxzceVTmkW7Ghjt11RsqpB3g8NtioXpdJlg4DGAxquCPR+neA+C6 gZte3KZPOGynCibfqXJoSBo+q3usufyWzyVD7435YgTZ9AChJVJgLX9CDVc1CsLejcpc ZHtt3eJlXgXLSQFVIqv3pA1dGI4nnz7U1Uc8vFQmHcNIICctvbg2rmelvNX4HE3e36w3 ZiRA== X-Gm-Message-State: APjAAAWbLwAc29Dv14GGMU2QBBPUxcWYGvR3Qf7PKOXmvdP/v7HrdLlO qur3TLc/4UWm6dWooz3sKBS+pX1v X-Google-Smtp-Source: APXvYqz1s+kvIKDz2ke6NAyqf+OTruYcjql/eZIGGmRQDi1kH5J/Dq128Qx2hAPA+A7rilSV10eB0A== X-Received: by 2002:a17:902:760e:: with SMTP id k14mr22849124pll.238.1576957015667; Sat, 21 Dec 2019 11:36:55 -0800 (PST) Received: from localhost.localdomain (c-73-241-114-122.hsd1.ca.comcast.net. [73.241.114.122]) by smtp.gmail.com with ESMTPSA id y197sm18512603pfc.79.2019.12.21.11.36.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 11:36:54 -0800 (PST) From: Richard Cochran To: netdev@vger.kernel.org Cc: David Miller , devicetree@vger.kernel.org, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Jacob Keller , Jakub Kicinski , Mark Rutland , Miroslav Lichvar , Murali Karicheri , Rob Herring , Willem de Bruijn , Wingman Kwok , Rob Herring Subject: [PATCH V8 net-next 10/12] net: mdio: of: Register discovered MII time stampers. Date: Sat, 21 Dec 2019 11:36:36 -0800 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When parsing a PHY node, register its time stamper, if any, and attach the instance to the PHY device. Signed-off-by: Richard Cochran Reviewed-by: Andrew Lunn Reviewed-by: Florian Fainelli Reviewed-by: Rob Herring --- drivers/net/phy/phy_device.c | 3 +++ drivers/of/of_mdio.c | 30 +++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index ee45838f90c9..debbda61e12b 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -881,6 +881,9 @@ EXPORT_SYMBOL(phy_device_register); */ void phy_device_remove(struct phy_device *phydev) { + if (phydev->mii_ts) + unregister_mii_timestamper(phydev->mii_ts); + device_del(&phydev->mdio.dev); /* Assert the reset signal */ diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index c6b87ce2b0cc..0b7aee235813 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -42,14 +42,37 @@ static int of_get_phy_id(struct device_node *device, u32 *phy_id) return -EINVAL; } +static struct mii_timestamper *of_find_mii_timestamper(struct device_node *node) +{ + struct of_phandle_args arg; + int err; + + err = of_parse_phandle_with_fixed_args(node, "timestamper", 1, 0, &arg); + + if (err == -ENOENT) + return NULL; + else if (err) + return ERR_PTR(err); + + if (arg.args_count != 1) + return ERR_PTR(-EINVAL); + + return register_mii_timestamper(arg.np, arg.args[0]); +} + static int of_mdiobus_register_phy(struct mii_bus *mdio, struct device_node *child, u32 addr) { + struct mii_timestamper *mii_ts; struct phy_device *phy; bool is_c45; int rc; u32 phy_id; + mii_ts = of_find_mii_timestamper(child); + if (IS_ERR(mii_ts)) + return PTR_ERR(mii_ts); + is_c45 = of_device_is_compatible(child, "ethernet-phy-ieee802.3-c45"); @@ -57,11 +80,14 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, phy = phy_device_create(mdio, addr, phy_id, 0, NULL); else phy = get_phy_device(mdio, addr, is_c45); - if (IS_ERR(phy)) + if (IS_ERR(phy)) { + unregister_mii_timestamper(mii_ts); return PTR_ERR(phy); + } rc = of_irq_get(child, 0); if (rc == -EPROBE_DEFER) { + unregister_mii_timestamper(mii_ts); phy_device_free(phy); return rc; } @@ -90,10 +116,12 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio, * register it */ rc = phy_device_register(phy); if (rc) { + unregister_mii_timestamper(mii_ts); phy_device_free(phy); of_node_put(child); return rc; } + phy->mii_ts = mii_ts; dev_dbg(&mdio->dev, "registered phy %pOFn at address %i\n", child, addr); From patchwork Sat Dec 21 19:36:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 1214581 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 (no SPF record) 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="X325lpMW"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47gG8b3qMJz9sP3 for ; Sun, 22 Dec 2019 06:37:03 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727439AbfLUThC (ORCPT ); Sat, 21 Dec 2019 14:37:02 -0500 Received: from mail-pl1-f195.google.com ([209.85.214.195]:43809 "EHLO mail-pl1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727401AbfLUTg6 (ORCPT ); Sat, 21 Dec 2019 14:36:58 -0500 Received: by mail-pl1-f195.google.com with SMTP id p27so5532384pli.10; Sat, 21 Dec 2019 11:36:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=24u9G4DyTIAy2pTqFGAddxQF2MRw+baziGMZlPjerS0=; b=X325lpMWT/wOdHHeM+FSu6A0zveoZlGY5BZAcWyb0fL/oQm0D0UP7jhdWzKYt/XXcE WBDnZSWa9aNoXKo8skS+BeEBXHNhIBp6Q+O/e2ZNcBvJkWNS74KOETibv6/9YZC+Diql 2F/EFNQo/TijNIYYhhV/GvtufaWHxYoS7VHdYYdKCUs+8h/x9uJoyhf+suhQE3+pk9FB 2BVw97EaoTLxc454cQXsAUVQwzX6FP//X8KHAXcTgREfUwHsTcKTs7xMRkqmRluA+hLq gNLAyMQ4JJU0KmwU9trTKbPz5qYCwxCXUeNXNKkgmvATLo9fy32Qyk5WJzDwzBIu2Zj6 TEnw== 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:mime-version:content-transfer-encoding; bh=24u9G4DyTIAy2pTqFGAddxQF2MRw+baziGMZlPjerS0=; b=eFLLRV9AKyeiLvFw5fkWq0Gyu3ytk5D9P0fDUzE1PsQAryhb9Vygan4cge4S3I3AzL znckB9JPrLtkKPRgxwzRErqVd06EyCr1HPE6WJu3R3+Q18sK1lTHVesQcqozdLwWhSVW 0bywdmWKgOYsbIMvCCXs7swo4U9PcLN/2kZggXDKbhD8KK7YRvWFE12x5lafkgrlw1PA 94zzcQO2S1bCSbajN3HYUCVzWAmHMYqClxjy6Pzs8CvQxbtevJ7YT1wuh8DQlsQj4/oP TfZ+9Lx75f1elJIty95lxXZJH30IZOSaNtQp8UYRYfaYnkLCatNPg+Xki0Nk2bv2Mp3W NM2w== X-Gm-Message-State: APjAAAUD554z0Py6tCE9rhOu8qk/6IaaaoNfl6R4j0+LoM+9cetruIwE C8rDfxHgB2HMzTPp2/W6APx8hCbi X-Google-Smtp-Source: APXvYqxCZRJNKp4OHblFlT8TV1HFCeLUk+DnAbga8zk0KA+2qmb9Ky2TydF2WomKznM+GrgSNhM4TQ== X-Received: by 2002:a17:902:6b85:: with SMTP id p5mr22318645plk.32.1576957017243; Sat, 21 Dec 2019 11:36:57 -0800 (PST) Received: from localhost.localdomain (c-73-241-114-122.hsd1.ca.comcast.net. [73.241.114.122]) by smtp.gmail.com with ESMTPSA id y197sm18512603pfc.79.2019.12.21.11.36.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 11:36:56 -0800 (PST) From: Richard Cochran To: netdev@vger.kernel.org Cc: David Miller , devicetree@vger.kernel.org, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Jacob Keller , Jakub Kicinski , Mark Rutland , Miroslav Lichvar , Murali Karicheri , Rob Herring , Willem de Bruijn , Wingman Kwok Subject: [PATCH V8 net-next 11/12] net: Introduce peer to peer one step PTP time stamping. Date: Sat, 21 Dec 2019 11:36:37 -0800 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The 1588 standard defines one step operation for both Sync and PDelay_Resp messages. Up until now, hardware with P2P one step has been rare, and kernel support was lacking. This patch adds support of the mode in anticipation of new hardware developments. Signed-off-by: Richard Cochran --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 1 + include/uapi/linux/net_tstamp.h | 8 ++++++++ net/core/dev_ioctl.c | 1 + 3 files changed, 10 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 192ff8d5da32..7343d7a28327 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -15402,6 +15402,7 @@ int bnx2x_configure_ptp_filters(struct bnx2x *bp) REG_WR(bp, rule, BNX2X_PTP_TX_ON_RULE_MASK); break; case HWTSTAMP_TX_ONESTEP_SYNC: + case HWTSTAMP_TX_ONESTEP_P2P: BNX2X_ERR("One-step timestamping is not supported\n"); return -ERANGE; } diff --git a/include/uapi/linux/net_tstamp.h b/include/uapi/linux/net_tstamp.h index e5b39721c6e4..f96e650d0af9 100644 --- a/include/uapi/linux/net_tstamp.h +++ b/include/uapi/linux/net_tstamp.h @@ -90,6 +90,14 @@ enum hwtstamp_tx_types { * queue. */ HWTSTAMP_TX_ONESTEP_SYNC, + + /* + * Same as HWTSTAMP_TX_ONESTEP_SYNC, but also enables time + * stamp insertion directly into PDelay_Resp packets. In this + * case, neither transmitted Sync nor PDelay_Resp packets will + * receive a time stamp via the socket error queue. + */ + HWTSTAMP_TX_ONESTEP_P2P, }; /* possible values for hwtstamp_config->rx_filter */ diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c index 5163d900bb4f..dbaebbe573f0 100644 --- a/net/core/dev_ioctl.c +++ b/net/core/dev_ioctl.c @@ -187,6 +187,7 @@ static int net_hwtstamp_validate(struct ifreq *ifr) case HWTSTAMP_TX_OFF: case HWTSTAMP_TX_ON: case HWTSTAMP_TX_ONESTEP_SYNC: + case HWTSTAMP_TX_ONESTEP_P2P: tx_type_valid = 1; break; } From patchwork Sat Dec 21 19:36:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Cochran X-Patchwork-Id: 1214582 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 (no SPF record) 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=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="lAWVj9RH"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 47gG8d5ZnZz9sPc for ; Sun, 22 Dec 2019 06:37:05 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727450AbfLUThE (ORCPT ); Sat, 21 Dec 2019 14:37:04 -0500 Received: from mail-pf1-f194.google.com ([209.85.210.194]:35228 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727431AbfLUThA (ORCPT ); Sat, 21 Dec 2019 14:37:00 -0500 Received: by mail-pf1-f194.google.com with SMTP id i23so1662456pfo.2; Sat, 21 Dec 2019 11:36:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=B8tQZZIPFBH7o841EDpYEZv9YKodWYIMP2Y+sKpNGnM=; b=lAWVj9RH0DlEv0jXE2I6ZBBEJOMzm+eB6jM76QRMuCIFWTSCFgnFkqMJBr9NAliLAm dlEU15y6RhjjGn8MZ49a42j+9Sy+VBQw1QqxkocUIJMrSm4Iy1SInHa5wj7DY43JR1Gc 3rY+UIcqn8uGcDOeYSDHEuta7E5YWDFlDOasuRGxyETCxvt65Q0pUevGW7vq9yXxK60h agyrn3cZwfSasQUC+VJv1m4WERbKfE4B9Aon/2CHWA9mtksV8WBnREPaU6gHo2f1jfPw ZulmPgwJ+qS++Xr4H8B+M8N09bKqp/tUPIK9Ulc9V3Dk00tJkpYyRVSpSEq3HSMYh7FL S91w== 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:mime-version:content-transfer-encoding; bh=B8tQZZIPFBH7o841EDpYEZv9YKodWYIMP2Y+sKpNGnM=; b=phcKiiuBd1eqoUmadpbutyiXR2M9+5KAATuQvZMyj09+B97mFsqMKRmq/WUCSk+VIu JKWrVXEel/at3d7zevmp0j9DoRvNhIc+yAAB+ZSHF/ofjRny6TQYy1rPCzIsXfX0JhJ6 FepF+ZOvjbB69ds5DvVtnHA7tlHuaj7HfaONa6PSp1Z/2321Pr/j/ktgy6VqP4+pq7lN LPrTzfaEfXoSB89Y0m4Qr/ECL15n92Y1uwm1Wl9ZvRjQEjUAVubX1Qah2vyNjDmom4d7 jCq3IaGea9DromLdqFpmgEcA93ZI2gc8rXnzr669k0NxddxESFvGkiX9obzBciHv9gxA TVNg== X-Gm-Message-State: APjAAAUq2DwERo28R4/9u7rPPO9GIrWziBdXDB2h4GG+RA8tyFZ35E5w A4eGfN5QN6Q29cVQ3Mj6ESfzeKRg X-Google-Smtp-Source: APXvYqyBDSsSwWwJQX/NEsm3pAxLPCfyEHxWokJGgipo1QrJG/jxST4q868vCwGUwaU/977vr+MnsQ== X-Received: by 2002:a63:d62:: with SMTP id 34mr23300839pgn.268.1576957018739; Sat, 21 Dec 2019 11:36:58 -0800 (PST) Received: from localhost.localdomain (c-73-241-114-122.hsd1.ca.comcast.net. [73.241.114.122]) by smtp.gmail.com with ESMTPSA id y197sm18512603pfc.79.2019.12.21.11.36.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 11:36:58 -0800 (PST) From: Richard Cochran To: netdev@vger.kernel.org Cc: David Miller , devicetree@vger.kernel.org, Andrew Lunn , Florian Fainelli , Heiner Kallweit , Jacob Keller , Jakub Kicinski , Mark Rutland , Miroslav Lichvar , Murali Karicheri , Rob Herring , Willem de Bruijn , Wingman Kwok Subject: [PATCH V8 net-next 12/12] ptp: Add a driver for InES time stamping IP core. Date: Sat, 21 Dec 2019 11:36:38 -0800 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The InES at the ZHAW offers a PTP time stamping IP core. The FPGA logic recognizes and time stamps PTP frames on the MII bus. This patch adds a driver for the core along with a device tree binding to allow hooking the driver to MII buses. Signed-off-by: Richard Cochran --- drivers/ptp/Kconfig | 10 + drivers/ptp/Makefile | 1 + drivers/ptp/ptp_ines.c | 852 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 863 insertions(+) create mode 100644 drivers/ptp/ptp_ines.c diff --git a/drivers/ptp/Kconfig b/drivers/ptp/Kconfig index b45d2b86d8ca..e466b3586754 100644 --- a/drivers/ptp/Kconfig +++ b/drivers/ptp/Kconfig @@ -89,6 +89,16 @@ config DP83640_PHY In order for this to work, your MAC driver must also implement the skb_tx_timestamp() function. +config PTP_1588_CLOCK_INES + tristate "ZHAW InES PTP time stamping IP core" + depends on NETWORK_PHY_TIMESTAMPING + depends on PHYLIB + depends on PTP_1588_CLOCK + help + This driver adds support for using the ZHAW InES 1588 IP + core. This clock is only useful if the MII bus of your MAC + is wired up to the core. + config PTP_1588_CLOCK_PCH tristate "Intel PCH EG20T as PTP clock" depends on X86_32 || COMPILE_TEST diff --git a/drivers/ptp/Makefile b/drivers/ptp/Makefile index 69a06f86a450..3fb91bebbaf7 100644 --- a/drivers/ptp/Makefile +++ b/drivers/ptp/Makefile @@ -6,6 +6,7 @@ ptp-y := ptp_clock.o ptp_chardev.o ptp_sysfs.o obj-$(CONFIG_PTP_1588_CLOCK) += ptp.o obj-$(CONFIG_PTP_1588_CLOCK_DTE) += ptp_dte.o +obj-$(CONFIG_PTP_1588_CLOCK_INES) += ptp_ines.o obj-$(CONFIG_PTP_1588_CLOCK_IXP46X) += ptp_ixp46x.o obj-$(CONFIG_PTP_1588_CLOCK_PCH) += ptp_pch.o obj-$(CONFIG_PTP_1588_CLOCK_KVM) += ptp_kvm.o diff --git a/drivers/ptp/ptp_ines.c b/drivers/ptp/ptp_ines.c new file mode 100644 index 000000000000..dfda54cbd866 --- /dev/null +++ b/drivers/ptp/ptp_ines.c @@ -0,0 +1,852 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2018 MOSER-BAER AG +// + +#define pr_fmt(fmt) "InES_PTP: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("Driver for the ZHAW InES PTP time stamping IP core"); +MODULE_AUTHOR("Richard Cochran "); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); + +/* GLOBAL register */ +#define MCAST_MAC_SELECT_SHIFT 2 +#define MCAST_MAC_SELECT_MASK 0x3 +#define IO_RESET BIT(1) +#define PTP_RESET BIT(0) + +/* VERSION register */ +#define IF_MAJOR_VER_SHIFT 12 +#define IF_MAJOR_VER_MASK 0xf +#define IF_MINOR_VER_SHIFT 8 +#define IF_MINOR_VER_MASK 0xf +#define FPGA_MAJOR_VER_SHIFT 4 +#define FPGA_MAJOR_VER_MASK 0xf +#define FPGA_MINOR_VER_SHIFT 0 +#define FPGA_MINOR_VER_MASK 0xf + +/* INT_STAT register */ +#define RX_INTR_STATUS_3 BIT(5) +#define RX_INTR_STATUS_2 BIT(4) +#define RX_INTR_STATUS_1 BIT(3) +#define TX_INTR_STATUS_3 BIT(2) +#define TX_INTR_STATUS_2 BIT(1) +#define TX_INTR_STATUS_1 BIT(0) + +/* INT_MSK register */ +#define RX_INTR_MASK_3 BIT(5) +#define RX_INTR_MASK_2 BIT(4) +#define RX_INTR_MASK_1 BIT(3) +#define TX_INTR_MASK_3 BIT(2) +#define TX_INTR_MASK_2 BIT(1) +#define TX_INTR_MASK_1 BIT(0) + +/* BUF_STAT register */ +#define RX_FIFO_NE_3 BIT(5) +#define RX_FIFO_NE_2 BIT(4) +#define RX_FIFO_NE_1 BIT(3) +#define TX_FIFO_NE_3 BIT(2) +#define TX_FIFO_NE_2 BIT(1) +#define TX_FIFO_NE_1 BIT(0) + +/* PORT_CONF register */ +#define CM_ONE_STEP BIT(6) +#define PHY_SPEED_SHIFT 4 +#define PHY_SPEED_MASK 0x3 +#define P2P_DELAY_WR_POS_SHIFT 2 +#define P2P_DELAY_WR_POS_MASK 0x3 +#define PTP_MODE_SHIFT 0 +#define PTP_MODE_MASK 0x3 + +/* TS_STAT_TX register */ +#define TS_ENABLE BIT(15) +#define DATA_READ_POS_SHIFT 8 +#define DATA_READ_POS_MASK 0x1f +#define DISCARDED_EVENTS_SHIFT 4 +#define DISCARDED_EVENTS_MASK 0xf + +#define INES_N_PORTS 3 +#define INES_REGISTER_SIZE 0x80 +#define INES_PORT_OFFSET 0x20 +#define INES_PORT_SIZE 0x20 +#define INES_FIFO_DEPTH 90 +#define INES_MAX_EVENTS 100 + +#define BC_PTP_V1 0 +#define BC_PTP_V2 1 +#define TC_E2E_PTP_V2 2 +#define TC_P2P_PTP_V2 3 + +#define OFF_PTP_CLOCK_ID 20 +#define OFF_PTP_PORT_NUM 28 + +#define PHY_SPEED_10 0 +#define PHY_SPEED_100 1 +#define PHY_SPEED_1000 2 + +#define PORT_CONF \ + ((PHY_SPEED_1000 << PHY_SPEED_SHIFT) | (BC_PTP_V2 << PTP_MODE_SHIFT)) + +#define ines_read32(s, r) __raw_readl((void __iomem *)&s->regs->r) +#define ines_write32(s, v, r) __raw_writel(v, (void __iomem *)&s->regs->r) + +#define MESSAGE_TYPE_SYNC 1 +#define MESSAGE_TYPE_P_DELAY_REQ 2 +#define MESSAGE_TYPE_P_DELAY_RESP 3 +#define MESSAGE_TYPE_DELAY_REQ 4 + +#define SYNC 0x0 +#define DELAY_REQ 0x1 +#define PDELAY_REQ 0x2 +#define PDELAY_RESP 0x3 + +static LIST_HEAD(ines_clocks); +static DEFINE_MUTEX(ines_clocks_lock); + +struct ines_global_regs { + u32 id; + u32 test; + u32 global; + u32 version; + u32 test2; + u32 int_stat; + u32 int_msk; + u32 buf_stat; +}; + +struct ines_port_registers { + u32 port_conf; + u32 p_delay; + u32 ts_stat_tx; + u32 ts_stat_rx; + u32 ts_tx; + u32 ts_rx; +}; + +struct ines_timestamp { + struct list_head list; + unsigned long tmo; + u16 tag; + u64 sec; + u64 nsec; + u64 clkid; + u16 portnum; + u16 seqid; +}; + +struct ines_port { + struct ines_port_registers *regs; + struct mii_timestamper mii_ts; + struct ines_clock *clock; + bool rxts_enabled; + bool txts_enabled; + unsigned int index; + struct delayed_work ts_work; + /* lock protects event list and tx_skb */ + spinlock_t lock; + struct sk_buff *tx_skb; + struct list_head events; + struct list_head pool; + struct ines_timestamp pool_data[INES_MAX_EVENTS]; +}; + +struct ines_clock { + struct ines_port port[INES_N_PORTS]; + struct ines_global_regs __iomem *regs; + void __iomem *base; + struct device_node *node; + struct device *dev; + struct list_head list; +}; + +static bool ines_match(struct sk_buff *skb, unsigned int ptp_class, + struct ines_timestamp *ts, struct device *dev); +static int ines_rxfifo_read(struct ines_port *port); +static u64 ines_rxts64(struct ines_port *port, unsigned int words); +static bool ines_timestamp_expired(struct ines_timestamp *ts); +static u64 ines_txts64(struct ines_port *port, unsigned int words); +static void ines_txtstamp_work(struct work_struct *work); +static bool is_sync_pdelay_resp(struct sk_buff *skb, int type); +static u8 tag_to_msgtype(u8 tag); + +static void ines_clock_cleanup(struct ines_clock *clock) +{ + struct ines_port *port; + int i; + + for (i = 0; i < INES_N_PORTS; i++) { + port = &clock->port[i]; + cancel_delayed_work_sync(&port->ts_work); + } +} + +static int ines_clock_init(struct ines_clock *clock, struct device *device, + void __iomem *addr) +{ + struct device_node *node = device->of_node; + unsigned long port_addr; + struct ines_port *port; + int i, j; + + INIT_LIST_HEAD(&clock->list); + clock->node = node; + clock->dev = device; + clock->base = addr; + clock->regs = clock->base; + + for (i = 0; i < INES_N_PORTS; i++) { + port = &clock->port[i]; + port_addr = (unsigned long) clock->base + + INES_PORT_OFFSET + i * INES_PORT_SIZE; + port->regs = (struct ines_port_registers *) port_addr; + port->clock = clock; + port->index = i; + INIT_DELAYED_WORK(&port->ts_work, ines_txtstamp_work); + spin_lock_init(&port->lock); + INIT_LIST_HEAD(&port->events); + INIT_LIST_HEAD(&port->pool); + for (j = 0; j < INES_MAX_EVENTS; j++) + list_add(&port->pool_data[j].list, &port->pool); + } + + ines_write32(clock, 0xBEEF, test); + ines_write32(clock, 0xBEEF, test2); + + dev_dbg(device, "ID 0x%x\n", ines_read32(clock, id)); + dev_dbg(device, "TEST 0x%x\n", ines_read32(clock, test)); + dev_dbg(device, "VERSION 0x%x\n", ines_read32(clock, version)); + dev_dbg(device, "TEST2 0x%x\n", ines_read32(clock, test2)); + + for (i = 0; i < INES_N_PORTS; i++) { + port = &clock->port[i]; + ines_write32(port, PORT_CONF, port_conf); + } + + return 0; +} + +static struct ines_port *ines_find_port(struct device_node *node, u32 index) +{ + struct ines_port *port = NULL; + struct ines_clock *clock; + struct list_head *this; + + mutex_lock(&ines_clocks_lock); + list_for_each(this, &ines_clocks) { + clock = list_entry(this, struct ines_clock, list); + if (clock->node == node) { + port = &clock->port[index]; + break; + } + } + mutex_unlock(&ines_clocks_lock); + return port; +} + +static u64 ines_find_rxts(struct ines_port *port, struct sk_buff *skb, int type) +{ + struct list_head *this, *next; + struct ines_timestamp *ts; + unsigned long flags; + u64 ns = 0; + + if (type == PTP_CLASS_NONE) + return 0; + + spin_lock_irqsave(&port->lock, flags); + ines_rxfifo_read(port); + list_for_each_safe(this, next, &port->events) { + ts = list_entry(this, struct ines_timestamp, list); + if (ines_timestamp_expired(ts)) { + list_del_init(&ts->list); + list_add(&ts->list, &port->pool); + continue; + } + if (ines_match(skb, type, ts, port->clock->dev)) { + ns = ts->sec * 1000000000ULL + ts->nsec; + list_del_init(&ts->list); + list_add(&ts->list, &port->pool); + break; + } + } + spin_unlock_irqrestore(&port->lock, flags); + + return ns; +} + +static u64 ines_find_txts(struct ines_port *port, struct sk_buff *skb) +{ + unsigned int class = ptp_classify_raw(skb), i; + u32 data_rd_pos, buf_stat, mask, ts_stat_tx; + struct ines_timestamp ts; + unsigned long flags; + u64 ns = 0; + + mask = TX_FIFO_NE_1 << port->index; + + spin_lock_irqsave(&port->lock, flags); + + for (i = 0; i < INES_FIFO_DEPTH; i++) { + + buf_stat = ines_read32(port->clock, buf_stat); + if (!(buf_stat & mask)) { + dev_dbg(port->clock->dev, + "Tx timestamp FIFO unexpectedly empty\n"); + break; + } + ts_stat_tx = ines_read32(port, ts_stat_tx); + data_rd_pos = (ts_stat_tx >> DATA_READ_POS_SHIFT) & + DATA_READ_POS_MASK; + if (data_rd_pos) { + dev_err(port->clock->dev, + "unexpected Tx read pos %u\n", data_rd_pos); + break; + } + + ts.tag = ines_read32(port, ts_tx); + ts.sec = ines_txts64(port, 3); + ts.nsec = ines_txts64(port, 2); + ts.clkid = ines_txts64(port, 4); + ts.portnum = ines_read32(port, ts_tx); + ts.seqid = ines_read32(port, ts_tx); + + if (ines_match(skb, class, &ts, port->clock->dev)) { + ns = ts.sec * 1000000000ULL + ts.nsec; + break; + } + } + + spin_unlock_irqrestore(&port->lock, flags); + return ns; +} + +static int ines_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr) +{ + struct ines_port *port = container_of(mii_ts, struct ines_port, mii_ts); + u32 cm_one_step = 0, port_conf, ts_stat_rx, ts_stat_tx; + struct hwtstamp_config cfg; + unsigned long flags; + + if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) + return -EFAULT; + + /* reserved for future extensions */ + if (cfg.flags) + return -EINVAL; + + switch (cfg.tx_type) { + case HWTSTAMP_TX_OFF: + ts_stat_tx = 0; + break; + case HWTSTAMP_TX_ON: + ts_stat_tx = TS_ENABLE; + break; + case HWTSTAMP_TX_ONESTEP_P2P: + ts_stat_tx = TS_ENABLE; + cm_one_step = CM_ONE_STEP; + break; + default: + return -ERANGE; + } + + switch (cfg.rx_filter) { + case HWTSTAMP_FILTER_NONE: + ts_stat_rx = 0; + break; + case HWTSTAMP_FILTER_ALL: + case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: + return -ERANGE; + case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + case HWTSTAMP_FILTER_PTP_V2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: + ts_stat_rx = TS_ENABLE; + cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; + break; + default: + return -ERANGE; + } + + spin_lock_irqsave(&port->lock, flags); + + port_conf = ines_read32(port, port_conf); + port_conf &= ~CM_ONE_STEP; + port_conf |= cm_one_step; + + ines_write32(port, port_conf, port_conf); + ines_write32(port, ts_stat_rx, ts_stat_rx); + ines_write32(port, ts_stat_tx, ts_stat_tx); + + port->rxts_enabled = ts_stat_rx == TS_ENABLE ? true : false; + port->txts_enabled = ts_stat_tx == TS_ENABLE ? true : false; + + spin_unlock_irqrestore(&port->lock, flags); + + return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0; +} + +static void ines_link_state(struct mii_timestamper *mii_ts, + struct phy_device *phydev) +{ + struct ines_port *port = container_of(mii_ts, struct ines_port, mii_ts); + u32 port_conf, speed_conf; + unsigned long flags; + + switch (phydev->speed) { + case SPEED_10: + speed_conf = PHY_SPEED_10 << PHY_SPEED_SHIFT; + break; + case SPEED_100: + speed_conf = PHY_SPEED_100 << PHY_SPEED_SHIFT; + break; + case SPEED_1000: + speed_conf = PHY_SPEED_1000 << PHY_SPEED_SHIFT; + break; + default: + dev_err(port->clock->dev, "bad speed: %d\n", phydev->speed); + return; + } + spin_lock_irqsave(&port->lock, flags); + + port_conf = ines_read32(port, port_conf); + port_conf &= ~(0x3 << PHY_SPEED_SHIFT); + port_conf |= speed_conf; + + ines_write32(port, port_conf, port_conf); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static bool ines_match(struct sk_buff *skb, unsigned int ptp_class, + struct ines_timestamp *ts, struct device *dev) +{ + u8 *msgtype, *data = skb_mac_header(skb); + unsigned int offset = 0; + __be16 *portn, *seqid; + __be64 *clkid; + + if (unlikely(ptp_class & PTP_CLASS_V1)) + return false; + + if (ptp_class & PTP_CLASS_VLAN) + offset += VLAN_HLEN; + + switch (ptp_class & PTP_CLASS_PMASK) { + case PTP_CLASS_IPV4: + offset += ETH_HLEN + IPV4_HLEN(data + offset) + UDP_HLEN; + break; + case PTP_CLASS_IPV6: + offset += ETH_HLEN + IP6_HLEN + UDP_HLEN; + break; + case PTP_CLASS_L2: + offset += ETH_HLEN; + break; + default: + return false; + } + + if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID + sizeof(*seqid)) + return false; + + msgtype = data + offset; + clkid = (__be64 *)(data + offset + OFF_PTP_CLOCK_ID); + portn = (__be16 *)(data + offset + OFF_PTP_PORT_NUM); + seqid = (__be16 *)(data + offset + OFF_PTP_SEQUENCE_ID); + + if (tag_to_msgtype(ts->tag & 0x7) != (*msgtype & 0xf)) { + dev_dbg(dev, "msgtype mismatch ts %hhu != skb %hhu\n", + tag_to_msgtype(ts->tag & 0x7), *msgtype & 0xf); + return false; + } + if (cpu_to_be64(ts->clkid) != *clkid) { + dev_dbg(dev, "clkid mismatch ts %llx != skb %llx\n", + cpu_to_be64(ts->clkid), *clkid); + return false; + } + if (ts->portnum != ntohs(*portn)) { + dev_dbg(dev, "portn mismatch ts %hu != skb %hu\n", + ts->portnum, ntohs(*portn)); + return false; + } + if (ts->seqid != ntohs(*seqid)) { + dev_dbg(dev, "seqid mismatch ts %hu != skb %hu\n", + ts->seqid, ntohs(*seqid)); + return false; + } + + return true; +} + +static bool ines_rxtstamp(struct mii_timestamper *mii_ts, + struct sk_buff *skb, int type) +{ + struct ines_port *port = container_of(mii_ts, struct ines_port, mii_ts); + struct skb_shared_hwtstamps *ssh; + u64 ns; + + if (!port->rxts_enabled) + return false; + + ns = ines_find_rxts(port, skb, type); + if (!ns) + return false; + + ssh = skb_hwtstamps(skb); + ssh->hwtstamp = ns_to_ktime(ns); + netif_rx(skb); + + return true; +} + +static int ines_rxfifo_read(struct ines_port *port) +{ + u32 data_rd_pos, buf_stat, mask, ts_stat_rx; + struct ines_timestamp *ts; + unsigned int i; + + mask = RX_FIFO_NE_1 << port->index; + + for (i = 0; i < INES_FIFO_DEPTH; i++) { + if (list_empty(&port->pool)) { + dev_err(port->clock->dev, "event pool is empty\n"); + return -1; + } + buf_stat = ines_read32(port->clock, buf_stat); + if (!(buf_stat & mask)) + break; + + ts_stat_rx = ines_read32(port, ts_stat_rx); + data_rd_pos = (ts_stat_rx >> DATA_READ_POS_SHIFT) & + DATA_READ_POS_MASK; + if (data_rd_pos) { + dev_err(port->clock->dev, "unexpected Rx read pos %u\n", + data_rd_pos); + break; + } + + ts = list_first_entry(&port->pool, struct ines_timestamp, list); + ts->tmo = jiffies + HZ; + ts->tag = ines_read32(port, ts_rx); + ts->sec = ines_rxts64(port, 3); + ts->nsec = ines_rxts64(port, 2); + ts->clkid = ines_rxts64(port, 4); + ts->portnum = ines_read32(port, ts_rx); + ts->seqid = ines_read32(port, ts_rx); + + list_del_init(&ts->list); + list_add_tail(&ts->list, &port->events); + } + + return 0; +} + +static u64 ines_rxts64(struct ines_port *port, unsigned int words) +{ + unsigned int i; + u64 result; + u16 word; + + word = ines_read32(port, ts_rx); + result = word; + words--; + for (i = 0; i < words; i++) { + word = ines_read32(port, ts_rx); + result <<= 16; + result |= word; + } + return result; +} + +static bool ines_timestamp_expired(struct ines_timestamp *ts) +{ + return time_after(jiffies, ts->tmo); +} + +static int ines_ts_info(struct mii_timestamper *mii_ts, + struct ethtool_ts_info *info) +{ + info->so_timestamping = + SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_TX_SOFTWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RX_SOFTWARE | + SOF_TIMESTAMPING_SOFTWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + + info->phc_index = -1; + + info->tx_types = + (1 << HWTSTAMP_TX_OFF) | + (1 << HWTSTAMP_TX_ON) | + (1 << HWTSTAMP_TX_ONESTEP_P2P); + + info->rx_filters = + (1 << HWTSTAMP_FILTER_NONE) | + (1 << HWTSTAMP_FILTER_PTP_V2_EVENT); + + return 0; +} + +static u64 ines_txts64(struct ines_port *port, unsigned int words) +{ + unsigned int i; + u64 result; + u16 word; + + word = ines_read32(port, ts_tx); + result = word; + words--; + for (i = 0; i < words; i++) { + word = ines_read32(port, ts_tx); + result <<= 16; + result |= word; + } + return result; +} + +static bool ines_txts_onestep(struct ines_port *port, struct sk_buff *skb, int type) +{ + unsigned long flags; + u32 port_conf; + + spin_lock_irqsave(&port->lock, flags); + port_conf = ines_read32(port, port_conf); + spin_unlock_irqrestore(&port->lock, flags); + + if (port_conf & CM_ONE_STEP) + return is_sync_pdelay_resp(skb, type); + + return false; +} + +static void ines_txtstamp(struct mii_timestamper *mii_ts, + struct sk_buff *skb, int type) +{ + struct ines_port *port = container_of(mii_ts, struct ines_port, mii_ts); + struct sk_buff *old_skb = NULL; + unsigned long flags; + + if (!port->txts_enabled || ines_txts_onestep(port, skb, type)) { + kfree_skb(skb); + return; + } + + spin_lock_irqsave(&port->lock, flags); + + if (port->tx_skb) + old_skb = port->tx_skb; + + port->tx_skb = skb; + + spin_unlock_irqrestore(&port->lock, flags); + + if (old_skb) + kfree_skb(old_skb); + + schedule_delayed_work(&port->ts_work, 1); +} + +static void ines_txtstamp_work(struct work_struct *work) +{ + struct ines_port *port = + container_of(work, struct ines_port, ts_work.work); + struct skb_shared_hwtstamps ssh; + struct sk_buff *skb; + unsigned long flags; + u64 ns; + + spin_lock_irqsave(&port->lock, flags); + skb = port->tx_skb; + port->tx_skb = NULL; + spin_unlock_irqrestore(&port->lock, flags); + + ns = ines_find_txts(port, skb); + if (!ns) { + kfree_skb(skb); + return; + } + ssh.hwtstamp = ns_to_ktime(ns); + skb_complete_tx_timestamp(skb, &ssh); +} + +static bool is_sync_pdelay_resp(struct sk_buff *skb, int type) +{ + u8 *data = skb->data, *msgtype; + unsigned int offset = 0; + + if (type & PTP_CLASS_VLAN) + offset += VLAN_HLEN; + + switch (type & PTP_CLASS_PMASK) { + case PTP_CLASS_IPV4: + offset += ETH_HLEN + IPV4_HLEN(data + offset) + UDP_HLEN; + break; + case PTP_CLASS_IPV6: + offset += ETH_HLEN + IP6_HLEN + UDP_HLEN; + break; + case PTP_CLASS_L2: + offset += ETH_HLEN; + break; + default: + return 0; + } + + if (type & PTP_CLASS_V1) + offset += OFF_PTP_CONTROL; + + if (skb->len < offset + 1) + return 0; + + msgtype = data + offset; + + switch ((*msgtype & 0xf)) { + case SYNC: + case PDELAY_RESP: + return true; + default: + return false; + } +} + +static u8 tag_to_msgtype(u8 tag) +{ + switch (tag) { + case MESSAGE_TYPE_SYNC: + return SYNC; + case MESSAGE_TYPE_P_DELAY_REQ: + return PDELAY_REQ; + case MESSAGE_TYPE_P_DELAY_RESP: + return PDELAY_RESP; + case MESSAGE_TYPE_DELAY_REQ: + return DELAY_REQ; + } + return 0xf; +} + +static struct mii_timestamper *ines_ptp_probe_channel(struct device *device, + unsigned int index) +{ + struct device_node *node = device->of_node; + struct ines_port *port; + + if (index > INES_N_PORTS - 1) { + dev_err(device, "bad port index %u\n", index); + return ERR_PTR(-EINVAL); + } + port = ines_find_port(node, index); + if (!port) { + dev_err(device, "missing port index %u\n", index); + return ERR_PTR(-ENODEV); + } + port->mii_ts.rxtstamp = ines_rxtstamp; + port->mii_ts.txtstamp = ines_txtstamp; + port->mii_ts.hwtstamp = ines_hwtstamp; + port->mii_ts.link_state = ines_link_state; + port->mii_ts.ts_info = ines_ts_info; + + return &port->mii_ts; +} + +static void ines_ptp_release_channel(struct device *device, + struct mii_timestamper *mii_ts) +{ +} + +static struct mii_timestamping_ctrl ines_ctrl = { + .probe_channel = ines_ptp_probe_channel, + .release_channel = ines_ptp_release_channel, +}; + +static int ines_ptp_ctrl_probe(struct platform_device *pld) +{ + struct ines_clock *clock; + struct resource *res; + void __iomem *addr; + int err = 0; + + res = platform_get_resource(pld, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pld->dev, "missing memory resource\n"); + return -EINVAL; + } + addr = devm_ioremap_resource(&pld->dev, res); + if (IS_ERR(addr)) { + err = PTR_ERR(addr); + goto out; + } + clock = kzalloc(sizeof(*clock), GFP_KERNEL); + if (!clock) { + err = -ENOMEM; + goto out; + } + if (ines_clock_init(clock, &pld->dev, addr)) { + kfree(clock); + err = -ENOMEM; + goto out; + } + err = register_mii_tstamp_controller(&pld->dev, &ines_ctrl); + if (err) { + kfree(clock); + goto out; + } + mutex_lock(&ines_clocks_lock); + list_add_tail(&ines_clocks, &clock->list); + mutex_unlock(&ines_clocks_lock); + + dev_set_drvdata(&pld->dev, clock); +out: + return err; +} + +static int ines_ptp_ctrl_remove(struct platform_device *pld) +{ + struct ines_clock *clock = dev_get_drvdata(&pld->dev); + + unregister_mii_tstamp_controller(&pld->dev); + mutex_lock(&ines_clocks_lock); + list_del(&clock->list); + mutex_unlock(&ines_clocks_lock); + ines_clock_cleanup(clock); + kfree(clock); + return 0; +} + +static const struct of_device_id ines_ptp_ctrl_of_match[] = { + { .compatible = "ines,ptp-ctrl" }, + { } +}; + +MODULE_DEVICE_TABLE(of, ines_ptp_ctrl_of_match); + +static struct platform_driver ines_ptp_ctrl_driver = { + .probe = ines_ptp_ctrl_probe, + .remove = ines_ptp_ctrl_remove, + .driver = { + .name = "ines_ptp_ctrl", + .of_match_table = of_match_ptr(ines_ptp_ctrl_of_match), + }, +}; +module_platform_driver(ines_ptp_ctrl_driver);