^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Copyright (C) 2018 MOSER-BAER AG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #define pr_fmt(fmt) "InES_PTP: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/if_vlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/mii_timestamper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/net_tstamp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/ptp_classify.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/ptp_clock_kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) MODULE_DESCRIPTION("Driver for the ZHAW InES PTP time stamping IP core");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) MODULE_AUTHOR("Richard Cochran <richardcochran@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) MODULE_VERSION("1.0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* GLOBAL register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define MCAST_MAC_SELECT_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define MCAST_MAC_SELECT_MASK 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define IO_RESET BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PTP_RESET BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* VERSION register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define IF_MAJOR_VER_SHIFT 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define IF_MAJOR_VER_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define IF_MINOR_VER_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define IF_MINOR_VER_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define FPGA_MAJOR_VER_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define FPGA_MAJOR_VER_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define FPGA_MINOR_VER_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define FPGA_MINOR_VER_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* INT_STAT register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define RX_INTR_STATUS_3 BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define RX_INTR_STATUS_2 BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define RX_INTR_STATUS_1 BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define TX_INTR_STATUS_3 BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define TX_INTR_STATUS_2 BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define TX_INTR_STATUS_1 BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* INT_MSK register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define RX_INTR_MASK_3 BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define RX_INTR_MASK_2 BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define RX_INTR_MASK_1 BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define TX_INTR_MASK_3 BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define TX_INTR_MASK_2 BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define TX_INTR_MASK_1 BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* BUF_STAT register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define RX_FIFO_NE_3 BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define RX_FIFO_NE_2 BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define RX_FIFO_NE_1 BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define TX_FIFO_NE_3 BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define TX_FIFO_NE_2 BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define TX_FIFO_NE_1 BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* PORT_CONF register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define CM_ONE_STEP BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define PHY_SPEED_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define PHY_SPEED_MASK 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define P2P_DELAY_WR_POS_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define P2P_DELAY_WR_POS_MASK 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define PTP_MODE_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define PTP_MODE_MASK 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* TS_STAT_TX register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define TS_ENABLE BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define DATA_READ_POS_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define DATA_READ_POS_MASK 0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define DISCARDED_EVENTS_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define DISCARDED_EVENTS_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define INES_N_PORTS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define INES_REGISTER_SIZE 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define INES_PORT_OFFSET 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define INES_PORT_SIZE 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define INES_FIFO_DEPTH 90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define INES_MAX_EVENTS 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define BC_PTP_V1 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define BC_PTP_V2 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define TC_E2E_PTP_V2 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define TC_P2P_PTP_V2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define PHY_SPEED_10 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define PHY_SPEED_100 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define PHY_SPEED_1000 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define PORT_CONF \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ((PHY_SPEED_1000 << PHY_SPEED_SHIFT) | (BC_PTP_V2 << PTP_MODE_SHIFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define ines_read32(s, r) __raw_readl((void __iomem *)&s->regs->r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define ines_write32(s, v, r) __raw_writel(v, (void __iomem *)&s->regs->r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define MESSAGE_TYPE_SYNC 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define MESSAGE_TYPE_P_DELAY_REQ 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define MESSAGE_TYPE_P_DELAY_RESP 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define MESSAGE_TYPE_DELAY_REQ 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define SYNC 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define DELAY_REQ 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define PDELAY_REQ 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define PDELAY_RESP 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static LIST_HEAD(ines_clocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static DEFINE_MUTEX(ines_clocks_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct ines_global_regs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) u32 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) u32 test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) u32 global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u32 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) u32 test2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u32 int_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u32 int_msk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u32 buf_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct ines_port_registers {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u32 port_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u32 p_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u32 ts_stat_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u32 ts_stat_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u32 ts_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u32 ts_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct ines_timestamp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) unsigned long tmo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) u16 tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u64 sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) u64 nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u64 clkid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) u16 portnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u16 seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct ines_port {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct ines_port_registers *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct mii_timestamper mii_ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct ines_clock *clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) bool rxts_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) bool txts_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unsigned int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct delayed_work ts_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* lock protects event list and tx_skb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct sk_buff *tx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct list_head events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct list_head pool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct ines_timestamp pool_data[INES_MAX_EVENTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct ines_clock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct ines_port port[INES_N_PORTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct ines_global_regs __iomem *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct device_node *node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static bool ines_match(struct sk_buff *skb, unsigned int ptp_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct ines_timestamp *ts, struct device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static int ines_rxfifo_read(struct ines_port *port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static u64 ines_rxts64(struct ines_port *port, unsigned int words);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static bool ines_timestamp_expired(struct ines_timestamp *ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static u64 ines_txts64(struct ines_port *port, unsigned int words);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static void ines_txtstamp_work(struct work_struct *work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static bool is_sync_pdelay_resp(struct sk_buff *skb, int type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static u8 tag_to_msgtype(u8 tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static void ines_clock_cleanup(struct ines_clock *clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct ines_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) for (i = 0; i < INES_N_PORTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) port = &clock->port[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) cancel_delayed_work_sync(&port->ts_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static int ines_clock_init(struct ines_clock *clock, struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) void __iomem *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct device_node *node = device->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) unsigned long port_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct ines_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) INIT_LIST_HEAD(&clock->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) clock->node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) clock->dev = device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) clock->base = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) clock->regs = clock->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) for (i = 0; i < INES_N_PORTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) port = &clock->port[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) port_addr = (unsigned long) clock->base +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) INES_PORT_OFFSET + i * INES_PORT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) port->regs = (struct ines_port_registers *) port_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) port->clock = clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) port->index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) INIT_DELAYED_WORK(&port->ts_work, ines_txtstamp_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) spin_lock_init(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) INIT_LIST_HEAD(&port->events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) INIT_LIST_HEAD(&port->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) for (j = 0; j < INES_MAX_EVENTS; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) list_add(&port->pool_data[j].list, &port->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) ines_write32(clock, 0xBEEF, test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) ines_write32(clock, 0xBEEF, test2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) dev_dbg(device, "ID 0x%x\n", ines_read32(clock, id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) dev_dbg(device, "TEST 0x%x\n", ines_read32(clock, test));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) dev_dbg(device, "VERSION 0x%x\n", ines_read32(clock, version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) dev_dbg(device, "TEST2 0x%x\n", ines_read32(clock, test2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) for (i = 0; i < INES_N_PORTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) port = &clock->port[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ines_write32(port, PORT_CONF, port_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static struct ines_port *ines_find_port(struct device_node *node, u32 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct ines_port *port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct ines_clock *clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct list_head *this;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) mutex_lock(&ines_clocks_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) list_for_each(this, &ines_clocks) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) clock = list_entry(this, struct ines_clock, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (clock->node == node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) port = &clock->port[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mutex_unlock(&ines_clocks_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) static u64 ines_find_rxts(struct ines_port *port, struct sk_buff *skb, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct list_head *this, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct ines_timestamp *ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) u64 ns = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (type == PTP_CLASS_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ines_rxfifo_read(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) list_for_each_safe(this, next, &port->events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) ts = list_entry(this, struct ines_timestamp, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (ines_timestamp_expired(ts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) list_del_init(&ts->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) list_add(&ts->list, &port->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) if (ines_match(skb, type, ts, port->clock->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) ns = ts->sec * 1000000000ULL + ts->nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) list_del_init(&ts->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) list_add(&ts->list, &port->pool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static u64 ines_find_txts(struct ines_port *port, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) unsigned int class = ptp_classify_raw(skb), i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) u32 data_rd_pos, buf_stat, mask, ts_stat_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct ines_timestamp ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) u64 ns = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) mask = TX_FIFO_NE_1 << port->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) for (i = 0; i < INES_FIFO_DEPTH; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) buf_stat = ines_read32(port->clock, buf_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (!(buf_stat & mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) dev_dbg(port->clock->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) "Tx timestamp FIFO unexpectedly empty\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ts_stat_tx = ines_read32(port, ts_stat_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) data_rd_pos = (ts_stat_tx >> DATA_READ_POS_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) DATA_READ_POS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (data_rd_pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) dev_err(port->clock->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) "unexpected Tx read pos %u\n", data_rd_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) ts.tag = ines_read32(port, ts_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ts.sec = ines_txts64(port, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ts.nsec = ines_txts64(port, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ts.clkid = ines_txts64(port, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ts.portnum = ines_read32(port, ts_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ts.seqid = ines_read32(port, ts_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (ines_match(skb, class, &ts, port->clock->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ns = ts.sec * 1000000000ULL + ts.nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static int ines_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct ines_port *port = container_of(mii_ts, struct ines_port, mii_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) u32 cm_one_step = 0, port_conf, ts_stat_rx, ts_stat_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) struct hwtstamp_config cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* reserved for future extensions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (cfg.flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) switch (cfg.tx_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) case HWTSTAMP_TX_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ts_stat_tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case HWTSTAMP_TX_ON:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ts_stat_tx = TS_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) case HWTSTAMP_TX_ONESTEP_P2P:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ts_stat_tx = TS_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) cm_one_step = CM_ONE_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) switch (cfg.rx_filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) case HWTSTAMP_FILTER_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ts_stat_rx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) case HWTSTAMP_FILTER_ALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) case HWTSTAMP_FILTER_PTP_V2_EVENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) case HWTSTAMP_FILTER_PTP_V2_SYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) ts_stat_rx = TS_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) port_conf = ines_read32(port, port_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) port_conf &= ~CM_ONE_STEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) port_conf |= cm_one_step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ines_write32(port, port_conf, port_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ines_write32(port, ts_stat_rx, ts_stat_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ines_write32(port, ts_stat_tx, ts_stat_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) port->rxts_enabled = ts_stat_rx == TS_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) port->txts_enabled = ts_stat_tx == TS_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) static void ines_link_state(struct mii_timestamper *mii_ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct ines_port *port = container_of(mii_ts, struct ines_port, mii_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) u32 port_conf, speed_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) switch (phydev->speed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) case SPEED_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) speed_conf = PHY_SPEED_10 << PHY_SPEED_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) case SPEED_100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) speed_conf = PHY_SPEED_100 << PHY_SPEED_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) case SPEED_1000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) speed_conf = PHY_SPEED_1000 << PHY_SPEED_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) dev_err(port->clock->dev, "bad speed: %d\n", phydev->speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) port_conf = ines_read32(port, port_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) port_conf &= ~(0x3 << PHY_SPEED_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) port_conf |= speed_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ines_write32(port, port_conf, port_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static bool ines_match(struct sk_buff *skb, unsigned int ptp_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct ines_timestamp *ts, struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct ptp_header *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) u16 portn, seqid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) u8 msgtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) u64 clkid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (unlikely(ptp_class & PTP_CLASS_V1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) hdr = ptp_parse_header(skb, ptp_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) msgtype = ptp_get_msgtype(hdr, ptp_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) clkid = be64_to_cpup((__be64 *)&hdr->source_port_identity.clock_identity.id[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) portn = be16_to_cpu(hdr->source_port_identity.port_number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) seqid = be16_to_cpu(hdr->sequence_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (tag_to_msgtype(ts->tag & 0x7) != msgtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) dev_dbg(dev, "msgtype mismatch ts %hhu != skb %hhu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) tag_to_msgtype(ts->tag & 0x7), msgtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (ts->clkid != clkid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) dev_dbg(dev, "clkid mismatch ts %llx != skb %llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ts->clkid, clkid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (ts->portnum != portn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) dev_dbg(dev, "portn mismatch ts %hu != skb %hu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) ts->portnum, portn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) if (ts->seqid != seqid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) dev_dbg(dev, "seqid mismatch ts %hu != skb %hu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ts->seqid, seqid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) static bool ines_rxtstamp(struct mii_timestamper *mii_ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct sk_buff *skb, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct ines_port *port = container_of(mii_ts, struct ines_port, mii_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct skb_shared_hwtstamps *ssh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) u64 ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (!port->rxts_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ns = ines_find_rxts(port, skb, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (!ns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) ssh = skb_hwtstamps(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ssh->hwtstamp = ns_to_ktime(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static int ines_rxfifo_read(struct ines_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) u32 data_rd_pos, buf_stat, mask, ts_stat_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct ines_timestamp *ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) mask = RX_FIFO_NE_1 << port->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) for (i = 0; i < INES_FIFO_DEPTH; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (list_empty(&port->pool)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dev_err(port->clock->dev, "event pool is empty\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) buf_stat = ines_read32(port->clock, buf_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (!(buf_stat & mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ts_stat_rx = ines_read32(port, ts_stat_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) data_rd_pos = (ts_stat_rx >> DATA_READ_POS_SHIFT) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) DATA_READ_POS_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (data_rd_pos) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) dev_err(port->clock->dev, "unexpected Rx read pos %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) data_rd_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) ts = list_first_entry(&port->pool, struct ines_timestamp, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ts->tmo = jiffies + HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ts->tag = ines_read32(port, ts_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ts->sec = ines_rxts64(port, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ts->nsec = ines_rxts64(port, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ts->clkid = ines_rxts64(port, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ts->portnum = ines_read32(port, ts_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) ts->seqid = ines_read32(port, ts_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) list_del_init(&ts->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) list_add_tail(&ts->list, &port->events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static u64 ines_rxts64(struct ines_port *port, unsigned int words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) u64 result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) u16 word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) word = ines_read32(port, ts_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) result = word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) words--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) for (i = 0; i < words; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) word = ines_read32(port, ts_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) result <<= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) result |= word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) static bool ines_timestamp_expired(struct ines_timestamp *ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return time_after(jiffies, ts->tmo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static int ines_ts_info(struct mii_timestamper *mii_ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) struct ethtool_ts_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) info->so_timestamping =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) SOF_TIMESTAMPING_TX_HARDWARE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) SOF_TIMESTAMPING_TX_SOFTWARE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) SOF_TIMESTAMPING_RX_HARDWARE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) SOF_TIMESTAMPING_RX_SOFTWARE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) SOF_TIMESTAMPING_SOFTWARE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) SOF_TIMESTAMPING_RAW_HARDWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) info->phc_index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) info->tx_types =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) (1 << HWTSTAMP_TX_OFF) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) (1 << HWTSTAMP_TX_ON) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) (1 << HWTSTAMP_TX_ONESTEP_P2P);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) info->rx_filters =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) (1 << HWTSTAMP_FILTER_NONE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) (1 << HWTSTAMP_FILTER_PTP_V2_EVENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static u64 ines_txts64(struct ines_port *port, unsigned int words)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) u64 result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) u16 word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) word = ines_read32(port, ts_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) result = word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) words--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) for (i = 0; i < words; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) word = ines_read32(port, ts_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) result <<= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) result |= word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static bool ines_txts_onestep(struct ines_port *port, struct sk_buff *skb, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) u32 port_conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) port_conf = ines_read32(port, port_conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (port_conf & CM_ONE_STEP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return is_sync_pdelay_resp(skb, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static void ines_txtstamp(struct mii_timestamper *mii_ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) struct sk_buff *skb, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct ines_port *port = container_of(mii_ts, struct ines_port, mii_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct sk_buff *old_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (!port->txts_enabled || ines_txts_onestep(port, skb, type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (port->tx_skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) old_skb = port->tx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) port->tx_skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) kfree_skb(old_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) schedule_delayed_work(&port->ts_work, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static void ines_txtstamp_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct ines_port *port =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) container_of(work, struct ines_port, ts_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct skb_shared_hwtstamps ssh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) u64 ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) skb = port->tx_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) port->tx_skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) ns = ines_find_txts(port, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (!ns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) ssh.hwtstamp = ns_to_ktime(ns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) skb_complete_tx_timestamp(skb, &ssh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) static bool is_sync_pdelay_resp(struct sk_buff *skb, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct ptp_header *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) u8 msgtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) hdr = ptp_parse_header(skb, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) msgtype = ptp_get_msgtype(hdr, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) switch ((msgtype & 0xf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) case SYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) case PDELAY_RESP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) static u8 tag_to_msgtype(u8 tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) switch (tag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) case MESSAGE_TYPE_SYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) case MESSAGE_TYPE_P_DELAY_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return PDELAY_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) case MESSAGE_TYPE_P_DELAY_RESP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return PDELAY_RESP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) case MESSAGE_TYPE_DELAY_REQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return DELAY_REQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static struct mii_timestamper *ines_ptp_probe_channel(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct device_node *node = device->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) struct ines_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (index > INES_N_PORTS - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) dev_err(device, "bad port index %u\n", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) port = ines_find_port(node, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) if (!port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) dev_err(device, "missing port index %u\n", index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) port->mii_ts.rxtstamp = ines_rxtstamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) port->mii_ts.txtstamp = ines_txtstamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) port->mii_ts.hwtstamp = ines_hwtstamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) port->mii_ts.link_state = ines_link_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) port->mii_ts.ts_info = ines_ts_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) return &port->mii_ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) static void ines_ptp_release_channel(struct device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) struct mii_timestamper *mii_ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static struct mii_timestamping_ctrl ines_ctrl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) .probe_channel = ines_ptp_probe_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) .release_channel = ines_ptp_release_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static int ines_ptp_ctrl_probe(struct platform_device *pld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct ines_clock *clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) void __iomem *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) addr = devm_platform_ioremap_resource(pld, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (IS_ERR(addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) err = PTR_ERR(addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) clock = kzalloc(sizeof(*clock), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (!clock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (ines_clock_init(clock, &pld->dev, addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) kfree(clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) err = register_mii_tstamp_controller(&pld->dev, &ines_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) kfree(clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) mutex_lock(&ines_clocks_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) list_add_tail(&ines_clocks, &clock->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) mutex_unlock(&ines_clocks_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) dev_set_drvdata(&pld->dev, clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static int ines_ptp_ctrl_remove(struct platform_device *pld)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct ines_clock *clock = dev_get_drvdata(&pld->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) unregister_mii_tstamp_controller(&pld->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) mutex_lock(&ines_clocks_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) list_del(&clock->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) mutex_unlock(&ines_clocks_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) ines_clock_cleanup(clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) kfree(clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static const struct of_device_id ines_ptp_ctrl_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) { .compatible = "ines,ptp-ctrl" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) MODULE_DEVICE_TABLE(of, ines_ptp_ctrl_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) static struct platform_driver ines_ptp_ctrl_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) .probe = ines_ptp_ctrl_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) .remove = ines_ptp_ctrl_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) .name = "ines_ptp_ctrl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) .of_match_table = of_match_ptr(ines_ptp_ctrl_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) module_platform_driver(ines_ptp_ctrl_driver);