blob: f4910332d3c6e4d700597cce8fbb533c59a2dd4f [file] [log] [blame]
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001/****************************************************************************
2
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
5
6 Project: openPOWERLINK
7
8 Description: proc fs entry with diagnostic information under Linux
9
10 License:
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
15
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
18
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
22
23 3. Neither the name of SYSTEC electronic GmbH nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without prior written permission. For written
26 permission, please contact info@systec-electronic.com.
27
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
40
41 Severability Clause:
42
43 If a provision of this License is or becomes illegal, invalid or
44 unenforceable in any jurisdiction, that shall not affect:
45 1. the validity or enforceability in that jurisdiction of any other
46 provision of this License; or
47 2. the validity or enforceability in other jurisdictions of that or
48 any other provision of this License.
49
50 -------------------------------------------------------------------------
51
52 $RCSfile: proc_fs.c,v $
53
54 $Author: D.Krueger $
55
56 $Revision: 1.13 $ $Date: 2008/11/07 13:55:56 $
57
58 $State: Exp $
59
60 Build Environment:
61 GNU
62
63 -------------------------------------------------------------------------
64
65 Revision History:
66
67 2006/07/31 d.k.: start of implementation
68
69****************************************************************************/
70
71#include "kernel/EplNmtk.h"
72#include "user/EplNmtu.h"
73
74#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
75#include "user/EplNmtMnu.h"
76#endif
77
78#include "kernel/EplDllkCal.h"
79
80//#include <linux/config.h>
81#include <linux/module.h>
82#include <linux/kernel.h>
83#include <linux/init.h>
84#include <linux/errno.h>
85#include <linux/major.h>
86#include <linux/version.h>
87#include <asm/io.h>
88#include <asm/uaccess.h>
89#include <asm/atomic.h>
90#include <linux/proc_fs.h>
91#include <linux/spinlock.h>
92
93#ifdef CONFIG_COLDFIRE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -080094#include <asm/coldfire.h>
95#include "fec.h"
Daniel Krueger9d7164c2008-12-19 11:41:57 -080096#endif
97
Daniel Krueger9d7164c2008-12-19 11:41:57 -080098/***************************************************************************/
99/* */
100/* */
101/* G L O B A L D E F I N I T I O N S */
102/* */
103/* */
104/***************************************************************************/
105
106//---------------------------------------------------------------------------
107// const defines
108//---------------------------------------------------------------------------
109
110#ifndef EPL_PROC_DEV_NAME
111#define EPL_PROC_DEV_NAME "epl"
112#endif
113
114#ifndef DBG_TRACE_POINTS
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800115#define DBG_TRACE_POINTS 23 // # of supported debug trace points
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800116#endif
117
118#ifndef DBG_TRACE_VALUES
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800119#define DBG_TRACE_VALUES 24 // # of supported debug trace values (size of circular buffer)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800120#endif
121
122//---------------------------------------------------------------------------
123// modul global types
124//---------------------------------------------------------------------------
125
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800126//---------------------------------------------------------------------------
127// local vars
128//---------------------------------------------------------------------------
129
130#ifdef _DBG_TRACE_POINTS_
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800131atomic_t aatmDbgTracePoint_l[DBG_TRACE_POINTS];
132DWORD adwDbgTraceValue_l[DBG_TRACE_VALUES];
133DWORD dwDbgTraceValueOld_l;
134unsigned int uiDbgTraceValuePos_l;
135spinlock_t spinlockDbgTraceValue_l;
136unsigned long ulDbTraceValueFlags_l;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800137#endif
138
139//---------------------------------------------------------------------------
140// local function prototypes
141//---------------------------------------------------------------------------
142
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800143static int EplLinProcRead(char *pcBuffer_p, char **ppcStart_p, off_t Offset_p,
144 int nBufferSize_p, int *pEof_p, void *pData_p);
145static int EplLinProcWrite(struct file *file, const char __user * buffer,
146 unsigned long count, void *data);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800147
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800148void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
149void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800150
151EPLDLLEXPORT DWORD PUBLIC EplIdentuGetRunningRequests(void);
152
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800153//=========================================================================//
154// //
155// P U B L I C F U N C T I O N S //
156// //
157//=========================================================================//
158
159tEplKernel EplLinProcInit(void)
160{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800161 struct proc_dir_entry *pProcDirEntry;
162 pProcDirEntry = create_proc_entry(EPL_PROC_DEV_NAME, S_IRUGO, NULL);
163 if (pProcDirEntry != NULL) {
164 pProcDirEntry->read_proc = EplLinProcRead;
165 pProcDirEntry->write_proc = EplLinProcWrite;
166 pProcDirEntry->data = NULL; // device number or something else
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800167
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800168 } else {
169 return kEplNoResource;
170 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800171
172#ifdef _DBG_TRACE_POINTS_
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800173 // initialize spinlock and circular buffer position
174 spin_lock_init(&spinlockDbgTraceValue_l);
175 uiDbgTraceValuePos_l = 0;
176 dwDbgTraceValueOld_l = 0;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800177#endif
178
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800179 return kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800180}
181
182tEplKernel EplLinProcFree(void)
183{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800184 remove_proc_entry(EPL_PROC_DEV_NAME, NULL);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800185
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800186 return kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800187}
188
189//---------------------------------------------------------------------------
190// Target specific event signaling (FEC Tx-/Rx-Interrupt, used by Edrv)
191//---------------------------------------------------------------------------
192
193#ifdef _DBG_TRACE_POINTS_
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800194void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800195{
196
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800197 if (bTracePointNumber_p >=
198 (sizeof(aatmDbgTracePoint_l) / sizeof(aatmDbgTracePoint_l[0]))) {
199 goto Exit;
200 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800201
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800202 atomic_inc(&aatmDbgTracePoint_l[bTracePointNumber_p]);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800203
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800204 Exit:
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800205
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800206 return;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800207
208}
209
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800210void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800211{
212
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800213 spin_lock_irqsave(&spinlockDbgTraceValue_l, ulDbTraceValueFlags_l);
214 if (dwDbgTraceValueOld_l != dwTraceValue_p) {
215 adwDbgTraceValue_l[uiDbgTraceValuePos_l] = dwTraceValue_p;
216 uiDbgTraceValuePos_l =
217 (uiDbgTraceValuePos_l + 1) % DBG_TRACE_VALUES;
218 dwDbgTraceValueOld_l = dwTraceValue_p;
219 }
220 spin_unlock_irqrestore(&spinlockDbgTraceValue_l, ulDbTraceValueFlags_l);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800221
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800222 return;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800223
224}
225#endif
226
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800227//---------------------------------------------------------------------------
228// Read function for PROC-FS read access
229//---------------------------------------------------------------------------
230
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800231static int EplLinProcRead(char *pcBuffer_p,
232 char **ppcStart_p,
233 off_t Offset_p,
234 int nBufferSize_p, int *pEof_p, void *pData_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800235{
236
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800237 int nSize;
238 int Eof;
239 tEplDllkCalStatistics *pDllkCalStats;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800240
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800241 nSize = 0;
242 Eof = 0;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800243
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800244 // count calls of this function
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800245#ifdef _DBG_TRACE_POINTS_
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800246 TgtDbgSignalTracePoint(0);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800247#endif
248
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800249 //---------------------------------------------------------------
250 // generate static information
251 //---------------------------------------------------------------
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800252
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800253 // ---- Driver information ----
254 nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
255 "%s %s (c) 2006 %s\n",
256 EPL_PRODUCT_NAME, EPL_PRODUCT_VERSION,
257 EPL_PRODUCT_MANUFACTURER);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800258
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800259 //---------------------------------------------------------------
260 // generate process information
261 //---------------------------------------------------------------
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800262
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800263 // ---- EPL state ----
264 nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
265 "NMT state: 0x%04X\n",
266 (WORD) EplNmtkGetNmtState());
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800267
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800268 EplDllkCalGetStatistics(&pDllkCalStats);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800269
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800270 nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
271 "CurAsyncTxGen=%lu CurAsyncTxNmt=%lu CurAsyncRx=%lu\nMaxAsyncTxGen=%lu MaxAsyncTxNmt=%lu MaxAsyncRx=%lu\n",
272 pDllkCalStats->m_ulCurTxFrameCountGen,
273 pDllkCalStats->m_ulCurTxFrameCountNmt,
274 pDllkCalStats->m_ulCurRxFrameCount,
275 pDllkCalStats->m_ulMaxTxFrameCountGen,
276 pDllkCalStats->m_ulMaxTxFrameCountNmt,
277 pDllkCalStats->m_ulMaxRxFrameCount);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800278
279#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800280 // fetch running IdentRequests
281 nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
282 "running IdentRequests: 0x%08lX\n",
283 EplIdentuGetRunningRequests());
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800284
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800285 // fetch state of NmtMnu module
286 {
287 unsigned int uiMandatorySlaveCount;
288 unsigned int uiSignalSlaveCount;
289 WORD wFlags;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800290
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800291 EplNmtMnuGetDiagnosticInfo(&uiMandatorySlaveCount,
292 &uiSignalSlaveCount, &wFlags);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800293
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800294 nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
295 "MN MandSlaveCount: %u SigSlaveCount: %u Flags: 0x%X\n",
296 uiMandatorySlaveCount, uiSignalSlaveCount,
297 wFlags);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800298
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800299 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800300#endif
301
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800302 // ---- FEC state ----
303#ifdef CONFIG_COLDFIRE
304 {
305 // Receive the base address
306 unsigned long base_addr;
307#if (EDRV_USED_ETH_CTRL == 0)
308 // Set the base address of FEC0
309 base_addr = FEC_BASE_ADDR_FEC0;
310#else
311 // Set the base address of FEC1
312 base_addr = FEC_BASE_ADDR_FEC1;
313#endif
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800314
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800315 nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
316 "FEC_ECR = 0x%08X FEC_EIR = 0x%08X FEC_EIMR = 0x%08X\nFEC_TCR = 0x%08X FECTFSR = 0x%08X FECRFSR = 0x%08X\n",
317 FEC_ECR(base_addr), FEC_EIR(base_addr),
318 FEC_EIMR(base_addr), FEC_TCR(base_addr),
319 FEC_FECTFSR(base_addr),
320 FEC_FECRFSR(base_addr));
321 }
322#endif
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800323
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800324 // ---- DBG: TracePoints ----
325#ifdef _DBG_TRACE_POINTS_
326 {
327 int nNum;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800328
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800329 nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
330 "DbgTracePoints:\n");
331 for (nNum = 0;
332 nNum < (sizeof(aatmDbgTracePoint_l) / sizeof(atomic_t));
333 nNum++) {
334 nSize +=
335 snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
336 " TracePoint[%2d]: %d\n", (int)nNum,
337 atomic_read(&aatmDbgTracePoint_l[nNum]));
338 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800339
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800340 nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
341 "DbgTraceValues:\n");
342 for (nNum = 0; nNum < DBG_TRACE_VALUES; nNum++) {
343 if (nNum == uiDbgTraceValuePos_l) { // next value will be stored at that position
344 nSize +=
345 snprintf(pcBuffer_p + nSize,
346 nBufferSize_p - nSize, "*%08lX",
347 adwDbgTraceValue_l[nNum]);
348 } else {
349 nSize +=
350 snprintf(pcBuffer_p + nSize,
351 nBufferSize_p - nSize, " %08lX",
352 adwDbgTraceValue_l[nNum]);
353 }
354 if ((nNum & 0x00000007) == 0x00000007) { // 8 values printed -> end of line reached
355 nSize +=
356 snprintf(pcBuffer_p + nSize,
357 nBufferSize_p - nSize, "\n");
358 }
359 }
360 if ((nNum & 0x00000007) != 0x00000007) { // number of values printed is not a multiple of 8 -> print new line
361 nSize +=
362 snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
363 "\n");
364 }
365 }
366#endif
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800367
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800368 Eof = 1;
369 goto Exit;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800370
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800371 Exit:
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800372
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800373 *pEof_p = Eof;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800374
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800375 return (nSize);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800376
377}
378
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800379//---------------------------------------------------------------------------
380// Write function for PROC-FS write access
381//---------------------------------------------------------------------------
382
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800383static int EplLinProcWrite(struct file *file, const char __user * buffer,
384 unsigned long count, void *data)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800385{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800386 char abBuffer[count + 1];
387 int iErr;
388 int iVal = 0;
389 tEplNmtEvent NmtEvent;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800390
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800391 if (count > 0) {
392 iErr = copy_from_user(abBuffer, buffer, count);
393 if (iErr != 0) {
394 return count;
395 }
396 abBuffer[count] = '\0';
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800397
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800398 iErr = sscanf(abBuffer, "%i", &iVal);
399 }
400 if ((iVal <= 0) || (iVal > 0x2F)) {
401 NmtEvent = kEplNmtEventSwReset;
402 } else {
403 NmtEvent = (tEplNmtEvent) iVal;
404 }
405 // execute specified NMT command on write access of /proc/epl
406 EplNmtuNmtEvent(NmtEvent);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800407
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800408 return count;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800409}