Line data Source code
1 : // This file (mu2e_ioctl.h) was created by Ron Rechenmacher <ron@fnal.gov> on
2 : // Feb 5, 2014. "TERMS AND CONDITIONS" governing this file are in the README
3 : // or COPYING file. If you do not have such a file, one can be obtained by
4 : // contacting Ron or Fermi Lab in Batavia IL, 60510, phone: 630-840-3000.
5 : // $RCSfile: .emacs.gnu,v $
6 : // rev="$Revision: 1.23 $$Date: 2012/01/23 15:32:40 $";
7 :
8 : #ifndef MU2E_MMAP_IOCTL_H
9 : #define MU2E_MMAP_IOCTL_H
10 :
11 : #ifdef __KERNEL__
12 : #include <asm/ioctl.h> // _IOWR
13 : #include <linux/utsname.h> /* uname */
14 : #include "trace.h"
15 : #define _trace_hash(str) trace_name_hash(str)
16 : #else
17 : #include <stdint.h> // uint16_t
18 : #include <sys/ioctl.h> // _IOWR
19 : #include <sys/types.h>
20 : #include <sys/utsname.h> /* uname */
21 : #include <unistd.h> // sysconf
22 :
23 : #ifndef __CLING__
24 : #include "trace.h"
25 : #define _trace_hash(str) trace_name_hash(str)
26 : #else
27 : #define _trace_hash(x) x[0]
28 : #endif
29 :
30 : #endif
31 :
32 : #define MU2E_DEV_FILE "mu2e%d" /* %d => minor number */
33 : #define MU2E_MAX_CHANNELS 2
34 : #define MU2E_MAX_NUM_DTCS 4 /* Keep resonable...shouldn't ever need more than 4...*/
35 :
36 : /// <summary>
37 : /// Data Header Packet definition, hardware view
38 : /// </summary>
39 : union DataHeaderPacket
40 : {
41 : /// <summary>
42 : /// Raw packet
43 : /// </summary>
44 : struct
45 : {
46 : uint16_t w0; ///< Word 0
47 : uint16_t w1; ///< Word 1
48 : uint16_t w2; ///< Word 2
49 : uint16_t w3; ///< Word 3
50 : uint16_t w4; ///< Word 4
51 : uint16_t w5; ///< Word 5
52 : uint16_t w6; ///< Word 6
53 : uint16_t w7; ///< Word 7
54 : } w;
55 : /// <summary>
56 : /// Decoded packet
57 : /// </summary>
58 : struct
59 : {
60 : uint16_t TransferByteCount; ///< Block Byte count
61 :
62 : uint16_t Resv1 : 4; ///< Reserved
63 : uint16_t PacketType : 4; ///< Type of packet
64 : uint16_t LinkID : 4; ///< Link ID of packet
65 : uint16_t SubsystemID : 3; ///< Subsystem ID
66 : uint16_t Valid : 1; ///< Is the packet valid?
67 :
68 : uint16_t PacketCount : 11; ///< Packet count requested
69 : uint16_t Resv2 : 5; ///< Reserved
70 : uint16_t ts10; ///< Timestamp bytes 1 and 2 (Least significant)
71 : uint16_t ts32; ///< Timestamp bytes 3 and 4
72 : uint16_t ts54; ///< Timestamp bytes 5 and 6 (Most significant)
73 : uint16_t Status : 8; ///< Status word
74 : uint16_t Version : 8; ///< Data packet format version
75 : uint16_t DTCID : 8; ///< ID of receiving DTC
76 : uint16_t EventWindowMode : 8; ///< Window mode byte from CFO
77 : } s;
78 : };
79 : /// <summary>
80 : /// Data Request Packet, hardware view
81 : /// </summary>
82 : union DataRequestPacket
83 : {
84 : /// <summary>
85 : /// Raw Packet
86 : /// </summary>
87 : struct
88 : {
89 : uint16_t w0; ///< Word 0
90 : uint16_t w1; ///< Word 1
91 : uint16_t w2; ///< Word 2
92 : uint16_t w3; ///< Word 3
93 : uint16_t w4; ///< Word 4
94 : uint16_t w5; ///< Word 5
95 : uint16_t w6; ///< Word 6
96 : uint16_t w7; ///< Word 7
97 : } w;
98 : /// <summary>
99 : /// Decoded packet
100 : /// </summary>
101 : struct
102 : {
103 : uint16_t TransferByteCount; ///< Block Byte count
104 :
105 : uint16_t Resv1 : 4; ///< Reserved
106 : uint16_t PacketType : 4; ///< Type of packet
107 : uint16_t LinkID : 4; ///< Link ID of packet
108 : uint16_t Resv0 : 3; ///< Reserved
109 : uint16_t Valid : 1; ///< Is the packet valid?
110 :
111 : uint16_t PacketCount : 8; ///< Packet count requested
112 : uint16_t Resv2 : 8; ///< Reserved
113 : uint16_t ts10; ///< Timestamp bytes 1 and 2 (Least significant)
114 : uint16_t ts32; ///< Timestamp bytes 3 and 4
115 : uint16_t ts54; ///< Timestamp bytes 5 and 6 (Most significant)
116 : uint16_t data32; ///< Data bytes 1 and 2
117 : uint16_t data54; ///< Data bytes 3 and 4
118 : } s;
119 : };
120 : /// <summary>
121 : /// DataPacket definition, hardware view
122 : /// </summary>
123 : struct DataPacket
124 : {
125 : uint16_t data10; ///< Bytes 1 and 2 of the Data Packet
126 : uint16_t data32; ///< Bytes 3 and 4 of the Data Packet
127 : uint16_t data54; ///< Bytes 5 and 6 of the Data Packet
128 : uint16_t data76; ///< Bytes 7 and 8 of the Data Packet
129 : uint16_t data98; ///< Bytes 9 and 10 of the Data Packet
130 : uint16_t dataBA; ///< Bytes 11 and 12 of the Data Packet
131 : uint16_t dataDC; ///< Bytes 13 and 14 of the Data Packet
132 : uint16_t dataFE; ///< Bytes 15 and 16 of the Data Packet
133 : };
134 :
135 : // Used in kernel mmap function
136 : #define page2chDirMap(pg, chn, dir, map) \
137 : chn = pg / 4; \
138 : dir = (pg % 4) / 2; \
139 : map = (pg % 2) / 1
140 :
141 : // Used in user space interface library
142 : #define chnDirMap2offset(chn, dir, map) \
143 : (sysconf(_SC_PAGE_SIZE) * (chn * 4) + sysconf(_SC_PAGE_SIZE) * ((dir & 1) * 2) + sysconf(_SC_PAGE_SIZE) * (map & 1))
144 :
145 : #define idx_add(idx, add, dtc, chn, dir) \
146 : __extension__({ \
147 : unsigned num_buffs = mu2e_channel_info_[dtc][chn][dir].num_buffs; \
148 : (add < 0) ? (((unsigned)-add > idx) ? (num_buffs - (-add - idx)) % num_buffs : (idx - (-add)) % num_buffs) \
149 : : (idx + add) % num_buffs; \
150 : })
151 :
152 : /*
153 : For _IO,_IOR,_IOW,_IORW ref. Documentation/ioctl/ioctl-number.txt
154 : _IO - implementation has neither copy_from nor copy_to user (or equivalents)
155 : _IOR - implementation has copy_to_user (or equiv., at end)
156 : _IOW - implementation has copy_from_user (or equiv., at beginnning)
157 : _IOWR - implementaions has both copy_from_user (at beginnning) and
158 : copy_to_user (at end)
159 : NOTE: for _IOR, _IOW: the size is only for the data at the address used in the
160 : ioctl call; NOT for the size at an address contained within the data
161 : pointed to by the address used in the ioctl call. So, if a small
162 : structure is pointed to (to be copied in) which has an address of a
163 : large buffer, the only thing that these macros should consider is the
164 : pointer used (directly) in the ioctl call.
165 : */
166 : #define MU2E_IOC_MAGIC 'C'
167 :
168 : #define M_IOC_REG_ACCESS _IOWR(MU2E_IOC_MAGIC, 9, m_ioc_reg_access_t)
169 : #define M_IOC_GET_TST_STATE _IOWR(MU2E_IOC_MAGIC, 1, m_ioc_cmd_t)
170 : #define M_IOC_TEST_START _IOW(MU2E_IOC_MAGIC, 2, m_ioc_cmd_t)
171 : #define M_IOC_TEST_STOP _IOW(MU2E_IOC_MAGIC, 3, m_ioc_cmd_t)
172 :
173 : #define M_IOC_GET_PCI_STATE _IOR(MU2E_IOC_MAGIC, 4, m_ioc_pcistate_t)
174 : #define M_IOC_GET_ENG_STATE _IOWR(MU2E_IOC_MAGIC, 5, m_ioc_engstate_t)
175 : #define M_IOC_GET_DMA_STATS _IOWR(MU2E_IOC_MAGIC, 6, m_ioc_engstats_t)
176 : #define M_IOC_GET_TRN_STATS _IOWR(MU2E_IOC_MAGIC, 7, TRNStatsArray)
177 :
178 : #define M_IOC_GET_INFO _IOWR(MU2E_IOC_MAGIC, 12, m_ioc_get_info_t)
179 : #define M_IOC_BUF_GIVE _IO(MU2E_IOC_MAGIC, 13) // arg=(chn<<24)|(dir<<16)|num
180 : #define M_IOC_DUMP _IO(MU2E_IOC_MAGIC, 14)
181 : #define M_IOC_BUF_XMIT _IO(MU2E_IOC_MAGIC, 16)
182 :
183 : #define M_IOC_DCS_LOCK _IO(MU2E_IOC_MAGIC, 17)
184 : #define M_IOC_DCS_RELEASE _IO(MU2E_IOC_MAGIC, 18)
185 : #define M_IOC_GET_VERSION _IOR(MU2E_IOC_MAGIC, 19, mu2e_string_t)
186 :
187 : /// <summary>
188 : /// Register Access information
189 : /// </summary>
190 : typedef uint16_t dtc_address_t;
191 : typedef uint32_t dtc_data_t;
192 : typedef struct
193 : {
194 : dtc_address_t reg_offset; ///< Offset of register from BAR0
195 : int access_type; ///< 0=read, 1=write, 2=write-with-readback
196 : dtc_data_t val; ///< Value of register
197 : } m_ioc_reg_access_t;
198 :
199 : /** Structure used in IOCTL to start/stop a test & to get current test state */
200 : typedef struct
201 : {
202 : int Engine; /**< Engine Number */
203 : unsigned TestMode; /**< Test Mode - Enable TX, Enable loopback */
204 : unsigned MinPktSize; /**< Min packet size */
205 : unsigned MaxPktSize; /**< Max packet size */
206 : } m_ioc_cmd_t;
207 :
208 : /** Structure used in IOCTL to get PCIe state from driver */
209 : typedef struct
210 : {
211 : unsigned Version; /**< Hardware design version info */
212 : int LinkState; /**< Link State - up or down */
213 : int LinkSpeed; /**< Link Speed */
214 : int LinkWidth; /**< Link Width */
215 : unsigned VendorId; /**< Vendor ID */
216 : unsigned DeviceId; /**< Device ID */
217 : int IntMode; /**< Legacy or MSI interrupts */
218 : int MPS; /**< Max Payload Size */
219 : int MRRS; /**< Max Read Request Size */
220 : int InitFCCplD; /**< Initial FC Credits for Completion Data */
221 : int InitFCCplH; /**< Initial FC Credits for Completion Header */
222 : int InitFCNPD; /**< Initial FC Credits for Non-Posted Data */
223 : int InitFCNPH; /**< Initial FC Credits for Non-Posted Data */
224 : int InitFCPD; /**< Initial FC Credits for Posted Data */
225 : int InitFCPH; /**< Initial FC Credits for Posted Data */
226 : } m_ioc_pcistate_t;
227 :
228 : /// <summary>
229 : /// Structure used in IOCTL to get DMA Engine state from driver
230 : /// </summary>
231 : typedef struct
232 : {
233 : int Engine; /**< Engine Number */
234 : int BDs; /**< Total Number of BDs */
235 : int Buffers; /**< Total Number of buffers */
236 : unsigned MinPktSize; /**< Minimum packet size */
237 : unsigned MaxPktSize; /**< Maximum packet size */
238 : int BDerrs; /**< Total BD errors */
239 : int BDSerrs; /**< Total BD short errors - only TX BDs */
240 : int IntEnab; /**< Interrupts enabled or not */
241 : unsigned TestMode; /**< Current Test Mode */
242 : } m_ioc_engstate_t;
243 :
244 : /// <summary>
245 : /// Structure used in IOCTL to get DMA statistics from driver (single data point)
246 : /// </summary>
247 : typedef struct /* MAYBE THIS SHOULD GO ELSEWHERE??? */
248 : {
249 : int Engine; /**< Engine Number */
250 : unsigned LBR; /**< Last Byte Rate */
251 : unsigned LAT; /**< Last Active Time */
252 : unsigned LWT; /**< Last Wait Time */
253 : } DMAStatistics;
254 :
255 : /// <summary>
256 : /// Structure used in IOCTL to get DMA statistics from driver
257 : /// </summary>
258 : typedef struct
259 : {
260 : int Count; /**< Number of statistics captures */
261 : DMAStatistics* engptr; /**< Pointer to array to store statistics */
262 : } m_ioc_engstats_t;
263 :
264 : /// <summary>
265 : /// Structure used in IOCTL to get transmit and receive statistics from driver
266 : /// </summary>
267 : typedef struct
268 : {
269 : unsigned int LTX; /**< Last TX Byte Rate */
270 : unsigned int LRX; /**< Last RX Byte Rate */
271 : } TRNStatistics;
272 :
273 : /** Structure used in IOCTL to get PCIe TRN statistics from driver */
274 : typedef struct
275 : {
276 : int Count; /**< Number of statistics captures */
277 : TRNStatistics* trnptr; /**< Pointer to array to store statistics */
278 : } TRNStatsArray;
279 :
280 : /** Structure used to hold software statistics */
281 : typedef struct
282 : {
283 : int Engine; /**< Engine Number */
284 : unsigned int LBR; /**< Last Byte Rate */
285 : } SWStatistics;
286 :
287 : /** Structure used in IOCTL to get software statistics from driver */
288 : typedef struct
289 : {
290 : int Count; /**< Number of statistics captures */
291 : SWStatistics* swptr; /**< Pointer to array to store statistics */
292 : } SWStatsArray;
293 :
294 : //------------------------------------------
295 :
296 : typedef unsigned char mu2e_databuff_t[0x10000]; /** sizeof(mu2e_databuff_t) is what we tell DTC FPGA (black box) DMA ENGINE MAX_DMA_SIZE */
297 : #define SET_DTC_MAX_DMA_SIZE 0xfff8 /* NOTE: max 32 bits!!! See use in mu2e_mem.c */
298 : typedef char mu2e_string_t[100];
299 :
300 : typedef enum
301 : {
302 : DTC_DMA_Engine_DAQ = 0,
303 : DTC_DMA_Engine_DCS = 1,
304 : DTC_DMA_Engine_Invalid = -1,
305 : } DTC_DMA_Engine;
306 :
307 : typedef enum
308 : {
309 : DTC_DMA_Direction_C2S = 0,
310 : DTC_DMA_Direction_S2C = 1,
311 : DTC_DMA_Direction_Invalid,
312 : } DTC_DMA_Direction;
313 :
314 : enum
315 : {
316 : C2S,
317 : S2C
318 : };
319 : enum
320 : {
321 : MU2E_MAP_BUFF,
322 : MU2E_MAP_META
323 : };
324 :
325 : #define DTC_Register_Engine_Control(eng, dir) (((eng * 0x100) + (dir * 0x2000)) + 0x4)
326 :
327 : /// <summary>
328 : /// Structure used in IOCTL to get information about DMA transfer buffer status
329 : /// </summary>
330 : typedef struct
331 : {
332 : int chn; ///< Channel (DAQ or DCS)
333 : int dir; ///< Direction (C2S or S2C)
334 : int tmo_ms; ///< Timeout for buffers
335 : unsigned buff_size; ///< Size of the buffers in this chn/dir
336 : unsigned num_buffs; ///< Number of buffers in this chn/dir
337 : unsigned hwIdx; ///< Current buffer index for the hardware
338 : unsigned swIdx; ///< Current buffer index for the software
339 : /* unsigned cmpltIdx; maybe also need... particularly/especially for S2C */
340 : } m_ioc_get_info_t;
341 :
342 : /* This inline references mu2e_channel_info_ -- the name of a variable in both
343 : userspace and kernel land. For userspace the variable is defined in
344 : the mu2edev class (and therefore the using namsspace
345 : */
346 0 : static inline unsigned mu2e_chn_info_delta_(
347 : int dtc, int chn, int dir, m_ioc_get_info_t (*mu2e_channel_info_)[MU2E_MAX_NUM_DTCS][MU2E_MAX_CHANNELS][2])
348 : {
349 0 : unsigned hw = (*mu2e_channel_info_)[dtc][chn][dir].hwIdx;
350 0 : unsigned sw = (*mu2e_channel_info_)[dtc][chn][dir].swIdx;
351 : unsigned retval;
352 0 : if(dir == C2S)
353 0 : retval = ((hw >= sw) ? hw - sw : (*mu2e_channel_info_)[dtc][chn][dir].num_buffs + hw - sw);
354 : else
355 0 : retval = ((sw >= hw) ? (*mu2e_channel_info_)[dtc][chn][dir].num_buffs - (sw - hw) : hw - sw);
356 :
357 : #ifndef __CLING__
358 0 : TRACE(27, "mu2e_mmap_ioctl::delta_ dtc=%d chn=%d dir=%d hw=%u sw=%u num_buffs=%u delta=%u", dtc, chn, dir, hw, sw, (*mu2e_channel_info_)[dtc][chn][dir].num_buffs, retval);
359 : #endif
360 0 : return retval;
361 : }
362 :
363 0 : static inline uint32_t mu2e_host_hash(int dtc, char* hostname_in)
364 : {
365 : #ifndef __KERNEL__
366 : struct utsname unameinfo;
367 : #endif
368 0 : char* hostname = hostname_in;
369 0 : uint16_t hostname_hash = 0;
370 : uint32_t scratchVal;
371 :
372 0 : if(hostname == NULL)
373 : {
374 : #ifdef __KERNEL__
375 : hostname = utsname()->nodename;
376 : #else
377 0 : uname(&unameinfo);
378 0 : hostname = unameinfo.nodename;
379 : #endif
380 : }
381 0 : hostname_hash = _trace_hash(hostname);
382 0 : scratchVal = ((uint32_t)hostname_hash << 16) + (uint16_t)dtc;
383 :
384 0 : return scratchVal;
385 : }
386 :
387 : // stuff from obsolete include/xpmon_be.h
388 : #define LINK_UP 1 /**< Link State is Up */
389 : #define INT_NONE 0x0 /**< No Interrupt capability */
390 : #define INT_LEGACY 0x1 /**< Legacy Interrupts capability */
391 : #define INT_MSI 0x2 /**< MSI Interrupts capability */
392 : #define INT_MSIX 0x3 /**< MSI-X Interrupts capability */
393 :
394 : #endif // MU2E_MMAP_IOCTL_H
|