Forum | Documentation | Website | Blog

Skip to content
Snippets Groups Projects
Commit 813f7dc8 authored by Lokesh Vutla's avatar Lokesh Vutla
Browse files

net: ti: prueth: Add support for reading timestamps from rx packets


When PTP packets are received on ICSS ports, dual_emac firmware record the
timestamps and appends the timestamp at the next 32 byte block after the end
of packet. Add support for reading this timestamp from packet and pass
it to userspace layer.

Signed-off-by: default avatarLokesh Vutla <lokeshvutla@ti.com>
parent 3b9b5f34
No related merge requests found
......@@ -89,6 +89,9 @@
#define PRUETH_BD_SHADOW_MASK BIT(14)
#define PRUETH_BD_SHADOW_SHIFT 14
#define PRUETH_BD_TIMESTAMP_MASK BIT(15)
#define PRUETH_BD_TIMESTAMP_SHIT 15
#define PRUETH_BD_PORT_MASK GENMASK(17, 16)
#define PRUETH_BD_PORT_SHIFT 16
......
......@@ -104,6 +104,7 @@ struct prueth_queue_info {
* @sv_frame: indicate if the frame is a SV frame for HSR/PRP
* @lookup_success: src mac found in FDB
* @flood: packet is to be flooded
* @timstamp: Specifies if timestamp is appended to the packet
*/
struct prueth_packet_info {
bool start_offset;
......@@ -115,6 +116,7 @@ struct prueth_packet_info {
bool sv_frame;
bool lookup_success;
bool flood;
bool timestamp;
};
/**
......@@ -384,6 +386,7 @@ struct prueth_emac {
int emac_ptp_tx_irq;
int hsr_ptp_tx_irq;
bool ptp_tx_enable;
bool ptp_rx_enable;
};
struct prueth_ndev_priority {
......
......@@ -175,6 +175,17 @@ static inline bool prueth_ptp_tx_ts_is_enabled(struct prueth_emac *emac)
return !!emac->ptp_tx_enable;
}
static inline void prueth_ptp_rx_ts_enable(struct prueth_emac *emac, bool enable)
{
emac->ptp_rx_enable = enable;
prueth_ptp_ts_enable(emac);
}
static inline bool prueth_ptp_rx_ts_is_enabled(struct prueth_emac *emac)
{
return !!emac->ptp_rx_enable;
}
static inline
void prueth_set_reg(struct prueth *prueth, enum prueth_mem region,
unsigned int reg, u32 mask, u32 set)
......@@ -1111,6 +1122,7 @@ void parse_packet_info(struct prueth *prueth, u32 buffer_descriptor,
pkt_info->lookup_success = !!(buffer_descriptor &
PRUETH_BD_LOOKUP_SUCCESS_MASK);
pkt_info->flood = !!(buffer_descriptor & PRUETH_BD_SW_FLOOD_MASK);
pkt_info->timestamp = !!(buffer_descriptor & PRUETH_BD_TIMESTAMP_MASK);
}
/* get packet from queue
......@@ -1133,9 +1145,11 @@ int emac_rx_packet(struct prueth_emac *emac, u16 *bd_rd_ptr,
u8 macid[6];
/* OCMC RAM is not cached and read order is not important */
void *ocmc_ram = (__force void *)emac->prueth->mem[PRUETH_MEM_OCMC].va;
struct skb_shared_hwtstamps *ssh;
unsigned int actual_pkt_len;
u16 start_offset = 0, type;
u8 offset = 0, *ptr;
u64 ts;
if (PRUETH_IS_HSR(prueth))
start_offset = (pkt_info.start_offset ?
......@@ -1218,8 +1232,16 @@ int emac_rx_packet(struct prueth_emac *emac, u16 *bd_rd_ptr,
else
src_addr = ocmc_ram + rxqueue->buffer_offset;
memcpy(dst_addr, src_addr, remaining);
src_addr += remaining;
} else {
memcpy(dst_addr, src_addr, actual_pkt_len);
src_addr += actual_pkt_len;
}
if (pkt_info.timestamp) {
src_addr = (void *)roundup((uintptr_t)src_addr, ICSS_BLOCK_SIZE);
dst_addr = &ts;
memcpy(dst_addr, src_addr, sizeof(ts));
}
/* Check if VLAN tag is present since SV payload location will change
......@@ -1277,6 +1299,12 @@ int emac_rx_packet(struct prueth_emac *emac, u16 *bd_rd_ptr,
prueth_sw_learn_fdb(emac, skb->data + ETH_ALEN);
}
if (prueth_ptp_rx_ts_is_enabled(emac)) {
ssh = skb_hwtstamps(skb);
memset(ssh, 0, sizeof(*ssh));
ssh->hwtstamp = ns_to_ktime(ts);
}
/* send packet up the stack */
skb->protocol = eth_type_trans(skb, ndev);
netif_receive_skb(skb);
......@@ -1745,6 +1773,7 @@ static int emac_ndo_stop(struct net_device *ndev)
free_irq(emac->rx_irq, ndev);
free_irq(emac->emac_ptp_tx_irq, ndev);
prueth_ptp_tx_ts_enable(emac, 0);
prueth_ptp_rx_ts_enable(emac, 0);
for (i = 0; i < PRUETH_PTP_TS_EVENTS; i++) {
if (emac->ptp_skb[i]) {
prueth_ptp_tx_ts_reset(emac, i);
......
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