Commit 186734c1 authored by Roger Quadros's avatar Roger Quadros Committed by David S. Miller

net: ti: icssg-prueth: add packet timestamping and ptp support

Add packet timestamping TS and PTP PHC clock support.

For AM65x and AM64x:
 - IEP1 is not used
 - IEP0 is configured in shadow mode with 1ms cycle and shared between
Linux and FW. It provides time and TS in number cycles, so special
conversation in ns is required.
 - IEP0 shared between PRUeth ports.
 - IEP0 supports PPS, periodic output.
 - IEP0 settime() and enabling PPS required FW interraction.
 - RX TS provided with each packet in CPPI5 descriptor.
 - TX TS returned through separate ICSSG hw queues for each port. TX TS
readiness is signaled by INTC IRQ. Only one packet at time can be requested
for TX TS.
Signed-off-by: default avatarRoger Quadros <rogerq@ti.com>
Co-developed-by: default avatarGrygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: default avatarGrygorii Strashko <grygorii.strashko@ti.com>
Signed-off-by: default avatarVignesh Raghavendra <vigneshr@ti.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarMD Danish Anwar <danishanwar@ti.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c1e0230e
...@@ -186,6 +186,7 @@ config CPMAC ...@@ -186,6 +186,7 @@ config CPMAC
config TI_ICSSG_PRUETH config TI_ICSSG_PRUETH
tristate "TI Gigabit PRU Ethernet driver" tristate "TI Gigabit PRU Ethernet driver"
select PHYLIB select PHYLIB
select TI_ICSS_IEP
depends on PRU_REMOTEPROC depends on PRU_REMOTEPROC
depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER depends on ARCH_K3 && OF && TI_K3_UDMA_GLUE_LAYER
help help
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/regmap.h> #include <linux/regmap.h>
struct icss_iep; struct icss_iep;
extern const struct icss_iep_clockops prueth_iep_clockops;
/* Firmware specific clock operations */ /* Firmware specific clock operations */
struct icss_iep_clockops { struct icss_iep_clockops {
......
...@@ -109,6 +109,26 @@ static void emac_get_ethtool_stats(struct net_device *ndev, ...@@ -109,6 +109,26 @@ static void emac_get_ethtool_stats(struct net_device *ndev,
*(data++) = emac->stats[i]; *(data++) = emac->stats[i];
} }
static int emac_get_ts_info(struct net_device *ndev,
struct ethtool_ts_info *info)
{
struct prueth_emac *emac = netdev_priv(ndev);
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 = icss_iep_get_ptp_clock_idx(emac->iep);
info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL);
return 0;
}
static int emac_set_channels(struct net_device *ndev, static int emac_set_channels(struct net_device *ndev,
struct ethtool_channels *ch) struct ethtool_channels *ch)
{ {
...@@ -176,6 +196,7 @@ const struct ethtool_ops icssg_ethtool_ops = { ...@@ -176,6 +196,7 @@ const struct ethtool_ops icssg_ethtool_ops = {
.get_sset_count = emac_get_sset_count, .get_sset_count = emac_get_sset_count,
.get_ethtool_stats = emac_get_ethtool_stats, .get_ethtool_stats = emac_get_ethtool_stats,
.get_strings = emac_get_strings, .get_strings = emac_get_strings,
.get_ts_info = emac_get_ts_info,
.get_channels = emac_get_channels, .get_channels = emac_get_channels,
.set_channels = emac_set_channels, .set_channels = emac_set_channels,
.get_link_ksettings = emac_get_link_ksettings, .get_link_ksettings = emac_get_link_ksettings,
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include <net/devlink.h> #include <net/devlink.h>
#include "icssg_config.h" #include "icssg_config.h"
#include "icss_iep.h"
#include "icssg_switch_map.h" #include "icssg_switch_map.h"
#define PRUETH_MAX_MTU (2000 - ETH_HLEN - ETH_FCS_LEN) #define PRUETH_MAX_MTU (2000 - ETH_HLEN - ETH_FCS_LEN)
...@@ -122,6 +123,8 @@ struct prueth_rx_chn { ...@@ -122,6 +123,8 @@ struct prueth_rx_chn {
*/ */
#define PRUETH_MAX_TX_QUEUES 4 #define PRUETH_MAX_TX_QUEUES 4
#define PRUETH_MAX_TX_TS_REQUESTS 50 /* Max simultaneous TX_TS requests */
/* data for each emac port */ /* data for each emac port */
struct prueth_emac { struct prueth_emac {
bool fw_running; bool fw_running;
...@@ -139,6 +142,9 @@ struct prueth_emac { ...@@ -139,6 +142,9 @@ struct prueth_emac {
struct device_node *phy_node; struct device_node *phy_node;
phy_interface_t phy_if; phy_interface_t phy_if;
enum prueth_port port_id; enum prueth_port port_id;
struct icss_iep *iep;
unsigned int rx_ts_enabled : 1;
unsigned int tx_ts_enabled : 1;
/* DMA related */ /* DMA related */
struct prueth_tx_chn tx_chns[PRUETH_MAX_TX_QUEUES]; struct prueth_tx_chn tx_chns[PRUETH_MAX_TX_QUEUES];
...@@ -150,7 +156,15 @@ struct prueth_emac { ...@@ -150,7 +156,15 @@ struct prueth_emac {
spinlock_t lock; /* serialize access */ spinlock_t lock; /* serialize access */
unsigned long state; /* TX HW Timestamping */
/* TX TS cookie will be index to the tx_ts_skb array */
struct sk_buff *tx_ts_skb[PRUETH_MAX_TX_TS_REQUESTS];
atomic_t tx_ts_pending;
int tx_ts_irq;
u8 cmd_seq;
/* shutdown related */
u32 cmd_data[4];
struct completion cmd_complete; struct completion cmd_complete;
/* Mutex to serialize access to firmware command interface */ /* Mutex to serialize access to firmware command interface */
struct mutex cmd_lock; struct mutex cmd_lock;
...@@ -193,6 +207,7 @@ struct prueth_pdata { ...@@ -193,6 +207,7 @@ struct prueth_pdata {
* @pdata: pointer to platform data for ICSSG driver * @pdata: pointer to platform data for ICSSG driver
* @icssg_hwcmdseq: seq counter or HWQ messages * @icssg_hwcmdseq: seq counter or HWQ messages
* @emacs_initialized: num of EMACs/ext ports that are up/running * @emacs_initialized: num of EMACs/ext ports that are up/running
* @iep0: pointer to IEP0 device
*/ */
struct prueth { struct prueth {
struct device *dev; struct device *dev;
...@@ -214,8 +229,15 @@ struct prueth { ...@@ -214,8 +229,15 @@ struct prueth {
struct platform_device *pdev; struct platform_device *pdev;
struct prueth_pdata pdata; struct prueth_pdata pdata;
u8 icssg_hwcmdseq; u8 icssg_hwcmdseq;
int emacs_initialized; int emacs_initialized;
struct icss_iep *iep0;
};
struct emac_tx_ts_response {
u32 reserved[2];
u32 cookie;
u32 lo_ts;
u32 hi_ts;
}; };
/* get PRUSS SLICE number from prueth_emac */ /* get PRUSS SLICE number from prueth_emac */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment