From patchwork Tue Nov 9 09:50:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Martin Kaistra X-Patchwork-Id: 12610287 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2C0C5C433F5 for ; Tue, 9 Nov 2021 09:50:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0C5F06128E for ; Tue, 9 Nov 2021 09:50:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245059AbhKIJxg (ORCPT ); Tue, 9 Nov 2021 04:53:36 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49794 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242807AbhKIJxd (ORCPT ); Tue, 9 Nov 2021 04:53:33 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16B56C061767; Tue, 9 Nov 2021 01:50:48 -0800 (PST) From: Martin Kaistra DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1636451445; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QAIgtG2gp3vW7HRXGd/1SQnk8hM3CErk4xOJRxIoPy4=; b=MxiShnBCeruIZ6OUNZDjlmPNckzWmVeIwodAdtDHG6sXcZ9jT/Oy1fKDexO4vZ8WQbolQZ BR+sKRxo7z5Nl/JlzO84QX4lg09wZihftSfbKflXA+2XO2Wwbhroq+Q4WPUvIyu8Opgk8+ mooLozMhbuwRdiNhv2f448PjGb8ud4GD0IQShn0r2KkF7Lvw8qv5G6yFpTvIu5ZFGQQSb7 ImA8Q2j0nmilMe0L+VWYn00TzKDS9yix9sx5dV3S5+sMNZjMNaBRzrwLr1lv9IQYy9tzFU qQaPb7hy5bdtaFh6xJYNq23rFXsnhTPOc9Uy0i9RH2KsiDuaffjowlJdQ5f1iA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1636451445; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QAIgtG2gp3vW7HRXGd/1SQnk8hM3CErk4xOJRxIoPy4=; b=l7HXjtYDaNWbSyXULGwrphGkVvQ3eIYb0bdPEbHuf1Pf4a3wJAxfDj4hZoghuXhFne/l+A abmjQN4xEfj2cPCA== To: Florian Fainelli , Andrew Lunn , Vivien Didelot Cc: martin.kaistra@linutronix.de, Richard Cochran , Kurt Kanzenbach , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , John Stultz , Thomas Gleixner , Stephen Boyd , Russell King , Marc Kleine-Budde , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v2 1/7] net: dsa: b53: Add BroadSync HD register definitions Date: Tue, 9 Nov 2021 10:50:03 +0100 Message-Id: <20211109095013.27829-2-martin.kaistra@linutronix.de> In-Reply-To: <20211109095013.27829-1-martin.kaistra@linutronix.de> References: <20211109095013.27829-1-martin.kaistra@linutronix.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Kurt Kanzenbach Add register definitions for the BroadSync HD features of BCM53128. These will be used to enable PTP support. Signed-off-by: Kurt Kanzenbach Signed-off-by: Martin Kaistra --- drivers/net/dsa/b53/b53_regs.h | 71 ++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h index b2c539a42154..0deb11a7c9cd 100644 --- a/drivers/net/dsa/b53/b53_regs.h +++ b/drivers/net/dsa/b53/b53_regs.h @@ -50,6 +50,12 @@ /* Jumbo Frame Registers */ #define B53_JUMBO_PAGE 0x40 +/* BroadSync HD Register Page */ +#define B53_BROADSYNC_PAGE 0x90 + +/* Traffic Remarking Register Page */ +#define B53_TRAFFICREMARKING_PAGE 0x91 + /* EEE Control Registers Page */ #define B53_EEE_PAGE 0x92 @@ -260,6 +266,27 @@ /* Broadcom header TX control (16 bit) */ #define B53_BRCM_HDR_TX_DIS 0x62 +/************************************************************************* + * ARL Control Registers + *************************************************************************/ + +/* Multiport Control Register (16 bit) */ +#define B53_MPORT_CTRL 0x0e +#define MPORT_CTRL_DIS_FORWARD 0 +#define MPORT_CTRL_CMP_ETYPE 1 +#define MPORT_CTRL_CMP_ADDR 2 +#define MPORT_CTRL_CMP_ADDR_ETYPE 3 +#define MPORT_CTRL_SHIFT(x) ((x) << 1) +#define MPORT_CTRL_MASK 0x2 +#define MPORT0_TS_EN BIT(15) + +/* Multiport Address N (N = 0–5) Register (64 bit) */ +#define B53_MPORT_ADDR(n) (0x10 + ((n) << 4)) +#define MPORT_ETYPE(x) ((u64)(x) << 48) + +/* Multiport Vector N (N = 0–5) Register (32 bit) */ +#define B53_MPORT_VCTR(n) (0x18 + ((n) << 4)) + /************************************************************************* * ARL Access Page Registers *************************************************************************/ @@ -479,6 +506,50 @@ #define JMS_MIN_SIZE 1518 #define JMS_MAX_SIZE 9724 +/************************************************************************* + * BroadSync HD Page Registers + *************************************************************************/ + +/* BroadSync HD Enable Control Register (16 bit) */ +#define B53_BROADSYNC_EN_CTRL 0x00 + +/* BroadSync HD Time Stamp Report Control Register */ +#define B53_BROADSYNC_TS_REPORT_CTRL 0x02 +#define TSRPT_PKT_EN BIT(0) + +/* BroadSync HD PCP Value Control Register */ +#define B53_BROADSYNC_PCP_CTRL 0x03 + +/* BroadSync HD Max Packet Size Register */ +#define B53_BROADSYNC_MAX_SDU 0x04 + +/* BroadSync HD Time Base Register (32 bit) */ +#define B53_BROADSYNC_TIMEBASE 0x10 + +/* BroadSync HD Time Base Adjustment Register (32 bit) */ +#define B53_BROADSYNC_TIMEBASE_ADJ 0x14 + +/* BroadSync HD Slot Number and Tick Counter Register (32 bit) */ +#define B53_BROADSYNC_SLOT_CNT 0x18 + +/* BroadSync HD Slot Adjustment Register (32 bit) */ +#define B53_BROADSYNC_SLOT_ADJ 0x1c + +/* BroadSync HD Class 5 Bandwidth Control Register */ +#define B53_BROADSYNC_CLS5_BW_CTRL 0x30 + +/* BroadSync HD Class 4 Bandwidth Control Register */ +#define B53_BROADSYNC_CLS4_BW_CTRL 0x60 + +/* BroadSync HD Egress Time Stamp Register */ +#define B53_BROADSYNC_EGRESS_TS 0x90 + +/* BroadSync HD Egress Time Stamp Status Register */ +#define B53_BROADSYNC_EGRESS_TS_STS 0xd0 + +/* BroadSync HD Link Status Register (16 bit) */ +#define B53_BROADSYNC_LINK_STS 0xe0 + /************************************************************************* * EEE Configuration Page Registers *************************************************************************/ From patchwork Tue Nov 9 09:50:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Kaistra X-Patchwork-Id: 12610289 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A39A8C433EF for ; Tue, 9 Nov 2021 09:51:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8A17C611CC for ; Tue, 9 Nov 2021 09:51:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245049AbhKIJxq (ORCPT ); Tue, 9 Nov 2021 04:53:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49808 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245074AbhKIJxh (ORCPT ); Tue, 9 Nov 2021 04:53:37 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C7B9C061764; Tue, 9 Nov 2021 01:50:51 -0800 (PST) From: Martin Kaistra DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1636451450; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7YbG2hfMz6xW/PCCxdMREuP3ECE7JRXSaX6c5e8BiT4=; b=VQAKOd3FX8ayXWNWBddYNpGSWuEsHVO4+pJfdRXsv2nYwmgu8LiTmGLMjslL2E7BUTbJNh dUcbW88NEmkxLLzUkEuOaJSq14zz2PDxzx03f737prjsXQnESEc8dwM3eP1aX6TyO9stmx szdKtDMQJH6/NEr40C+wlCPjQCbDSk/iJsvu9mrDBHUh4kI5f8WC3N7mDq6a7GSJyBSWcG TEZjnSEH6VVhKaJoTE/pAKp1gh0Rqe5HPeOnxwf0ngWyywSc2u30R+LZCXCWGZrnpU3SaO cKnVtRMWp7jbVV2dSaOXX7GE5Q1cuYzhQvR9OGwgZb3e/4096aCKupWU5d7k1w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1636451450; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7YbG2hfMz6xW/PCCxdMREuP3ECE7JRXSaX6c5e8BiT4=; b=U7NWNeeJLgWaTYKHm46ULD0N/00omlOgkZpUPCpdXqAort78/KTRotlpt3pPZAYV1rJvXl o6lNPCgiRMVOulAg== To: Florian Fainelli , Andrew Lunn , Vivien Didelot Cc: martin.kaistra@linutronix.de, Richard Cochran , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , John Stultz , Thomas Gleixner , Stephen Boyd , Russell King , Marc Kleine-Budde , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v2 2/7] net: dsa: b53: Move struct b53_device to include/linux/dsa/b53.h Date: Tue, 9 Nov 2021 10:50:04 +0100 Message-Id: <20211109095013.27829-3-martin.kaistra@linutronix.de> In-Reply-To: <20211109095013.27829-1-martin.kaistra@linutronix.de> References: <20211109095013.27829-1-martin.kaistra@linutronix.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org In order to access the b53 structs from net/dsa/tag_brcm.c move the definitions from drivers/net/dsa/b53/b53_priv.h to the new file include/linux/dsa/b53.h. Signed-off-by: Martin Kaistra --- drivers/net/dsa/b53/b53_priv.h | 90 +---------------------------- include/linux/dsa/b53.h | 100 +++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 89 deletions(-) create mode 100644 include/linux/dsa/b53.h diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h index 579da74ada64..1652e489b737 100644 --- a/drivers/net/dsa/b53/b53_priv.h +++ b/drivers/net/dsa/b53/b53_priv.h @@ -23,44 +23,13 @@ #include #include #include -#include +#include #include "b53_regs.h" -struct b53_device; struct net_device; struct phylink_link_state; -struct b53_io_ops { - int (*read8)(struct b53_device *dev, u8 page, u8 reg, u8 *value); - int (*read16)(struct b53_device *dev, u8 page, u8 reg, u16 *value); - int (*read32)(struct b53_device *dev, u8 page, u8 reg, u32 *value); - int (*read48)(struct b53_device *dev, u8 page, u8 reg, u64 *value); - int (*read64)(struct b53_device *dev, u8 page, u8 reg, u64 *value); - int (*write8)(struct b53_device *dev, u8 page, u8 reg, u8 value); - int (*write16)(struct b53_device *dev, u8 page, u8 reg, u16 value); - int (*write32)(struct b53_device *dev, u8 page, u8 reg, u32 value); - int (*write48)(struct b53_device *dev, u8 page, u8 reg, u64 value); - int (*write64)(struct b53_device *dev, u8 page, u8 reg, u64 value); - int (*phy_read16)(struct b53_device *dev, int addr, int reg, u16 *value); - int (*phy_write16)(struct b53_device *dev, int addr, int reg, u16 value); - int (*irq_enable)(struct b53_device *dev, int port); - void (*irq_disable)(struct b53_device *dev, int port); - u8 (*serdes_map_lane)(struct b53_device *dev, int port); - int (*serdes_link_state)(struct b53_device *dev, int port, - struct phylink_link_state *state); - void (*serdes_config)(struct b53_device *dev, int port, - unsigned int mode, - const struct phylink_link_state *state); - void (*serdes_an_restart)(struct b53_device *dev, int port); - void (*serdes_link_set)(struct b53_device *dev, int port, - unsigned int mode, phy_interface_t interface, - bool link_up); - void (*serdes_phylink_validate)(struct b53_device *dev, int port, - unsigned long *supported, - struct phylink_link_state *state); -}; - #define B53_INVALID_LANE 0xff enum { @@ -89,63 +58,6 @@ enum { #define B53_N_PORTS 9 #define B53_N_PORTS_25 6 -struct b53_port { - u16 vlan_ctl_mask; - struct ethtool_eee eee; -}; - -struct b53_vlan { - u16 members; - u16 untag; - bool valid; -}; - -struct b53_device { - struct dsa_switch *ds; - struct b53_platform_data *pdata; - const char *name; - - struct mutex reg_mutex; - struct mutex stats_mutex; - struct mutex arl_mutex; - const struct b53_io_ops *ops; - - /* chip specific data */ - u32 chip_id; - u8 core_rev; - u8 vta_regs[3]; - u8 duplex_reg; - u8 jumbo_pm_reg; - u8 jumbo_size_reg; - int reset_gpio; - u8 num_arl_bins; - u16 num_arl_buckets; - enum dsa_tag_protocol tag_protocol; - - /* used ports mask */ - u16 enabled_ports; - unsigned int imp_port; - - /* connect specific data */ - u8 current_page; - struct device *dev; - u8 serdes_lane; - - /* Master MDIO bus we got probed from */ - struct mii_bus *bus; - - void *priv; - - /* run time configuration */ - bool enable_jumbo; - - unsigned int num_vlans; - struct b53_vlan *vlans; - bool vlan_enabled; - unsigned int num_ports; - struct b53_port *ports; -}; - #define b53_for_each_port(dev, i) \ for (i = 0; i < B53_N_PORTS; i++) \ if (dev->enabled_ports & BIT(i)) diff --git a/include/linux/dsa/b53.h b/include/linux/dsa/b53.h new file mode 100644 index 000000000000..af782a1da362 --- /dev/null +++ b/include/linux/dsa/b53.h @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: ISC */ +/* + * Copyright (C) 2011-2013 Jonas Gorski + * + * Included by drivers/net/dsa/b53/b53_priv.h and net/dsa/tag_brcm.c + */ + +#include + +struct b53_device; +struct phylink_link_state; + +struct b53_io_ops { + int (*read8)(struct b53_device *dev, u8 page, u8 reg, u8 *value); + int (*read16)(struct b53_device *dev, u8 page, u8 reg, u16 *value); + int (*read32)(struct b53_device *dev, u8 page, u8 reg, u32 *value); + int (*read48)(struct b53_device *dev, u8 page, u8 reg, u64 *value); + int (*read64)(struct b53_device *dev, u8 page, u8 reg, u64 *value); + int (*write8)(struct b53_device *dev, u8 page, u8 reg, u8 value); + int (*write16)(struct b53_device *dev, u8 page, u8 reg, u16 value); + int (*write32)(struct b53_device *dev, u8 page, u8 reg, u32 value); + int (*write48)(struct b53_device *dev, u8 page, u8 reg, u64 value); + int (*write64)(struct b53_device *dev, u8 page, u8 reg, u64 value); + int (*phy_read16)(struct b53_device *dev, int addr, int reg, + u16 *value); + int (*phy_write16)(struct b53_device *dev, int addr, int reg, + u16 value); + int (*irq_enable)(struct b53_device *dev, int port); + void (*irq_disable)(struct b53_device *dev, int port); + u8 (*serdes_map_lane)(struct b53_device *dev, int port); + int (*serdes_link_state)(struct b53_device *dev, int port, + struct phylink_link_state *state); + void (*serdes_config)(struct b53_device *dev, int port, + unsigned int mode, + const struct phylink_link_state *state); + void (*serdes_an_restart)(struct b53_device *dev, int port); + void (*serdes_link_set)(struct b53_device *dev, int port, + unsigned int mode, phy_interface_t interface, + bool link_up); + void (*serdes_phylink_validate)(struct b53_device *dev, int port, + unsigned long *supported, + struct phylink_link_state *state); +}; + +struct b53_port { + u16 vlan_ctl_mask; + struct ethtool_eee eee; +}; + +struct b53_vlan { + u16 members; + u16 untag; + bool valid; +}; + +struct b53_device { + struct dsa_switch *ds; + struct b53_platform_data *pdata; + const char *name; + + struct mutex reg_mutex; + struct mutex stats_mutex; + struct mutex arl_mutex; + const struct b53_io_ops *ops; + + /* chip specific data */ + u32 chip_id; + u8 core_rev; + u8 vta_regs[3]; + u8 duplex_reg; + u8 jumbo_pm_reg; + u8 jumbo_size_reg; + int reset_gpio; + u8 num_arl_bins; + u16 num_arl_buckets; + enum dsa_tag_protocol tag_protocol; + + /* used ports mask */ + u16 enabled_ports; + unsigned int imp_port; + + /* connect specific data */ + u8 current_page; + struct device *dev; + u8 serdes_lane; + + /* Master MDIO bus we got probed from */ + struct mii_bus *bus; + + void *priv; + + /* run time configuration */ + bool enable_jumbo; + + unsigned int num_vlans; + struct b53_vlan *vlans; + bool vlan_enabled; + unsigned int num_ports; + struct b53_port *ports; +}; From patchwork Tue Nov 9 09:50:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Kaistra X-Patchwork-Id: 12610291 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1AD9EC433FE for ; Tue, 9 Nov 2021 09:51:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 05F0A611CC for ; Tue, 9 Nov 2021 09:51:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245088AbhKIJxw (ORCPT ); Tue, 9 Nov 2021 04:53:52 -0500 Received: from Galois.linutronix.de ([193.142.43.55]:34980 "EHLO galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245096AbhKIJxm (ORCPT ); Tue, 9 Nov 2021 04:53:42 -0500 From: Martin Kaistra DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1636451454; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aW6ZznmXqA8zEDZbkYNLIXCfqLwCLA1w/y4b1/dzeTg=; b=m3zlKfKywp4n3ayFQdZDSqn2H/wfESZNm2Q/nl3EIJpTpmBfm8abioTbu3+rkyDm7lArAE RDLRiyAwTMhj95XRd2cgMBpMyrOloh0Xd2pkK5tQM+tDUHURoS9vlnixuMpFwwQsVwtYkU a7S5ysCRwwzXzcDSaw+3HEgyx3JYckf/D3A/+1TFQAO0FZawE3ouJuqLZfKeV1Q4kK8AnW 0xD5Dm4VXD4lz6Ev4xzP/wejgxR63Vb/RZ7Hn/zRdLO8u8z7TWObw5bxS/Hzq9ZpD+7gC6 QKk1j1w24M+WqpqO677BzBzYA2kHcoyUDlO0R7V/dTUt6BLULERl/EPPvf62VA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1636451454; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aW6ZznmXqA8zEDZbkYNLIXCfqLwCLA1w/y4b1/dzeTg=; b=TUOEXKdGjBNqOQnGPSRh99U599f1AuTHSpAt0pJnQucHgbOv+kldDhBi+Dxu/70jswABDE I6+SkObPLqr6EaBw== To: Florian Fainelli , Andrew Lunn , Vivien Didelot Cc: martin.kaistra@linutronix.de, Richard Cochran , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , John Stultz , Thomas Gleixner , Stephen Boyd , Russell King , Marc Kleine-Budde , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v2 3/7] timecounter: allow for non-power of two overflow Date: Tue, 9 Nov 2021 10:50:05 +0100 Message-Id: <20211109095013.27829-4-martin.kaistra@linutronix.de> In-Reply-To: <20211109095013.27829-1-martin.kaistra@linutronix.de> References: <20211109095013.27829-1-martin.kaistra@linutronix.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Some hardware counters which are used as clocks have an overflow point which is not a power of two. In order to be able to use the cycle counter infrastructure with such hardware, add support for more generic overflow logic. Signed-off-by: Martin Kaistra --- include/linux/timecounter.h | 3 +++ kernel/time/timecounter.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/include/linux/timecounter.h b/include/linux/timecounter.h index c6540ceea143..c71196a742b3 100644 --- a/include/linux/timecounter.h +++ b/include/linux/timecounter.h @@ -26,12 +26,15 @@ * see CYCLECOUNTER_MASK() helper macro * @mult: cycle to nanosecond multiplier * @shift: cycle to nanosecond divisor (power of two) + * @overflow_point: non-power of two overflow point (optional), + * smaller than mask */ struct cyclecounter { u64 (*read)(const struct cyclecounter *cc); u64 mask; u32 mult; u32 shift; + u64 overflow_point; }; /** diff --git a/kernel/time/timecounter.c b/kernel/time/timecounter.c index e6285288d765..afd2910a9724 100644 --- a/kernel/time/timecounter.c +++ b/kernel/time/timecounter.c @@ -39,6 +39,9 @@ static u64 timecounter_read_delta(struct timecounter *tc) /* calculate the delta since the last timecounter_read_delta(): */ cycle_delta = (cycle_now - tc->cycle_last) & tc->cc->mask; + if (tc->cc->overflow_point && (cycle_now - tc->cycle_last) > tc->cc->mask) + cycle_delta -= tc->cc->mask - tc->cc->overflow_point; + /* convert to nanoseconds: */ ns_offset = cyclecounter_cyc2ns(tc->cc, cycle_delta, tc->mask, &tc->frac); From patchwork Tue Nov 9 09:50:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Kaistra X-Patchwork-Id: 12610293 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7858CC433FE for ; Tue, 9 Nov 2021 09:51:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 66ABC61872 for ; Tue, 9 Nov 2021 09:51:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245137AbhKIJxy (ORCPT ); Tue, 9 Nov 2021 04:53:54 -0500 Received: from Galois.linutronix.de ([193.142.43.55]:34996 "EHLO galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243025AbhKIJxp (ORCPT ); Tue, 9 Nov 2021 04:53:45 -0500 From: Martin Kaistra DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1636451458; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QAt7uB7Rq1Gug4mydJ8aonujRo/omdVnLFrGhsNrjT0=; b=XsIX2I/53lE8DozkbLMYoS29Zotdh0WH6GHkaY4hqdS+VUGeI8SKoKPRKCqxUJRLCi1wu+ o5B11JzGvbUocxbw3rXvQecgua3BwkUFJqCbrKefmJK3itNzy60c7T6Cri+6ez5E32xRvv plZ23KGKWimF8BeJERyp+Fj65mrtsI1h8Lyk7UNwJvq77X77MiKGXT695mEd9KGBxIsgx9 Ooebo3eSuOUgb/WJAZSDRx7Nl3bIOkIa3XvZ5cZkyDvQZNEFYYRkjHf3LjKSoQxYtJP4De lk4o4D4S7CErwAtXLorOekl1RZL4j7ILa+IShvZmb4P20Pk1hcDFMxP5jaJ5ZQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1636451458; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QAt7uB7Rq1Gug4mydJ8aonujRo/omdVnLFrGhsNrjT0=; b=g85ekpsr+HvhAZUkYM07LId2YQ3T8W9NVQkWlZWWgBuKqUplMtqMpOIe7TxfVkg4CwfRMa BSs68dk+rP3OGlCQ== To: Florian Fainelli , Andrew Lunn , Vivien Didelot Cc: martin.kaistra@linutronix.de, Richard Cochran , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , John Stultz , Thomas Gleixner , Stephen Boyd , Russell King , Marc Kleine-Budde , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v2 4/7] net: dsa: b53: Add PHC clock support Date: Tue, 9 Nov 2021 10:50:06 +0100 Message-Id: <20211109095013.27829-5-martin.kaistra@linutronix.de> In-Reply-To: <20211109095013.27829-1-martin.kaistra@linutronix.de> References: <20211109095013.27829-1-martin.kaistra@linutronix.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The BCM53128 switch has an internal clock, which can be used for timestamping. Add support for it. The 32-bit free running clock counts nanoseconds. In order to account for the wrap-around at 999999999 (0x3B9AC9FF) while using the cycle counter infrastructure, we need to set a 30bit mask and use the overflow_point property. Enable the Broadsync HD timestamping feature in b53_ptp_init() for PTPv2 Ethertype (0x88f7). Signed-off-by: Martin Kaistra --- drivers/net/dsa/b53/Kconfig | 8 ++ drivers/net/dsa/b53/Makefile | 4 + drivers/net/dsa/b53/b53_common.c | 17 +++ drivers/net/dsa/b53/b53_ptp.c | 196 +++++++++++++++++++++++++++++++ drivers/net/dsa/b53/b53_ptp.h | 35 ++++++ include/linux/dsa/b53.h | 14 +++ 6 files changed, 274 insertions(+) create mode 100644 drivers/net/dsa/b53/b53_ptp.c create mode 100644 drivers/net/dsa/b53/b53_ptp.h diff --git a/drivers/net/dsa/b53/Kconfig b/drivers/net/dsa/b53/Kconfig index 90b525160b71..71009c93db13 100644 --- a/drivers/net/dsa/b53/Kconfig +++ b/drivers/net/dsa/b53/Kconfig @@ -45,3 +45,11 @@ config B53_SERDES default ARCH_BCM_NSP help Select to enable support for SerDes on e.g: Northstar Plus SoCs. + +config B53_PTP + bool "B53 PTP support" + depends on B53 + depends on PTP_1588_CLOCK + default n + help + Select to enable support for PTP diff --git a/drivers/net/dsa/b53/Makefile b/drivers/net/dsa/b53/Makefile index b1be13023ae4..07c9ac1ce9e8 100644 --- a/drivers/net/dsa/b53/Makefile +++ b/drivers/net/dsa/b53/Makefile @@ -6,3 +6,7 @@ obj-$(CONFIG_B53_MDIO_DRIVER) += b53_mdio.o obj-$(CONFIG_B53_MMAP_DRIVER) += b53_mmap.o obj-$(CONFIG_B53_SRAB_DRIVER) += b53_srab.o obj-$(CONFIG_B53_SERDES) += b53_serdes.o + +ifdef CONFIG_B53_PTP +obj-$(CONFIG_B53) += b53_ptp.o +endif diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index af4761968733..ed590efbd3bf 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -31,6 +31,7 @@ #include "b53_regs.h" #include "b53_priv.h" +#include "b53_ptp.h" struct b53_mib_desc { u8 size; @@ -1131,12 +1132,24 @@ static int b53_setup(struct dsa_switch *ds) b53_disable_port(ds, port); } + if (dev->broadsync_hd) { + ret = b53_ptp_init(dev); + if (ret) { + dev_err(ds->dev, "failed to initialize PTP\n"); + return ret; + } + } + return b53_setup_devlink_resources(ds); } static void b53_teardown(struct dsa_switch *ds) { + struct b53_device *dev = ds->priv; + dsa_devlink_resources_unregister(ds); + if (dev->broadsync_hd) + b53_ptp_exit(ds->priv); } static void b53_force_link(struct b53_device *dev, int port, int link) @@ -2286,6 +2299,7 @@ static const struct dsa_switch_ops b53_switch_ops = { .port_mdb_del = b53_mdb_del, .port_max_mtu = b53_get_max_mtu, .port_change_mtu = b53_change_mtu, + .get_ts_info = b53_get_ts_info, }; struct b53_chip_data { @@ -2301,6 +2315,7 @@ struct b53_chip_data { u8 duplex_reg; u8 jumbo_pm_reg; u8 jumbo_size_reg; + bool broadsync_hd; }; #define B53_VTA_REGS \ @@ -2421,6 +2436,7 @@ static const struct b53_chip_data b53_switch_chips[] = { .duplex_reg = B53_DUPLEX_STAT_GE, .jumbo_pm_reg = B53_JUMBO_PORT_MASK, .jumbo_size_reg = B53_JUMBO_MAX_SIZE, + .broadsync_hd = true, }, { .chip_id = BCM63XX_DEVICE_ID, @@ -2589,6 +2605,7 @@ static int b53_switch_init(struct b53_device *dev) dev->num_vlans = chip->vlans; dev->num_arl_bins = chip->arl_bins; dev->num_arl_buckets = chip->arl_buckets; + dev->broadsync_hd = chip->broadsync_hd; break; } } diff --git a/drivers/net/dsa/b53/b53_ptp.c b/drivers/net/dsa/b53/b53_ptp.c new file mode 100644 index 000000000000..8629c510b1a0 --- /dev/null +++ b/drivers/net/dsa/b53/b53_ptp.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: ISC +/* + * B53 switch PTP support + * + * Author: Martin Kaistra + * Copyright (C) 2021 Linutronix GmbH + */ + +#include "b53_priv.h" +#include "b53_ptp.h" + +static int b53_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts) +{ + struct b53_device *dev = + container_of(ptp, struct b53_device, ptp_clock_info); + u64 ns; + + mutex_lock(&dev->ptp_mutex); + ns = timecounter_read(&dev->tc); + mutex_unlock(&dev->ptp_mutex); + + *ts = ns_to_timespec64(ns); + + return 0; +} + +static int b53_ptp_settime(struct ptp_clock_info *ptp, + const struct timespec64 *ts) +{ + struct b53_device *dev = + container_of(ptp, struct b53_device, ptp_clock_info); + u64 ns; + + ns = timespec64_to_ns(ts); + + mutex_lock(&dev->ptp_mutex); + timecounter_init(&dev->tc, &dev->cc, ns); + mutex_unlock(&dev->ptp_mutex); + + return 0; +} + +static int b53_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) +{ + struct b53_device *dev = + container_of(ptp, struct b53_device, ptp_clock_info); + u64 adj, diff; + u32 mult; + bool neg_adj = false; + + if (scaled_ppm < 0) { + neg_adj = true; + scaled_ppm = -scaled_ppm; + } + + mult = (1 << 28); + adj = 64; + adj *= (u64)scaled_ppm; + diff = div_u64(adj, 15625ULL); + + mutex_lock(&dev->ptp_mutex); + timecounter_read(&dev->tc); + dev->cc.mult = neg_adj ? mult - diff : mult + diff; + mutex_unlock(&dev->ptp_mutex); + + return 0; +} + +static int b53_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) +{ + struct b53_device *dev = + container_of(ptp, struct b53_device, ptp_clock_info); + + mutex_lock(&dev->ptp_mutex); + timecounter_adjtime(&dev->tc, delta); + mutex_unlock(&dev->ptp_mutex); + + return 0; +} + +static u64 b53_ptp_read(const struct cyclecounter *cc) +{ + struct b53_device *dev = container_of(cc, struct b53_device, cc); + u32 ts; + + b53_read32(dev, B53_BROADSYNC_PAGE, B53_BROADSYNC_TIMEBASE, &ts); + + return ts; +} + +static int b53_ptp_enable(struct ptp_clock_info *ptp, + struct ptp_clock_request *rq, int on) +{ + return -EOPNOTSUPP; +} + +static long b53_hwtstamp_work(struct ptp_clock_info *ptp) +{ + struct b53_device *dev = + container_of(ptp, struct b53_device, ptp_clock_info); + + mutex_lock(&dev->ptp_mutex); + timecounter_read(&dev->tc); + mutex_unlock(&dev->ptp_mutex); + + return B53_PTP_OVERFLOW_PERIOD; +} + +int b53_ptp_init(struct b53_device *dev) +{ + mutex_init(&dev->ptp_mutex); + + /* Enable BroadSync HD for all ports */ + b53_write16(dev, B53_BROADSYNC_PAGE, B53_BROADSYNC_EN_CTRL, + dev->enabled_ports); + + /* Enable BroadSync HD Time Stamping Reporting (Egress) */ + b53_write8(dev, B53_BROADSYNC_PAGE, B53_BROADSYNC_TS_REPORT_CTRL, + TSRPT_PKT_EN); + + /* Enable BroadSync HD Time Stamping for PTPv2 ingress */ + + /* MPORT_CTRL0 | MPORT0_TS_EN */ + b53_write16(dev, B53_ARLCTRL_PAGE, B53_MPORT_CTRL, + MPORT0_TS_EN | + (MPORT_CTRL_CMP_ETYPE << MPORT_CTRL_SHIFT(0))); + /* Forward to IMP port */ + b53_write32(dev, B53_ARLCTRL_PAGE, B53_MPORT_VCTR(0), + BIT(dev->imp_port)); + /* PTPv2 Ether Type */ + b53_write64(dev, B53_ARLCTRL_PAGE, B53_MPORT_ADDR(0), + MPORT_ETYPE(ETH_P_1588)); + + /* Setup PTP clock */ + memset(&dev->ptp_clock_info, 0, sizeof(dev->ptp_clock_info)); + + dev->ptp_clock_info.owner = THIS_MODULE; + snprintf(dev->ptp_clock_info.name, sizeof(dev->ptp_clock_info.name), + dev_name(dev->dev)); + + dev->ptp_clock_info.max_adj = 1000000000ULL; + dev->ptp_clock_info.adjfine = b53_ptp_adjfine; + dev->ptp_clock_info.adjtime = b53_ptp_adjtime; + dev->ptp_clock_info.gettime64 = b53_ptp_gettime; + dev->ptp_clock_info.settime64 = b53_ptp_settime; + dev->ptp_clock_info.enable = b53_ptp_enable; + dev->ptp_clock_info.do_aux_work = b53_hwtstamp_work; + + dev->ptp_clock = ptp_clock_register(&dev->ptp_clock_info, dev->dev); + if (IS_ERR(dev->ptp_clock)) + return PTR_ERR(dev->ptp_clock); + + /* The switch provides a 32 bit free running counter. Use the Linux + * cycle counter infrastructure which is suited for such scenarios. + */ + dev->cc.read = b53_ptp_read; + dev->cc.mask = CYCLECOUNTER_MASK(30); + dev->cc.overflow_point = 999999999; + dev->cc.mult = (1 << 28); + dev->cc.shift = 28; + + timecounter_init(&dev->tc, &dev->cc, ktime_to_ns(ktime_get_real())); + + ptp_schedule_worker(dev->ptp_clock, 0); + + return 0; +} +EXPORT_SYMBOL(b53_ptp_init); + +int b53_get_ts_info(struct dsa_switch *ds, int port, + struct ethtool_ts_info *info) +{ + struct b53_device *dev = ds->priv; + + info->phc_index = dev->ptp_clock ? ptp_clock_index(dev->ptp_clock) : -1; + info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | + SOF_TIMESTAMPING_RX_HARDWARE | + SOF_TIMESTAMPING_RAW_HARDWARE; + info->tx_types = BIT(HWTSTAMP_TX_OFF); + info->rx_filters = BIT(HWTSTAMP_FILTER_NONE); + + return 0; +} +EXPORT_SYMBOL(b53_get_ts_info); + +void b53_ptp_exit(struct b53_device *dev) +{ + if (dev->ptp_clock) + ptp_clock_unregister(dev->ptp_clock); + dev->ptp_clock = NULL; +} +EXPORT_SYMBOL(b53_ptp_exit); + +MODULE_AUTHOR("Martin Kaistra "); +MODULE_DESCRIPTION("B53 Switch PTP support"); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/dsa/b53/b53_ptp.h b/drivers/net/dsa/b53/b53_ptp.h new file mode 100644 index 000000000000..5cd2fd9621a2 --- /dev/null +++ b/drivers/net/dsa/b53/b53_ptp.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: ISC */ +/* + * Author: Martin Kaistra + * Copyright (C) 2021 Linutronix GmbH + */ + +#ifndef _B53_PTP_H +#define _B53_PTP_H + +#include "b53_priv.h" + +#ifdef CONFIG_B53_PTP +int b53_ptp_init(struct b53_device *dev); +void b53_ptp_exit(struct b53_device *dev); +int b53_get_ts_info(struct dsa_switch *ds, int port, + struct ethtool_ts_info *info); +#else /* !CONFIG_B53_PTP */ + +static inline int b53_ptp_init(struct b53_device *dev) +{ + return 0; +} + +static inline void b53_ptp_exit(struct b53_device *dev) +{ +} + +static inline int b53_get_ts_info(struct dsa_switch *ds, int port, + struct ethtool_ts_info *info) +{ + return -EOPNOTSUPP; +} + +#endif +#endif diff --git a/include/linux/dsa/b53.h b/include/linux/dsa/b53.h index af782a1da362..85aa6d9dc53d 100644 --- a/include/linux/dsa/b53.h +++ b/include/linux/dsa/b53.h @@ -1,10 +1,14 @@ /* SPDX-License-Identifier: ISC */ /* * Copyright (C) 2011-2013 Jonas Gorski + * Copyright (C) 2021 Linutronix GmbH * * Included by drivers/net/dsa/b53/b53_priv.h and net/dsa/tag_brcm.c */ +#include +#include +#include #include struct b53_device; @@ -97,4 +101,14 @@ struct b53_device { bool vlan_enabled; unsigned int num_ports; struct b53_port *ports; + + /* PTP */ + bool broadsync_hd; + struct ptp_clock *ptp_clock; + struct ptp_clock_info ptp_clock_info; + struct cyclecounter cc; + struct timecounter tc; + struct mutex ptp_mutex; +#define B53_PTP_OVERFLOW_PERIOD (HZ / 2) + struct delayed_work overflow_work; }; From patchwork Tue Nov 9 09:50:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Kaistra X-Patchwork-Id: 12610295 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8CCC9C433F5 for ; Tue, 9 Nov 2021 09:51:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 77637611CC for ; Tue, 9 Nov 2021 09:51:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245084AbhKIJyE (ORCPT ); Tue, 9 Nov 2021 04:54:04 -0500 Received: from Galois.linutronix.de ([193.142.43.55]:35012 "EHLO galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245074AbhKIJxu (ORCPT ); Tue, 9 Nov 2021 04:53:50 -0500 From: Martin Kaistra DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1636451462; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xQswiKvKoyJnh7CLEzRLDmgSKq/tGhgbu7FVjEL+3G8=; b=wN0pMFKG5ZWI5QjMuGncMAgcKn5pZxNuIenHzW3tzyYwCrGaFckY+BWlY8WU7u5bXhFN1B xpXTJ3Ml2/VogoBa0Mlg3xYu+9WAIMbyqtIS9BHkRWrTy68Zolg+Zk6953DgdeCmwxt7ql HeVB3OTjY1UtgXB/Kgfd9v3y5716mbSE/hwy92wecTDhxtObBZ3J5fJBJEWDr8ucT2PXJc L5dwEq6O/MDmr1Kbgg6+wxsAOo64An89olRPVqP9S+iK2YcRu8jDlQh0Jk2CLSg2DbhmHj RjLVNurZYDuP4WL2+XKitvHK1CL6AKbmT7xmJIXaTMioeU2XfX6t4qRs59Zxtw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1636451462; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xQswiKvKoyJnh7CLEzRLDmgSKq/tGhgbu7FVjEL+3G8=; b=Xv92KSMwH1rDqdjROAnjFp0GZXDVFNXua3mNhkGhbf0SjXCjPD26dYvuPqB1z2JL5+9Hgb 79TqYTw3yEDdHLCA== To: Florian Fainelli , Andrew Lunn , Vivien Didelot Cc: martin.kaistra@linutronix.de, Richard Cochran , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , John Stultz , Thomas Gleixner , Stephen Boyd , Russell King , Marc Kleine-Budde , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v2 5/7] net: dsa: b53: Add logic for RX timestamping Date: Tue, 9 Nov 2021 10:50:07 +0100 Message-Id: <20211109095013.27829-6-martin.kaistra@linutronix.de> In-Reply-To: <20211109095013.27829-1-martin.kaistra@linutronix.de> References: <20211109095013.27829-1-martin.kaistra@linutronix.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Packets received by the tagger with opcode=1 contain the 32-bit timestamp according to the timebase register. This timestamp is saved in BRCM_SKB_CB(skb)->meta_tstamp. b53_port_rxtstamp() takes this and puts the full time information from the timecounter into shwt->hwtstamp. Signed-off-by: Martin Kaistra --- drivers/net/dsa/b53/b53_common.c | 1 + drivers/net/dsa/b53/b53_ptp.c | 28 +++++++++++++++++++++++++ drivers/net/dsa/b53/b53_ptp.h | 10 +++++++++ include/linux/dsa/b53.h | 30 +++++++++++++++++++++++++++ net/dsa/tag_brcm.c | 35 ++++++++++++++++++++++++-------- 5 files changed, 95 insertions(+), 9 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index ed590efbd3bf..a9408f9cd414 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -2300,6 +2300,7 @@ static const struct dsa_switch_ops b53_switch_ops = { .port_max_mtu = b53_get_max_mtu, .port_change_mtu = b53_change_mtu, .get_ts_info = b53_get_ts_info, + .port_rxtstamp = b53_port_rxtstamp, }; struct b53_chip_data { diff --git a/drivers/net/dsa/b53/b53_ptp.c b/drivers/net/dsa/b53/b53_ptp.c index 8629c510b1a0..f8dd8d484d93 100644 --- a/drivers/net/dsa/b53/b53_ptp.c +++ b/drivers/net/dsa/b53/b53_ptp.c @@ -6,6 +6,8 @@ * Copyright (C) 2021 Linutronix GmbH */ +#include + #include "b53_priv.h" #include "b53_ptp.h" @@ -106,6 +108,32 @@ static long b53_hwtstamp_work(struct ptp_clock_info *ptp) return B53_PTP_OVERFLOW_PERIOD; } +bool b53_port_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb, + unsigned int type) +{ + struct b53_device *dev = ds->priv; + struct b53_port_hwtstamp *ps = &dev->ports[port].port_hwtstamp; + struct skb_shared_hwtstamps *shwt; + u64 ns; + + if (type != PTP_CLASS_V2_L2) + return false; + + if (!test_bit(B53_HWTSTAMP_ENABLED, &ps->state)) + return false; + + mutex_lock(&dev->ptp_mutex); + ns = timecounter_cyc2time(&dev->tc, BRCM_SKB_CB(skb)->meta_tstamp); + mutex_unlock(&dev->ptp_mutex); + + shwt = skb_hwtstamps(skb); + memset(shwt, 0, sizeof(*shwt)); + shwt->hwtstamp = ns_to_ktime(ns); + + return false; +} +EXPORT_SYMBOL(b53_port_rxtstamp); + int b53_ptp_init(struct b53_device *dev) { mutex_init(&dev->ptp_mutex); diff --git a/drivers/net/dsa/b53/b53_ptp.h b/drivers/net/dsa/b53/b53_ptp.h index 5cd2fd9621a2..3b3437870c55 100644 --- a/drivers/net/dsa/b53/b53_ptp.h +++ b/drivers/net/dsa/b53/b53_ptp.h @@ -9,11 +9,15 @@ #include "b53_priv.h" +#define SKB_PTP_TYPE(__skb) (*(unsigned int *)((__skb)->cb)) + #ifdef CONFIG_B53_PTP int b53_ptp_init(struct b53_device *dev); void b53_ptp_exit(struct b53_device *dev); int b53_get_ts_info(struct dsa_switch *ds, int port, struct ethtool_ts_info *info); +bool b53_port_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb, + unsigned int type); #else /* !CONFIG_B53_PTP */ static inline int b53_ptp_init(struct b53_device *dev) @@ -31,5 +35,11 @@ static inline int b53_get_ts_info(struct dsa_switch *ds, int port, return -EOPNOTSUPP; } +static inline bool b53_port_rxtstamp(struct dsa_switch *ds, int port, + struct sk_buff *skb, unsigned int type) +{ + return false; +} + #endif #endif diff --git a/include/linux/dsa/b53.h b/include/linux/dsa/b53.h index 85aa6d9dc53d..542e5e3040d6 100644 --- a/include/linux/dsa/b53.h +++ b/include/linux/dsa/b53.h @@ -46,9 +46,32 @@ struct b53_io_ops { struct phylink_link_state *state); }; +/* state flags for b53_port_hwtstamp::state */ +enum { + B53_HWTSTAMP_ENABLED, + B53_HWTSTAMP_TX_IN_PROGRESS, +}; + +struct b53_port_hwtstamp { + /* Port index */ + int port_id; + + /* Timestamping state */ + unsigned long state; + + /* Resources for transmit timestamping */ + unsigned long tx_tstamp_start; + struct sk_buff *tx_skb; + + /* Current timestamp configuration */ + struct hwtstamp_config tstamp_config; +}; + struct b53_port { u16 vlan_ctl_mask; struct ethtool_eee eee; + /* Per-port timestamping resources */ + struct b53_port_hwtstamp port_hwtstamp; }; struct b53_vlan { @@ -112,3 +135,10 @@ struct b53_device { #define B53_PTP_OVERFLOW_PERIOD (HZ / 2) struct delayed_work overflow_work; }; + +struct brcm_skb_cb { + struct sk_buff *clone; + u32 meta_tstamp; +}; + +#define BRCM_SKB_CB(skb) ((struct brcm_skb_cb *)(skb)->cb) diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c index 96dbb8ee2fee..d611c1073deb 100644 --- a/net/dsa/tag_brcm.c +++ b/net/dsa/tag_brcm.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "dsa_priv.h" @@ -31,7 +32,10 @@ /* 6th byte in the tag */ #define BRCM_LEG_PORT_ID (0xf) -/* Newer Broadcom tag (4 bytes) */ +/* Newer Broadcom tag (4 bytes) + * For egress, when opcode = 0001, additional 4 bytes are used for + * the time stamp. + */ #define BRCM_TAG_LEN 4 /* Tag is constructed and desconstructed using byte by byte access @@ -136,19 +140,29 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb, */ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb, struct net_device *dev, - unsigned int offset) + unsigned int offset, + int *tag_len) { int source_port; u8 *brcm_tag; + u32 tstamp; + + *tag_len = 8; if (unlikely(!pskb_may_pull(skb, BRCM_TAG_LEN))) return NULL; brcm_tag = skb->data - offset; - /* The opcode should never be different than 0b000 */ - if (unlikely((brcm_tag[0] >> BRCM_OPCODE_SHIFT) & BRCM_OPCODE_MASK)) - return NULL; + if ((brcm_tag[0] >> BRCM_OPCODE_SHIFT) & BRCM_OPCODE_MASK) { + if (unlikely(!pskb_may_pull(skb, *tag_len))) + return NULL; + + tstamp = brcm_tag[4] << 24 | brcm_tag[5] << 16 | brcm_tag[6] << 8 | brcm_tag[7]; + BRCM_SKB_CB(skb)->meta_tstamp = tstamp; + } else { + *tag_len = BRCM_TAG_LEN; + } /* We should never see a reserved reason code without knowing how to * handle it @@ -164,7 +178,7 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb, return NULL; /* Remove Broadcom tag and update checksum */ - skb_pull_rcsum(skb, BRCM_TAG_LEN); + skb_pull_rcsum(skb, *tag_len); dsa_default_offload_fwd_mark(skb); @@ -184,13 +198,14 @@ static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev) { struct sk_buff *nskb; + int tag_len; /* skb->data points to the EtherType, the tag is right before it */ - nskb = brcm_tag_rcv_ll(skb, dev, 2); + nskb = brcm_tag_rcv_ll(skb, dev, 2, &tag_len); if (!nskb) return nskb; - dsa_strip_etype_header(skb, BRCM_TAG_LEN); + dsa_strip_etype_header(skb, tag_len); return nskb; } @@ -295,8 +310,10 @@ static struct sk_buff *brcm_tag_xmit_prepend(struct sk_buff *skb, static struct sk_buff *brcm_tag_rcv_prepend(struct sk_buff *skb, struct net_device *dev) { + int tag_len; + /* tag is prepended to the packet */ - return brcm_tag_rcv_ll(skb, dev, ETH_HLEN); + return brcm_tag_rcv_ll(skb, dev, ETH_HLEN, &tag_len); } static const struct dsa_device_ops brcm_prepend_netdev_ops = { From patchwork Tue Nov 9 09:50:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Kaistra X-Patchwork-Id: 12610297 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F1C5FC433FE for ; Tue, 9 Nov 2021 09:51:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DBC266128B for ; Tue, 9 Nov 2021 09:51:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245113AbhKIJyF (ORCPT ); Tue, 9 Nov 2021 04:54:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245106AbhKIJxy (ORCPT ); Tue, 9 Nov 2021 04:53:54 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D05FC0613B9; Tue, 9 Nov 2021 01:51:08 -0800 (PST) From: Martin Kaistra DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1636451467; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nJgE1Oggh7wQq8N7HhcPzV1VqckTR+2ntDU2O4TJk/M=; b=qpEkXcDqcisjbA0djXVk7UFyyyEuftY8gGBx6d+Xb2znpjdk0LLIy7MUx/K40BuZUfA//h U5/IEEV1Jww+QsPbNqo11mKV6jWfYyDobR0bkeaKRxFk7uDA2igg68ZRLz/EGyMiehQ07d 6KwapMaXWc/7lW6O4jau9xXCgZoIHUHTI/JqtPGid9w7E9Ip9jqk8PhmaHdhTKN78nX5YE vNGCzWCNyFPGo7At7Cs50+EsN6z8cYOkPvK79tyQiWH+vjEMKWCIcjgLiaGc8QvIscIBri PR52quUfCaNeiEdnWE4CHrmC4GO59USTtthZ0yiu7sScu5BUjcKpOIpf6qu/Zw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1636451467; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nJgE1Oggh7wQq8N7HhcPzV1VqckTR+2ntDU2O4TJk/M=; b=PKn/t/688GQmkta1UU9vAAHPxf2YZ+2RygAKrOlWZfKvIAH+wmQ/MTocRtTXYTfje+mZlo nrviuW02Uw2pTxCQ== To: Florian Fainelli , Andrew Lunn , Vivien Didelot Cc: martin.kaistra@linutronix.de, Richard Cochran , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , John Stultz , Thomas Gleixner , Stephen Boyd , Russell King , Marc Kleine-Budde , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v2 6/7] net: dsa: b53: Add logic for TX timestamping Date: Tue, 9 Nov 2021 10:50:08 +0100 Message-Id: <20211109095013.27829-7-martin.kaistra@linutronix.de> In-Reply-To: <20211109095013.27829-1-martin.kaistra@linutronix.de> References: <20211109095013.27829-1-martin.kaistra@linutronix.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org In order to get the switch to generate a timestamp for a transmitted packet, we need to set the TS bit in the BRCM tag. The switch will then create a status frame, which gets send back to the cpu. In b53_port_txtstamp() we put the skb into a waiting position. When a status frame is received, we extract the timestamp and put the time according to our timecounter into the waiting skb. When TX_TSTAMP_TIMEOUT is reached and we have no means to correctly get back a full timestamp, we cancel the process. As the status frame doesn't contain a reference to the original packet, only one packet with timestamp request can be sent at a time. Signed-off-by: Martin Kaistra --- drivers/net/dsa/b53/b53_common.c | 1 + drivers/net/dsa/b53/b53_ptp.c | 56 ++++++++++++++++++++++++++++++++ drivers/net/dsa/b53/b53_ptp.h | 8 +++++ net/dsa/tag_brcm.c | 46 ++++++++++++++++++++++++++ 4 files changed, 111 insertions(+) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index a9408f9cd414..56a9de89b38b 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -2301,6 +2301,7 @@ static const struct dsa_switch_ops b53_switch_ops = { .port_change_mtu = b53_change_mtu, .get_ts_info = b53_get_ts_info, .port_rxtstamp = b53_port_rxtstamp, + .port_txtstamp = b53_port_txtstamp, }; struct b53_chip_data { diff --git a/drivers/net/dsa/b53/b53_ptp.c b/drivers/net/dsa/b53/b53_ptp.c index f8dd8d484d93..5567135ba8b9 100644 --- a/drivers/net/dsa/b53/b53_ptp.c +++ b/drivers/net/dsa/b53/b53_ptp.c @@ -100,14 +100,65 @@ static long b53_hwtstamp_work(struct ptp_clock_info *ptp) { struct b53_device *dev = container_of(ptp, struct b53_device, ptp_clock_info); + struct dsa_switch *ds = dev->ds; + int i; mutex_lock(&dev->ptp_mutex); timecounter_read(&dev->tc); mutex_unlock(&dev->ptp_mutex); + for (i = 0; i < ds->num_ports; i++) { + struct b53_port_hwtstamp *ps; + + if (!dsa_is_user_port(ds, i)) + continue; + + ps = &dev->ports[i].port_hwtstamp; + + if (test_bit(B53_HWTSTAMP_TX_IN_PROGRESS, &ps->state) && + time_is_before_jiffies(ps->tx_tstamp_start + + TX_TSTAMP_TIMEOUT)) { + dev_err(dev->dev, + "Timeout while waiting for Tx timestamp!\n"); + dev_kfree_skb_any(ps->tx_skb); + ps->tx_skb = NULL; + clear_bit_unlock(B53_HWTSTAMP_TX_IN_PROGRESS, + &ps->state); + } + } + return B53_PTP_OVERFLOW_PERIOD; } +void b53_port_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb) +{ + struct b53_device *dev = ds->priv; + struct b53_port_hwtstamp *ps = &dev->ports[port].port_hwtstamp; + struct sk_buff *clone; + unsigned int type; + + type = ptp_classify_raw(skb); + + if (type != PTP_CLASS_V2_L2) + return; + + if (!test_bit(B53_HWTSTAMP_ENABLED, &ps->state)) + return; + + clone = skb_clone_sk(skb); + if (!clone) + return; + + if (test_and_set_bit_lock(B53_HWTSTAMP_TX_IN_PROGRESS, &ps->state)) { + kfree_skb(clone); + return; + } + + ps->tx_skb = clone; + ps->tx_tstamp_start = jiffies; +} +EXPORT_SYMBOL(b53_port_txtstamp); + bool b53_port_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb, unsigned int type) { @@ -136,6 +187,8 @@ EXPORT_SYMBOL(b53_port_rxtstamp); int b53_ptp_init(struct b53_device *dev) { + struct dsa_port *dp; + mutex_init(&dev->ptp_mutex); /* Enable BroadSync HD for all ports */ @@ -191,6 +244,9 @@ int b53_ptp_init(struct b53_device *dev) ptp_schedule_worker(dev->ptp_clock, 0); + dsa_switch_for_each_port(dp, dev->ds) + dp->priv = &dev->ports[dp->index].port_hwtstamp; + return 0; } EXPORT_SYMBOL(b53_ptp_init); diff --git a/drivers/net/dsa/b53/b53_ptp.h b/drivers/net/dsa/b53/b53_ptp.h index 3b3437870c55..f888f0a2022a 100644 --- a/drivers/net/dsa/b53/b53_ptp.h +++ b/drivers/net/dsa/b53/b53_ptp.h @@ -10,6 +10,7 @@ #include "b53_priv.h" #define SKB_PTP_TYPE(__skb) (*(unsigned int *)((__skb)->cb)) +#define TX_TSTAMP_TIMEOUT msecs_to_jiffies(40) #ifdef CONFIG_B53_PTP int b53_ptp_init(struct b53_device *dev); @@ -18,6 +19,8 @@ int b53_get_ts_info(struct dsa_switch *ds, int port, struct ethtool_ts_info *info); bool b53_port_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb, unsigned int type); +void b53_port_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb); + #else /* !CONFIG_B53_PTP */ static inline int b53_ptp_init(struct b53_device *dev) @@ -41,5 +44,10 @@ static inline bool b53_port_rxtstamp(struct dsa_switch *ds, int port, return false; } +static inline void b53_port_txtstamp(struct dsa_switch *ds, int port, + struct sk_buff *skb) +{ +} + #endif #endif diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c index d611c1073deb..a44ac81fa097 100644 --- a/net/dsa/tag_brcm.c +++ b/net/dsa/tag_brcm.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -76,6 +77,7 @@ #define BRCM_EG_TC_SHIFT 5 #define BRCM_EG_TC_MASK 0x7 #define BRCM_EG_PID_MASK 0x1f +#define BRCM_EG_T_R 0x20 #if IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM) || \ IS_ENABLED(CONFIG_NET_DSA_TAG_BRCM_PREPEND) @@ -85,6 +87,8 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb, unsigned int offset) { struct dsa_port *dp = dsa_slave_to_port(dev); + unsigned int type = ptp_classify_raw(skb); + struct b53_port_hwtstamp *ps = dp->priv; u16 queue = skb_get_queue_mapping(skb); u8 *brcm_tag; @@ -112,7 +116,13 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb, */ brcm_tag[0] = (1 << BRCM_OPCODE_SHIFT) | ((queue & BRCM_IG_TC_MASK) << BRCM_IG_TC_SHIFT); + brcm_tag[1] = 0; + + if (type == PTP_CLASS_V2_L2 && + test_bit(B53_HWTSTAMP_TX_IN_PROGRESS, &ps->state)) + brcm_tag[1] = 1 << BRCM_IG_TS_SHIFT; + brcm_tag[2] = 0; if (dp->index == 8) brcm_tag[2] = BRCM_IG_DSTMAP2_MASK; @@ -126,6 +136,33 @@ static struct sk_buff *brcm_tag_xmit_ll(struct sk_buff *skb, return skb; } +static int set_txtstamp(struct dsa_port *dp, + int port, + u64 ns) +{ + struct b53_device *b53_dev = dp->ds->priv; + struct b53_port_hwtstamp *ps = dp->priv; + struct skb_shared_hwtstamps shhwtstamps; + struct sk_buff *tmp_skb; + + if (!ps->tx_skb) + return 0; + + mutex_lock(&b53_dev->ptp_mutex); + ns = timecounter_cyc2time(&b53_dev->tc, ns); + mutex_unlock(&b53_dev->ptp_mutex); + + memset(&shhwtstamps, 0, sizeof(shhwtstamps)); + shhwtstamps.hwtstamp = ns_to_ktime(ns); + tmp_skb = ps->tx_skb; + ps->tx_skb = NULL; + + clear_bit_unlock(B53_HWTSTAMP_TX_IN_PROGRESS, &ps->state); + skb_complete_tx_timestamp(tmp_skb, &shhwtstamps); + + return 0; +} + /* Frames with this tag have one of these two layouts: * ----------------------------------- * | MAC DA | MAC SA | 4b tag | Type | DSA_TAG_PROTO_BRCM @@ -143,6 +180,7 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb, unsigned int offset, int *tag_len) { + struct dsa_port *dp; int source_port; u8 *brcm_tag; u32 tstamp; @@ -177,6 +215,14 @@ static struct sk_buff *brcm_tag_rcv_ll(struct sk_buff *skb, if (!skb->dev) return NULL; + /* Check whether this is a status frame */ + if (unlikely(*tag_len == 8 && brcm_tag[3] & BRCM_EG_T_R)) { + dp = dsa_slave_to_port(skb->dev); + + set_txtstamp(dp, source_port, tstamp); + return NULL; + } + /* Remove Broadcom tag and update checksum */ skb_pull_rcsum(skb, *tag_len); From patchwork Tue Nov 9 09:50:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Kaistra X-Patchwork-Id: 12610299 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C686C433EF for ; Tue, 9 Nov 2021 09:51:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 261D861251 for ; Tue, 9 Nov 2021 09:51:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245157AbhKIJyP (ORCPT ); Tue, 9 Nov 2021 04:54:15 -0500 Received: from Galois.linutronix.de ([193.142.43.55]:35044 "EHLO galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244998AbhKIJx5 (ORCPT ); Tue, 9 Nov 2021 04:53:57 -0500 From: Martin Kaistra DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1636451471; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2tHBO2b/mRYqYaDxmJViJfyYebaSLivzcR+D3MQPfYI=; b=pIO4YMV7vjsKIUiMyfskBgshhCRgjBXAVW5BQsGFdKBssH/g6xEuRFeNOwSajPv/Y9lnR6 Jk6e2lEpK6hzPEZmnoujPZgvnbHHchLRmSnbzeXbupwFhvkTDiEbNfd5x2N7FRDSn/meQT f7plRlTymJstIxhoxLbUAgX06GFtBgpkGgwxGNn2ICjyDKpMalqklKzrGGCIADtSRbD/Pk 9gSDWSTXgpQhGdDmLq5RTSlaud0wA3hfBucB7dCHxwpkgZwbEPFbS2SgbPc0PZc4SYKhrz sQ0n45cIWsMjqNbQzVFf5NCRSsHYkAUgjUPc1CLb/WeO2ppEjHYJgQx+CSlAaA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1636451471; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2tHBO2b/mRYqYaDxmJViJfyYebaSLivzcR+D3MQPfYI=; b=ghE+auZmb+06eJQ90iZy85RhAs34/Y0gR0NjNZ+1KDjFS5bX28Lir+LjJ/OgrFa7iHvoF/ AfvfeKWw8x0icfDQ== To: Florian Fainelli , Andrew Lunn , Vivien Didelot Cc: martin.kaistra@linutronix.de, Richard Cochran , Kurt Kanzenbach , Vladimir Oltean , "David S. Miller" , Jakub Kicinski , John Stultz , Thomas Gleixner , Stephen Boyd , Russell King , Marc Kleine-Budde , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH v2 7/7] net: dsa: b53: Expose PTP timestamping ioctls to userspace Date: Tue, 9 Nov 2021 10:50:09 +0100 Message-Id: <20211109095013.27829-8-martin.kaistra@linutronix.de> In-Reply-To: <20211109095013.27829-1-martin.kaistra@linutronix.de> References: <20211109095013.27829-1-martin.kaistra@linutronix.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Allow userspace to use the PTP support. Currently only L2 is supported. Signed-off-by: Martin Kaistra Reviewed-by: Kurt Kanzenbach --- drivers/net/dsa/b53/b53_common.c | 2 + drivers/net/dsa/b53/b53_ptp.c | 90 +++++++++++++++++++++++++++++++- drivers/net/dsa/b53/b53_ptp.h | 14 +++++ 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index 56a9de89b38b..3e7e5f83cc84 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -2302,6 +2302,8 @@ static const struct dsa_switch_ops b53_switch_ops = { .get_ts_info = b53_get_ts_info, .port_rxtstamp = b53_port_rxtstamp, .port_txtstamp = b53_port_txtstamp, + .port_hwtstamp_set = b53_port_hwtstamp_set, + .port_hwtstamp_get = b53_port_hwtstamp_get, }; struct b53_chip_data { diff --git a/drivers/net/dsa/b53/b53_ptp.c b/drivers/net/dsa/b53/b53_ptp.c index 5567135ba8b9..f611ac219fb5 100644 --- a/drivers/net/dsa/b53/b53_ptp.c +++ b/drivers/net/dsa/b53/b53_ptp.c @@ -260,13 +260,99 @@ int b53_get_ts_info(struct dsa_switch *ds, int port, info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE | SOF_TIMESTAMPING_RAW_HARDWARE; - info->tx_types = BIT(HWTSTAMP_TX_OFF); - info->rx_filters = BIT(HWTSTAMP_FILTER_NONE); + info->tx_types = BIT(HWTSTAMP_TX_ON); + info->rx_filters = BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT); return 0; } EXPORT_SYMBOL(b53_get_ts_info); +static int b53_set_hwtstamp_config(struct b53_device *dev, int port, + struct hwtstamp_config *config) +{ + struct b53_port_hwtstamp *ps = &dev->ports[port].port_hwtstamp; + bool tstamp_enable = false; + + clear_bit_unlock(B53_HWTSTAMP_ENABLED, &ps->state); + + /* Reserved for future extensions */ + if (config->flags) + return -EINVAL; + + switch (config->tx_type) { + case HWTSTAMP_TX_ON: + tstamp_enable = true; + break; + case HWTSTAMP_TX_OFF: + tstamp_enable = false; + break; + default: + return -ERANGE; + } + + switch (config->rx_filter) { + case HWTSTAMP_FILTER_NONE: + tstamp_enable = false; + break; + case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: + case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: + case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: + config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; + break; + default: + return -ERANGE; + } + + if (ps->tx_skb) { + dev_kfree_skb_any(ps->tx_skb); + ps->tx_skb = NULL; + } + clear_bit(B53_HWTSTAMP_TX_IN_PROGRESS, &ps->state); + + if (tstamp_enable) + set_bit(B53_HWTSTAMP_ENABLED, &ps->state); + + return 0; +} + +int b53_port_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr) +{ + struct b53_device *dev = ds->priv; + struct b53_port_hwtstamp *ps; + struct hwtstamp_config config; + int err; + + ps = &dev->ports[port].port_hwtstamp; + + if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) + return -EFAULT; + + err = b53_set_hwtstamp_config(dev, port, &config); + if (err) + return err; + + /* Save the chosen configuration to be returned later */ + memcpy(&ps->tstamp_config, &config, sizeof(config)); + + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : + 0; +} +EXPORT_SYMBOL(b53_port_hwtstamp_set); + +int b53_port_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr) +{ + struct b53_device *dev = ds->priv; + struct b53_port_hwtstamp *ps; + struct hwtstamp_config *config; + + ps = &dev->ports[port].port_hwtstamp; + config = &ps->tstamp_config; + + return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ? -EFAULT : + 0; +} +EXPORT_SYMBOL(b53_port_hwtstamp_get); + void b53_ptp_exit(struct b53_device *dev) { if (dev->ptp_clock) diff --git a/drivers/net/dsa/b53/b53_ptp.h b/drivers/net/dsa/b53/b53_ptp.h index f888f0a2022a..3a341f752e31 100644 --- a/drivers/net/dsa/b53/b53_ptp.h +++ b/drivers/net/dsa/b53/b53_ptp.h @@ -17,6 +17,8 @@ int b53_ptp_init(struct b53_device *dev); void b53_ptp_exit(struct b53_device *dev); int b53_get_ts_info(struct dsa_switch *ds, int port, struct ethtool_ts_info *info); +int b53_port_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr); +int b53_port_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr); bool b53_port_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb, unsigned int type); void b53_port_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb); @@ -38,6 +40,18 @@ static inline int b53_get_ts_info(struct dsa_switch *ds, int port, return -EOPNOTSUPP; } +static inline int b53_port_hwtstamp_set(struct dsa_switch *ds, int port, + struct ifreq *ifr) +{ + return -EOPNOTSUPP; +} + +static inline int b53_port_hwtstamp_get(struct dsa_switch *ds, int port, + struct ifreq *ifr) +{ + return -EOPNOTSUPP; +} + static inline bool b53_port_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb, unsigned int type) {