1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
/*
* drivers/net/fec_1588.h
*
* Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef FEC_1588_H
#define FEC_1588_H
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/circ_buf.h>
#define FALSE 0
#define TRUE 1
/* FEC 1588 register bits */
#define FEC_T_CTRL_SLAVE 0x00002000
#define FEC_T_CTRL_CAPTURE 0x00000800
#define FEC_T_CTRL_RESTART 0x00000200
#define FEC_T_CTRL_PERIOD_RST 0x00000030
#define FEC_T_CTRL_ENABLE 0x00000001
#define FEC_T_INC_MASK 0x0000007f
#define FEC_T_INC_OFFSET 0
#define FEC_T_INC_CORR_MASK 0x00007f00
#define FEC_T_INC_CORR_OFFSET 8
#define FEC_T_INC_50MHZ 20
#define FEC_ATIME_50MHZ 50000000
#define FEC_T_INC_CLK FEC_T_INC_50MHZ
#define FEC_ATIME_CLK FEC_ATIME_50MHZ
#define FEC_T_PERIOD_ONE_SEC 0x3B9ACA00
/* IEEE 1588 definition */
#define FEC_ECNTRL_TS_EN 0x10
#define DEFAULT_PTP_RX_BUF_SZ 64
#define DEFAULT_PTP_TX_BUF_SZ 64
/* 1588stack API defines */
#define PTP_ENBL_TXTS_IOCTL SIOCDEVPRIVATE
#define PTP_DSBL_TXTS_IOCTL (SIOCDEVPRIVATE + 1)
#define PTP_ENBL_RXTS_IOCTL (SIOCDEVPRIVATE + 2)
#define PTP_DSBL_RXTS_IOCTL (SIOCDEVPRIVATE + 3)
#define PTP_GET_TX_TIMESTAMP (SIOCDEVPRIVATE + 4)
#define PTP_GET_RX_TIMESTAMP (SIOCDEVPRIVATE + 5)
#define PTP_SET_RTC_TIME (SIOCDEVPRIVATE + 6)
#define PTP_GET_CURRENT_TIME (SIOCDEVPRIVATE + 7)
#define PTP_SET_COMPENSATION (SIOCDEVPRIVATE + 9)
#define PTP_GET_ORIG_COMP (SIOCDEVPRIVATE + 10)
#define PTP_FLUSH_TIMESTAMP (SIOCDEVPRIVATE + 11)
/* IEEE1588 ptp head format */
#define PTP_CTRL_OFFS 0x52
#define PTP_SOURCE_PORT_LENGTH 10
#define PTP_HEADER_SEQ_OFFS 30
#define PTP_HEADER_CTL_OFFS 32
#define PTP_SPID_OFFS 20
#define PTP_HEADER_SZE 34
#define PTP_EVENT_PORT 0x013F
#define FEC_VLAN_TAG_LEN 0x04
#define FEC_ETHTYPE_LEN 0x02
/* 1588-2008 network protocol enumeration values */
#define FEC_PTP_PROT_IPV4 1
#define FEC_PTP_PROT_IPV6 2
#define FEC_PTP_PROT_802_3 3
#define FEC_PTP_PROT_DONTCARE 0xFFFF
#define FEC_PACKET_TYPE_UDP 0x11
#define FEC_PTP_ORIG_COMP 0x15555555
#define FEC_PTP_SPINNER_2 2
#define FEC_PTP_SPINNER_4 4
/* PTP standard time representation structure */
struct ptp_time{
u64 sec; /* seconds */
u32 nsec; /* nanoseconds */
};
/* struct needed to identify a timestamp */
struct fec_ptp_ident {
u8 version;
u8 message_type;
u16 netw_prot;
u16 seq_id;
u8 spid[10];
};
/* interface for PTP driver command GET_TX_TIME */
struct fec_ptp_ts_data {
struct fec_ptp_ident ident;
/* PTP timestamp */
struct ptp_time ts;
};
/* circular buffer for ptp timestamps over ioctl */
struct fec_ptp_circular {
int front;
int end;
int size;
struct fec_ptp_ts_data *data_buf;
};
/* interface for PTP driver command SET_RTC_TIME/GET_CURRENT_TIME */
struct ptp_rtc_time {
struct ptp_time rtc_time;
};
/* interface for PTP driver command SET_COMPENSATION */
struct ptp_set_comp {
u32 drift;
bool o_ops;
u32 freq_compensation;
};
/* interface for PTP driver command GET_ORIG_COMP */
struct ptp_get_comp {
/* the initial compensation value */
u32 dw_origcomp;
/* the minimum compensation value */
u32 dw_mincomp;
/*the max compensation value*/
u32 dw_maxcomp;
/*the min drift applying min compensation value in ppm*/
u32 dw_mindrift;
/*the max drift applying max compensation value in ppm*/
u32 dw_maxdrift;
};
struct ptp_time_correct {
u32 corr_period;
u32 corr_inc;
};
/* PTP message version */
#define PTP_1588_MSG_VER_1 1
#define PTP_1588_MSG_VER_2 2
#define BD_ENET_TX_TS 0x20000000
#define BD_ENET_TX_BDU 0x80000000
struct fec_ptp_private {
void __iomem *hwp;
int dev_id;
struct fec_ptp_circular tx_timestamps;
struct fec_ptp_circular rx_timestamps;
spinlock_t cnt_lock;
u64 prtc;
u8 ptp_active;
u8 ptp_slave;
struct circ_buf txstamp;
};
#ifdef CONFIG_FEC_1588
static inline int fec_ptp_malloc_priv(struct fec_ptp_private **priv)
{
*priv = kzalloc(sizeof(struct fec_ptp_private), GFP_KERNEL);
return 1;
}
extern int fec_ptp_init(struct fec_ptp_private *priv, int id);
extern void fec_ptp_cleanup(struct fec_ptp_private *priv);
extern int fec_ptp_start(struct fec_ptp_private *priv);
extern void fec_ptp_stop(struct fec_ptp_private *priv);
extern int fec_ptp_do_txstamp(struct sk_buff *skb);
extern void fec_ptp_store_txstamp(struct fec_ptp_private *priv,
struct sk_buff *skb,
struct bufdesc *bdp);
extern void fec_ptp_store_rxstamp(struct fec_ptp_private *priv,
struct sk_buff *skb,
struct bufdesc *bdp);
extern int fec_ptp_ioctl(struct fec_ptp_private *priv,
struct ifreq *ifr, int cmd);
#else
static inline int fec_ptp_malloc_priv(struct fec_ptp_private **priv)
{
return 0;
}
static inline int fec_ptp_init(struct fec_ptp_private *priv, int id)
{
return 1;
}
static inline void fec_ptp_cleanup(struct fec_ptp_private *priv) { }
static inline int fec_ptp_start(struct fec_ptp_private *priv)
{
return 1;
}
static inline void fec_ptp_stop(struct fec_ptp_private *priv) {}
static inline int fec_ptp_do_txstamp(struct sk_buff *skb)
{
return 0;
}
static inline void fec_ptp_store_txstamp(struct fec_ptp_private *priv,
struct sk_buff *skb,
struct bufdesc *bdp) {}
static inline void fec_ptp_store_rxstamp(struct fec_ptp_private *priv,
struct sk_buff *skb,
struct bufdesc *bdp) {}
static inline int fec_ptp_ioctl(struct fec_ptp_private *priv,
struct ifreq *ifr, int cmd)
{
return 0;
}
#endif /* 1588 */
#endif
|